Compare commits
19 Commits
devel_24_L
...
master
Author | SHA1 | Date | |
---|---|---|---|
6820ee8c74 | |||
ddb5a0b77a | |||
69646971ce | |||
e71ec4be85 | |||
dbe2370a44 | |||
00d2677066 | |||
4208e47534 | |||
2dedeaad90 | |||
083600a95f | |||
902dc20340 | |||
164498446a | |||
cef5ad073b | |||
c2279c553d | |||
d959e7988d | |||
202bff5870 | |||
8437d8d561 | |||
714fc3dcb7 | |||
e030738a5f | |||
28b2b53d03 |
2
CMCore
2
CMCore
Submodule CMCore updated: 6a21b387f5...072153aa91
Submodule CMPlatform updated: 2ad618e1ff...5e8b83cce4
Submodule CMSceneGraph updated: 8b585e15eb...bde86e8016
2
CMUtil
2
CMUtil
Submodule CMUtil updated: ff819d8a60...c0990c52eb
@@ -10,10 +10,10 @@
|
||||
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Vulkan/${group}")
|
||||
endmacro()
|
||||
|
||||
CreateProject("Basic" 1st_draw_triangle_in_NDC first_triangle.cpp)
|
||||
CreateProject("Basic" 2nd_draw_triangle_use_UBO second_triangle.cpp)
|
||||
CreateProject("Basic" 3rd_draw_triangle_use_RenderList third_triangle.cpp)
|
||||
CreateProject("Basic" 4th_draw_triangle_use_MaterialInstance fourth_triangle.cpp)
|
||||
CreateProject("Basic" 1st_draw_triangle_in_NDC first_triangle.cpp)
|
||||
CreateProject("Basic" 2nd_draw_triangle_use_UBO second_triangle.cpp)
|
||||
CreateProject("Basic" 3rd_AutoInstance third_triangle.cpp)
|
||||
CreateProject("Basic" 4th_AutoMergeMaterialInstance fourth_triangle.cpp)
|
||||
|
||||
#CreateProject("Basic" FragCoord FragCoordTest.cpp)
|
||||
#CreateProject("Basic" indices_rect indices_rect.cpp)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// fourth_triangle
|
||||
// 该范例主要演示使用材质实例传递颜色参数绘制三角形
|
||||
// AutoMergeMaterialInstance
|
||||
// 该范例主要演示使用一个材质下的不同材质实例传递颜色参数绘制三角形,并依赖RenderList中的自动合并功能,让同一材质下所有不同材质实例的对象一次渲染完成。
|
||||
|
||||
#include"VulkanAppFramework.h"
|
||||
#include<hgl/math/Math.h>
|
||||
@@ -7,6 +7,7 @@
|
||||
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
|
||||
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
|
||||
#include<hgl/graph/RenderList.h>
|
||||
#include<hgl/color/Color.h>
|
||||
|
||||
using namespace hgl;
|
||||
using namespace hgl::graph;
|
||||
@@ -23,15 +24,7 @@ constexpr float position_data[VERTEX_COUNT*2]=
|
||||
0.1, 0.9
|
||||
};
|
||||
|
||||
constexpr float color_data[6][4]=
|
||||
{
|
||||
{1,0,0,1},
|
||||
{1,1,0,1},
|
||||
{0,1,0,1},
|
||||
{0,1,1,1},
|
||||
{0,0,1,1},
|
||||
{1,0,1,1},
|
||||
};
|
||||
constexpr uint DRAW_OBJECT_COUNT=12;
|
||||
|
||||
class TestApp:public VulkanApplicationFramework
|
||||
{
|
||||
@@ -40,8 +33,13 @@ private:
|
||||
SceneNode render_root;
|
||||
RenderList * render_list =nullptr;
|
||||
|
||||
MaterialInstance * material_instance[6]{};
|
||||
Renderable * render_obj[6] {};
|
||||
Material * material =nullptr;
|
||||
|
||||
struct
|
||||
{
|
||||
MaterialInstance * mi;
|
||||
Renderable * r;
|
||||
}render_obj[DRAW_OBJECT_COUNT]{};
|
||||
|
||||
Pipeline * pipeline =nullptr;
|
||||
|
||||
@@ -57,42 +55,48 @@ private:
|
||||
|
||||
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureColor2D(&cfg);
|
||||
|
||||
/* for(uint i=0;i<6;i++)
|
||||
{
|
||||
material_instance[i]=db->CreateMaterialInstance(mci);
|
||||
material=db->CreateMaterial(mci);
|
||||
|
||||
if(!material_instance[i])
|
||||
if(!material)
|
||||
return(false);
|
||||
|
||||
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
|
||||
{
|
||||
render_obj[i].mi=db->CreateMaterialInstance(material);
|
||||
|
||||
if(!render_obj[i].mi)
|
||||
return(false);
|
||||
|
||||
material_instance[i]->SetFloat4(0,color_data[i]);
|
||||
}*/
|
||||
Color4f color=GetColor4f((COLOR)(i+int(COLOR::Blue)),1.0);
|
||||
|
||||
render_obj[i].mi->WriteMIData(color,sizeof(Color4f)); //设置MaterialInstance的数据
|
||||
}
|
||||
}
|
||||
|
||||
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
|
||||
// pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行,为Framework重载,默认使用swapchain的render target
|
||||
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::Triangles);
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
bool InitVBO()
|
||||
{
|
||||
//RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
|
||||
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
|
||||
|
||||
//if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
|
||||
//
|
||||
//render_obj=rpc.Create(material_instance,pipeline);
|
||||
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
|
||||
|
||||
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
|
||||
{
|
||||
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
|
||||
|
||||
//if(!render_obj)
|
||||
// return(false);
|
||||
//
|
||||
//for(uint i=0;i<6;i++)
|
||||
//{
|
||||
// render_root.CreateSubNode(rotate(deg2rad(60*i),Vector3f(0,0,1)),render_obj);
|
||||
//}
|
||||
if(!render_obj[i].r)
|
||||
return(false);
|
||||
|
||||
//render_root.RefreshMatrix();
|
||||
render_root.CreateSubNode(rotate(deg2rad(360/DRAW_OBJECT_COUNT*i),Vector3f(0,0,1)),render_obj[i].r);
|
||||
}
|
||||
|
||||
//render_list->Expend(&render_root);
|
||||
render_root.RefreshMatrix();
|
||||
|
||||
render_list->Expend(&render_root);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// third_triangle
|
||||
// 该范例主要演示使用场景树系统绘制多个三角形,并利用RenderList进行排序以及自动合并进行Instance渲染
|
||||
// AutoInstance
|
||||
// 该范例主要演示使用RenderList系统绘制多个三角形,并利用RenderList进行排序以及自动合并进行Instance渲染
|
||||
|
||||
#include"VulkanAppFramework.h"
|
||||
#include<hgl/math/Math.h>
|
||||
|
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
#include<hgl/graph/RenderNode.h>
|
||||
#include<hgl/graph/VKVBOList.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
struct RenderExtraBuffer;
|
||||
class RenderAssignBuffer;
|
||||
|
||||
/**
|
||||
* ͬһ<EFBFBD><EFBFBD><EFBFBD>ʵĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>б<EFBFBD>
|
||||
* 同一材质的对象渲染列表
|
||||
*/
|
||||
class MaterialRenderList
|
||||
{
|
||||
@@ -19,7 +19,7 @@ class MaterialRenderList
|
||||
|
||||
private:
|
||||
|
||||
RenderExtraBuffer *extra_buffer;
|
||||
RenderAssignBuffer *assign_buffer;
|
||||
|
||||
struct RenderItem
|
||||
{
|
||||
@@ -39,13 +39,14 @@ private:
|
||||
DataArray<RenderItem> ri_array;
|
||||
uint ri_count;
|
||||
|
||||
void StatMI();
|
||||
void Stat();
|
||||
|
||||
protected:
|
||||
|
||||
VBOList * vbo_list;
|
||||
|
||||
MaterialInstance * last_mi;
|
||||
const VIL * last_vil;
|
||||
Pipeline * last_pipeline;
|
||||
const VertexInputData * last_vid;
|
||||
uint last_index;
|
||||
|
@@ -23,7 +23,7 @@ namespace hgl
|
||||
|
||||
using RenderNodeList=List<RenderNode>;
|
||||
|
||||
using MaterialInstanceSets=SortedSets<MaterialInstance *>;
|
||||
using MaterialInstanceSets=SortedSets<MaterialInstance *>; ///<材质实例集合
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#endif//HGL_GRAPH_RENDER_NODE_INCLUDE
|
||||
|
@@ -6,6 +6,11 @@
|
||||
#include<hgl/type/String.h>
|
||||
#include<hgl/graph/VKShaderModuleMap.h>
|
||||
#include<hgl/graph/VKDescriptorSetType.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
class ActiveMemoryBlockManager;
|
||||
}
|
||||
VK_NAMESPACE_BEGIN
|
||||
using ShaderStageCreateInfoList=List<VkPipelineShaderStageCreateInfo>;
|
||||
|
||||
@@ -30,15 +35,18 @@ class Material
|
||||
MaterialParameters *mp_array[DESCRIPTOR_SET_TYPE_COUNT];
|
||||
|
||||
uint32_t mi_data_bytes; ///<实例数据大小
|
||||
uint32_t mi_max_count; ///<最大实例数量(注:代表一次drawcall大小,而不是整个的大小)
|
||||
uint32_t mi_max_count; ///<实例一次渲染最大数量限制
|
||||
|
||||
ActiveMemoryBlockManager *mi_data_manager;
|
||||
|
||||
private:
|
||||
|
||||
friend class RenderResource;
|
||||
|
||||
Material(const AnsiString &);
|
||||
|
||||
public:
|
||||
|
||||
Material(const AnsiString &);
|
||||
virtual ~Material();
|
||||
|
||||
const UTF8String & GetName ()const{return name;}
|
||||
@@ -62,12 +70,20 @@ public:
|
||||
|
||||
const bool hasSet (const DescriptorSetType &type)const;
|
||||
|
||||
const VIL * GetDefaultVIL()const;
|
||||
VIL * CreateVIL(const VILConfig *format_map=nullptr);
|
||||
bool Release(VIL *);
|
||||
const uint GetVILCount();
|
||||
|
||||
public:
|
||||
|
||||
const bool HasMI ()const{return mi_data_bytes>0;}
|
||||
const uint32_t GetMIDataBytes ()const{return mi_data_bytes;}
|
||||
const uint32_t GetMIMaxCount ()const{return mi_max_count;}
|
||||
|
||||
void ReleaseMI(int); ///<释放材质实例
|
||||
void *GetMIData(int); ///<取得指定ID号的材质实例数据访问指针
|
||||
|
||||
MaterialInstance *CreateMI(const VILConfig *vil_cfg=nullptr);
|
||||
};//class Material
|
||||
|
||||
|
@@ -50,6 +50,8 @@ protected:
|
||||
|
||||
VIL *vil;
|
||||
|
||||
int mi_id;
|
||||
|
||||
public:
|
||||
|
||||
Material * GetMaterial () {return material;}
|
||||
@@ -60,11 +62,18 @@ private:
|
||||
|
||||
friend class Material;
|
||||
|
||||
MaterialInstance(Material *,VIL *);
|
||||
MaterialInstance(Material *,VIL *,const int);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~MaterialInstance()=default;
|
||||
virtual ~MaterialInstance()
|
||||
{
|
||||
material->ReleaseMI(mi_id);
|
||||
}
|
||||
|
||||
const int GetMIID ()const{return mi_id;} ///<取得材质实例ID
|
||||
void * GetMIData (){return material->GetMIData(mi_id);} ///<取得材质实例数据
|
||||
void WriteMIData (const void *data,const int size); ///<写入材质实例数据
|
||||
|
||||
bool BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic=false);
|
||||
bool BindSSBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic=false);
|
||||
|
@@ -54,9 +54,15 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
Pipeline *CreatePipeline(MaterialInstance *, const InlinePipeline &, const Prim &prim,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(MaterialInstance *, const PipelineData *, const Prim &prim,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(MaterialInstance *, const OSString &, const Prim &prim,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(Material *,const VIL *,const PipelineData *, const Prim &,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(Material *,const VIL *,const InlinePipeline &, const Prim &,const bool prim_restart=false);
|
||||
|
||||
Pipeline *CreatePipeline(Material *mtl, const PipelineData *, const Prim &,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(Material *mtl, const InlinePipeline &, const Prim &,const bool prim_restart=false);
|
||||
|
||||
Pipeline *CreatePipeline(MaterialInstance *, const InlinePipeline &, const Prim &,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(MaterialInstance *, const PipelineData *, const Prim &,const bool prim_restart=false);
|
||||
Pipeline *CreatePipeline(MaterialInstance *, const OSString &, const Prim &,const bool prim_restart=false);
|
||||
};//class RenderPass
|
||||
VK_NAMESPACE_END
|
||||
#endif//HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE
|
||||
|
@@ -56,7 +56,7 @@ constexpr const ShaderBufferSource SBS_LocalToWorld=
|
||||
|
||||
constexpr const char MaterialInstanceStruct[]="MaterialInstance";
|
||||
|
||||
constexpr const ShaderBufferSource SBS_MaterialInstanceData=
|
||||
constexpr const ShaderBufferSource SBS_MaterialInstance=
|
||||
{
|
||||
"MaterialInstanceData",
|
||||
"mtl",
|
||||
|
@@ -44,7 +44,8 @@ SET(SCENE_GRAPH_HEADER ${SG_INCLUDE_PATH}/SceneInfo.h
|
||||
|
||||
SET(SCENE_GRAPH_SOURCE RenderList.cpp
|
||||
MaterialRenderList.cpp
|
||||
RenderExtraBuffer.h
|
||||
RenderAssignBuffer.h
|
||||
RenderAssignBuffer.cpp
|
||||
SceneNode.cpp
|
||||
SceneOrient.cpp)
|
||||
|
||||
|
@@ -3,8 +3,9 @@
|
||||
#include<hgl/graph/VKDevice.h>
|
||||
#include<hgl/graph/VKCommandBuffer.h>
|
||||
#include<hgl/graph/VKVertexInput.h>
|
||||
#include<hgl/graph/VKRenderAssign.h>
|
||||
#include<hgl/util/sort/Sort.h>
|
||||
#include"RenderExtraBuffer.h"
|
||||
#include"RenderAssignBuffer.h"
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -33,10 +34,10 @@ int Comparator<hgl::graph::RenderNode>::compare(const hgl::graph::RenderNode &ob
|
||||
return off;
|
||||
}
|
||||
|
||||
//比较材质实例
|
||||
//比较顶点输入格式
|
||||
{
|
||||
off=ri_one->GetMaterialInstance()
|
||||
-ri_two->GetMaterialInstance();
|
||||
off=ri_one->GetMaterialInstance()->GetVIL()
|
||||
-ri_two->GetMaterialInstance()->GetVIL();
|
||||
|
||||
if(off)
|
||||
return off;
|
||||
@@ -60,7 +61,7 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,Material *m)
|
||||
device=d;
|
||||
cmd_buf=nullptr;
|
||||
mtl=m;
|
||||
extra_buffer=nullptr;
|
||||
assign_buffer=new RenderAssignBuffer(d,mtl->GetMIDataBytes());
|
||||
|
||||
vbo_list=new VBOList(mtl->GetVertexInput()->GetCount());
|
||||
}
|
||||
@@ -68,7 +69,7 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,Material *m)
|
||||
MaterialRenderList::~MaterialRenderList()
|
||||
{
|
||||
SAFE_CLEAR(vbo_list);
|
||||
SAFE_CLEAR(extra_buffer)
|
||||
SAFE_CLEAR(assign_buffer)
|
||||
}
|
||||
|
||||
void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat)
|
||||
@@ -90,24 +91,13 @@ void MaterialRenderList::End()
|
||||
|
||||
if(node_count<=0)return;
|
||||
|
||||
if(!extra_buffer)
|
||||
extra_buffer=new RenderExtraBuffer;
|
||||
|
||||
if(extra_buffer->node_count<node_count)
|
||||
extra_buffer->NodeAlloc(device,node_count);
|
||||
if(mtl->HasMI())
|
||||
StatMI();
|
||||
|
||||
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);
|
||||
assign_buffer->WriteNode(rn_list.GetData(),node_count,mi_set);
|
||||
}
|
||||
|
||||
void MaterialRenderList::RenderItem::Set(Renderable *ri)
|
||||
@@ -117,6 +107,19 @@ void MaterialRenderList::RenderItem::Set(Renderable *ri)
|
||||
vid =ri->GetVertexInputData();
|
||||
}
|
||||
|
||||
void MaterialRenderList::StatMI()
|
||||
{
|
||||
mi_set.Clear();
|
||||
|
||||
for(RenderNode &rn:rn_list)
|
||||
mi_set.Add(rn.ri->GetMaterialInstance());
|
||||
|
||||
if(mi_set.GetCount()>mtl->GetMIMaxCount())
|
||||
{
|
||||
//超出最大数量了怎么办???
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialRenderList::Stat()
|
||||
{
|
||||
const uint count=rn_list.GetCount();
|
||||
@@ -125,10 +128,8 @@ void MaterialRenderList::Stat()
|
||||
ri_array.Clear();
|
||||
ri_array.Alloc(count);
|
||||
|
||||
mi_set.Clear();
|
||||
|
||||
RenderItem *ri=ri_array.GetData();
|
||||
|
||||
|
||||
ri_count=1;
|
||||
|
||||
ri->first=0;
|
||||
@@ -136,18 +137,16 @@ void MaterialRenderList::Stat()
|
||||
ri->Set(rn->ri);
|
||||
|
||||
last_pipeline =ri->pipeline;
|
||||
last_mi =ri->mi;
|
||||
last_vil =ri->mi->GetVIL();
|
||||
last_vid =ri->vid;
|
||||
|
||||
mi_set.Add(last_mi);
|
||||
|
||||
++rn;
|
||||
|
||||
for(uint i=1;i<count;i++)
|
||||
{
|
||||
{
|
||||
if(last_pipeline==rn->ri->GetPipeline())
|
||||
if(last_mi==rn->ri->GetMaterialInstance())
|
||||
if(last_vid==rn->ri->GetVertexInputData())
|
||||
if(last_vil==rn->ri->GetMaterialInstance()->GetVIL())
|
||||
if(last_vid->Comp(rn->ri->GetVertexInputData()))
|
||||
{
|
||||
++ri->count;
|
||||
++rn;
|
||||
@@ -161,11 +160,8 @@ void MaterialRenderList::Stat()
|
||||
ri->count=1;
|
||||
ri->Set(rn->ri);
|
||||
|
||||
if(last_mi!=ri->mi)
|
||||
mi_set.Add(ri->mi);
|
||||
|
||||
last_pipeline =ri->pipeline;
|
||||
last_mi =ri->mi;
|
||||
last_vil =ri->mi->GetVIL();
|
||||
last_vid =ri->vid;
|
||||
|
||||
++rn;
|
||||
@@ -176,15 +172,7 @@ void MaterialRenderList::Bind(MaterialInstance *mi)
|
||||
{
|
||||
if(!mi)return;
|
||||
|
||||
const VIL *vil=mi->GetVIL();
|
||||
|
||||
const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign);
|
||||
|
||||
if(assign_binding_count>0)
|
||||
{
|
||||
mi->BindUBO(DescriptorSetType::PerFrame,"l2w",extra_buffer->assigns_l2w);
|
||||
// mi->BindUBO(DescriptorSetType::PerFrame,"Assign",extra_buffer->assigns_mi);
|
||||
}
|
||||
assign_buffer->Bind(mi);
|
||||
|
||||
cmd_buf->BindDescriptorSets(mi->GetMaterial());
|
||||
}
|
||||
@@ -193,7 +181,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
|
||||
{
|
||||
//binding号都是在VertexInput::CreateVIL时连续紧密排列生成的,所以bind时first_binding写0就行了。
|
||||
|
||||
const VIL *vil=last_mi->GetVIL();
|
||||
const VIL *vil=last_vil;
|
||||
|
||||
if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count)
|
||||
return(false); //这里基本不太可能,因为CreateRenderable时就会检查值是否一样
|
||||
@@ -233,25 +221,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
|
||||
// }
|
||||
//}
|
||||
|
||||
//if(count<binding_count)//LocalToWorld组,由RenderList合成
|
||||
//{
|
||||
// const uint l2w_binding_count=vil->GetCount(VertexInputGroup::LocalToWorld);
|
||||
|
||||
// if(l2w_binding_count>0) //有变换矩阵信息
|
||||
// {
|
||||
// if(l2w_binding_count!=4)
|
||||
// return(false);
|
||||
|
||||
// hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4);
|
||||
|
||||
// for(uint i=0;i<4;i++)
|
||||
// buffer_offset[count+i]=ri_index*16; //mat4每列都是rgba32f,自然是16字节
|
||||
|
||||
// count+=l2w_binding_count;
|
||||
// }
|
||||
//}
|
||||
|
||||
if(!vbo_list->IsFull())
|
||||
if(!vbo_list->IsFull()) //Assign组
|
||||
{
|
||||
const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign);
|
||||
|
||||
@@ -260,11 +230,10 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
|
||||
if(assign_binding_count!=1)
|
||||
return(false);
|
||||
|
||||
vbo_list->Add(extra_buffer->assigns_vbo->GetBuffer(),extra_buffer->assigns_vbo_strip*ri_index);
|
||||
vbo_list->Add(assign_buffer->GetAssignVBO(),ASSIGN_VBO_STRIDE_BYTES*ri_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if(count!=binding_count)
|
||||
//{
|
||||
// //还有没支持的绑定组????
|
||||
@@ -272,7 +241,6 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
|
||||
// return(false);
|
||||
//}
|
||||
|
||||
//cmd_buf->BindVBO(0,count,buffer_list,buffer_offset);
|
||||
cmd_buf->BindVBO(vbo_list);
|
||||
|
||||
return(true);
|
||||
@@ -285,16 +253,15 @@ void MaterialRenderList::Render(RenderItem *ri)
|
||||
cmd_buf->BindPipeline(ri->pipeline);
|
||||
last_pipeline=ri->pipeline;
|
||||
|
||||
last_mi=nullptr;
|
||||
last_vid=nullptr;
|
||||
|
||||
//这里未来尝试换pipeline同时不换mi/primitive是否需要重新绑定mi/primitive
|
||||
}
|
||||
|
||||
if(last_mi!=ri->mi)
|
||||
if(last_vil!=ri->mi->GetVIL())
|
||||
{
|
||||
Bind(ri->mi);
|
||||
last_mi=ri->mi;
|
||||
last_vil=ri->mi->GetVIL();
|
||||
|
||||
last_vid=nullptr;
|
||||
}
|
||||
@@ -333,7 +300,7 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb)
|
||||
RenderItem *ri=ri_array.GetData();
|
||||
|
||||
last_pipeline =nullptr;
|
||||
last_mi =nullptr;
|
||||
last_vil =nullptr;
|
||||
last_vid =nullptr;
|
||||
|
||||
for(uint i=0;i<ri_count;i++)
|
||||
|
152
src/SceneGraph/RenderAssignBuffer.cpp
Normal file
152
src/SceneGraph/RenderAssignBuffer.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include"RenderAssignBuffer.h"
|
||||
#include<hgl/graph/VKVertexAttribBuffer.h>
|
||||
#include<hgl/graph/VKDevice.h>
|
||||
#include<hgl/graph/VKMaterialInstance.h>
|
||||
#include<hgl/graph/RenderNode.h>
|
||||
#include<hgl/graph/VKRenderable.h>
|
||||
#include<hgl/graph/VKRenderAssign.h>
|
||||
#include<hgl/graph/mtl/UBOCommon.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
RenderAssignBuffer::RenderAssignBuffer(GPUDevice *dev,const uint mi_bytes)
|
||||
{
|
||||
hgl_zero(*this);
|
||||
|
||||
device=dev;
|
||||
|
||||
mi_data_bytes=mi_bytes;
|
||||
|
||||
ubo_mi=nullptr;
|
||||
mi_count=0;
|
||||
}
|
||||
|
||||
VkBuffer RenderAssignBuffer::GetAssignVBO()const
|
||||
{
|
||||
return vbo_assigns->GetBuffer();
|
||||
}
|
||||
|
||||
void RenderAssignBuffer::Bind(MaterialInstance *mi)const
|
||||
{
|
||||
const VIL *vil=mi->GetVIL();
|
||||
|
||||
const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign);
|
||||
|
||||
if(assign_binding_count<=0)return;
|
||||
|
||||
mi->BindUBO(DescriptorSetType::PerFrame,mtl::SBS_LocalToWorld.name,ubo_l2w);
|
||||
mi->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,ubo_mi);
|
||||
}
|
||||
|
||||
void RenderAssignBuffer::Clear()
|
||||
{
|
||||
SAFE_CLEAR(ubo_l2w);
|
||||
SAFE_CLEAR(ubo_mi);
|
||||
SAFE_CLEAR(vbo_assigns);
|
||||
|
||||
node_count=0;
|
||||
mi_count=0;
|
||||
}
|
||||
|
||||
void RenderAssignBuffer::Alloc(const uint nc,const uint mc)
|
||||
{
|
||||
Clear();
|
||||
|
||||
{
|
||||
node_count=nc;
|
||||
|
||||
ubo_l2w=device->CreateUBO(node_count*sizeof(Matrix4f));
|
||||
}
|
||||
|
||||
if(mi_data_bytes>0&&mc>0)
|
||||
{
|
||||
mi_count=mc;
|
||||
|
||||
ubo_mi=device->CreateUBO(mi_data_bytes*mi_count);
|
||||
}
|
||||
|
||||
vbo_assigns=device->CreateVBO(ASSIGN_VBO_FMT,node_count);
|
||||
}
|
||||
|
||||
void RenderAssignBuffer::WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
|
||||
{
|
||||
RenderNode *rn;
|
||||
|
||||
Alloc(count,mi_set.GetCount());
|
||||
|
||||
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_assigns->Map());
|
||||
|
||||
{
|
||||
Matrix4f *tp=(hgl::Matrix4f *)(ubo_l2w->Map());
|
||||
Matrix4f *l2w=tp;
|
||||
|
||||
rn=render_node;
|
||||
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*l2w=rn->local_to_world;
|
||||
++l2w;
|
||||
|
||||
*idp=i;
|
||||
++idp;
|
||||
|
||||
*idp=mi_set.Find(rn->ri->GetMaterialInstance());
|
||||
++idp;
|
||||
|
||||
++rn;
|
||||
}
|
||||
|
||||
ubo_l2w->Unmap();
|
||||
}
|
||||
|
||||
vbo_assigns->Unmap();
|
||||
}
|
||||
|
||||
//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();
|
||||
// }
|
||||
//}
|
||||
|
||||
VK_NAMESPACE_END
|
67
src/SceneGraph/RenderAssignBuffer.h
Normal file
67
src/SceneGraph/RenderAssignBuffer.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
#include<hgl/graph/RenderNode.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
// ubo_range大致分为三档:
|
||||
//
|
||||
// 16k: Mali-T系列或更早、Mali-G71为16k
|
||||
//
|
||||
// 64k: 大部分手机与PC均为64k
|
||||
//
|
||||
// >64k: Intel 核显与 PowerVR 为128MB,AMD显卡为4GB,可视为随显存无上限。
|
||||
//
|
||||
// 我们使用uint8类型在vertex input中保存MaterialInstance ID,表示范围0-255。
|
||||
// 所以MaterialInstance结构容量按16k/64k分为两个档次,64字节和256字节
|
||||
|
||||
// 如果一定要使用超过16K/64K硬件限制的容量,有两种办法
|
||||
// 一、分多次渲染,使用UBO Offset偏移UBO数据区。
|
||||
// 二、使用SSBO,但这样会导致性能下降,所以不推荐使用。
|
||||
|
||||
// 但我们不解决这个问题
|
||||
// 我们天然要求将材质实例数据分为两个等级,同时要求一次渲染不能超过256种材质实例。
|
||||
// 所以 UBO Range为16k时,实例数据不能超过64字节。UBO Range为64k时,实例数据不能超过256字节。
|
||||
|
||||
|
||||
struct RenderNode;
|
||||
class MaterialInstance;
|
||||
|
||||
/*
|
||||
* 渲染节点额外提供的数据
|
||||
*/
|
||||
class RenderAssignBuffer
|
||||
{
|
||||
private:
|
||||
|
||||
GPUDevice *device;
|
||||
|
||||
uint node_count; ///<渲染节点数量
|
||||
DeviceBuffer *ubo_l2w; ///<Local2World数据
|
||||
|
||||
uint32_t mi_data_bytes; ///<材质实例数据字节数
|
||||
uint32_t mi_count; ///<材质实例数量
|
||||
DeviceBuffer *ubo_mi; ///<材质实例数据
|
||||
|
||||
//Assign VBO
|
||||
VBO *vbo_assigns; ///<RG16UI格式的VertexInputStream,,,,X:L2W ID,Y:MI ID
|
||||
|
||||
private:
|
||||
|
||||
void Alloc(const uint nc,const uint mc);
|
||||
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
|
||||
VkBuffer GetAssignVBO()const;
|
||||
|
||||
void Bind(MaterialInstance *)const;
|
||||
|
||||
public:
|
||||
|
||||
RenderAssignBuffer(GPUDevice *dev,const uint32_t mi_bytes);
|
||||
~RenderAssignBuffer(){Clear();}
|
||||
|
||||
void WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set);
|
||||
|
||||
};//struct RenderAssignBuffer
|
||||
VK_NAMESPACE_END
|
@@ -1,209 +0,0 @@
|
||||
#pragma once
|
||||
#include<hgl/graph/VKVertexAttribBuffer.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
// ubo_range大致分为三档:
|
||||
//
|
||||
// 16k: Mali-T系列或更早、Mali-G71为16k
|
||||
//
|
||||
// 64k: 大部分手机与PC均为64k
|
||||
//
|
||||
// >64k: Intel 核显与 PowerVR 为128MB,AMD显卡为4GB,可视为随显存无上限。
|
||||
//
|
||||
// 我们使用uint8类型在vertex input中保存MaterialInstance ID,表示范围0-255。
|
||||
// 所以MaterialInstance结构容量按16k/64k分为两个档次,64字节和256字节
|
||||
|
||||
// 如果一定要使用超过16K/64K硬件限制的容量,有两种办法
|
||||
// 一、分多次渲染,使用UBO Offset偏移UBO数据区。
|
||||
// 二、使用SSBO,但这样会导致性能下降,所以不推荐使用。
|
||||
|
||||
// 但我们不解决这个问题
|
||||
// 我们天然要求将材质实例数据分为两个等级,同时要求一次渲染不能超过256种材质实例。
|
||||
// 所以 UBO Range为16k时,实例数据不能超过64字节。UBO Range为64k时,实例数据不能超过256字节。
|
||||
|
||||
/*
|
||||
* 渲染节点额外提供的数据
|
||||
*/
|
||||
struct RenderExtraBuffer
|
||||
{
|
||||
uint node_count; ///<渲染节点数量
|
||||
// uint mi_count; ///<材质实例数量
|
||||
|
||||
//uint mi_size; ///<单个材质实例数量长度
|
||||
//DeviceBuffer *mi_data_buffer; ///<材质实例数据UBO/SSBO
|
||||
|
||||
//VBO *mi_id;
|
||||
//VkBuffer mi_id_buffer;
|
||||
|
||||
// VBO *bone_id,*bone_weight;
|
||||
// VkBuffer bone_id_buffer,bone_weight_buffer;
|
||||
|
||||
VBO *l2w_vbo[4];
|
||||
VkBuffer l2w_buffer[4];
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
//Assign UBO
|
||||
DeviceBuffer *assigns_l2w;
|
||||
DeviceBuffer *assigns_mi;
|
||||
|
||||
//Assign VBO
|
||||
VBO *assigns_vbo; ///<RG16UI格式的VertexInputStream,,,,X:L2W ID,Y:MI ID
|
||||
|
||||
const uint assigns_vbo_strip=2; ///<Assign VBO的每个节点的字节数
|
||||
|
||||
public:
|
||||
|
||||
RenderExtraBuffer()
|
||||
{
|
||||
hgl_zero(*this);
|
||||
}
|
||||
|
||||
~RenderExtraBuffer()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void ClearNode()
|
||||
{
|
||||
SAFE_CLEAR(assigns_l2w);
|
||||
SAFE_CLEAR(assigns_mi);
|
||||
SAFE_CLEAR(assigns_vbo);
|
||||
|
||||
SAFE_CLEAR(l2w_vbo[0])
|
||||
SAFE_CLEAR(l2w_vbo[1])
|
||||
SAFE_CLEAR(l2w_vbo[2])
|
||||
SAFE_CLEAR(l2w_vbo[3])
|
||||
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)
|
||||
{
|
||||
ClearNode();
|
||||
node_count=power_to_2(c);
|
||||
|
||||
for(uint i=0;i<4;i++)
|
||||
{
|
||||
l2w_vbo[i]=dev->CreateVBO(VF_V4F,node_count);
|
||||
l2w_buffer[i]=l2w_vbo[i]->GetBuffer();
|
||||
}
|
||||
|
||||
assigns_l2w=dev->CreateUBO(node_count*sizeof(Matrix4f));
|
||||
//assigns_mi=dev->CreateUBO(node_count*sizeof(uint8));
|
||||
assigns_vbo=dev->CreateVBO(VF_V1U16,node_count);
|
||||
}
|
||||
|
||||
//void MIAlloc(GPUDevice *dev,const uint c,const uint mis)
|
||||
//{
|
||||
// ClearMI();
|
||||
// if(c<=0||mi_size<=0)return;
|
||||
//
|
||||
// mi_count=power_to_2(c);
|
||||
// mi_size=mis;
|
||||
|
||||
// mi_id=dev->CreateVBO(VF_V1U8,mi_count);
|
||||
// mi_id_buffer=mi_id->GetBuffer();
|
||||
|
||||
// mi_data_buffer=dev->CreateUBO(mi_count*mi_size);
|
||||
//}
|
||||
|
||||
void WriteLocalToWorld(RenderNode *render_node,const uint count)
|
||||
{
|
||||
RenderNode *rn;
|
||||
|
||||
//old l2w in vertex input stream
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
//new l2w array in ubo
|
||||
{
|
||||
Matrix4f *tp=(hgl::Matrix4f *)(assigns_l2w->Map());
|
||||
uint16 *idp=(uint16 *)(assigns_vbo->Map());
|
||||
|
||||
rn=render_node;
|
||||
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*tp=rn->local_to_world;
|
||||
++tp;
|
||||
|
||||
*idp=i;
|
||||
++idp;
|
||||
|
||||
++rn;
|
||||
}
|
||||
|
||||
assigns_vbo->Unmap();
|
||||
assigns_l2w->Unmap();
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
@@ -1,26 +1,58 @@
|
||||
# 静态渲染管理
|
||||
|
||||
## 建立静态渲染管理的意义是什么?
|
||||
## 静态渲染的意义是什么?
|
||||
|
||||
静态渲染管理中的“静态”并不是指在场景中静止不动的所有物件,也不是指永远不会增加或删除的物件。
|
||||
而是说大部分时间,都会出现在场景中的物件。
|
||||
静态渲染管理中的“静态”并不是指在场景中静止不动的所有物件,而是说大部分时间都会出现在场景中的物件。它包含地形、花草树木、房屋、常见人物,武器装备等等。如果归划好,可以将绝大部分的物件都划入静态渲染中。
|
||||
|
||||
它的意义为的是所有添加进管理器的模型原始资源,都会一直存在。与它们本身是否显示在画面中,并无关联。为的是避开对显存资源的动态调配。
|
||||
|
||||
在静态渲染管理器中的所有模型,会根据顶点数据格式(Vertex Input Format)分类。每种格式所有模型共用一个大的顶点缓冲对象(Vertex Buffer Object),以达到在渲染时渲染不同模型不会切换VBO的效果,并进一步达成一个格式,一次Drawcall全部画面的极致效果。
|
||||
在静态渲染管理器中的所有模型,会根据顶点数据格式(Vertex Input Format)分类。每种格式所有模型共用一套超大VBO(Vertex Buffer Object),以达到在渲染时渲染不同模型不会切换VBO的效果,并进一步达成“一个格式,一次Drawcall全部画完”的极致效果。
|
||||
|
||||
## 定义
|
||||
## 材质的定义
|
||||
|
||||
1.Material 材质可以简单理解为是Shader的包装。
|
||||
|
||||
2.Vertex Input Layout 顶点输入布局,指的是在渲染中Material所需的顶点输入数据格式。
|
||||
|
||||
但需要注意的是:VertexInputLayout与Material并无从属关系。
|
||||
一个Material可能会有多个VertexInputLayout的版本,不同具体格式的数据输入.
|
||||
多个Material也可能会共用一个VertexInputLayout,比如为某个模型设定的不同画质渲染,它们shader不同,但是共用同一套模型数据。
|
||||
|
||||
3.Material Instance 材质实例是指同一材质下,不同的参数配置或不同的顶点输入格式。
|
||||
2.Material Instance 材质实例是指同一材质下,不同的参数配置。
|
||||
|
||||
## 我们需要做什么?
|
||||
|
||||
|
||||
1.在Shader中,建立两个UBO或SSBO
|
||||
|
||||
```glsl
|
||||
//一个用于存所有Local to World矩阵的数组
|
||||
|
||||
#define MI_MAX_COUNT (UBORange/sizeof(mat4))
|
||||
|
||||
layout(set=?,binding=?) uniform LocalToWorldData
|
||||
{
|
||||
mat4 mats[L2W_MAX_COUNT];
|
||||
}l2w;
|
||||
```
|
||||
|
||||
```glsl
|
||||
//一个用于存所有MaterialInstance数据的数组
|
||||
|
||||
#define MI_MAX_COUNT (UBORange/sizeof(MaterialInstance))
|
||||
|
||||
layout(set=?,binding=?) uniform MaterialInstanceData
|
||||
{
|
||||
MaterialInstance mi_array[MI_MAX_COUNT];
|
||||
}mi;
|
||||
```
|
||||
|
||||
2.建立一个RG8UI或RG16UI的Vertex Input Stream,用于保存访问LocalToWorld/MaterialInstance的索引
|
||||
|
||||
```glsl
|
||||
layout(location=?) in uvec2 Assign; //Local To World矩阵ID与材质ID输入数据流
|
||||
|
||||
mat4 GetLocalToWorld()
|
||||
{
|
||||
return l2w.mats[Assign.x];
|
||||
}
|
||||
|
||||
MaterialInstance GetMaterialInstance()
|
||||
{
|
||||
return mi.mi_array[Assign.y];
|
||||
}
|
||||
```
|
||||
|
||||
|
@@ -12,6 +12,8 @@ const VkDeviceSize GPUDevice::GetSSBORange (){return attr->physical_device->Get
|
||||
|
||||
bool GPUDevice::CreateBuffer(DeviceBufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode)
|
||||
{
|
||||
if(size<=0)return(false);
|
||||
|
||||
BufferCreateInfo buf_info;
|
||||
|
||||
buf_info.usage = buf_usage;
|
||||
@@ -55,6 +57,8 @@ bool GPUDevice::CreateBuffer(DeviceBufferData *buf,VkBufferUsageFlags buf_usage,
|
||||
|
||||
VBO *GPUDevice::CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode)
|
||||
{
|
||||
if(count==0)return(nullptr);
|
||||
|
||||
const uint32_t stride=GetStrideByFormat(format);
|
||||
|
||||
if(stride==0)
|
||||
@@ -75,6 +79,8 @@ VBO *GPUDevice::CreateVBO(VkFormat format,uint32_t count,const void *data,Sharin
|
||||
|
||||
IndexBuffer *GPUDevice::CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sharing_mode)
|
||||
{
|
||||
if(count==0)return(nullptr);
|
||||
|
||||
uint32_t stride;
|
||||
|
||||
if(index_type==IndexType::U8 )stride=1;else
|
||||
@@ -94,6 +100,8 @@ IndexBuffer *GPUDevice::CreateIBO(IndexType index_type,uint32_t count,const void
|
||||
|
||||
DeviceBuffer *GPUDevice::CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode)
|
||||
{
|
||||
if(size<=0)return(nullptr);
|
||||
|
||||
DeviceBufferData buf;
|
||||
|
||||
if(!CreateBuffer(&buf,buf_usage,range,size,data,sharing_mode))
|
||||
|
@@ -3,7 +3,12 @@
|
||||
#include<hgl/graph/VKMaterialDescriptorManager.h>
|
||||
#include<hgl/graph/VKVertexInput.h>
|
||||
#include"VKPipelineLayoutData.h"
|
||||
#include<hgl/type/ActiveMemoryBlockManager.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
void ReleaseVertexInput(VertexInput *vi);
|
||||
|
||||
Material::Material(const AnsiString &n)
|
||||
{
|
||||
name=n;
|
||||
@@ -16,21 +21,20 @@ Material::Material(const AnsiString &n)
|
||||
hgl_zero(mp_array);
|
||||
|
||||
mi_data_bytes=0;
|
||||
mi_max_count=0;
|
||||
mi_data_manager=nullptr;
|
||||
}
|
||||
|
||||
Material::~Material()
|
||||
{
|
||||
SAFE_CLEAR(vertex_input);
|
||||
SAFE_CLEAR(mi_data_manager);
|
||||
|
||||
ReleaseVertexInput(vertex_input);
|
||||
delete shader_maps; //不用SAFE_CLEAR是因为这个一定会有
|
||||
SAFE_CLEAR(desc_manager);
|
||||
SAFE_CLEAR(pipeline_layout_data);
|
||||
|
||||
for(int i=0;i<DESCRIPTOR_SET_TYPE_COUNT;i++)
|
||||
SAFE_CLEAR(mp_array[i]);
|
||||
|
||||
mi_data_bytes=0;
|
||||
mi_max_count=0;
|
||||
}
|
||||
|
||||
const VkPipelineLayout Material::GetPipelineLayout()const
|
||||
@@ -43,6 +47,11 @@ const bool Material::hasSet(const DescriptorSetType &dst)const
|
||||
return desc_manager->hasSet(dst);
|
||||
}
|
||||
|
||||
const VIL *Material::GetDefaultVIL()const
|
||||
{
|
||||
return vertex_input->GetDefaultVIL();
|
||||
}
|
||||
|
||||
VIL *Material::CreateVIL(const VILConfig *format_map)
|
||||
{
|
||||
return vertex_input->CreateVIL(format_map);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include<hgl/graph/VKMaterialInstance.h>
|
||||
#include<hgl/graph/VKMaterialParameters.h>
|
||||
#include<hgl/graph/VKShaderModule.h>
|
||||
#include<hgl/type/ActiveMemoryBlockManager.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
MaterialInstance *Material::CreateMI(const VILConfig *vil_cfg)
|
||||
@@ -10,14 +11,48 @@ MaterialInstance *Material::CreateMI(const VILConfig *vil_cfg)
|
||||
|
||||
if(!vil)return(nullptr);
|
||||
|
||||
return(new MaterialInstance(this,vil));
|
||||
int mi_id=-1;
|
||||
|
||||
if(mi_data_manager)
|
||||
mi_data_manager->GetOrCreate(&mi_id,1);
|
||||
else
|
||||
mi_id=-1;
|
||||
|
||||
return(new MaterialInstance(this,vil,mi_id));
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(Material *mtl,VIL *v)
|
||||
void Material::ReleaseMI(int mi_id)
|
||||
{
|
||||
if(mi_id<0||!mi_data_manager)return;
|
||||
|
||||
mi_data_manager->Release(&mi_id,1);
|
||||
}
|
||||
|
||||
void *Material::GetMIData(int id)
|
||||
{
|
||||
if(!mi_data_manager)
|
||||
return(nullptr);
|
||||
|
||||
return mi_data_manager->GetData(id);
|
||||
}
|
||||
|
||||
void MaterialInstance::WriteMIData(const void *data,const int size)
|
||||
{
|
||||
if(!data||size<=0||size>material->GetMIDataBytes())return;
|
||||
|
||||
void *tp=GetMIData();
|
||||
|
||||
if(tp)
|
||||
memcpy(tp,data,size);
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(Material *mtl,VIL *v,const int id)
|
||||
{
|
||||
material=mtl;
|
||||
|
||||
vil=v;
|
||||
|
||||
mi_id=id;
|
||||
}
|
||||
|
||||
bool MaterialInstance::BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic)
|
||||
|
@@ -56,33 +56,14 @@ Pipeline *RenderPass::CreatePipeline(PipelineData *pd,const ShaderStageCreateInf
|
||||
return(new Pipeline(device,graphicsPipeline,pd));
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const InlinePipeline &ip,const Prim &prim,const bool prim_restart)
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(Material *mtl,const VIL *vil,const PipelineData *cpd,const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
if(!mi)return(nullptr);
|
||||
|
||||
Material *mtl=mi->GetMaterial();
|
||||
const PipelineData *cpd=GetPipelineData(ip);
|
||||
|
||||
PipelineData *pd=new PipelineData(cpd);
|
||||
|
||||
pd->SetPrim(prim,prim_restart);
|
||||
|
||||
Pipeline *p=CreatePipeline(pd,mtl->GetStageList(),mtl->GetPipelineLayout(),mi->GetVIL());
|
||||
|
||||
if(p)
|
||||
pipeline_list.Add(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cpd,const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
Material *mtl=mi->GetMaterial();
|
||||
PipelineData *pd=new PipelineData(cpd);
|
||||
|
||||
pd->SetPrim(prim,prim_restart);
|
||||
|
||||
Pipeline *p=CreatePipeline(pd,mtl->GetStageList(),mtl->GetPipelineLayout(),mi->GetVIL());
|
||||
Pipeline *p=CreatePipeline(pd,mtl->GetStageList(),mtl->GetPipelineLayout(),vil);
|
||||
|
||||
if(p)
|
||||
pipeline_list.Add(p);
|
||||
@@ -90,6 +71,35 @@ Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cp
|
||||
return(p);
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(Material *mtl,const VIL *vil,const InlinePipeline &ip,const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
if(!mtl)return(nullptr);
|
||||
|
||||
return CreatePipeline(mtl,vil,GetPipelineData(ip),prim,prim_restart);
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(Material *mtl,const PipelineData *pd, const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
return CreatePipeline(mtl,mtl->GetDefaultVIL(),pd,prim,prim_restart);
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(Material *mtl,const InlinePipeline &ip, const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
return CreatePipeline(mtl,mtl->GetDefaultVIL(),ip,prim,prim_restart);
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const InlinePipeline &ip,const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
if(!mi)return(nullptr);
|
||||
|
||||
return CreatePipeline(mi->GetMaterial(),mi->GetVIL(),ip,prim,prim_restart);
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cpd,const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
return CreatePipeline(mi->GetMaterial(),mi->GetVIL(),cpd,prim,prim_restart);
|
||||
}
|
||||
|
||||
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const OSString &pipeline_filename,const Prim &prim,const bool prim_restart)
|
||||
{
|
||||
const PipelineData *pd=GetPipelineData(pipeline_filename);
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include<hgl/io/ConstBufferReader.h>
|
||||
#include<hgl/shadergen/MaterialCreateInfo.h>
|
||||
#include<hgl/shadergen/ShaderDescriptorInfo.h>
|
||||
#include<hgl/type/ActiveMemoryBlockManager.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
@@ -123,7 +124,7 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
|
||||
ShaderCreateInfoVertex *vert=mci->GetVS();
|
||||
|
||||
if(vert)
|
||||
mtl->vertex_input=new VertexInput(vert->sdm->GetShaderStageIO().input);
|
||||
mtl->vertex_input=GetVertexInput(vert->sdm->GetShaderStageIO().input);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -147,6 +148,11 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
|
||||
mtl->mi_data_bytes =mci->GetMIDataBytes();
|
||||
mtl->mi_max_count =mci->GetMIMaxCount();
|
||||
|
||||
if(mtl->mi_data_bytes>0)
|
||||
{
|
||||
mtl->mi_data_manager=new ActiveMemoryBlockManager(mtl->mi_data_bytes);
|
||||
}
|
||||
|
||||
Add(mtl);
|
||||
|
||||
material_by_name.Add(mtl_name,mtl);
|
||||
|
@@ -27,10 +27,7 @@ MaterialCreateInfo::MaterialCreateInfo(const MaterialCreateConfig *mc)
|
||||
}
|
||||
|
||||
{
|
||||
l2w_max_count=ubo_range/sizeof(Matrix4f);
|
||||
|
||||
if(l2w_max_count>HGL_U16_MAX)
|
||||
l2w_max_count=HGL_U16_MAX;
|
||||
l2w_max_count=hgl_min<uint32_t>(ubo_range/sizeof(Matrix4f),HGL_U16_MAX);
|
||||
|
||||
l2w_shader_stage=0;
|
||||
l2w_ubo=nullptr;
|
||||
@@ -158,20 +155,15 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
|
||||
if(data_bytes>0)
|
||||
mi_codes=glsl_codes;
|
||||
|
||||
{
|
||||
mi_max_count=ubo_range/data_bytes;
|
||||
|
||||
if(mi_max_count>HGL_U16_MAX) //我们使用uint16传递材质实例ID,所以最大数量为65535。未来如考虑使用更多,需综合考虑
|
||||
mi_max_count=HGL_U16_MAX;
|
||||
}
|
||||
mi_max_count=hgl_min<uint32_t>(ubo_range/data_bytes,HGL_U16_MAX);
|
||||
|
||||
mdi.AddStruct(MaterialInstanceStruct,mi_codes);
|
||||
mdi.AddStruct(SBS_MaterialInstanceData);
|
||||
mdi.AddStruct(SBS_MaterialInstance);
|
||||
|
||||
mi_ubo=new UBODescriptor();
|
||||
|
||||
mi_ubo->type=SBS_MaterialInstanceData.struct_name;
|
||||
hgl::strcpy(mi_ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstanceData.name);
|
||||
mi_ubo->type=SBS_MaterialInstance.struct_name;
|
||||
hgl::strcpy(mi_ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstance.name);
|
||||
mi_ubo->stage_flag=shader_stage_flag_bits;
|
||||
|
||||
mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,mi_ubo);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include<hgl/shadergen/ShaderDescriptorInfo.h>
|
||||
#include<hgl/graph/VertexAttrib.h>
|
||||
#include<hgl/graph/VKShaderStage.h>
|
||||
#include<hgl/graph/VKRenderAssign.h>
|
||||
#include"GLSLCompiler.h"
|
||||
#include"common/MFCommon.h"
|
||||
|
||||
@@ -39,9 +40,10 @@ void ShaderCreateInfoVertex::AddJoint()
|
||||
|
||||
void ShaderCreateInfoVertex::AddAssign()
|
||||
{
|
||||
char name[]="Assign";
|
||||
|
||||
AddInput(VAT_UINT,name,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::Assign);
|
||||
AddInput( ASSIGN_VAT_FMT,
|
||||
ASSIGN_VIS_NAME,
|
||||
VK_VERTEX_INPUT_RATE_INSTANCE,
|
||||
VertexInputGroup::Assign);
|
||||
|
||||
AddFunction(mtl::func::GetLocalToWorld);
|
||||
}
|
||||
|
Reference in New Issue
Block a user