moved GPUArrays to RenderList.cpp

This commit is contained in:
hyzboy 2020-12-18 16:52:45 +08:00
parent e03800955e
commit 5806a88964
2 changed files with 106 additions and 45 deletions

View File

@ -9,55 +9,34 @@ namespace hgl
{ {
namespace graph namespace graph
{ {
template<typename T> struct GPUArray struct L2WArrays;
{
List<T> list;
GPUBuffer *buffer;
public:
GPUArray()
{
buffer=nullptr;
}
~GPUArray()
{
SAFE_CLEAR(buffer);
}
void Clear()
{
list.ClearData();
}
void Add(const T &data)
{
list.Add(data);
}
};//
class RenderList class RenderList
{ {
GPUDevice *device;
RenderCmdBuffer *cmd_buf; RenderCmdBuffer *cmd_buf;
private: private:
GPUArray<Matrix4f> LocalToWorld; L2WArrays *LocalToWorld;
List<SceneNode *> scene_node_list; List<SceneNode *> scene_node_list;
Pipeline * last_pipeline; Pipeline * last_pipeline;
MaterialInstance * last_mat_inst;
RenderableInstance *last_ri; RenderableInstance *last_ri;
void Render(SceneNode *,RenderableInstance *); void Render(SceneNode *,RenderableInstance *);
void Render(SceneNode *,List<RenderableInstance *> &); void Render(SceneNode *,List<RenderableInstance *> &);
private:
friend class GPUDevice;
RenderList(GPUDevice *);
public: public:
RenderList(); virtual ~RenderList();
virtual ~RenderList()=default;
void Begin (); void Begin ();
void Add (SceneNode *); void Add (SceneNode *);

View File

@ -1,6 +1,7 @@
#include<hgl/graph/RenderList.h> #include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h> #include<hgl/graph/Camera.h>
#include<hgl/graph/SceneNode.h> #include<hgl/graph/SceneNode.h>
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKRenderable.h> #include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKCommandBuffer.h> #include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VertexAttribDataAccess.h> #include<hgl/graph/VertexAttribDataAccess.h>
@ -11,6 +12,45 @@ namespace hgl
{ {
namespace graph namespace graph
{ {
constexpr uint32_t L2WItemBytes=sizeof(Matrix4f); ///<单个L2W数据字节数
struct L2WArrays
{
uint alloc_count;
uint count;
List<Matrix4f> items;
GPUBuffer *buffer;
Matrix4f *buffer_address;
List<uint32_t> offset;
public:
L2WArrays()
{
alloc_count=0;
count=0;
buffer=nullptr;
buffer_address=nullptr;
}
~L2WArrays()
{
if(buffer)
{
buffer->Unmap();
delete buffer;
}
}
void Init(const uint32_t c)
{
count=c;
items.SetCount(count);
offset.SetCount(count);
}
};//
float CameraLengthComp(Camera *cam,SceneNode *obj_one,SceneNode *obj_two) float CameraLengthComp(Camera *cam,SceneNode *obj_one,SceneNode *obj_two)
{ {
if(!cam||!obj_one||!obj_two) if(!cam||!obj_one||!obj_two)
@ -27,22 +67,27 @@ namespace hgl
// return (((Frustum *)fc)->BoxIn(node->GetWorldBoundingBox())!=Frustum::OUTSIDE); // return (((Frustum *)fc)->BoxIn(node->GetWorldBoundingBox())!=Frustum::OUTSIDE);
//} //}
RenderList::RenderList() RenderList::RenderList(GPUDevice *gd)
{ {
device =gd;
cmd_buf =nullptr; cmd_buf =nullptr;
last_pipeline =nullptr; last_pipeline =nullptr;
last_mat_inst =nullptr;
last_ri =nullptr; last_ri =nullptr;
LocalToWorld=new L2WArrays;
}
RenderList::~RenderList()
{
delete LocalToWorld;
} }
void RenderList::Begin() void RenderList::Begin()
{ {
LocalToWorld.Clear();
scene_node_list.ClearData(); scene_node_list.ClearData();
last_pipeline =nullptr; last_pipeline =nullptr;
last_mat_inst =nullptr;
last_ri =nullptr; last_ri =nullptr;
} }
@ -50,18 +95,61 @@ namespace hgl
{ {
if(!node)return; if(!node)return;
LocalToWorld.Add(node->GetLocalToWorldMatrix());
scene_node_list.Add(node); scene_node_list.Add(node);
} }
void RenderList::End() void RenderList::End()
{ {
//清0计数器
uint32_t l2w_count=0; //local to world矩阵总数量
//统计Render
const uint32_t count=scene_node_list.GetCount(); const uint32_t count=scene_node_list.GetCount();
LocalToWorld->Init(count);
Matrix4f *mp=LocalToWorld->items.GetData();
uint32_t *op=LocalToWorld->offset.GetData();
for(SceneNode *node:scene_node_list) for(SceneNode *node:scene_node_list)
{ {
const Matrix4f &mat=node->GetLocalToWorldMatrix();
if(!mat.IsIdentity())
{
hgl_cpy(mp,&mat);
++mp;
*op=(l2w_count)*L2WItemBytes;
++l2w_count;
}
else
{
*op=l2w_count;
}
++op;
} }
if(LocalToWorld->buffer)
{
if(LocalToWorld->alloc_count<l2w_count)
{
LocalToWorld->buffer->Unmap();
delete LocalToWorld->buffer;
LocalToWorld->buffer=nullptr;
// LocalToWorld->buffer_address=nullptr; //下面一定会重写,所以这一行没必要操作
}
}
if(!LocalToWorld->buffer)
{
LocalToWorld->alloc_count=power_to_2(l2w_count);
LocalToWorld->buffer=device->CreateUBO(LocalToWorld->alloc_count*L2WItemBytes);
LocalToWorld->buffer_address=(Matrix4f *)(LocalToWorld->buffer->Map());
}
hgl_cpy(LocalToWorld->buffer_address,LocalToWorld->items.GetData(),l2w_count);
} }
void RenderList::Render(SceneNode *node,RenderableInstance *ri) void RenderList::Render(SceneNode *node,RenderableInstance *ri)
@ -71,15 +159,12 @@ namespace hgl
last_pipeline=ri->GetPipeline(); last_pipeline=ri->GetPipeline();
cmd_buf->BindPipeline(last_pipeline); cmd_buf->BindPipeline(last_pipeline);
last_mat_inst=nullptr;
} }
if(last_mat_inst!=ri->GetMaterialInstance())
{ {
last_mat_inst=ri->GetMaterialInstance(); MaterialInstance *mi=ri->GetMaterialInstance();
cmd_buf->BindDescriptorSets(last_mat_inst->GetDescriptorSets()); cmd_buf->BindDescriptorSets(mi->GetDescriptorSets());
} }
//更新fin_mvp //更新fin_mvp
@ -123,7 +208,6 @@ namespace hgl
cmd_buf=cb; cmd_buf=cb;
last_pipeline=nullptr; last_pipeline=nullptr;
last_mat_inst=nullptr;
last_ri=nullptr; last_ri=nullptr;
const int count=scene_node_list.GetCount(); const int count=scene_node_list.GetCount();
@ -131,8 +215,6 @@ namespace hgl
for(int i=0;i<count;i++) for(int i=0;i<count;i++)
{ {
// cmb_buf->....offset L2W Matrix
Render(*node,(*node)->renderable_instances); Render(*node,(*node)->renderable_instances);
++node; ++node;
} }