ULRE/src/SceneGraph/Vulkan/VKCommandBufferRender.cpp
hyzboy 4b2f344c5c renamed to MeshDataBuffer from PrimitiveDataBuffer,
renamed to MeshRenderData from PrimitiveRenderData
2025-05-18 02:07:10 +08:00

218 lines
6.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VKRenderPass.h>
#include<hgl/graph/VKFramebuffer.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKDeviceAttribute.h>
#include<hgl/graph/VKPhysicalDevice.h>
#include<hgl/graph/VKIndexBuffer.h>
#include<hgl/graph/VKRenderTarget.h>
VK_NAMESPACE_BEGIN
RenderCmdBuffer::RenderCmdBuffer(const VulkanDevAttr *attr,VkCommandBuffer cb):VulkanCmdBuffer(attr,cb)
{
cv_count=0;
clear_values=nullptr;
hgl_zero(render_area);
hgl_zero(viewport);
pipeline_layout=VK_NULL_HANDLE;
}
RenderCmdBuffer::~RenderCmdBuffer()
{
if(clear_values)
hgl_free(clear_values);
}
void RenderCmdBuffer::SetClear()
{
if(cv_count>0)
{
clear_values=hgl_align_realloc<VkClearValue>(clear_values,cv_count);
clear_values[cv_count-1].depthStencil.depth = 1.0f;
clear_values[cv_count-1].depthStencil.stencil = 0;
}
else if(clear_values)
{
hgl_free(clear_values);
clear_values=nullptr;
}
}
void RenderCmdBuffer::SetRenderArea(const VkExtent2D &ext2d)
{
render_area.offset.x=0;
render_area.offset.y=0;
render_area.extent=ext2d;
}
bool RenderCmdBuffer::BindFramebuffer(Framebuffer *fbo)
{
if(!fbo)return(false);
cv_count=fbo->GetAttachmentCount();
SetClear();
render_area.offset.x=0;
render_area.offset.y=0;
render_area.extent=fbo->GetExtent();
rp_begin.renderPass = *fbo->GetRenderPass();
rp_begin.framebuffer = *fbo;
rp_begin.renderArea = render_area;
rp_begin.clearValueCount = cv_count;
rp_begin.pClearValues = clear_values;
viewport.x = 0;
viewport.y = 0;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
viewport.width = render_area.extent.width;
viewport.height = render_area.extent.height;
return(true);
};
bool RenderCmdBuffer::BeginRenderPass()
{
vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
vkCmdSetViewport(cmd_buf,0,1,&viewport);
vkCmdSetScissor(cmd_buf,0,1,&render_area);
pipeline_layout=VK_NULL_HANDLE;
return(true);
}
bool RenderCmdBuffer::BindDescriptorSets(Material *mtl)
{
if(!mtl)return(false);
if(desc_binding)
desc_binding->Bind(mtl);
{
uint32_t count=0;
MaterialParameters *mp;
VkDescriptorSet ds[DESCRIPTOR_SET_TYPE_COUNT];
ENUM_CLASS_FOR(DescriptorSetType,int,i)
{
mp=mtl->GetMP((DescriptorSetType)i);
if(mp)
{
mp->Update();
ds[count]=mp->GetVkDescriptorSet();
++count;
}
}
if(count>0)
{
pipeline_layout=mtl->GetPipelineLayout();
vkCmdBindDescriptorSets(cmd_buf,VK_PIPELINE_BIND_POINT_GRAPHICS,pipeline_layout,0,count,ds,0,0);
}
}
return(true);
}
void RenderCmdBuffer::BindIBO(IndexBuffer *ibo,const VkDeviceSize byte_offset)
{
if(!ibo)return;
vkCmdBindIndexBuffer(cmd_buf,
ibo->GetBuffer(),
byte_offset,
VkIndexType(ibo->GetType()));
}
bool RenderCmdBuffer::BindDataBuffer(const MeshDataBuffer *pdb)
{
if(!pdb)
return(false);
if(pdb->vab_count<=0)
return(false);
vkCmdBindVertexBuffers(cmd_buf,
0, //first binding
pdb->vab_count,
pdb->vab_list,
pdb->vab_offset); //vab byte offsets
if(pdb->ibo)
BindIBO(pdb->ibo);
return(true);
}
void RenderCmdBuffer::DrawIndirect( VkBuffer buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
if(this->dev_attr->physical_device->SupportMDI())
vkCmdDrawIndirect(cmd_buf,buffer,offset,drawCount,stride);
else
for(uint32_t i=0;i<drawCount;i++)
vkCmdDrawIndirect(cmd_buf,buffer,offset+i*stride,1,stride);
}
void RenderCmdBuffer::DrawIndexedIndirect( VkBuffer buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
if(this->dev_attr->physical_device->SupportMDI())
vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset,drawCount,stride);
else
for(uint32_t i=0;i<drawCount;i++)
vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset+i*stride,1,stride);
}
void RenderCmdBuffer::Draw(const MeshDataBuffer *pdb,const MeshRenderData *prd,const uint32_t instance_count,const uint32_t first_instance)
{
if(!pdb||!prd)
return;
if (pdb->ibo)
vkCmdDrawIndexed( cmd_buf,
prd->index_count,
instance_count,
prd->first_index,
prd->vertex_offset, //这里的vertexOffset是针对所有VAB的
first_instance); //这里的first_instance针对的是instance Rate更新的VAB的起始实例数不是指instance批量渲染
else
vkCmdDraw( cmd_buf,
prd->vertex_count,
instance_count,
prd->vertex_offset,
first_instance);
}
//void RenderCmdBuffer::DrawIndexed(const IBAccess *iba,const uint32_t instance_count)
//{
// if(!iba||instance_count<=0)return;
//
// vkCmdBindIndexBuffer(cmd_buf,
// iba->buffer->GetBuffer(),
// iba->start*iba->buffer->GetStride(),
// VkIndexType(iba->buffer->GetType()));
//
// vkCmdDrawIndexed(cmd_buf,
// iba->count,
// instance_count,
// 0, //first index
// 0, //vertex offset
// 0); //first instance
//}
VK_NAMESPACE_END