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

View File

@ -30,9 +30,9 @@ public:
virtual ~IndirectCommandBuffer()=default;
T * MapCmd () {return (T *)Map();}
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 () {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 size) override{return DeviceBuffer::Flush(size*sizeof(T));}

View File

@ -16,6 +16,12 @@
* for(pipeline)
* for(material_instance)
* for(vab)
*
*
* Indirect Command Buffer
IndirectCommandBuffer使Indirect渲染的
VBOINDIRECT缓冲区便
*/
template<>
@ -73,10 +79,16 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
assign_buffer=new RenderAssignBuffer(device,material);
vab_list=new VABList(material->GetVertexInput()->GetCount());
icb_draw=nullptr;
icb_draw_indexed=nullptr;
}
MaterialRenderList::~MaterialRenderList()
{
SAFE_CLEAR(icb_draw_indexed)
SAFE_CLEAR(icb_draw)
SAFE_CLEAR(vab_list);
SAFE_CLEAR(assign_buffer);
}
@ -114,11 +126,36 @@ void MaterialRenderList::RenderItem::Set(Renderable *ri)
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()
{
const uint count=rn_list.GetCount();
RenderNode *rn=rn_list.GetData();
ReallocICB();
VkDrawIndirectCommand *dicp=icb_draw->MapCmd();
VkDrawIndexedIndirectCommand *diicp=icb_draw_indexed->MapCmd();
ri_array.Clear();
ri_array.Alloc(count);
@ -126,7 +163,7 @@ void MaterialRenderList::Stat()
ri_count=1;
ri->first=0;
ri->first_instance=0;
ri->instance_count=1;
ri->Set(rn->ri);
@ -135,40 +172,45 @@ void MaterialRenderList::Stat()
last_vdm =ri->pdb->vdm;
last_render_data=ri->prd;
if(last_vdm)
vdm_set.Add(last_vdm);
++rn;
for(uint i=1;i<count;i++)
{
if(last_pipeline==rn->ri->GetPipeline())
{
if(last_data_buffer->vdm&&last_data_buffer->vdm==rn->ri->GetDataBuffer()->vdm)
{
if(last_data_buffer->Comp(rn->ri->GetDataBuffer()))
if(last_render_data->_Comp(rn->ri->GetRenderData())==0)
{
++ri->instance_count;
++rn;
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
{
if(last_data_buffer->Comp(rn->ri->GetDataBuffer()))
if(last_render_data->_Comp(rn->ri->GetRenderData())==0)
{
++ri->instance_count;
++rn;
continue;
}
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;
ri->first=i;
ri->first_instance=i;
ri->instance_count=1;
ri->Set(rn->ri);
@ -177,12 +219,11 @@ void MaterialRenderList::Stat()
last_vdm =ri->pdb->vdm;
last_render_data=ri->prd;
if(last_vdm)
vdm_set.Add(last_vdm);
++rn;
}
icb_draw->Unmap();
icb_draw_indexed->Unmap();
}
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_render_data=nullptr;
BindVAB(ri->pdb,ri->first);
BindVAB(ri->pdb,ri->first_instance);
if(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)

View File

@ -184,12 +184,12 @@ void RenderCmdBuffer::DrawIndexedIndirect( VkBuffer buffer,
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;
if (prb->ibo)
if (pdb->ibo)
vkCmdDrawIndexed( cmd_buf,
prd->index_count,
instance_count,