From e259b76653c471597a8b474f3dc5cc03fb285356 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Mon, 13 Sep 2021 20:39:25 +0800 Subject: [PATCH] new MaterialDescriptorSets --- inc/hgl/graph/VK.h | 13 ++ inc/hgl/graph/VKDevice.h | 2 +- inc/hgl/graph/VKMaterial.h | 10 +- inc/hgl/graph/VKMaterialDescriptorSets.h | 82 ++++++++++++ inc/hgl/graph/VKMaterialParameters.h | 4 +- inc/hgl/graph/VKShaderModule.h | 9 +- inc/hgl/graph/VKShaderModuleMap.h | 24 ---- inc/hgl/graph/VKShaderResource.h | 71 ++++++++++ inc/hgl/graph/shader/ShaderResource.h | 124 ------------------ src/SceneGraph/CMakeLists.txt | 30 ++--- .../Vulkan/VKDescriptorSetLayoutCreater.cpp | 91 ++++--------- .../Vulkan/VKDescriptorSetLayoutCreater.h | 37 +----- src/SceneGraph/Vulkan/VKDeviceMaterial.cpp | 27 +--- src/SceneGraph/Vulkan/VKMaterial.cpp | 27 +++- .../Vulkan/VKMaterialDescriptorSets.cpp | 107 +++++++++++++++ .../Vulkan/VKMaterialParameters.cpp | 12 +- .../Vulkan/VKRenderResourceMaterial.cpp | 67 +++++----- src/SceneGraph/Vulkan/VKShaderModuleMap.cpp | 25 ---- .../VKShaderResource.cpp} | 28 +--- 19 files changed, 394 insertions(+), 396 deletions(-) create mode 100644 inc/hgl/graph/VKMaterialDescriptorSets.h create mode 100644 inc/hgl/graph/VKShaderResource.h delete mode 100644 inc/hgl/graph/shader/ShaderResource.h create mode 100644 src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp rename src/SceneGraph/{shader/ShaderResource.cpp => Vulkan/VKShaderResource.cpp} (78%) diff --git a/inc/hgl/graph/VK.h b/inc/hgl/graph/VK.h index 32a5c1ab..37010c33 100644 --- a/inc/hgl/graph/VK.h +++ b/inc/hgl/graph/VK.h @@ -14,6 +14,18 @@ VK_NAMESPACE_BEGIN +#ifndef VK_DESCRIPTOR_TYPE_BEGIN_RANGE +constexpr size_t VK_DESCRIPTOR_TYPE_BEGIN_RANGE=VK_DESCRIPTOR_TYPE_SAMPLER; +#endif//VK_DESCRIPTOR_TYPE_BEGIN_RANGE + +#ifndef VK_DESCRIPTOR_TYPE_END_RANGE +constexpr size_t VK_DESCRIPTOR_TYPE_END_RANGE=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; +#endif//VK_DESCRIPTOR_TYPE_END_RANGE + +#ifndef VK_DESCRIPTOR_TYPE_RANGE_SIZE +constexpr size_t VK_DESCRIPTOR_TYPE_RANGE_SIZE=VK_DESCRIPTOR_TYPE_END_RANGE-VK_DESCRIPTOR_TYPE_BEGIN_RANGE+1; +#endif//VK_DESCRIPTOR_TYPE_RANGE_SIZE + using CharPointerList=hgl::List; using BindingMapping=Map; @@ -78,6 +90,7 @@ class ShaderResource; class ShaderModule; class VertexShaderModule; class ShaderModuleMap; +class MaterialDescriptorSets; class Material; class MaterialParameters; diff --git a/inc/hgl/graph/VKDevice.h b/inc/hgl/graph/VKDevice.h index 84832b21..c1ce6897 100644 --- a/inc/hgl/graph/VKDevice.h +++ b/inc/hgl/graph/VKDevice.h @@ -191,7 +191,7 @@ public: // public: //shader & material - DescriptorSetLayoutCreater *CreateDescriptorSetLayoutCreater(); + DescriptorSetLayoutCreater *CreateDescriptorSetLayoutCreater(const MaterialDescriptorSets *); ShaderModule *CreateShaderModule(ShaderResource *); diff --git a/inc/hgl/graph/VKMaterial.h b/inc/hgl/graph/VKMaterial.h index a8ee66bc..227b9e1f 100644 --- a/inc/hgl/graph/VKMaterial.h +++ b/inc/hgl/graph/VKMaterial.h @@ -18,8 +18,10 @@ class Material UTF8String mtl_name; ShaderModuleMap *shader_maps; + MaterialDescriptorSets *mds; + VertexShaderModule *vertex_sm; - List *shader_stage_list; + List shader_stage_list; DescriptorSetLayoutCreater *dsl_creater; @@ -29,15 +31,15 @@ class Material public: - Material(const UTF8String &name,ShaderModuleMap *smm,List *,DescriptorSetLayoutCreater *dslc); + Material(const UTF8String &name,ShaderModuleMap *smm,MaterialDescriptorSets *_mds,DescriptorSetLayoutCreater *); ~Material(); const UTF8String & GetName ()const{return mtl_name;} const VertexShaderModule * GetVertexShaderModule ()const{return vertex_sm;} - const uint32_t GetStageCount ()const{return shader_stage_list->GetCount();} - const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list->GetData();} + const uint32_t GetStageCount ()const{return shader_stage_list.GetCount();} + const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();} const VkPipelineLayout GetPipelineLayout ()const; diff --git a/inc/hgl/graph/VKMaterialDescriptorSets.h b/inc/hgl/graph/VKMaterialDescriptorSets.h new file mode 100644 index 00000000..9d22d415 --- /dev/null +++ b/inc/hgl/graph/VKMaterialDescriptorSets.h @@ -0,0 +1,82 @@ +#ifndef HGL_GRAPH_VULKAN_MATERIAL_DESCRIPTOR_SETS_INCLUDE +#define HGL_GRAPH_VULKAN_MATERIAL_DESCRIPTOR_SETS_INCLUDE + +#include + +VK_NAMESPACE_BEGIN + +struct ShaderDescriptor +{ + char name[128]; + + VkDescriptorType desc_type; + DescriptorSetType set_type; + uint32_t set; + uint32_t binding; + uint32_t stage_flag; +}; + +using ShaderDescriptorList=List; + +class MaterialDescriptorSets +{ + ShaderDescriptor *sd_list; + uint sd_count; + + ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + + Map sd_by_name; + Map binding_map[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + + int *binding_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + +private: + + struct ShaderDescriptorSet + { + uint32_t count; + VkDescriptorSetLayoutBinding *binding_list; + }; + + ShaderDescriptorSet sds[size_t(DescriptorSetType::RANGE_SIZE)]; + +public: + + MaterialDescriptorSets(ShaderDescriptor *,const uint); + ~MaterialDescriptorSets(); + + const ShaderDescriptorList * GetDescriptorList ()const {return descriptor_list;} + ShaderDescriptorList * GetDescriptorList (VkDescriptorType desc_type) + { + if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; + + return descriptor_list+desc_type; + } + + //ShaderDescriptorList &GetUBO (){return descriptor_list[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER];} + //ShaderDescriptorList &GetSSBO (){return descriptor_list[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER];} + //ShaderDescriptorList &GetUBODynamic (){return descriptor_list[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC];} + //ShaderDescriptorList &GetSSBODynamic(){return descriptor_list[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC];} + //ShaderDescriptorList &GetSampler (){return descriptor_list[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER];} + + + const int GetBinding(const VkDescriptorType &desc_type,const AnsiString &name)const; + + const int GetUBO(const AnsiString &name)const{return GetBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,name);} + const int GetSSBO(const AnsiString &name)const{return GetBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,name);} + const int GetSampler(const AnsiString &name)const{return GetBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,name);} + + const int *GetBindingList(const VkDescriptorType &desc_type)const + { + if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; + + return binding_list[(size_t)desc_type]; + } + + const int GetSetBindingCount(const DescriptorSetType &type)const{return sds[(size_t)type].count;} + const VkDescriptorSetLayoutBinding *GetSetBindingList(const DescriptorSetType &type)const{return sds[(size_t)type].binding_list;} +};//class MaterialDescriptorSets +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_MATERIAL_DESCRIPTOR_SETS_INCLUDE diff --git a/inc/hgl/graph/VKMaterialParameters.h b/inc/hgl/graph/VKMaterialParameters.h index 864d7c24..cca2e6c5 100644 --- a/inc/hgl/graph/VKMaterialParameters.h +++ b/inc/hgl/graph/VKMaterialParameters.h @@ -7,7 +7,7 @@ VK_NAMESPACE_BEGIN class MaterialParameters { - const ShaderModuleMap *shader_map; + const MaterialDescriptorSets *mds; DescriptorSetType ds_type; @@ -17,7 +17,7 @@ private: friend class Material; - MaterialParameters(const ShaderModuleMap *,const DescriptorSetType &type,DescriptorSets *); + MaterialParameters(const MaterialDescriptorSets *,const DescriptorSetType &type,DescriptorSets *); public: diff --git a/inc/hgl/graph/VKShaderModule.h b/inc/hgl/graph/VKShaderModule.h index b623a4c1..d7843de3 100644 --- a/inc/hgl/graph/VKShaderModule.h +++ b/inc/hgl/graph/VKShaderModule.h @@ -1,7 +1,7 @@ #ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE #define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE -#include +#include #include VK_NAMESPACE_BEGIN @@ -45,13 +45,6 @@ public: const bool IsMesh ()const{return stage_create_info->stage==VK_SHADER_STAGE_MESH_BIT_NV;} const VkPipelineShaderStageCreateInfo * GetCreateInfo ()const{return stage_create_info;} - - const int GetBinding (VkDescriptorType desc_type,const AnsiString &name)const - { - return shader_resource->GetBinding(desc_type,name); - } - - const ShaderDescriptorList * GetDescriptorList()const{return shader_resource->GetDescriptorList();} };//class ShaderModule class VertexAttributeBinding; diff --git a/inc/hgl/graph/VKShaderModuleMap.h b/inc/hgl/graph/VKShaderModuleMap.h index 646f049e..cbe059cb 100644 --- a/inc/hgl/graph/VKShaderModuleMap.h +++ b/inc/hgl/graph/VKShaderModuleMap.h @@ -17,30 +17,6 @@ public: ~ShaderModuleMap()=default; bool Add(const ShaderModule *sm); - -public: - - const int GetBinding(VkDescriptorType,const AnsiString &)const; - -#define GET_BO_BINDING(name,vk_name) const int Get##name(const AnsiString &obj_name)const{return GetBinding(VK_DESCRIPTOR_TYPE_##vk_name,obj_name);} -// GET_BO_BINDING(Sampler, SAMPLER) - - GET_BO_BINDING(Sampler, COMBINED_IMAGE_SAMPLER) -// GET_BO_BINDING(SampledImage, SAMPLED_IMAGE) - GET_BO_BINDING(StorageImage, STORAGE_IMAGE) - - GET_BO_BINDING(UTBO, UNIFORM_TEXEL_BUFFER) - GET_BO_BINDING(SSTBO, STORAGE_TEXEL_BUFFER) - GET_BO_BINDING(UBO, UNIFORM_BUFFER) - GET_BO_BINDING(SSBO, STORAGE_BUFFER) - - //shader中并不区分普通UBO和动态UBO,所以Material/ShaderResource中的数据,只有UBO - -// GET_BO_BINDING(UBODynamic, UNIFORM_BUFFER_DYNAMIC) -// GET_BO_BINDING(SSBODynamic, STORAGE_BUFFER_DYNAMIC) - - GET_BO_BINDING(InputAttachment, INPUT_ATTACHMENT) - #undef GET_BO_BINDING };//class ShaderModuleMap:public Map VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_SHADER_MODULE_MAP_INCLUDE diff --git a/inc/hgl/graph/VKShaderResource.h b/inc/hgl/graph/VKShaderResource.h new file mode 100644 index 00000000..7932b6e1 --- /dev/null +++ b/inc/hgl/graph/VKShaderResource.h @@ -0,0 +1,71 @@ +#ifndef HGL_GRAPH_VULKAN_SHADER_RESOURCE_INCLUDE +#define HGL_GRAPH_VULKAN_SHADER_RESOURCE_INCLUDE + +#include +#include +#include +#include + +VK_NAMESPACE_BEGIN + +struct ShaderStage +{ + AnsiString name; + uint location; + + VertexAttribType type; ///<成份数量(如vec4中的4) + VkFormat format; ///<对应的Vulkan格式(如vec4对应的FMT_RGBA32F) + + uint binding; + + bool global; ///<是否全局数据 + bool dynamic; ///<是否动态数量 +};//struct ShaderStage + +using ShaderStageList =ObjectList; + +class ShaderResource +{ + VkShaderStageFlagBits stage_flag; + + const void *spv_data; + uint32 spv_size; + + ShaderStageList stage_inputs; + ShaderStageList stage_outputs; + +public: + + ShaderResource(const VkShaderStageFlagBits &,const void *,const uint32); + virtual ~ShaderResource()=default; + + const VkShaderStageFlagBits GetStage ()const {return stage_flag;} + const os_char * GetStageName ()const; + + const uint32_t * GetCode ()const {return (uint32_t *)spv_data;} + const uint32_t GetCodeSize ()const {return spv_size;} + + ShaderStageList & GetStageInputs () {return stage_inputs;} + ShaderStageList & GetStageOutputs () {return stage_outputs;} + + const uint GetStageInputCount ()const {return stage_inputs.GetCount();} + const uint GetStageOutputCount ()const {return stage_outputs.GetCount();} + + const ShaderStage * GetStageInput (const AnsiString &)const; + const int GetStageInputBinding(const AnsiString &)const; +};//class ShaderResource + +ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize); + +struct ShaderModuleCreateInfo:public vkstruct_flag +{ +public: + + ShaderModuleCreateInfo(ShaderResource *sr) + { + codeSize=sr->GetCodeSize(); + pCode =sr->GetCode(); + } +};//struct ShaderModuleCreateInfo +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_SHADER_RESOURCE_INCLUDE \ No newline at end of file diff --git a/inc/hgl/graph/shader/ShaderResource.h b/inc/hgl/graph/shader/ShaderResource.h deleted file mode 100644 index 604d6afc..00000000 --- a/inc/hgl/graph/shader/ShaderResource.h +++ /dev/null @@ -1,124 +0,0 @@ -#pragma once -#include -#include -#include -#include - -VK_NAMESPACE_BEGIN - -struct ShaderStage -{ - AnsiString name; - uint location; - - VertexAttribType type; ///<成份数量(如vec4中的4) - VkFormat format; ///<对应的Vulkan格式(如vec4对应的FMT_RGBA32F) - - uint binding; - - bool global; ///<是否全局数据 - bool dynamic; ///<是否动态数量 -};//struct ShaderStage - -using ShaderStageList =ObjectList; - -struct ShaderDescriptor -{ - char name[128]; - - VkDescriptorType desc_type; - DescriptorSetType set_type; - uint32_t set; - uint32_t binding; - uint32_t stage_flag; -}; - -using ShaderDescriptorList=List; - -#ifndef VK_DESCRIPTOR_TYPE_BEGIN_RANGE -constexpr size_t VK_DESCRIPTOR_TYPE_BEGIN_RANGE=VK_DESCRIPTOR_TYPE_SAMPLER; -#endif//VK_DESCRIPTOR_TYPE_BEGIN_RANGE - -#ifndef VK_DESCRIPTOR_TYPE_END_RANGE -constexpr size_t VK_DESCRIPTOR_TYPE_END_RANGE=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; -#endif//VK_DESCRIPTOR_TYPE_END_RANGE - -#ifndef VK_DESCRIPTOR_TYPE_RANGE_SIZE -constexpr size_t VK_DESCRIPTOR_TYPE_RANGE_SIZE=VK_DESCRIPTOR_TYPE_END_RANGE-VK_DESCRIPTOR_TYPE_BEGIN_RANGE+1; -#endif//VK_DESCRIPTOR_TYPE_RANGE_SIZE - -class MaterialDescriptorSets -{ - ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; - -public: - - const ShaderDescriptorList * GetDescriptorList ()const {return descriptor_list;} - ShaderDescriptorList * GetDescriptorList (VkDescriptorType desc_type) - { - if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; - - return descriptor_list+desc_type; - } - - ShaderDescriptorList &GetUBO (){return descriptor_list[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER];} - ShaderDescriptorList &GetSSBO (){return descriptor_list[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER];} - ShaderDescriptorList &GetUBODynamic (){return descriptor_list[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC];} - ShaderDescriptorList &GetSSBODynamic(){return descriptor_list[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC];} - ShaderDescriptorList &GetSampler (){return descriptor_list[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER];} - - const int GetBinding (VkDescriptorType desc_type,const AnsiString &name)const; - //const DescriptorBindingList * GetBindingList (VkDescriptorType desc_type)const - //{ - // if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; - - // return &(descriptor_list[desc_type].binding_list); - //} -};// - -class ShaderResource -{ - VkShaderStageFlagBits stage_flag; - - const void *spv_data; - uint32 spv_size; - - ShaderStageList stage_inputs; - ShaderStageList stage_outputs; - -public: - - ShaderResource(const VkShaderStageFlagBits &,const void *,const uint32); - virtual ~ShaderResource()=default; - - const VkShaderStageFlagBits GetStage ()const {return stage_flag;} - const os_char * GetStageName ()const; - - const uint32_t * GetCode ()const {return (uint32_t *)spv_data;} - const uint32_t GetCodeSize ()const {return spv_size;} - - ShaderStageList & GetStageInputs () {return stage_inputs;} - ShaderStageList & GetStageOutputs () {return stage_outputs;} - - const uint GetStageInputCount ()const {return stage_inputs.GetCount();} - const uint GetStageOutputCount ()const {return stage_outputs.GetCount();} - - const ShaderStage * GetStageInput (const AnsiString &)const; - const int GetStageInputBinding(const AnsiString &)const; -};//class ShaderResource - -ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize); - -struct ShaderModuleCreateInfo:public vkstruct_flag -{ -public: - - ShaderModuleCreateInfo(ShaderResource *sr) - { - codeSize=sr->GetCodeSize(); - pCode =sr->GetCode(); - } -}; -VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index a101cd4d..a2d6219c 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -1,21 +1,9 @@ set(SG_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph) -SET(SHADER_RESOURCE_FILES ${SG_INCLUDE_PATH}/shader/ShaderResource.h - shader/ShaderResource.cpp) - -file(GLOB SG_MATERIAL_HEADER ${SG_INCLUDE_PATH}/material/*.*) - -file(GLOB SG_MATERIAL_SOURCE material/*.*) - -SOURCE_GROUP("Material" FILES ${SG_MATERIAL_HEADER} - ${SG_MATERIAL_SOURCE}) - -SOURCE_GROUP("Material\\Shader" FILES ${SHADER_RESOURCE_FILES}) - SET(SG_TEXTURE_SOURCE ${SG_INCLUDE_PATH}/TextureLoader.h Texture2DLoader.cpp) -SOURCE_GROUP("Material\\Texture" FILES ${SG_TEXTURE_SOURCE}) +SOURCE_GROUP("Texture" FILES ${SG_TEXTURE_SOURCE}) SET(SG_VAD_SOURCE ${SG_INCLUDE_PATH}/VertexAttribData.h ${SG_INCLUDE_PATH}/VertexAttribDataAccess.h @@ -95,6 +83,16 @@ SET(VK_RR_SOURCE ${SG_INCLUDE_PATH}/VKRenderResource.h SOURCE_GROUP("Vulkan\\RenderResource" FILES ${VK_RR_SOURCE}) +SET(VK_RR_SHADER_FILES ${SG_INCLUDE_PATH}/VKShaderResource.h + Vulkan/VKShaderResource.cpp) + +SOURCE_GROUP("Vulkan\\RenderResource\\Shader" FILES ${VK_RR_SHADER_FILES}) + +SET(VK_RR_MATERIAL_FILES ${SG_INCLUDE_PATH}/VKMaterialDescriptorSets.h + Vulkan/VKMaterialDescriptorSets.cpp) + +SOURCE_GROUP("Vulkan\\RenderResource\\Material" FILES ${VK_RR_MATERIAL_FILES}) + SET(VK_INST_SOURCE ${SG_INCLUDE_PATH}/VKInstance.h Vulkan/VKInstance.cpp) @@ -216,6 +214,8 @@ IF(WIN32) ENDIF(WIN32) SET(VULKAN_RENDER_SOURCE ${VK_RR_SOURCE} + ${VK_RR_SHADER_FILES} + ${VK_RR_MATERIAL_FILES} ${VK_INST_SOURCE} ${VK_DEBUG_SOURCE} ${VK_MEMORY_SOURCE} @@ -233,11 +233,7 @@ SET(VULKAN_RENDER_SOURCE ${VK_RR_SOURCE} add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER} ${SCENE_GRAPH_SOURCE} - ${SHADER_RESOURCE_FILES} - ${SG_TEXTURE_SOURCE} - ${SG_MATERIAL_HEADER} - ${SG_MATERIAL_SOURCE} ${TILE_SOURCE} ${SG_VAD_SOURCE} diff --git a/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.cpp b/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.cpp index d6e8a467..59b70277 100644 --- a/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.cpp +++ b/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.cpp @@ -1,11 +1,24 @@ #include"VKDescriptorSetLayoutCreater.h" #include #include +#include VK_NAMESPACE_BEGIN -DescriptorSetLayoutCreater *GPUDevice::CreateDescriptorSetLayoutCreater() +DescriptorSetLayoutCreater *GPUDevice::CreateDescriptorSetLayoutCreater(const MaterialDescriptorSets *mds) { - return(new DescriptorSetLayoutCreater(attr->device,attr->desc_pool)); + return(new DescriptorSetLayoutCreater(attr->device,attr->desc_pool,mds)); +} + +DescriptorSetLayoutCreater::DescriptorSetLayoutCreater(VkDevice dev,VkDescriptorPool dp,const MaterialDescriptorSets *_mds) +{ + hgl_zero(fin_dsl); + fin_dsl_count=0; + device=dev; + pool=dp; + mds=_mds; + + ENUM_CLASS_FOR(DescriptorSetType,int,i) + layouts[i]=nullptr; } DescriptorSetLayoutCreater::~DescriptorSetLayoutCreater() @@ -13,63 +26,9 @@ DescriptorSetLayoutCreater::~DescriptorSetLayoutCreater() if(pipeline_layout) vkDestroyPipelineLayout(device,pipeline_layout,nullptr); - for(ShaderDescriptorSet s:sds) - if(s.layout) - vkDestroyDescriptorSetLayout(device,s.layout,nullptr); -} - -void DescriptorSetLayoutCreater::Bind(const ShaderDescriptorList *sd_list,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags) -{ - if(!sd_list||sd_list->GetCount()<=0)return; - - uint32_t binding_count[size_t(DescriptorSetType::RANGE_SIZE)], - old_count[size_t(DescriptorSetType::RANGE_SIZE)], - fin_count[size_t(DescriptorSetType::RANGE_SIZE)]; - VkDescriptorSetLayoutBinding *p[size_t(DescriptorSetType::RANGE_SIZE)]; - - hgl_zero(binding_count); - hgl_zero(old_count); - hgl_zero(fin_count); - hgl_zero(p); - - for(const ShaderDescriptor &sd:*sd_list) - { - all_set.Add(sd.set_type); - - ++binding_count[(size_t)sd.set_type]; - } - ENUM_CLASS_FOR(DescriptorSetType,int,i) - if(binding_count[i]>0) - { - old_count[i]=sds[i].binding_list.GetCount(); - - sds[i].binding_list.PreMalloc(old_count[i]+binding_count[i]); - p[i]=sds[i].binding_list.GetData()+old_count[i]; - } - - for(const ShaderDescriptor &sd:*sd_list) - { - //重复的绑定点是有可能存在的,比如CameraInfo在vs/fs中同时存在 - - if(!all_binding.IsMember(sd.binding)) - { - p[(size_t)sd.set_type]->binding = sd.binding; - p[(size_t)sd.set_type]->descriptorType = sd.desc_type; - p[(size_t)sd.set_type]->descriptorCount = 1; - p[(size_t)sd.set_type]->stageFlags = stageFlags; - p[(size_t)sd.set_type]->pImmutableSamplers = nullptr; - - all_binding.Add(sd.binding); - - ++p[(size_t)sd.set_type]; - ++fin_count[(size_t)sd.set_type]; - } - } - - ENUM_CLASS_FOR(DescriptorSetType,int,i) - if(binding_count[i]>0) - sds[i].binding_list.SetCount(old_count[i]+fin_count[i]); + if(layouts[i]) + vkDestroyDescriptorSetLayout(device,layouts[i],nullptr); } bool DescriptorSetLayoutCreater::CreatePipelineLayout() @@ -78,7 +37,7 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout() ENUM_CLASS_FOR(DescriptorSetType,int,i) { - const int count=sds[i].binding_list.GetCount(); + const int count=mds->GetSetBindingCount((DescriptorSetType)i); if(count<=0) continue; @@ -86,15 +45,15 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout() DescriptorSetLayoutCreateInfo descriptor_layout; descriptor_layout.bindingCount = count; - descriptor_layout.pBindings = sds[i].binding_list.GetData(); + descriptor_layout.pBindings = mds->GetSetBindingList((DescriptorSetType)i); - if(sds[i].layout) - vkDestroyDescriptorSetLayout(device,sds[i].layout,nullptr); + if(layouts[i]) + vkDestroyDescriptorSetLayout(device,layouts[i],nullptr); - if(vkCreateDescriptorSetLayout(device,&descriptor_layout,nullptr,&(sds[i].layout))!=VK_SUCCESS) + if(vkCreateDescriptorSetLayout(device,&descriptor_layout,nullptr,layouts+i)!=VK_SUCCESS) return(false); - fin_dsl[fin_dsl_count]=sds[i].layout; + fin_dsl[fin_dsl_count]=layouts[i]; ++fin_dsl_count; } @@ -127,7 +86,7 @@ DescriptorSets *DescriptorSetLayoutCreater::Create(const DescriptorSetType &type ENUM_CLASS_RANGE_ERROR_RETURN_NULLPTR(DescriptorSetType,type); - const uint32_t count=sds[(size_t)type].binding_list.GetCount(); + const uint32_t count=mds->GetSetBindingCount(type); if(!count) return(nullptr); @@ -136,7 +95,7 @@ DescriptorSets *DescriptorSetLayoutCreater::Create(const DescriptorSetType &type alloc_info.descriptorPool = pool; alloc_info.descriptorSetCount = 1; - alloc_info.pSetLayouts = &(sds[(size_t)type].layout); + alloc_info.pSetLayouts = layouts+size_t(type); VkDescriptorSet desc_set; diff --git a/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.h b/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.h index cb2faef1..9fb35a29 100644 --- a/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.h +++ b/src/SceneGraph/Vulkan/VKDescriptorSetLayoutCreater.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include VK_NAMESPACE_BEGIN @@ -15,17 +15,9 @@ class DescriptorSetLayoutCreater VkDevice device; VkDescriptorPool pool; - Sets all_set; - Sets all_binding; - - struct ShaderDescriptorSet - { - List binding_list; - VkDescriptorSetLayout layout; - }; - - ShaderDescriptorSet sds[size_t(DescriptorSetType::RANGE_SIZE)]; + const MaterialDescriptorSets *mds; + VkDescriptorSetLayout layouts[size_t(DescriptorSetType::RANGE_SIZE)]; VkDescriptorSetLayout fin_dsl[size_t(DescriptorSetType::RANGE_SIZE)]; uint32_t fin_dsl_count; @@ -33,30 +25,9 @@ class DescriptorSetLayoutCreater public: - DescriptorSetLayoutCreater(VkDevice dev,VkDescriptorPool dp) - { - ENUM_CLASS_FOR(DescriptorSetType,int,i) - sds[i].layout=nullptr; - - hgl_zero(fin_dsl); - fin_dsl_count=0; - device=dev;pool=dp; - } + DescriptorSetLayoutCreater(VkDevice,VkDescriptorPool,const MaterialDescriptorSets *); ~DescriptorSetLayoutCreater(); - void Bind(const ShaderDescriptorList *sd_list,VkDescriptorType type,VkShaderStageFlagBits stage); - - void Bind(const ShaderDescriptorList *sdl,VkShaderStageFlagBits stage) - { - for(uint32_t i=VK_DESCRIPTOR_TYPE_BEGIN_RANGE;i<=VK_DESCRIPTOR_TYPE_END_RANGE;i++) - { - if(sdl->GetCount()>0) - Bind(sdl,(VkDescriptorType)i,stage); - - ++sdl; - } - } - //以下代码不再需要,使用一个void Bind(const ShaderResource &sr,VkShaderStageFlagBits stage)即可全部替代,而且更方便,但以此为提示 // //#define DESC_SET_BIND_FUNC(name,vkname) void Bind##name(const uint32_t binding,VkShaderStageFlagBits stage_flag){Bind(binding,VK_DESCRIPTOR_TYPE_##vkname,stage_flag);} \ diff --git a/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp b/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp index f569f6f4..7c8011e5 100644 --- a/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceMaterial.cpp @@ -1,5 +1,6 @@ #include #include +#include #include"VKDescriptorSetLayoutCreater.h" VK_NAMESPACE_BEGIN @@ -15,34 +16,16 @@ Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,ShaderModuleMap * if(!shader_maps->Get(VK_SHADER_STAGE_VERTEX_BIT,sm)) return(nullptr); - DescriptorSetLayoutCreater *dsl_creater=CreateDescriptorSetLayoutCreater(); - List *shader_stage_list=new List; - - shader_stage_list->SetCount(shader_count); - - VkPipelineShaderStageCreateInfo *p=shader_stage_list->GetData(); - - auto **itp=shader_maps->GetDataList(); - for(int i=0;iright; - hgl_cpy(p,sm->GetCreateInfo()); - - dsl_creater->Bind(sm->GetDescriptorList(),sm->GetStage()); - - ++p; - ++itp; - } - + DescriptorSetLayoutCreater *dsl_creater=CreateDescriptorSetLayoutCreater(mds); + if(!dsl_creater->CreatePipelineLayout()) { - delete shader_stage_list; - delete dsl_creater; delete shader_maps; + SAFE_CLEAR(mds); return(nullptr); } - return(new Material(mtl_name,shader_maps,shader_stage_list,dsl_creater)); + return(new Material(mtl_name,shader_maps,mds,dsl_creater)); } Material *GPUDevice::CreateMaterial(const UTF8String &mtl_name,const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module,MaterialDescriptorSets *mds) diff --git a/src/SceneGraph/Vulkan/VKMaterial.cpp b/src/SceneGraph/Vulkan/VKMaterial.cpp index 3178ff5d..6c86de73 100644 --- a/src/SceneGraph/Vulkan/VKMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKMaterial.cpp @@ -1,15 +1,34 @@ #include #include +#include #include"VKDescriptorSetLayoutCreater.h" VK_NAMESPACE_BEGIN -Material::Material(const UTF8String &name,ShaderModuleMap *smm,List *psci_list,DescriptorSetLayoutCreater *dslc) +Material::Material(const UTF8String &name,ShaderModuleMap *smm,MaterialDescriptorSets *_mds,DescriptorSetLayoutCreater *dslc) { mtl_name=name; shader_maps=smm; - shader_stage_list=psci_list; + mds=_mds; dsl_creater=dslc; 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;iright; + hgl_cpy(p,sm->GetCreateInfo()); + + ++p; + ++itp; + } + } + if(smm->Get(VK_SHADER_STAGE_VERTEX_BIT,sm)) { vertex_sm=(VertexShaderModule *)sm; @@ -41,8 +60,8 @@ Material::~Material() delete vab; } - delete shader_stage_list; delete shader_maps; + SAFE_CLEAR(mds); } const VkPipelineLayout Material::GetPipelineLayout()const @@ -56,6 +75,6 @@ MaterialParameters *Material::CreateMP(const DescriptorSetType &type)const if(!ds)return(nullptr); - return(new MaterialParameters(shader_maps,type,ds)); + return(new MaterialParameters(mds,type,ds)); } VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp b/src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp new file mode 100644 index 00000000..58b2be1c --- /dev/null +++ b/src/SceneGraph/Vulkan/VKMaterialDescriptorSets.cpp @@ -0,0 +1,107 @@ +#include +#include + +VK_NAMESPACE_BEGIN +void WriteDescriptorSetLayoutBinding(VkDescriptorSetLayoutBinding *dslb,ShaderDescriptor *sd) +{ + dslb->binding =sd->binding; + dslb->descriptorType =sd->desc_type; + dslb->descriptorCount =1; + dslb->stageFlags =sd->stage_flag; + dslb->pImmutableSamplers=nullptr; +} + +MaterialDescriptorSets::MaterialDescriptorSets(ShaderDescriptor *sd,const uint count) +{ + sd_list=sd; + sd_count=count; + + if(sd_count<=0)return; + + { + hgl_zero(sds); + + { + ShaderDescriptor *sp=sd_list; + + for(uint i=0;idesc_type>=VK_DESCRIPTOR_TYPE_BEGIN_RANGE + &&sp->desc_type<=VK_DESCRIPTOR_TYPE_END_RANGE) + descriptor_list[(size_t)sp->desc_type].Add(sp); + + sd_by_name.Add(sp->name,sp); + binding_map[size_t(sp->desc_type)].Add(sp->name,sp->binding); + + ++sds[sp->set].count; + + ++sp; + } + } + + VkDescriptorSetLayoutBinding *sds_ptr[size_t(DescriptorSetType::RANGE_SIZE)]; + + { + ENUM_CLASS_FOR(DescriptorSetType,int,i) + if(sds[i].count>0) + { + sds[i].binding_list=new VkDescriptorSetLayoutBinding[sds[i].count]; + sds_ptr[i]=sds[i].binding_list; + } + } + + { + ShaderDescriptorList *sdl=descriptor_list; + ShaderDescriptor **sdp; + + for(uint i=VK_DESCRIPTOR_TYPE_BEGIN_RANGE; + i<=VK_DESCRIPTOR_TYPE_END_RANGE;i++) + { + if(sdl->GetCount()>0) + { + binding_list[i]=new int[sdl->GetCount()]; + + sdp=sdl->GetData(); + for(int j=0;jGetCount();j++) + { + binding_list[i][j]=(*sdp)->binding; + + WriteDescriptorSetLayoutBinding(sds_ptr[(*sdp)->set], + *sdp); + + ++sds_ptr[(*sdp)->set]; + + ++sdp; + } + } + else + { + binding_list[i]=nullptr; + } + } + } + } +} + +MaterialDescriptorSets::~MaterialDescriptorSets() +{ + ENUM_CLASS_FOR(DescriptorSetType,int,i) + if(sds[i].count) + delete[] sds[i].binding_list; + + delete[] sd_list; //"delete[] nullptr" isn't bug. +} + +const int MaterialDescriptorSets::GetBinding(const VkDescriptorType &desc_type,const AnsiString &name)const +{ + if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE) + return -1; + + if(name.IsEmpty())return -1; + + int result; + + return(binding_map[size_t(desc_type)].Get(name,result)?result:-1); +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKMaterialParameters.cpp b/src/SceneGraph/Vulkan/VKMaterialParameters.cpp index 40fe114c..845ae8b9 100644 --- a/src/SceneGraph/Vulkan/VKMaterialParameters.cpp +++ b/src/SceneGraph/Vulkan/VKMaterialParameters.cpp @@ -1,12 +1,12 @@ #include - +#include #include #include VK_NAMESPACE_BEGIN -MaterialParameters::MaterialParameters(const ShaderModuleMap *smm,const DescriptorSetType &type,DescriptorSets *ds) +MaterialParameters::MaterialParameters(const MaterialDescriptorSets *_mds,const DescriptorSetType &type,DescriptorSets *ds) { - shader_map=smm; + mds=_mds; ds_type=type; descriptor_sets=ds; } @@ -21,7 +21,7 @@ bool MaterialParameters::BindUBO(const AnsiString &name,GPUBuffer *ubo,bool dyna if(name.IsEmpty()||!ubo) return(false); - const int index=shader_map->GetUBO(name); + const int index=mds->GetUBO(name); if(index<0) return(false); @@ -37,7 +37,7 @@ bool MaterialParameters::BindSSBO(const AnsiString &name,GPUBuffer *ssbo,bool dy if(name.IsEmpty()||!ssbo) return(false); - const int index=shader_map->GetSSBO(name); + const int index=mds->GetSSBO(name); if(index<0) return(false); @@ -53,7 +53,7 @@ bool MaterialParameters::BindSampler(const AnsiString &name,Texture *tex,Sampler if(name.IsEmpty()||!tex||!sampler) return(false); - const int index=shader_map->GetSampler(name); + const int index=mds->GetSampler(name); if(index<0) return(false); diff --git a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp index 2845a6c7..2057f1bd 100644 --- a/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp +++ b/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp @@ -2,7 +2,8 @@ #include #include #include -#include +#include +#include #include #include @@ -26,50 +27,36 @@ const ShaderModule *RenderResource::CreateShaderModule(const OSString &filename, return sm; } -const bool LoadShaderDescriptor(ShaderResource *sr,const uint8 *data) -{ - const uint8 count=*data++; - - if(count<=0)return(true); - - ShaderDescriptorList *sd_list; - const VkDescriptorType desc_type; - - - +void LoadShaderDescriptor(const uint8 *data,ShaderDescriptor *sd_list,const uint count) +{ + ShaderDescriptor *sd=sd_list; uint str_len; - sd_list->SetCount(count); - - ShaderDescriptor *sd=sd_list->GetData(); - for(uint i=0;iset=*data++; - sd->binding=*data++; - str_len=*data++; + sd->desc_type=VkDescriptorType(*data++); - memcpy(sd->name,(char *)data,str_len); - sd->name[str_len]=0; - data+=str_len; + { + str_len=*data++; + memcpy(sd->name,(char *)data,str_len); + data+=str_len; + } + + sd->set =*data++; + sd->binding =*data++; + sd->stage_flag =*(uint32 *)data; + data+=sizeof(uint32); sd->set_type=CheckDescriptorSetType(sd->name); if(sd->set_type==DescriptorSetType::Renderable) { - if(desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;else - if(desc_type==VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;else - sd->desc_type=desc_type; - } - else - { - sd->desc_type=desc_type; + if(sd->desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;else + if(sd->desc_type==VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; } ++sd; } - - return data; } Material *RenderResource::CreateMaterial(const OSString &filename) @@ -149,12 +136,24 @@ Material *RenderResource::CreateMaterial(const OSString &filename) break; } - if(!LoadShaderDescriptor(sr,filedata)) - result=false; + MaterialDescriptorSets *mds=nullptr; + { + const uint8 count=*sp; + ++sp; + + if(count>0) + { + ShaderDescriptor *sd_list=hgl_zero_new(count); + + LoadShaderDescriptor(filedata,sd_list,count); + + mds=new MaterialDescriptorSets(sd_list,count); + } + } if(result) { - mtl=device->CreateMaterial(ToUTF8String(filename),smm); + mtl=device->CreateMaterial(ToUTF8String(filename),smm,mds); Add(mtl); } else diff --git a/src/SceneGraph/Vulkan/VKShaderModuleMap.cpp b/src/SceneGraph/Vulkan/VKShaderModuleMap.cpp index 8938ae25..605eaa06 100644 --- a/src/SceneGraph/Vulkan/VKShaderModuleMap.cpp +++ b/src/SceneGraph/Vulkan/VKShaderModuleMap.cpp @@ -12,29 +12,4 @@ bool ShaderModuleMap::Add(const ShaderModule *sm) return this->Map::Add(stage,sm); } - -const int ShaderModuleMap::GetBinding(VkDescriptorType desc_type,const AnsiString &name)const -{ - if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE - ||name.IsEmpty()) - return(-1); - - int binding; - const int shader_count=GetCount(); - - const ShaderModule *sm; - auto **itp=GetDataList(); - for(int i=0;iright; - binding=sm->GetBinding(desc_type,name); - if(binding!=-1) - return binding; - - ++itp; - } - - return(-1); -} VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/shader/ShaderResource.cpp b/src/SceneGraph/Vulkan/VKShaderResource.cpp similarity index 78% rename from src/SceneGraph/shader/ShaderResource.cpp rename to src/SceneGraph/Vulkan/VKShaderResource.cpp index 28ae2c39..0a241fb9 100644 --- a/src/SceneGraph/shader/ShaderResource.cpp +++ b/src/SceneGraph/Vulkan/VKShaderResource.cpp @@ -1,6 +1,6 @@ -#include -#include +#include #include +#include #include VK_NAMESPACE_BEGIN @@ -23,16 +23,6 @@ VK_NAMESPACE_BEGIN { MapObject shader_resource_by_filename; - constexpr char SHADER_FILE_HEADER[] ="Shader\x1A"; - constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1; - - constexpr uint32 SHADER_FILE_MIN_SIZE =SHADER_FILE_HEADER_BYTES - +1 //version - +sizeof(uint32) //shader flag - +sizeof(uint32) //spv_size - +1 //input states count - +1; //output states count - const uint8 *LoadShaderStages(ShaderStageList &ss_list,const uint8 *data) { const uint count=*data++; @@ -133,20 +123,6 @@ VK_NAMESPACE_BEGIN return -1; } - - const int ShaderResource::GetBinding(VkDescriptorType desc_type,const AnsiString &name)const - { - if(desc_type>=VK_DESCRIPTOR_TYPE_RANGE_SIZE)return -1; - if(name.IsEmpty())return -1; - - const ShaderDescriptorList *sdl=descriptor_list+(size_t)desc_type; - - for(const ShaderDescriptor &sd:*sdl) - if(name==sd.name) - return sd.binding; - - return -1; - } ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize) {