optimized codes about CreateMaterial

This commit is contained in:
HuYingzhuo(hugo/hyzboy) 2023-06-14 16:49:19 +08:00
parent b021b05cb0
commit 82f3ad070b
8 changed files with 126 additions and 136 deletions

View File

@ -18,7 +18,6 @@
#include<hgl/graph/VKDescriptorSetType.h> #include<hgl/graph/VKDescriptorSetType.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class TileData; class TileData;
class TileFont; class TileFont;
class FontSource; class FontSource;
@ -188,7 +187,9 @@ public: //shader & material
ShaderModule *CreateShaderModule(VkShaderStageFlagBits,const uint32_t *,const size_t); ShaderModule *CreateShaderModule(VkShaderStageFlagBits,const uint32_t *,const size_t);
Material *CreateMaterial(const UTF8String &mtl_name,ShaderModuleMap *shader_maps,MaterialDescriptorManager *,VertexInput *); PipelineLayoutData *CreatePipelineLayoutData(const MaterialDescriptorManager *desc_manager);
MaterialParameters *CreateMP(const MaterialDescriptorManager *desc_manager,const PipelineLayoutData *pld,const DescriptorSetType &desc_set_type);
public: //Command Buffer 相关 public: //Command Buffer 相关

View File

@ -11,7 +11,7 @@ using ShaderStageCreateInfoList=List<VkPipelineShaderStageCreateInfo>;
struct MaterialData struct MaterialData
{ {
UTF8String name; AnsiString name;
VertexInput *vertex_input; VertexInput *vertex_input;
@ -25,12 +25,12 @@ struct MaterialData
MaterialParameters *mp_array[DESCRIPTOR_SET_TYPE_COUNT]; MaterialParameters *mp_array[DESCRIPTOR_SET_TYPE_COUNT];
uint32_t mi_data_bytes; uint32_t mi_data_bytes; ///<实例数据大小
uint32_t mi_max_count; ///<最大实例数量(注代表一次drawcall大小而不是整个的大小)
private: public:
friend class Material;
MaterialData(const AnsiString &n);
~MaterialData(); ~MaterialData();
};//struct MaterialData };//struct MaterialData

View File

@ -27,6 +27,7 @@ namespace hgl{namespace graph
AnsiString mi_codes; ///<MaterialInstance代码 AnsiString mi_codes; ///<MaterialInstance代码
uint32_t mi_data_bytes; ///<MaterialInstance数据长度 uint32_t mi_data_bytes; ///<MaterialInstance数据长度
uint32_t mi_shader_stage; ///<MaterialInstance着色器阶段 uint32_t mi_shader_stage; ///<MaterialInstance着色器阶段
uint32_t mi_max_count; ///<MaterialInstance最大数量
ShaderCreateInfoMap shader_map; ///<着色器列表 ShaderCreateInfoMap shader_map; ///<着色器列表
@ -53,10 +54,14 @@ namespace hgl{namespace graph
ShaderCreateInfoGeometry * GetGS()const{return geom;} ShaderCreateInfoGeometry * GetGS()const{return geom;}
ShaderCreateInfoFragment * GetFS()const{return frag;} ShaderCreateInfoFragment * GetFS()const{return frag;}
const ShaderCreateInfoMap &GetShaderMap()const{return shader_map;}
public: public:
const MaterialDescriptorInfo &GetMDI()const{return mdi;} const MaterialDescriptorInfo &GetMDI()const{return mdi;}
const uint32_t GetMIDataBytes()const{return mi_data_bytes;}
const uint32_t GetMIDataBytes ()const{return mi_data_bytes;}
const uint32_t GetMIMaxCount ()const{return mi_max_count;}
public: public:

View File

@ -35,86 +35,23 @@ namespace
return(new DescriptorSet(device,binding_count,pld->pipeline_layout,desc_set)); return(new DescriptorSet(device,binding_count,pld->pipeline_layout,desc_set));
} }
void CreateShaderStageList(List<VkPipelineShaderStageCreateInfo> &shader_stage_list,ShaderModuleMap *shader_maps)
{
const ShaderModule *sm;
const int shader_count=shader_maps->GetCount();
shader_stage_list.SetCount(shader_count);
VkPipelineShaderStageCreateInfo *p=shader_stage_list.GetData();
auto **itp=shader_maps->GetDataList();
for(int i=0;i<shader_count;i++)
{
sm=(*itp)->value;
hgl_cpy(p,sm->GetCreateInfo(),1);
++p;
++itp;
}
}
MaterialParameters *CreateMP(VkDevice device,VkDescriptorPool desc_pool,const MaterialDescriptorManager *desc_manager,const PipelineLayoutData *pld,const DescriptorSetType &desc_set_type)
{
if(!desc_manager||!pld)return(nullptr);
RANGE_CHECK_RETURN_NULLPTR(desc_set_type)
DescriptorSet *ds=CreateDS(device,desc_pool,pld,desc_set_type);
if(!ds)return(nullptr);
#ifdef _DEBUG
const UTF8String addr_string=HexToString<char,uint64_t>((uint64_t)(ds->GetDescriptorSet()));
LOG_INFO(U8_TEXT("Create [DescriptSets:")+addr_string+("] OK! Material Name: \"")+desc_manager->GetMaterialName()+U8_TEXT("\" Type: ")+GetDescriptorSetTypeName(desc_set_type));
#endif//_DEBUG
return(new MaterialParameters(desc_manager,desc_set_type,ds));
}
}//namespace }//namespace
Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,ShaderModuleMap *shader_maps,MaterialDescriptorManager *desc_manager,VertexInput *vi) MaterialParameters *GPUDevice::CreateMP(const MaterialDescriptorManager *desc_manager,const PipelineLayoutData *pld,const DescriptorSetType &desc_set_type)
{ {
const int shader_count=shader_maps->GetCount(); if(!desc_manager||!pld)return(nullptr);
RANGE_CHECK_RETURN_NULLPTR(desc_set_type)
if(shader_count<1) DescriptorSet *ds=CreateDS(attr->device,attr->desc_pool,pld,desc_set_type);
return(nullptr);
PipelineLayoutData *pld=CreatePipelineLayoutData(attr->device,desc_manager); if(!ds)return(nullptr);
if(!pld) #ifdef _DEBUG
{ const UTF8String addr_string=HexToString<char,uint64_t>((uint64_t)(ds->GetDescriptorSet()));
delete shader_maps;
SAFE_CLEAR(desc_manager);
return(nullptr);
}
MaterialData *data=new MaterialData; LOG_INFO(U8_TEXT("Create [DescriptSets:")+addr_string+("] OK! Material Name: \"")+desc_manager->GetMaterialName()+U8_TEXT("\" Type: ")+GetDescriptorSetTypeName(desc_set_type));
#endif//_DEBUG
data->name =mtl_name; return(new MaterialParameters(desc_manager,desc_set_type,ds));
data->shader_maps =shader_maps;
data->desc_manager =desc_manager;
data->vertex_input =vi;
CreateShaderStageList(data->shader_stage_list,shader_maps);
data->pipeline_layout_data=pld;
if(desc_manager)
{
ENUM_CLASS_FOR(DescriptorSetType,int,dst)
{
if(desc_manager->hasSet((DescriptorSetType)dst))
data->mp_array[dst]=CreateMP(attr->device,attr->desc_pool,desc_manager,pld,(DescriptorSetType)dst);
else
data->mp_array[dst]=nullptr;
}
}
else
hgl_zero(data->mp_array);
return(new Material(data));
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -4,16 +4,33 @@
#include<hgl/graph/VKVertexInput.h> #include<hgl/graph/VKVertexInput.h>
#include"VKPipelineLayoutData.h" #include"VKPipelineLayoutData.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
MaterialData::MaterialData(const AnsiString &n)
{
name=n;
vertex_input=nullptr;
shader_maps=new ShaderModuleMap;
desc_manager=nullptr;
pipeline_layout_data=nullptr;
hgl_zero(mp_array);
mi_data_bytes=0;
mi_max_count=0;
}
MaterialData::~MaterialData() MaterialData::~MaterialData()
{ {
for(int i=0;i<DESCRIPTOR_SET_TYPE_COUNT;i++) SAFE_CLEAR(vertex_input);
if(mp_array[i]) delete shader_maps; //不用SAFE_CLEAR是因为这个一定会有
delete mp_array[i];
delete shader_maps;
SAFE_CLEAR(desc_manager); SAFE_CLEAR(desc_manager);
SAFE_CLEAR(pipeline_layout_data);
delete vertex_input; for(int i=0;i<DESCRIPTOR_SET_TYPE_COUNT;i++)
SAFE_CLEAR(mp_array[i]);
mi_data_bytes=0;
mi_max_count=0;
} }
Material::~Material() Material::~Material()

View File

@ -4,7 +4,7 @@
#include<hgl/graph/VKMaterialDescriptorManager.h> #include<hgl/graph/VKMaterialDescriptorManager.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
PipelineLayoutData *CreatePipelineLayoutData(VkDevice device,const MaterialDescriptorManager *desc_manager) PipelineLayoutData *GPUDevice::CreatePipelineLayoutData(const MaterialDescriptorManager *desc_manager)
{ {
PipelineLayoutData *pld=hgl_zero_new<PipelineLayoutData>(); PipelineLayoutData *pld=hgl_zero_new<PipelineLayoutData>();
@ -18,9 +18,9 @@ PipelineLayoutData *CreatePipelineLayoutData(VkDevice device,const MaterialDescr
continue; continue;
if(pld->layouts[i]) if(pld->layouts[i])
vkDestroyDescriptorSetLayout(device,pld->layouts[i],nullptr); vkDestroyDescriptorSetLayout(attr->device,pld->layouts[i],nullptr);
if(vkCreateDescriptorSetLayout(device,dslci,nullptr,pld->layouts+i)!=VK_SUCCESS) if(vkCreateDescriptorSetLayout(attr->device,dslci,nullptr,pld->layouts+i)!=VK_SUCCESS)
{ {
delete pld; delete pld;
return(nullptr); return(nullptr);
@ -56,9 +56,9 @@ PipelineLayoutData *CreatePipelineLayoutData(VkDevice device,const MaterialDescr
pPipelineLayoutCreateInfo.pushConstantRangeCount = 0;//1; pPipelineLayoutCreateInfo.pushConstantRangeCount = 0;//1;
pPipelineLayoutCreateInfo.pPushConstantRanges = nullptr;//&push_constant_range; pPipelineLayoutCreateInfo.pPushConstantRanges = nullptr;//&push_constant_range;
pld->device=device; pld->device=attr->device;
if(vkCreatePipelineLayout(device,&pPipelineLayoutCreateInfo,nullptr,&(pld->pipeline_layout))!=VK_SUCCESS) if(vkCreatePipelineLayout(attr->device,&pPipelineLayoutCreateInfo,nullptr,&(pld->pipeline_layout))!=VK_SUCCESS)
{ {
delete pld; delete pld;
return(nullptr); return(nullptr);

View File

@ -12,6 +12,30 @@
#include<hgl/shadergen/ShaderDescriptorInfo.h> #include<hgl/shadergen/ShaderDescriptorInfo.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
namespace
{
void CreateShaderStageList(List<VkPipelineShaderStageCreateInfo> &shader_stage_list,ShaderModuleMap *shader_maps)
{
const ShaderModule *sm;
const int shader_count=shader_maps->GetCount();
shader_stage_list.SetCount(shader_count);
VkPipelineShaderStageCreateInfo *p=shader_stage_list.GetData();
auto **itp=shader_maps->GetDataList();
for(int i=0;i<shader_count;i++)
{
sm=(*itp)->value;
hgl_cpy(p,sm->GetCreateInfo(),1);
++p;
++itp;
}
}
}//namespace
const ShaderModule *RenderResource::CreateShaderModule(const AnsiString &sm_name,const ShaderCreateInfo *sci) const ShaderModule *RenderResource::CreateShaderModule(const AnsiString &sm_name,const ShaderCreateInfo *sci)
{ {
if(!device)return(nullptr); if(!device)return(nullptr);
@ -62,64 +86,66 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
if(material_by_name.Get(mtl_name,mtl)) if(material_by_name.Get(mtl_name,mtl))
return mtl; return mtl;
const uint count=GetShaderCountByBits(mci->GetShaderStage()); const ShaderCreateInfoMap &sci_map=mci->GetShaderMap();
const ShaderModule *sm; const uint sci_count=sci_map.GetCount();
ShaderModuleMap *smm=new ShaderModuleMap; if(sci_count<2)
VertexInput *vertex_input=nullptr; return(nullptr);
const ShaderCreateInfoVertex *vert=mci->GetVS(); if(!mci->GetFS())
return(nullptr);
AutoDelete<MaterialData> data=new MaterialData(mtl_name);
if(vert)
{ {
sm=CreateShaderModule(mtl_name,vert); const ShaderModule *sm;
if(!sm) auto **sci=sci_map.GetDataList();
return(false);
if(smm->Add(sm)) for(uint i=0;i<sci_count;i++)
vertex_input=new VertexInput(vert->sdm->GetShaderStageIO().input); {
sm=CreateShaderModule(mtl_name,(*sci)->value);
if(!sm)
return(nullptr);
data->shader_maps->Add(sm);
if((*sci)->key==VK_SHADER_STAGE_VERTEX_BIT)
data->vertex_input=new VertexInput((*sci)->value->sdm->GetShaderStageIO().input);
++sci;
}
CreateShaderStageList(data->shader_stage_list,data->shader_maps);
} }
const ShaderCreateInfoGeometry *geom=mci->GetGS();
if(geom)
{
sm=CreateShaderModule(mtl_name,geom);
smm->Add(sm);
}
const ShaderCreateInfoFragment *frag=mci->GetFS();
if(frag)
{
sm=CreateShaderModule(mtl_name,frag);
smm->Add(sm);
}
MaterialDescriptorManager *mdm=nullptr;
{ {
const auto &mdi=mci->GetMDI(); const auto &mdi=mci->GetMDI();
if(mdi.GetCount()>0) if(mdi.GetCount()>0)
mdm=new MaterialDescriptorManager(mci->GetName(),mdi.Get()); data->desc_manager=new MaterialDescriptorManager(mci->GetName(),mdi.Get());
} }
mtl=device->CreateMaterial(mci->GetName(),smm,mdm,vertex_input); data->pipeline_layout_data=device->CreatePipelineLayoutData(data->desc_manager);
if(!mtl) if(data->desc_manager)
{ {
delete mdm; ENUM_CLASS_FOR(DescriptorSetType,int,dst)
delete smm; {
} if(data->desc_manager->hasSet((DescriptorSetType)dst))
else data->mp_array[dst]=device->CreateMP(data->desc_manager,data->pipeline_layout_data,(DescriptorSetType)dst);
{ }
Add(mtl);
} }
data->mi_data_bytes =mci->GetMIDataBytes();
data->mi_max_count =mci->GetMIMaxCount();
mtl=new Material(data);
data.Discard(); //mtl已经接管了data的内容这里不需要再释放
Add(mtl);
material_by_name.Add(mtl_name,mtl); material_by_name.Add(mtl_name,mtl);
return mtl; return mtl;
} }

View File

@ -141,10 +141,14 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
if(data_bytes>0) if(data_bytes>0)
mi_codes=glsl_codes; mi_codes=glsl_codes;
const uint32_t ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16kIntel/PowerVR为128MAMD无限制。nVidia和Mali-G除G71外为64k const uint32_t ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16knVidia和Mali-G系列除G71外为64kIntel/PowerVR为128MAMD无限制。
const uint32_t mi_max_count=ubo_range/data_bytes;
const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count>256?256:mi_max_count); //我们使用uint8传递材质实例ID所以最大数量为256。未来如考虑使用更多需综合考虑 mi_max_count=ubo_range/data_bytes;
if(mi_max_count>256) //我们使用uint8传递材质实例ID所以最大数量为256。未来如考虑使用更多需综合考虑
mi_max_count=256;
const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count);
mdi.AddStruct(MaterialInstanceStruct,mi_codes); mdi.AddStruct(MaterialInstanceStruct,mi_codes);
mdi.AddStruct(SBS_MaterialInstanceData); mdi.AddStruct(SBS_MaterialInstanceData);