diff --git a/inc/hgl/graph/VKDevice.h b/inc/hgl/graph/VKDevice.h index d3aa9e5d..bd5a533f 100644 --- a/inc/hgl/graph/VKDevice.h +++ b/inc/hgl/graph/VKDevice.h @@ -18,7 +18,6 @@ #include VK_NAMESPACE_BEGIN - class TileData; class TileFont; class FontSource; @@ -187,8 +186,10 @@ public: // public: //shader & material 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 相关 diff --git a/inc/hgl/graph/VKMaterial.h b/inc/hgl/graph/VKMaterial.h index 5dcbc5b1..ccccdd2f 100644 --- a/inc/hgl/graph/VKMaterial.h +++ b/inc/hgl/graph/VKMaterial.h @@ -11,7 +11,7 @@ using ShaderStageCreateInfoList=List; struct MaterialData { - UTF8String name; + AnsiString name; VertexInput *vertex_input; @@ -25,12 +25,12 @@ struct MaterialData MaterialParameters *mp_array[DESCRIPTOR_SET_TYPE_COUNT]; - uint32_t mi_data_bytes; + uint32_t mi_data_bytes; ///<实例数据大小 + uint32_t mi_max_count; ///<最大实例数量(注:代表一次drawcall大小,而不是整个的大小) -private: - - friend class Material; +public: + MaterialData(const AnsiString &n); ~MaterialData(); };//struct MaterialData diff --git a/inc/hgl/shadergen/MaterialCreateInfo.h b/inc/hgl/shadergen/MaterialCreateInfo.h index d1ad2570..a09714d9 100644 --- a/inc/hgl/shadergen/MaterialCreateInfo.h +++ b/inc/hgl/shadergen/MaterialCreateInfo.h @@ -27,6 +27,7 @@ namespace hgl{namespace graph AnsiString mi_codes; ///pipeline_layout,desc_set)); } - - void CreateShaderStageList(List &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;ivalue; - 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((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 -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) - return(nullptr); + DescriptorSet *ds=CreateDS(attr->device,attr->desc_pool,pld,desc_set_type); - PipelineLayoutData *pld=CreatePipelineLayoutData(attr->device,desc_manager); - - if(!pld) - { - delete shader_maps; - SAFE_CLEAR(desc_manager); - return(nullptr); - } + if(!ds)return(nullptr); - MaterialData *data=new MaterialData; +#ifdef _DEBUG + const UTF8String addr_string=HexToString((uint64_t)(ds->GetDescriptorSet())); - data->name =mtl_name; - data->shader_maps =shader_maps; - data->desc_manager =desc_manager; - data->vertex_input =vi; + LOG_INFO(U8_TEXT("Create [DescriptSets:")+addr_string+("] OK! Material Name: \"")+desc_manager->GetMaterialName()+U8_TEXT("\" Type: ")+GetDescriptorSetTypeName(desc_set_type)); +#endif//_DEBUG - 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)); + return(new MaterialParameters(desc_manager,desc_set_type,ds)); } VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMaterial.cpp b/src/SceneGraph/Vulkan/VKMaterial.cpp index 61100181..46715f8f 100644 --- a/src/SceneGraph/Vulkan/VKMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKMaterial.cpp @@ -4,16 +4,33 @@ #include #include"VKPipelineLayoutData.h" 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() { - for(int i=0;i VK_NAMESPACE_BEGIN -PipelineLayoutData *CreatePipelineLayoutData(VkDevice device,const MaterialDescriptorManager *desc_manager) +PipelineLayoutData *GPUDevice::CreatePipelineLayoutData(const MaterialDescriptorManager *desc_manager) { PipelineLayoutData *pld=hgl_zero_new(); @@ -18,9 +18,9 @@ PipelineLayoutData *CreatePipelineLayoutData(VkDevice device,const MaterialDescr continue; 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; return(nullptr); @@ -56,9 +56,9 @@ PipelineLayoutData *CreatePipelineLayoutData(VkDevice device,const MaterialDescr pPipelineLayoutCreateInfo.pushConstantRangeCount = 0;//1; 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; return(nullptr); diff --git a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp index 127d367c..30ac1122 100644 --- a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp @@ -12,6 +12,30 @@ #include VK_NAMESPACE_BEGIN + +namespace +{ + void CreateShaderStageList(List &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;ivalue; + hgl_cpy(p,sm->GetCreateInfo(),1); + + ++p; + ++itp; + } + } +}//namespace + const ShaderModule *RenderResource::CreateShaderModule(const AnsiString &sm_name,const ShaderCreateInfo *sci) { if(!device)return(nullptr); @@ -62,64 +86,66 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci) if(material_by_name.Get(mtl_name,mtl)) return mtl; - const uint count=GetShaderCountByBits(mci->GetShaderStage()); - const ShaderModule *sm; + const ShaderCreateInfoMap &sci_map=mci->GetShaderMap(); + const uint sci_count=sci_map.GetCount(); - ShaderModuleMap *smm=new ShaderModuleMap; - VertexInput *vertex_input=nullptr; + if(sci_count<2) + return(nullptr); - const ShaderCreateInfoVertex *vert=mci->GetVS(); + if(!mci->GetFS()) + return(nullptr); + + AutoDelete data=new MaterialData(mtl_name); - if(vert) { - sm=CreateShaderModule(mtl_name,vert); + const ShaderModule *sm; - if(!sm) - return(false); + auto **sci=sci_map.GetDataList(); - if(smm->Add(sm)) - vertex_input=new VertexInput(vert->sdm->GetShaderStageIO().input); + for(uint i=0;ivalue); + + 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(); 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; - delete smm; - } - else - { - Add(mtl); + ENUM_CLASS_FOR(DescriptorSetType,int,dst) + { + if(data->desc_manager->hasSet((DescriptorSetType)dst)) + data->mp_array[dst]=device->CreateMP(data->desc_manager,data->pipeline_layout_data,(DescriptorSetType)dst); + } } + 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); return mtl; } diff --git a/src/ShaderGen/MaterialCreateInfo.cpp b/src/ShaderGen/MaterialCreateInfo.cpp index 3da3f283..c25d2058 100644 --- a/src/ShaderGen/MaterialCreateInfo.cpp +++ b/src/ShaderGen/MaterialCreateInfo.cpp @@ -141,10 +141,14 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const if(data_bytes>0) mi_codes=glsl_codes; - const uint32_t ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16k,Intel/PowerVR为128M,AMD无限制。nVidia和Mali-G除G71外为64k - const uint32_t mi_max_count=ubo_range/data_bytes; + const uint32_t ubo_range=config->dev_attr->physical_device->GetUBORange(); //Mali-T系/G71为16k,nVidia和Mali-G系列除G71外为64k,Intel/PowerVR为128M,AMD无限制。 + + 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>256?256:mi_max_count); //我们使用uint8传递材质实例ID,所以最大数量为256。未来如考虑使用更多,需综合考虑 + const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count); mdi.AddStruct(MaterialInstanceStruct,mi_codes); mdi.AddStruct(SBS_MaterialInstanceData);