finished to stat about IndirectDraw data in MaterialRenderList

This commit is contained in:
hyzboy 2024-05-30 13:14:13 +08:00
parent ac0d1bee59
commit 6ce713aed5
4 changed files with 71 additions and 26 deletions

View File

@ -2,6 +2,7 @@
#include<hgl/graph/RenderNode.h> #include<hgl/graph/RenderNode.h>
#include<hgl/graph/VKVABList.h> #include<hgl/graph/VKVABList.h>
#include<hgl/type/SortedSets.h> #include<hgl/type/SortedSets.h>
#include<hgl/graph/VKIndirectCommandBuffer.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class RenderAssignBuffer; class RenderAssignBuffer;
@ -24,7 +25,7 @@ private:
struct RenderItem struct RenderItem
{ {
uint32_t first; uint32_t first_instance; ///<绘制实例(和instance渲染无关,对应InstanceRate更新的VAB)
uint32_t instance_count; uint32_t instance_count;
Pipeline * pipeline; Pipeline * pipeline;
@ -38,7 +39,10 @@ private:
void Set(Renderable *); void Set(Renderable *);
}; };
SortedSets<const VDM *> vdm_set; IndirectDrawBuffer *icb_draw;
IndirectDrawIndexedBuffer *icb_draw_indexed;
void ReallocICB();
DataArray<RenderItem> ri_array; DataArray<RenderItem> ri_array;
uint ri_count; uint ri_count;

View File

@ -30,9 +30,9 @@ public:
virtual ~IndirectCommandBuffer()=default; virtual ~IndirectCommandBuffer()=default;
T * MapCmd () {return (T *)Map();}
void * Map (VkDeviceSize start,VkDeviceSize size) override{return DeviceBuffer::Map(start*sizeof(T),size*sizeof(T));} void * Map (VkDeviceSize start,VkDeviceSize size) override{return DeviceBuffer::Map(start*sizeof(T),size*sizeof(T));}
T * MapCmd (VkDeviceSize start,VkDeviceSize size) {return (T *)Map(start,size);} T * MapCmd (VkDeviceSize start,VkDeviceSize size) {return (T *)Map(start,size);}
T * MapCmd () {return (T *)Map(0,max_count);}
void Flush (VkDeviceSize start,VkDeviceSize size) override{return DeviceBuffer::Flush(start*sizeof(T),size*sizeof(T));} void Flush (VkDeviceSize start,VkDeviceSize size) override{return DeviceBuffer::Flush(start*sizeof(T),size*sizeof(T));}
void Flush (VkDeviceSize size) override{return DeviceBuffer::Flush(size*sizeof(T));} void Flush (VkDeviceSize size) override{return DeviceBuffer::Flush(size*sizeof(T));}

View File

@ -16,6 +16,12 @@
* for(pipeline) * for(pipeline)
* for(material_instance) * for(material_instance)
* for(vab) * for(vab)
*
*
* Indirect Command Buffer
IndirectCommandBuffer使Indirect渲染的
VBOINDIRECT缓冲区便
*/ */
template<> template<>
@ -73,10 +79,16 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
assign_buffer=new RenderAssignBuffer(device,material); assign_buffer=new RenderAssignBuffer(device,material);
vab_list=new VABList(material->GetVertexInput()->GetCount()); vab_list=new VABList(material->GetVertexInput()->GetCount());
icb_draw=nullptr;
icb_draw_indexed=nullptr;
} }
MaterialRenderList::~MaterialRenderList() MaterialRenderList::~MaterialRenderList()
{ {
SAFE_CLEAR(icb_draw_indexed)
SAFE_CLEAR(icb_draw)
SAFE_CLEAR(vab_list); SAFE_CLEAR(vab_list);
SAFE_CLEAR(assign_buffer); SAFE_CLEAR(assign_buffer);
} }
@ -114,11 +126,36 @@ void MaterialRenderList::RenderItem::Set(Renderable *ri)
prd =ri->GetRenderData(); prd =ri->GetRenderData();
} }
void MaterialRenderList::ReallocICB()
{
const uint32_t icb_new_count=power_to_2(rn_list.GetCount());
if(icb_draw)
{
if(icb_new_count<=icb_draw->GetMaxCount())
return;
delete icb_draw;
icb_draw=nullptr;
delete icb_draw_indexed;
icb_draw_indexed=nullptr;
}
icb_draw=device->CreateIndirectDrawBuffer(icb_new_count);
icb_draw_indexed=device->CreateIndirectDrawIndexedBuffer(icb_new_count);
}
void MaterialRenderList::Stat() void MaterialRenderList::Stat()
{ {
const uint count=rn_list.GetCount(); const uint count=rn_list.GetCount();
RenderNode *rn=rn_list.GetData(); RenderNode *rn=rn_list.GetData();
ReallocICB();
VkDrawIndirectCommand *dicp=icb_draw->MapCmd();
VkDrawIndexedIndirectCommand *diicp=icb_draw_indexed->MapCmd();
ri_array.Clear(); ri_array.Clear();
ri_array.Alloc(count); ri_array.Alloc(count);
@ -126,7 +163,7 @@ void MaterialRenderList::Stat()
ri_count=1; ri_count=1;
ri->first=0; ri->first_instance=0;
ri->instance_count=1; ri->instance_count=1;
ri->Set(rn->ri); ri->Set(rn->ri);
@ -135,26 +172,11 @@ void MaterialRenderList::Stat()
last_vdm =ri->pdb->vdm; last_vdm =ri->pdb->vdm;
last_render_data=ri->prd; last_render_data=ri->prd;
if(last_vdm)
vdm_set.Add(last_vdm);
++rn; ++rn;
for(uint i=1;i<count;i++) for(uint i=1;i<count;i++)
{ {
if(last_pipeline==rn->ri->GetPipeline()) if(last_pipeline==rn->ri->GetPipeline())
{
if(last_data_buffer->vdm&&last_data_buffer->vdm==rn->ri->GetDataBuffer()->vdm)
{
if(last_render_data->_Comp(rn->ri->GetRenderData())==0)
{
++ri->instance_count;
++rn;
continue;
}
}
else
{
if(last_data_buffer->Comp(rn->ri->GetDataBuffer())) if(last_data_buffer->Comp(rn->ri->GetDataBuffer()))
if(last_render_data->_Comp(rn->ri->GetRenderData())==0) if(last_render_data->_Comp(rn->ri->GetRenderData())==0)
{ {
@ -162,13 +184,33 @@ void MaterialRenderList::Stat()
++rn; ++rn;
continue; continue;
} }
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;
} }
else
{
dicp->vertexCount =ri->prd->vertex_count;
dicp->instanceCount =ri->instance_count;
dicp->firstVertex =ri->prd->vertex_offset;
dicp->firstInstance =ri->first_instance;
}
++dicp;
++diicp;
} }
++ri_count; ++ri_count;
++ri; ++ri;
ri->first=i; ri->first_instance=i;
ri->instance_count=1; ri->instance_count=1;
ri->Set(rn->ri); ri->Set(rn->ri);
@ -177,12 +219,11 @@ void MaterialRenderList::Stat()
last_vdm =ri->pdb->vdm; last_vdm =ri->pdb->vdm;
last_render_data=ri->prd; last_render_data=ri->prd;
if(last_vdm)
vdm_set.Add(last_vdm);
++rn; ++rn;
} }
icb_draw->Unmap();
icb_draw_indexed->Unmap();
} }
bool MaterialRenderList::BindVAB(const PrimitiveDataBuffer *pdb,const uint ri_index) bool MaterialRenderList::BindVAB(const PrimitiveDataBuffer *pdb,const uint ri_index)
@ -263,13 +304,13 @@ void MaterialRenderList::Render(RenderItem *ri)
last_data_buffer=ri->pdb; last_data_buffer=ri->pdb;
last_render_data=nullptr; last_render_data=nullptr;
BindVAB(ri->pdb,ri->first); BindVAB(ri->pdb,ri->first_instance);
if(ri->pdb->ibo) if(ri->pdb->ibo)
cmd_buf->BindIBO(ri->pdb->ibo); cmd_buf->BindIBO(ri->pdb->ibo);
} }
cmd_buf->Draw(ri->pdb,ri->prd,ri->instance_count,ri->first); cmd_buf->Draw(ri->pdb,ri->prd,ri->instance_count,ri->first_instance);
} }
void MaterialRenderList::Render(RenderCmdBuffer *rcb) void MaterialRenderList::Render(RenderCmdBuffer *rcb)

View File

@ -184,12 +184,12 @@ void RenderCmdBuffer::DrawIndexedIndirect( VkBuffer buffer,
vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset+i*stride,1,stride); vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset+i*stride,1,stride);
} }
void RenderCmdBuffer::Draw(const PrimitiveDataBuffer *prb,const PrimitiveRenderData *prd,const uint32_t instance_count,const uint32_t first_instance) void RenderCmdBuffer::Draw(const PrimitiveDataBuffer *pdb,const PrimitiveRenderData *prd,const uint32_t instance_count,const uint32_t first_instance)
{ {
if(!prb||!prd) if(!pdb||!prd)
return; return;
if (prb->ibo) if (pdb->ibo)
vkCmdDrawIndexed( cmd_buf, vkCmdDrawIndexed( cmd_buf,
prd->index_count, prd->index_count,
instance_count, instance_count,