finished to stat about IndirectDraw data in MaterialRenderList
This commit is contained in:
parent
ac0d1bee59
commit
6ce713aed5
@ -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;
|
||||||
|
@ -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));}
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
* for(pipeline)
|
* for(pipeline)
|
||||||
* for(material_instance)
|
* for(material_instance)
|
||||||
* for(vab)
|
* for(vab)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 关于Indirect Command Buffer
|
||||||
|
|
||||||
|
建立一个大的IndirectCommandBuffer,用于存放所有的渲染指令,包括那些不能使用Indirect渲染的。
|
||||||
|
这样就可以保证所有的渲染操作就算要切VBO,也不需要切换INDIRECT缓冲区,定位指令也很方便。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user