diff --git a/CMSceneGraph b/CMSceneGraph index 861d1668..062c9cd6 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 861d1668cb6d8f730c89158933a133ba2c8ad426 +Subproject commit 062c9cd64239ada350cce73dd50b833759c48e56 diff --git a/inc/hgl/shadergen/MaterialDescriptorManager.h b/inc/hgl/shadergen/MaterialDescriptorManager.h new file mode 100644 index 00000000..939252be --- /dev/null +++ b/inc/hgl/shadergen/MaterialDescriptorManager.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +SHADERGEN_NAMESPACE_BEGIN +/** +* 材质描述符管理

+* 该类使用于SHADER生成前,用于统计编号set/binding +*/ +class MaterialDescriptorManager +{ + struct ShaderDescriptorSet + { + DescriptorSetType set_type; + + int set; + int count; + + ObjectMap descriptor_map; + + List ubo_list; + List sampler_list; + + public: + + const ShaderDescriptor *AddDescriptor(VkShaderStageFlagBits ssb,ShaderDescriptor *new_sd); ///<添加一个描述符,如果它本身存在,则返回false + }; + + using ShaderDescriptorSetArray=ShaderDescriptorSet[size_t(DescriptorSetType::RANGE_SIZE)]; + + ShaderDescriptorSetArray desc_set_array; + +public: + + MaterialDescriptorManager(); + ~MaterialDescriptorManager()=default; + + const UBODescriptor *AddUBO(VkShaderStageFlagBits ssb,DescriptorSetType type,UBODescriptor *sd); + const SamplerDescriptor *AddSampler(VkShaderStageFlagBits ssb,DescriptorSetType type,SamplerDescriptor *sd); + + const DescriptorSetType GetSetType(const AnsiString &)const; + + void Resort(); //排序产生set号与binding号 +}; +SHADERGEN_NAMESPACE_END diff --git a/inc/hgl/shadergen/ShaderCommon.h b/inc/hgl/shadergen/ShaderCommon.h new file mode 100644 index 00000000..1230db29 --- /dev/null +++ b/inc/hgl/shadergen/ShaderCommon.h @@ -0,0 +1,13 @@ +#ifndef HGL_SHADER_GEN_COMMON_INCLUDE +#define HGL_SHADER_GEN_COMMON_INCLUDE + +#include +#include + +#define SHADERGEN_NAMESPACE_BEGIN namespace hgl{namespace shadergen{ +#define SHADERGEN_NAMESPACE_END }} +#define SHADERGEN_NAMESPACE_USING using namespace hgl::shadergen; + +SHADERGEN_NAMESPACE_BEGIN +SHADERGEN_NAMESPACE_END +#endif//HGL_SHADER_GEN_COMMON_INCLUDE diff --git a/inc/hgl/shadergen/ShaderDescriptorManager.h b/inc/hgl/shadergen/ShaderDescriptorManager.h new file mode 100644 index 00000000..31306a22 --- /dev/null +++ b/inc/hgl/shadergen/ShaderDescriptorManager.h @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include +#include +#include + +SHADERGEN_NAMESPACE_BEGIN +/** +* Shader数据管理器,用于生成正式Shader前的资源统计 +*/ +class ShaderDescriptorManager +{ + ShaderStageIO stage_io; + + MaterialDescriptorManager * material_descriptor_manager; + + //ubo/object在这里以及MaterialDescriptorManager中均有一份,mdm中的用于产生set/binding号,这里的用于产生shader + List ubo_list; + List sampler_list; + + ObjectList const_value_list; + ObjectList subpass_input; + + ShaderPushConstant push_constant; + + AnsiString source_codes; + +public: + + ShaderDescriptorManager(VkShaderStageFlagBits,MaterialDescriptorManager *); + ~ShaderDescriptorManager()=default; + + const VkShaderStageFlagBits GetStageBits()const { return stage_io.cur; } + const AnsiString GetStageName()const { return AnsiString(GetShaderStageName(stage_io.cur)); } + + void SetPrevShader(VkShaderStageFlagBits prev) { stage_io.prev=prev; } + void SetNextShader(VkShaderStageFlagBits next) { stage_io.next=next; } + +public: + + const ShaderStageIO & GetShaderStageIO()const{return stage_io;} + + const List & GetUBOList()const{return ubo_list;} + const List & GetSamplerList()const{return sampler_list;} + + const ObjectList & GetConstList()const{return const_value_list;} + + const ObjectList & GetSubpassInputList()const { return subpass_input; } + + const AnsiString &GetSources()const{return source_codes;} + +public: + + bool AddInput(ShaderStage *); + bool AddOutput(ShaderStage *); + + bool AddUBO(DescriptorSetType type,UBODescriptor *sd); + bool AddSampler(DescriptorSetType type,SamplerDescriptor *sd); + + bool AddConstValue(ConstValueDescriptor *sd); + bool AddSubpassInput(const AnsiString name,uint8_t index); + + void SetPushConstant(const AnsiString name,uint8_t offset,uint8_t size); + + void AddSource(const AnsiString &str) + { + source_codes+=str; + source_codes+="\n"; + } + +#ifdef _DEBUG + void DebugOutput(int); +#endif//_DEBUG +};//class ShaderDescriptorManager +SHADERGEN_NAMESPACE_END diff --git a/src/ShaderGen/CMakeLists.txt b/src/ShaderGen/CMakeLists.txt index 3c5813c4..924f873a 100644 --- a/src/ShaderGen/CMakeLists.txt +++ b/src/ShaderGen/CMakeLists.txt @@ -8,9 +8,13 @@ SET(SHADERGEN_HEADER_FILES ${SHADERGEN_INCLUDE_PATH}/ShadingProgram.h ${SHADERGEN_INCLUDE_PATH}/ShaderCommon.h ${SHADERGEN_INCLUDE_PATH}/ShaderDescriptorManager.h ${SHADERGEN_INCLUDE_PATH}/MaterialDescriptorManager.h + ${SHADERGEN_INCLUDE_PATH}/VertexPolicy.h + ${SHADERGEN_INCLUDE_PATH}/MaterialGen.h ) -SET(SHADERGEN_SOURCE_FILES PMC.cpp +SET(SHADERGEN_SOURCE_FILES +#PMC.cpp +# VertexPolicy.cpp ShaderDescriptorManager.cpp MaterialDescriptorManager.cpp ) @@ -20,4 +24,5 @@ SET(SHADERGEN_SOURCE_FILES PMC.cpp add_cm_library(ULRE.ShaderGen "ULRE" ${SHADERGEN_HEADER_FILES} ${SHADERGEN_SOURCE_FILES} - ShaderGen.cpp) + ShaderGen.cpp + MaterialCreater.cpp) diff --git a/src/ShaderGen/MaterialCreater.cpp b/src/ShaderGen/MaterialCreater.cpp new file mode 100644 index 00000000..cb09c21b --- /dev/null +++ b/src/ShaderGen/MaterialCreater.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +SHADERGEN_NAMESPACE_BEGIN +class ShaderCreater +{ + VkShaderStageFlagBits shader_stage; ///<着色器阶段 + +public: + + ShaderDescriptorManager sdm; + + VkShaderStageFlagBits GetShaderStage()const{return shader_stage;} + +public: + + ShaderCreater(VkShaderStageFlagBits ss,MaterialDescriptorManager *mdm):sdm(ss,mdm) + { + shader_stage=ss; + } + + ~ShaderCreater() + { + } +}; + +class ShaderCreaterMap:public ObjectMap +{ +public: + + using ObjectMap::ObjectMap; + + bool Add(ShaderCreater *sc) + { + if(!sc)return(false); + + VkShaderStageFlagBits flag=sc->GetShaderStage(); + + if(KeyExist(flag)) + return(false); + + ObjectMap::Add(flag,sc); + return(true); + } +}; + +class VertexShaderCreater:public ShaderCreater +{ + List input; + +public: + + VertexShaderCreater(MaterialDescriptorManager *mdm):ShaderCreater(VK_SHADER_STAGE_VERTEX_BIT,mdm){} + ~VertexShaderCreater()=default; + + int AddInput(const AnsiString &name,const VertexAttribType &type) + { + ShaderStage ss; + + hgl::strcpy(ss.name,sizeof(ss.name),name.c_str()); + + ss.location=input.GetCount(); + ss.basetype=(uint8) type.basetype; + ss.vec_size= type.vec_size; + + return input.Add(ss); + } +}; + +class GeometryShaderCreater:public ShaderCreater +{ +public: + + GeometryShaderCreater(MaterialDescriptorManager *mdm):ShaderCreater(VK_SHADER_STAGE_GEOMETRY_BIT,mdm){} + ~GeometryShaderCreater()=default; +}; + +class FragmentShaderCreater:public ShaderCreater +{ +public: + + FragmentShaderCreater(MaterialDescriptorManager *mdm):ShaderCreater(VK_SHADER_STAGE_FRAGMENT_BIT,mdm){} + ~FragmentShaderCreater()=default; +}; + +class MaterialCreater +{ + uint rt_count; ///<输出的RT数量 + + uint32_t shader_stage; ///<着色器阶段 + + MaterialDescriptorManager MDM; ///<材质描述符管理器 + + ShaderCreaterMap shader_map; ///<着色器列表 + + VertexShaderCreater *vert; + GeometryShaderCreater *geom; + FragmentShaderCreater *frag; + +public: + + bool hasShader(const VkShaderStageFlagBits ss)const{return shader_stage&ss;} + + bool hasVertex ()const{return hasShader(VK_SHADER_STAGE_VERTEX_BIT);} +// bool hasTessCtrl()const{return hasShader(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);} +// bool hasTessEval()const{return hasShader(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);} + bool hasGeometry()const{return hasShader(VK_SHADER_STAGE_GEOMETRY_BIT);} + bool hasFragment()const{return hasShader(VK_SHADER_STAGE_FRAGMENT_BIT);} +// bool hasCompute ()const{return hasShader(VK_SHADER_STAGE_COMPUTE_BIT);} + +public: + + MaterialCreater(const uint rc,const uint32 ss) + { + rt_count=rc; + shader_stage=ss; + + if(hasVertex ())shader_map.Add(vert=new VertexShaderCreater (&MDM));else vert=nullptr; + if(hasGeometry ())shader_map.Add(geom=new GeometryShaderCreater(&MDM));else geom=nullptr; + if(hasFragment ())shader_map.Add(frag=new FragmentShaderCreater(&MDM));else frag=nullptr; + } + + ~MaterialCreater() + { + } + + int AddVertexInput(const AnsiString &name,const VertexAttribType &type) + { + if(!vert)return(-1); + + return vert->AddInput(name,type); + } + + bool AddUBO(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const AnsiString &type_name,const AnsiString &name) + { + if(!shader_map.KeyExist(flag_bits)) + return(false); + + ShaderCreater *sc=shader_map[flag_bits]; + + if(!sc) + return(false); + + UBODescriptor *ubo=new UBODescriptor(); + + ubo->type=type_name; + ubo->name=name; + + return sc->sdm.AddUBO(set_type,ubo); + } + + bool AddSampler(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const AnsiString &type_name,const AnsiString &name) + { + if(!shader_map.KeyExist(flag_bits)) + return(false); + + ShaderCreater *sc=shader_map[flag_bits]; + + if(!sc) + return(false); + + SamplerDescriptor *sampler=new SamplerDescriptor(); + + sampler->type=type_name; + sampler->name=name; + + return sc->sdm.AddSampler(set_type,sampler); + } +};//class MaterialCreater + +int main() +{ + MaterialCreater mc(1,VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT); + + return 0; +} +SHADERGEN_NAMESPACE_END diff --git a/src/ShaderGen/MaterialDescriptorManager.cpp b/src/ShaderGen/MaterialDescriptorManager.cpp new file mode 100644 index 00000000..e623c527 --- /dev/null +++ b/src/ShaderGen/MaterialDescriptorManager.cpp @@ -0,0 +1,109 @@ +#include + +SHADERGEN_NAMESPACE_BEGIN +MaterialDescriptorManager::MaterialDescriptorManager() +{ + int set_type=(int)DescriptorSetType::BEGIN_RANGE; + + for(auto &p:desc_set_array) + { + p.set_type=(DescriptorSetType)set_type; + + ++set_type; + + p.set=-1; + p.count=0; + } +} + +const DescriptorSetType MaterialDescriptorManager::GetSetType(const AnsiString &name)const +{ + for(auto &sds:desc_set_array) + if(sds.descriptor_map.KeyExist(name)) + return(sds.set_type); + + return DescriptorSetType::Global; +} + +/** +* 添加一个描述符,如果它本身存在,则返回false +*/ +const ShaderDescriptor *MaterialDescriptorManager::ShaderDescriptorSet::AddDescriptor(VkShaderStageFlagBits ssb,ShaderDescriptor *new_sd) +{ + ShaderDescriptor *sd; + + if(descriptor_map.Get(new_sd->name,sd)) + { + sd->stage_flag|=ssb; + return(sd); + } + else + { + new_sd->set_type=set_type; + new_sd->stage_flag=ssb; + + descriptor_map.Add(new_sd->name, new_sd); + + count++; + + return(new_sd); + } +} + +const UBODescriptor *MaterialDescriptorManager::AddUBO(VkShaderStageFlagBits ssb,DescriptorSetType type,UBODescriptor *sd) +{ + RANGE_CHECK_RETURN_NULLPTR(type); + if(!sd)return(nullptr); + + ShaderDescriptorSet *sds=desc_set_array+(size_t)type; + + const ShaderDescriptor *obj=sds->AddDescriptor(ssb,sd); + + if(!obj)return(nullptr); + + sds->ubo_list.Add((UBODescriptor *)obj); + return((UBODescriptor *)obj); +} + +const SamplerDescriptor *MaterialDescriptorManager::AddSampler(VkShaderStageFlagBits ssb,DescriptorSetType type,SamplerDescriptor *sd) +{ + RANGE_CHECK_RETURN_NULLPTR(type); + if(!sd)return(nullptr); + + ShaderDescriptorSet *sds=desc_set_array+(size_t)type; + + const ShaderDescriptor *obj=sds->AddDescriptor(ssb,sd); + + if(!obj)return(nullptr); + + sds->sampler_list.Add((SamplerDescriptor *)obj); + return((SamplerDescriptor *)obj); +} + +void MaterialDescriptorManager::Resort() +{ + //重新生成set/binding + { + int set=0; + + for(auto &p:desc_set_array) + { + if(p.count>0) + { + p.set=set; + + auto *sdp=p.descriptor_map.GetDataList(); + for(int i=0;iright->set=set; + (*sdp)->right->binding=i; + + ++sdp; + } + + ++set; + } + } + } +} +SHADERGEN_NAMESPACE_END \ No newline at end of file diff --git a/src/ShaderGen/ShaderDescriptorManager.cpp b/src/ShaderGen/ShaderDescriptorManager.cpp new file mode 100644 index 00000000..c9a15adf --- /dev/null +++ b/src/ShaderGen/ShaderDescriptorManager.cpp @@ -0,0 +1,151 @@ +#include + +SHADERGEN_NAMESPACE_BEGIN +ShaderDescriptorManager::ShaderDescriptorManager(VkShaderStageFlagBits cur,MaterialDescriptorManager *mdm) +{ + material_descriptor_manager=mdm; + + stage_io.cur=cur; + stage_io.prev=(VkShaderStageFlagBits)0; + stage_io.next=(VkShaderStageFlagBits)0; + + hgl_zero(push_constant); +} + +namespace +{ + bool Find(ObjectList &ol,const ShaderStage *ss) + { + for(int i=0;iname,ss->name)==0) + return(true); + + return(false); + } +}//namespace + +bool ShaderDescriptorManager::AddInput(ShaderStage *ss) +{ + if(!ss)return(false); + + if(Find(stage_io.input,ss))return(false); + + ss->location=stage_io.input.GetCount(); + stage_io.input.Add(ss); + return(true); +} + +bool ShaderDescriptorManager::AddOutput(ShaderStage *ss) +{ + if(!ss)return(false); + + if(Find(stage_io.output,ss))return(false); + + ss->location=stage_io.output.GetCount(); + stage_io.output.Add(ss); + return(true); +} + +bool ShaderDescriptorManager::AddUBO(DescriptorSetType type,UBODescriptor *sd) +{ + const UBODescriptor *obj=material_descriptor_manager->AddUBO(stage_io.cur,type,sd); + + if(!obj) + return(false); + + ubo_list.Add(obj); + return obj; +} + +bool ShaderDescriptorManager::AddSampler(DescriptorSetType type,SamplerDescriptor *sd) +{ + const SamplerDescriptor *obj=material_descriptor_manager->AddSampler(stage_io.cur,type,sd); + + if(!obj) + return(false); + + sampler_list.Add(obj); + return obj; +} + +bool ShaderDescriptorManager::AddConstValue(ConstValueDescriptor *sd) +{ + if(!sd)return(false); + + for(auto *p:const_value_list) + if(p->name.Comp(sd->name)==0) + return(false); + + sd->constant_id=const_value_list.Add(sd); + return(true); +} + +bool ShaderDescriptorManager::AddSubpassInput(const UTF8String name,uint8_t index) +{ + for(auto *si:subpass_input) + { + if(si->input_attachment_index==index)return(false); + if(si->name.Comp(name))return(false); + } + + SubpassInputDescriptor *ssi=new SubpassInputDescriptor; + + ssi->name=name; + ssi->input_attachment_index=index; + + subpass_input.Add(ssi); + return(true); +} + +void ShaderDescriptorManager::SetPushConstant(const UTF8String name,uint8_t offset,uint8_t size) +{ + push_constant.name =name; + push_constant.offset=offset; + push_constant.size =size; +} + +#ifdef _DEBUG +void ShaderDescriptorManager::DebugOutput(int index) +{ + UTF8String name=GetShaderStageName(stage_io.cur); + UTF8String prev_name=GetShaderStageName(stage_io.prev); + UTF8String next_name=GetShaderStageName(stage_io.next); + + LOG_INFO(UTF8String::numberOf(index)+": "+name+" shader"); + LOG_INFO("\tprev next is "+prev_name); + LOG_INFO("\tnext next is "+next_name); + + if(stage_io.input.GetCount()>0) + { + LOG_INFO("\tStage Input "+UTF8String::numberOf(stage_io.input.GetCount())); + + for(auto *ss:stage_io.input) + LOG_INFO("\t\tlayout(location="+UTF8String::numberOf(ss->location)+") in "+UTF8String(GetShaderStageTypeName(ss))+"\t"+UTF8String(ss->name)); + } + + if(stage_io.output.GetCount()>0) + { + LOG_INFO("\tStage Output "+UTF8String::numberOf(stage_io.output.GetCount())); + + for(auto *ss:stage_io.output) + LOG_INFO("\t\tlayout(location="+UTF8String::numberOf(ss->location)+") out "+UTF8String(GetShaderStageTypeName(ss))+"\t"+UTF8String(ss->name)); + } + + if(ubo_list.GetCount()>0) + { + LOG_INFO("\tUBO "+UTF8String::numberOf(ubo_list.GetCount())); + + for(auto *ubo:ubo_list) + LOG_INFO("\t\tlayout(set="+UTF8String::numberOf(ubo->set)+",binding="+UTF8String::numberOf(ubo->binding)+") uniform "+ubo->type+"\t"+ubo->type); + } + + if(sampler_list.GetCount()>0) + { + LOG_INFO("\tSampler "+UTF8String::numberOf(sampler_list.GetCount())); + + for(auto *ubo:ubo_list) + LOG_INFO("\t\tlayout(set="+UTF8String::numberOf(ubo->set)+",binding="+UTF8String::numberOf(ubo->binding)+") uniform "+ubo->type+"\t"+ubo->type); + } +} +#endif//_DEBUG +SHADERGEN_NAMESPACE_END \ No newline at end of file