diff --git a/inc/hgl/graph/MaterialRenderList.h b/inc/hgl/graph/MaterialRenderList.h index 8ae398fd..c86218de 100644 --- a/inc/hgl/graph/MaterialRenderList.h +++ b/inc/hgl/graph/MaterialRenderList.h @@ -25,7 +25,7 @@ private: struct RenderItem { - uint32_t first_instance; ///<绘制实例(和instance渲染无关,对应InstanceRate更新的VAB) + uint32_t first_instance; ///<第一个绘制实例(和instance渲染无关,对应InstanceRate的VAB) uint32_t instance_count; Pipeline * pipeline; @@ -43,6 +43,8 @@ private: IndirectDrawIndexedBuffer *icb_draw_indexed; void ReallocICB(); + void WriteICB(VkDrawIndirectCommand *,RenderItem *ri); + void WriteICB(VkDrawIndexedIndirectCommand *,RenderItem *ri); DataArray ri_array; uint ri_count; @@ -58,8 +60,12 @@ protected: const VDM * last_vdm; const PrimitiveRenderData * last_render_data; + int first_indirect_draw_index=-1; + uint indirect_draw_count=0; + bool BindVAB(const PrimitiveDataBuffer *,const uint); + void ProcIndirectRender(); void Render(RenderItem *); public: diff --git a/inc/hgl/graph/VKIndirectCommandBuffer.h b/inc/hgl/graph/VKIndirectCommandBuffer.h index d0b401ea..6d5f107d 100644 --- a/inc/hgl/graph/VKIndirectCommandBuffer.h +++ b/inc/hgl/graph/VKIndirectCommandBuffer.h @@ -52,9 +52,13 @@ public: using IndirectCommandBuffer::IndirectCommandBuffer; - void Draw(VkCommandBuffer cmd_buf,uint32_t offset,uint32_t draw_count,uint32_t stride) const + void Draw(VkCommandBuffer cmd_buf,uint32_t cmd_offset,uint32_t draw_count) const { - vkCmdDrawIndirect(cmd_buf,buf.buffer,offset,draw_count,stride); + vkCmdDrawIndirect(cmd_buf, + buf.buffer, + cmd_offset*sizeof(VkDrawIndirectCommand), + draw_count, + sizeof(VkDrawIndirectCommand)); } };//class IndirectDrawBuffer:public IndirectCommandBuffer @@ -66,9 +70,13 @@ public: using IndirectCommandBuffer::IndirectCommandBuffer; - void DrawIndexed(VkCommandBuffer cmd_buf,uint32_t offset,uint32_t draw_count,uint32_t stride) const + void DrawIndexed(VkCommandBuffer cmd_buf,uint32_t cmd_offset,uint32_t draw_count) const { - vkCmdDrawIndexedIndirect(cmd_buf,buf.buffer,offset,draw_count,stride); + vkCmdDrawIndexedIndirect(cmd_buf, + buf.buffer, + cmd_offset*sizeof(VkDrawIndexedIndirectCommand), + draw_count, + sizeof(VkDrawIndexedIndirectCommand)); } };//class IndirectDrawIndexedBuffer:public IndirectCommandBuffer diff --git a/src/SceneGraph/MaterialRenderList.cpp b/src/SceneGraph/MaterialRenderList.cpp index c29bf984..c00e8a01 100644 --- a/src/SceneGraph/MaterialRenderList.cpp +++ b/src/SceneGraph/MaterialRenderList.cpp @@ -146,6 +146,22 @@ void MaterialRenderList::ReallocICB() icb_draw_indexed=device->CreateIndirectDrawIndexedBuffer(icb_new_count); } +void MaterialRenderList::WriteICB(VkDrawIndirectCommand *dicp,RenderItem *ri) +{ + dicp->vertexCount =ri->prd->vertex_count; + dicp->instanceCount =ri->instance_count; + dicp->firstVertex =ri->prd->vertex_offset; + dicp->firstInstance =ri->first_instance; +} +void MaterialRenderList::WriteICB(VkDrawIndexedIndirectCommand *diicp,RenderItem *ri) +{ + diicp->indexCount =ri->prd->index_count; + diicp->instanceCount=ri->instance_count; + diicp->firstIndex =ri->prd->first_index; + diicp->vertexOffset =ri->prd->vertex_offset; + diicp->firstInstance=ri->first_instance; +} + void MaterialRenderList::Stat() { const uint count=rn_list.GetCount(); @@ -188,20 +204,9 @@ void MaterialRenderList::Stat() if(ri->pdb->vdm) { if(ri->pdb->ibo) - { - diicp->indexCount =ri->prd->index_count; - diicp->instanceCount=ri->instance_count; - diicp->firstIndex =ri->prd->first_index; - diicp->vertexOffset =ri->prd->vertex_offset; - diicp->firstInstance=ri->first_instance; - } + WriteICB(diicp,ri); else - { - dicp->vertexCount =ri->prd->vertex_count; - dicp->instanceCount =ri->instance_count; - dicp->firstVertex =ri->prd->vertex_offset; - dicp->firstInstance =ri->first_instance; - } + WriteICB(dicp,ri); ++dicp; ++diicp; @@ -222,6 +227,14 @@ void MaterialRenderList::Stat() ++rn; } + if(ri->pdb->vdm) + { + if(ri->pdb->ibo) + WriteICB(diicp,ri); + else + WriteICB(dicp,ri); + } + icb_draw->Unmap(); icb_draw_indexed->Unmap(); } @@ -287,6 +300,17 @@ bool MaterialRenderList::BindVAB(const PrimitiveDataBuffer *pdb,const uint ri_in return(true); } +void MaterialRenderList::ProcIndirectRender() +{ + if(last_data_buffer->ibo) + icb_draw_indexed->DrawIndexed(*cmd_buf,first_indirect_draw_index,indirect_draw_count); + else + icb_draw->Draw(*cmd_buf,first_indirect_draw_index,indirect_draw_count); + + first_indirect_draw_index=-1; + indirect_draw_count=0; +} + void MaterialRenderList::Render(RenderItem *ri) { if(last_pipeline!=ri->pipeline) @@ -299,8 +323,11 @@ void MaterialRenderList::Render(RenderItem *ri) //这里未来尝试换pipeline同时不换mi/primitive是否需要重新绑定mi/primitive } - if(!ri->pdb->Comp(last_data_buffer)) + if(!ri->pdb->Comp(last_data_buffer)) //换buf了 { + if(indirect_draw_count) //如果有间接绘制的数据,赶紧给画了 + ProcIndirectRender(); + last_data_buffer=ri->pdb; last_render_data=nullptr; @@ -310,7 +337,17 @@ void MaterialRenderList::Render(RenderItem *ri) cmd_buf->BindIBO(ri->pdb->ibo); } - cmd_buf->Draw(ri->pdb,ri->prd,ri->instance_count,ri->first_instance); + //if(device-> support indirect) + { + if(indirect_draw_count==0) + first_indirect_draw_index=ri->first_instance; + + ++indirect_draw_count; + } + //else + //{ + // cmd_buf->Draw(ri->pdb,ri->prd,ri->instance_count,ri->first_instance); + //} } void MaterialRenderList::Render(RenderCmdBuffer *rcb) @@ -340,5 +377,8 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb) Render(ri); ++ri; } + + if(indirect_draw_count) //如果有间接绘制的数据,赶紧给画了 + ProcIndirectRender(); } VK_NAMESPACE_END