split to two class they are RenderL2WBuffer and RenderMIBuffer from RenderAssignBuffer, two sample program RUN OK!

This commit is contained in:
hyzboy 2024-03-26 01:51:59 +08:00
parent 0639440a13
commit 0f38f94139
4 changed files with 164 additions and 115 deletions

View File

@ -3,7 +3,8 @@
#include<hgl/graph/VKVBOList.h>
VK_NAMESPACE_BEGIN
class RenderAssignBuffer;
class RenderL2WBuffer;
class RenderMIBuffer;
/**
*
@ -19,7 +20,8 @@ class MaterialRenderList
private:
RenderAssignBuffer *assign_buffer;
RenderL2WBuffer *l2w_buffer;
RenderMIBuffer *mi_buffer;
struct RenderItem
{
@ -39,8 +41,6 @@ private:
DataArray<RenderItem> ri_array;
uint ri_count;
bool has_l2w;
bool has_mi;
VkDeviceSize l2w_buffer_size[4];
void StatMI();

View File

@ -53,13 +53,15 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
cmd_buf=nullptr;
material=m;
has_l2w=l2w;
has_mi=material->HasMI();
if(has_l2w||has_mi)
assign_buffer=new RenderAssignBuffer(d,has_l2w,material->GetMIDataBytes());
if(l2w)
l2w_buffer=new RenderL2WBuffer(device);
else
assign_buffer=nullptr;
l2w_buffer=nullptr;
if(material->HasMI())
mi_buffer=new RenderMIBuffer(device,material->GetMIDataBytes());
else
mi_buffer=nullptr;
vbo_list=new VBOList(material->GetVertexInput()->GetCount());
}
@ -67,7 +69,8 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
MaterialRenderList::~MaterialRenderList()
{
SAFE_CLEAR(vbo_list);
SAFE_CLEAR(assign_buffer)
SAFE_CLEAR(mi_buffer);
SAFE_CLEAR(l2w_buffer);
}
void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat)
@ -91,13 +94,15 @@ void MaterialRenderList::End()
Stat();
if(assign_buffer)
if(l2w_buffer)
{
if(has_mi)
StatMI();
l2w_buffer->WriteNode(rn_list.GetData(),node_count);
}
//写入LocalToWorld数据
assign_buffer->WriteNode(rn_list.GetData(),node_count,mi_set);
if(mi_buffer)
{
StatMI();
mi_buffer->WriteNode(rn_list.GetData(),node_count,mi_set);
}
}
@ -182,16 +187,16 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
vbo_list->Add(vid->buffer_list,vid->buffer_offset,vid->binding_count);
}
if(has_l2w)//LocalToWorld组由RenderList合成
if(l2w_buffer)//LocalToWorld组由RenderList合成
{
for(uint i=0;i<4;i++)
l2w_buffer_size[i]=ri_index*16; //mat4每列都是rgba32f自然是16字节
vbo_list->Add(assign_buffer->GetLocalToWorldVBO(),l2w_buffer_size,4);
vbo_list->Add(l2w_buffer->GetVBO(),l2w_buffer_size,4);
}
if(has_mi) //材质实例组
vbo_list->Add(assign_buffer->GetMIVBO(),MI_VBO_STRIDE_BYTES*ri_index);
if(mi_buffer) //材质实例组
vbo_list->Add(mi_buffer->GetVBO(),MI_VBO_STRIDE_BYTES*ri_index);
//if(!vbo_list.IsFull()) //Joint组暂未支持
//{
@ -281,8 +286,8 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb)
last_pipeline =nullptr;
last_vid =nullptr;
if(assign_buffer)
assign_buffer->Bind(material);
if(mi_buffer)
mi_buffer->Bind(material);
cmd_buf->BindDescriptorSets(material);

View File

@ -8,37 +8,21 @@
#include<hgl/graph/mtl/UBOCommon.h>
VK_NAMESPACE_BEGIN
RenderAssignBuffer::RenderAssignBuffer(GPUDevice *dev,const bool has_l2w,const uint mi_bytes)
RenderL2WBuffer::RenderL2WBuffer(GPUDevice *dev)
{
hgl_zero(*this);
device=dev;
mi_data_bytes=mi_bytes;
}
void RenderAssignBuffer::Bind(Material *mtl)const
void RenderL2WBuffer::Clear()
{
if(!mtl)return;
if(!mtl->HasMI())
return;
mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,ubo_mi);
}
void RenderAssignBuffer::Clear()
{
SAFE_CLEAR(ubo_mi);
SAFE_CLEAR(vbo_mi);
SAFE_CLEAR(l2w_vbo[0])
SAFE_CLEAR(l2w_vbo[1])
SAFE_CLEAR(l2w_vbo[2])
SAFE_CLEAR(l2w_vbo[3])
node_count=0;
mi_count=0;
}
#ifdef _DEBUG
@ -62,7 +46,7 @@ namespace
}
#endif//_DEBUG
void RenderAssignBuffer::Alloc(const uint nc,const uint mc)
void RenderL2WBuffer::Alloc(const uint nc)
{
Clear();
@ -76,6 +60,78 @@ void RenderAssignBuffer::Alloc(const uint nc,const uint mc)
}
}
#ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils();
if(du)
{
for(int i=0;i<4;i++)
{
du->SetBuffer(l2w_buffer[i],l2w_buffer_name[i]);
du->SetDeviceMemory(l2w_vbo[i]->GetVkMemory(),l2w_memory_name[i]);
}
}
#endif//_DEBUG
}
void RenderL2WBuffer::WriteNode(RenderNode *render_node,const uint count)
{
RenderNode *rn;
Alloc(count);
glm::vec4 *tp;
for(uint col=0;col<4;col++)
{
tp=(glm::vec4 *)(l2w_vbo[col]->Map());
rn=render_node;
for(uint i=0;i<count;i++)
{
*tp=rn->local_to_world[col];
++tp;
++rn;
}
l2w_vbo[col]->Unmap();
}
}
VK_NAMESPACE_END
VK_NAMESPACE_BEGIN
RenderMIBuffer::RenderMIBuffer(GPUDevice *dev,const uint mi_bytes)
{
hgl_zero(*this);
device=dev;
mi_data_bytes=mi_bytes;
}
void RenderMIBuffer::Bind(Material *mtl)const
{
if(!mtl)return;
mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,ubo_mi);
}
void RenderMIBuffer::Clear()
{
SAFE_CLEAR(ubo_mi);
SAFE_CLEAR(vbo_mi);
mi_count=0;
node_count=0;
}
void RenderMIBuffer::Alloc(const uint nc,const uint mc)
{
Clear();
node_count=nc;
if(mi_data_bytes>0&&mc>0)
{
mi_count=mc;
@ -91,84 +147,45 @@ void RenderAssignBuffer::Alloc(const uint nc,const uint mc)
if(du)
{
if(l2w_buffer[0])
{
for(int i=0;i<4;i++)
{
du->SetBuffer(l2w_buffer[i],l2w_buffer_name[i]);
du->SetDeviceMemory(l2w_vbo[i]->GetVkMemory(),l2w_memory_name[i]);
}
}
du->SetBuffer(ubo_mi->GetBuffer(),"UBO:Buffer:MaterialInstance");
du->SetDeviceMemory(ubo_mi->GetVkMemory(),"UBO:Memory:MaterialInstance");
if(ubo_mi)
{
du->SetBuffer(ubo_mi->GetBuffer(),"UBO:Buffer:MaterialInstance");
du->SetDeviceMemory(ubo_mi->GetVkMemory(),"UBO:Memory:MaterialInstance");
}
if(vbo_mi)
{
du->SetBuffer(vbo_mi->GetBuffer(),"VBO:Buffer:MaterialInstanceID");
du->SetDeviceMemory(vbo_mi->GetVkMemory(),"VBO:Memory:MaterialInstanceID");
}
du->SetBuffer(vbo_mi->GetBuffer(),"VBO:Buffer:MaterialInstanceID");
du->SetDeviceMemory(vbo_mi->GetVkMemory(),"VBO:Memory:MaterialInstanceID");
}
#endif//_DEBUG
}
void RenderAssignBuffer::WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
void RenderMIBuffer::WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
{
RenderNode *rn;
Alloc(count,mi_set.GetCount());
if(l2w_buffer[0])
uint8 *mip=(uint8 *)(ubo_mi->Map());
for(MaterialInstance *mi:mi_set)
{
glm::vec4 *tp;
memcpy(mip,mi->GetMIData(),mi_data_bytes);
mip+=mi_data_bytes;
}
for(uint col=0;col<4;col++)
ubo_mi->Unmap();
uint16 *idp=(uint16 *)(vbo_mi->Map());
{
rn=render_node;
for(uint i=0;i<count;i++)
{
tp=(glm::vec4 *)(l2w_vbo[col]->Map());
*idp=mi_set.Find(rn->ri->GetMaterialInstance());
++idp;
rn=render_node;
for(uint i=0;i<count;i++)
{
*tp=rn->local_to_world[col];
++tp;
++rn;
}
l2w_vbo[col]->Unmap();
++rn;
}
}
if(ubo_mi)
{
uint8 *mip=(uint8 *)(ubo_mi->Map());
for(MaterialInstance *mi:mi_set)
{
memcpy(mip,mi->GetMIData(),mi_data_bytes);
mip+=mi_data_bytes;
}
ubo_mi->Unmap();
uint16 *idp=(uint16 *)(vbo_mi->Map());
{
rn=render_node;
for(uint i=0;i<count;i++)
{
*idp=mi_set.Find(rn->ri->GetMaterialInstance());
++idp;
++rn;
}
}
vbo_mi->Unmap();
}
vbo_mi->Unmap();
}
VK_NAMESPACE_END

View File

@ -25,13 +25,8 @@ VK_NAMESPACE_BEGIN
struct RenderNode;
class MaterialInstance;
/*
*
*/
class RenderAssignBuffer
class RenderL2WBuffer
{
private:
GPUDevice *device;
uint node_count; ///<渲染节点数量
@ -39,6 +34,35 @@ private:
VBO *l2w_vbo[4];
VkBuffer l2w_buffer[4];
private:
void Alloc(const uint nc);
void Clear();
public:
const VkBuffer *GetVBO()const{return l2w_buffer;}
public:
RenderL2WBuffer(GPUDevice *dev);
~RenderL2WBuffer(){Clear();}
void WriteNode(RenderNode *render_node,const uint count);
};//class RenderL2WBuffer
/*
*
*/
class RenderMIBuffer
{
private:
GPUDevice *device;
uint node_count; ///<渲染节点数量
uint32_t mi_data_bytes; ///<材质实例数据字节数
uint32_t mi_count; ///<材质实例数量
DeviceBuffer *ubo_mi; ///<材质实例数据
@ -54,17 +78,20 @@ private:
public:
const VkBuffer *GetLocalToWorldVBO()const{return l2w_buffer;}
const VkBuffer GetMIVBO ()const{return mi_buffer;}
const VkBuffer GetVBO()const{return mi_buffer;}
void Bind(Material *)const;
public:
RenderAssignBuffer(GPUDevice *dev,const bool has_l2w,const uint32_t mi_bytes);
~RenderAssignBuffer(){Clear();}
RenderMIBuffer(GPUDevice *dev,const uint32_t mi_bytes);
~RenderMIBuffer(){Clear();}
void WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set);
//下一代将MaterialInstanceSets使用提前化这样不用每一次绘制都重新写入MI DATA可以提升效率。
//虽然这样就不自动化了,但我们要的就是不自动化。
//必须在外部全部准备好MaterialInstanceSets然后一次性写入。
//渲染时找不到就直接用0号材质实例
};//struct RenderAssignBuffer
void WriteNode(RenderNode *render_node,const uint nc,const MaterialInstanceSets &mi_set);
};//struct RenderMIBuffer
VK_NAMESPACE_END