added WriteMaterialInstance in RenderExtraBuffer

This commit is contained in:
HuYingzhuo(hugo/hyzboy) 2023-06-01 21:25:50 +08:00
parent e076b72f1a
commit f8fe0e46d6
4 changed files with 90 additions and 34 deletions

View File

@ -2,7 +2,7 @@
#include<hgl/graph/RenderNode.h> #include<hgl/graph/RenderNode.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
struct RenderNodeExtraBuffer; struct RenderExtraBuffer;
/** /**
* *
@ -18,7 +18,7 @@ class MaterialRenderList
private: private:
RenderNodeExtraBuffer *extra_buffer; RenderExtraBuffer *extra_buffer;
struct RenderItem struct RenderItem
{ {
@ -34,7 +34,7 @@ private:
void Set(Renderable *); void Set(Renderable *);
}; };
SortedSets<MaterialInstance *> mi_set; MaterialInstanceSets mi_set;
List<RenderItem> ri_list; List<RenderItem> ri_list;
uint ri_count; uint ri_count;

View File

@ -2,12 +2,14 @@
#define HGL_GRAPH_RENDER_NODE_INCLUDE #define HGL_GRAPH_RENDER_NODE_INCLUDE
#include<hgl/graph/VK.h> #include<hgl/graph/VK.h>
#include<hgl/type/SortedSets.h>
namespace hgl namespace hgl
{ {
namespace graph namespace graph
{ {
class Renderable; class Renderable;
class Material; class Material;
class MaterialInstance;
class GPUDevice; class GPUDevice;
struct VertexInputData; struct VertexInputData;
struct IndexBufferData; struct IndexBufferData;
@ -20,6 +22,8 @@ namespace hgl
}; };
using RenderNodeList=List<RenderNode>; using RenderNodeList=List<RenderNode>;
using MaterialInstanceSets=SortedSets<MaterialInstance *>;
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl
#endif//HGL_GRAPH_RENDER_NODE_INCLUDE #endif//HGL_GRAPH_RENDER_NODE_INCLUDE

View File

@ -96,23 +96,28 @@ void MaterialRenderList::End()
Sort(rn_list,&rnc); Sort(rn_list,&rnc);
} }
//写入LocalToWorld数据 const uint node_count=rn_list.GetCount();
{
uint count=rn_list.GetCount();
if(count<=0)return; if(node_count<=0)return;
if(!extra_buffer) if(!extra_buffer)
extra_buffer=new RenderNodeExtraBuffer; extra_buffer=new RenderExtraBuffer;
if(extra_buffer->node_count<count) if(extra_buffer->node_count<node_count)
extra_buffer->NodeAlloc(device,count); extra_buffer->NodeAlloc(device,node_count);
//写入数据
extra_buffer->WriteData(rn_list.GetData(),count);
}
Stat(); Stat();
//写入LocalToWorld数据
extra_buffer->WriteLocalToWorld(rn_list.GetData(),node_count);
const uint mi_count=mi_set.GetCount();
if(mi_count<=0)return;
if(extra_buffer->mi_count<mi_count)
extra_buffer->MIAlloc(device,mi_count,);
extra_buffer->WriteMaterialInstance(rn_list.GetData(),node_count,mi_set);
} }
void MaterialRenderList::RenderItem::Set(Renderable *ri) void MaterialRenderList::RenderItem::Set(Renderable *ri)
@ -181,7 +186,7 @@ void MaterialRenderList::Bind(MaterialInstance *mi)
{ {
} }
bool MaterialRenderList::Bind(const VertexInputData *vid,const uint first) bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
{ {
//binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。 //binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。
@ -253,7 +258,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint first)
hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4); hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4);
for(uint i=0;i<4;i++) for(uint i=0;i<4;i++)
buffer_offset[count+i]=first*16; //mat4每列都是rgba32f自然是16字节 buffer_offset[count+i]=ri_index*16; //mat4每列都是rgba32f自然是16字节
count+=l2w_binding_count; count+=l2w_binding_count;
} }

View File

@ -4,7 +4,7 @@
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
// ubo_range大致分为三档: // ubo_range大致分为三档:
// //
// 16k: Mali-T系列或更早、Mali-G71、nVidia GeForce RTX 3070 Laptop为16k // 16k: Mali-T系列或更早、Mali-G71为16k
// //
// 64k: 大部分手机与PC均为64k // 64k: 大部分手机与PC均为64k
// //
@ -24,7 +24,7 @@ VK_NAMESPACE_BEGIN
/* /*
* *
*/ */
struct RenderNodeExtraBuffer struct RenderExtraBuffer
{ {
uint node_count; ///<渲染节点数量 uint node_count; ///<渲染节点数量
uint mi_count; ///<材质实例数量 uint mi_count; ///<材质实例数量
@ -35,32 +35,26 @@ struct RenderNodeExtraBuffer
VBO *mi_id; VBO *mi_id;
VkBuffer mi_id_buffer; VkBuffer mi_id_buffer;
VBO *bone_id,*bone_weight; // VBO *bone_id,*bone_weight;
VkBuffer bone_id_buffer,bone_weight_buffer; // VkBuffer bone_id_buffer,bone_weight_buffer;
VBO *l2w_vbo[4]; VBO *l2w_vbo[4];
VkBuffer l2w_buffer[4]; VkBuffer l2w_buffer[4];
public: public:
RenderNodeExtraBuffer() RenderExtraBuffer()
{ {
hgl_zero(*this); hgl_zero(*this);
} }
~RenderNodeExtraBuffer() ~RenderExtraBuffer()
{ {
Clear(); Clear();
} }
void Clear() void ClearNode()
{ {
SAFE_CLEAR(mi_id)
SAFE_CLEAR(mi_data_buffer);
SAFE_CLEAR(bone_id)
SAFE_CLEAR(bone_weight)
SAFE_CLEAR(l2w_vbo[0]) SAFE_CLEAR(l2w_vbo[0])
SAFE_CLEAR(l2w_vbo[1]) SAFE_CLEAR(l2w_vbo[1])
SAFE_CLEAR(l2w_vbo[2]) SAFE_CLEAR(l2w_vbo[2])
@ -68,9 +62,26 @@ public:
node_count=0; node_count=0;
} }
void ClearMI()
{
SAFE_CLEAR(mi_id)
SAFE_CLEAR(mi_data_buffer);
mi_count=0;
mi_size=0;
}
void Clear()
{
ClearNode();
ClearMI();
// SAFE_CLEAR(bone_id)
// SAFE_CLEAR(bone_weight)
}
void NodeAlloc(GPUDevice *dev,const uint c) void NodeAlloc(GPUDevice *dev,const uint c)
{ {
Clear(); ClearNode();
node_count=power_to_2(c); node_count=power_to_2(c);
for(uint i=0;i<4;i++) for(uint i=0;i<4;i++)
@ -80,11 +91,13 @@ public:
} }
} }
void MIAlloc(GPUDevice *dev,const uint c) void MIAlloc(GPUDevice *dev,const uint c,const uint mis)
{ {
ClearMI();
if(c<=0||mi_size<=0)return; if(c<=0||mi_size<=0)return;
mi_count=power_to_2(c); mi_count=power_to_2(c);
mi_size=mis;
mi_id=dev->CreateVBO(VF_V1U8,mi_count); mi_id=dev->CreateVBO(VF_V1U8,mi_count);
mi_id_buffer=mi_id->GetBuffer(); mi_id_buffer=mi_id->GetBuffer();
@ -92,7 +105,7 @@ public:
mi_data_buffer=dev->CreateUBO(mi_count*mi_size); mi_data_buffer=dev->CreateUBO(mi_count*mi_size);
} }
void WriteData(RenderNode *render_node,const uint count) void WriteLocalToWorld(RenderNode *render_node,const uint count)
{ {
RenderNode *rn; RenderNode *rn;
glm::vec4 *tp; glm::vec4 *tp;
@ -113,5 +126,39 @@ public:
l2w_vbo[col]->Unmap(); l2w_vbo[col]->Unmap();
} }
} }
};//struct RenderNodeExtraBuffer
void WriteMaterialInstance(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
{
//MaterialInstance ID
{
uint8 *tp=(uint8 *)(mi_id->Map());
for(uint i=0;i<count;i++)
{
*tp=mi_set.Find(render_node->ri->GetMaterialInstance());
++tp;
++render_node;
}
mi_id->Unmap();
}
//MaterialInstance Data
{
const uint count=mi_set.GetCount();
uint8 *tp=(uint8 *)(mi_data_buffer->Map());
const MaterialInstance **mi=mi_set.GetData();
for(uint i=0;i<count;i++)
{
memcpy(tp,(*mi)->GetData(),mi_size);
++mi;
tp+=mi_size;
}
mi_data_buffer->Unmap();
}
}
};//struct RenderExtraBuffer
VK_NAMESPACE_END VK_NAMESPACE_END