diff --git a/CMSceneGraph b/CMSceneGraph index c4823cd3..1e711048 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit c4823cd334a539362fc2cf2d0b49e299bb8ce9b4 +Subproject commit 1e71104806a845a3a81414d2f2a05ea2e29c5d2b diff --git a/inc/hgl/graph/VKShaderModule.h b/inc/hgl/graph/VKShaderModule.h index 330b0111..0889dea6 100644 --- a/inc/hgl/graph/VKShaderModule.h +++ b/inc/hgl/graph/VKShaderModule.h @@ -58,7 +58,7 @@ public: class VertexShaderModule:public ShaderModule { uint32_t attr_count; - VertexAttribType *type_list; + VAT *type_list; const char **name_list; ShaderStage **ssi_list; diff --git a/inc/hgl/shadergen/MaterialDescriptorManager.h b/inc/hgl/shadergen/MaterialDescriptorManager.h index d4e0b550..d02207cf 100644 --- a/inc/hgl/shadergen/MaterialDescriptorManager.h +++ b/inc/hgl/shadergen/MaterialDescriptorManager.h @@ -24,47 +24,49 @@ class MaterialDescriptorManager ObjectMap descriptor_map; - ObjectList ubo_list; - ObjectList sampler_list; - public: - const ShaderDescriptor *AddDescriptor(VkShaderStageFlagBits ssb,ShaderDescriptor *new_sd); ///<添加一个描述符,如果它本身存在,则返回false + ShaderDescriptor *AddDescriptor(VkShaderStageFlagBits ssb,ShaderDescriptor *new_sd); ///<添加一个描述符,如果它本身存在,则返回false }; using ShaderDescriptorSetArray=ShaderDescriptorSet[size_t(DescriptorSetType::RANGE_SIZE)]; ShaderDescriptorSetArray desc_set_array; - Map ubo_code_map; + Map ubo_struct_map; + Map ubo_map; + Map sampler_map; public: MaterialDescriptorManager(); ~MaterialDescriptorManager()=default; - bool AddUBOCode(const AnsiString &name,const AnsiString &code) + bool AddUBOStruct(const AnsiString &name,const AnsiString &code) { - if(ubo_code_map.KeyExist(name)) + if(ubo_struct_map.KeyExist(name)) return(false); - ubo_code_map.Add(name,code); + ubo_struct_map.Add(name,code); return(true); } - bool GetUBOCode(const AnsiString &name,AnsiString &code) const + bool GetUBOStruct(const AnsiString &name,AnsiString &code) const { - return(ubo_code_map.Get(name,code)); + return(ubo_struct_map.Get(name,code)); } - bool hasUBOCode(const AnsiString &name) const + bool hasUBOStruct(const AnsiString &name) const { - return(ubo_code_map.KeyExist(name)); + return(ubo_struct_map.KeyExist(name)); } const UBODescriptor *AddUBO(VkShaderStageFlagBits ssb,DescriptorSetType set_type,UBODescriptor *sd); const SamplerDescriptor *AddSampler(VkShaderStageFlagBits ssb,DescriptorSetType set_type,SamplerDescriptor *sd); + UBODescriptor *GetUBO(const AnsiString &name); + SamplerDescriptor *GetSampler(const AnsiString &name); + const DescriptorSetType GetSetType(const AnsiString &)const; void Resort(); //排序产生set号与binding号 diff --git a/src/SceneGraph/Vulkan/VKShaderModule.cpp b/src/SceneGraph/Vulkan/VKShaderModule.cpp index 8b330450..8f172903 100644 --- a/src/SceneGraph/Vulkan/VKShaderModule.cpp +++ b/src/SceneGraph/Vulkan/VKShaderModule.cpp @@ -49,12 +49,12 @@ VertexShaderModule::VertexShaderModule(VkDevice dev,VkPipelineShaderStageCreateI attr_count=stage_input_list.GetCount(); ssi_list=stage_input_list.GetData(); name_list=new const char *[attr_count]; - type_list=new VertexAttribType[attr_count]; + type_list=new VAT[attr_count]; for(uint i=0;iname; - type_list[i].basetype =VertexAttribType::BaseType(ssi_list[i]->basetype); + type_list[i].basetype =VATBaseType(ssi_list[i]->basetype); type_list[i].vec_size =ssi_list[i]->vec_size; } } @@ -70,7 +70,7 @@ VertexShaderModule::~VertexShaderModule() delete[] name_list; } -const VkFormat GetVulkanFormat(const VertexAttribType::BaseType &base_type,const uint vec_size); //VertexAttrib.cpp +const VkFormat GetVulkanFormat(const VATBaseType &base_type,const uint vec_size); //VertexAttrib.cpp VIL *VertexShaderModule::CreateVIL(const VILConfig *cfg) { @@ -100,7 +100,7 @@ VIL *VertexShaderModule::CreateVIL(const VILConfig *cfg) if(!cfg||!cfg->Get((*si)->name,vac)) { - attr->format =GetVulkanFormat(VertexAttribType::BaseType((*si)->basetype),(*si)->vec_size); + attr->format =GetVulkanFormat(VATBaseType((*si)->basetype),(*si)->vec_size); //if(memcmp((*si)->name.c_str(),"Inst_",5)==0) //不可以使用CaseComp("Inst_",5)会被认为是比较一个5字长的字符串,而不是只比较5个字符 // bind->inputRate =VK_VERTEX_INPUT_RATE_INSTANCE; @@ -112,7 +112,7 @@ VIL *VertexShaderModule::CreateVIL(const VILConfig *cfg) if(vac.format!=PF_UNDEFINED) attr->format =vac.format; else - attr->format =GetVulkanFormat(VertexAttribType::BaseType((*si)->basetype),(*si)->vec_size); + attr->format =GetVulkanFormat(VATBaseType((*si)->basetype),(*si)->vec_size); bind->inputRate =vac.instance?VK_VERTEX_INPUT_RATE_INSTANCE:VK_VERTEX_INPUT_RATE_VERTEX; } diff --git a/src/ShaderGen/MaterialCreater.cpp b/src/ShaderGen/MaterialCreater.cpp index e843212c..b2d7debd 100644 --- a/src/ShaderGen/MaterialCreater.cpp +++ b/src/ShaderGen/MaterialCreater.cpp @@ -31,6 +31,55 @@ public: ~ShaderCreater() { } + + int AddInput(const VAT &type,const AnsiString &name) + { + ShaderStage *ss=new ShaderStage; + + hgl::strcpy(ss->name,sizeof(ss->name),name.c_str()); + + ss->basetype=(uint8) type.basetype; + ss->vec_size= type.vec_size; + + return sdm.AddInput(ss); + } + + int AddInput(const AnsiString &type,const AnsiString &name) + { + VAT vat; + + if(!ParseVertexAttribType(&vat,type)) + return(-2); + + return AddInput(vat,name); + } + + int AddOutput(const VAT &type,const AnsiString &name) + { + ShaderStage *ss=new ShaderStage; + + hgl::strcpy(ss->name,sizeof(ss->name),name.c_str()); + + ss->basetype=(uint8) type.basetype; + ss->vec_size= type.vec_size; + + return sdm.AddOutput(ss); + } + + int AddOutput(const AnsiString &type,const AnsiString &name) + { + VAT vat; + + if(!ParseVertexAttribType(&vat,type)) + return(-2); + + return AddOutput(vat,name); + } + + bool AddFunction(const AnsiString &return_type,const AnsiString &func_name,const AnsiString ¶m_list,const AnsiString &codes) + { + //return sdm.AddFunction(return_type,func_name,param_list,code); + } }; class ShaderCreaterMap:public ObjectMap @@ -55,25 +104,10 @@ public: class VertexShaderCreater:public ShaderCreater { - List input; - public: VertexShaderCreater():ShaderCreater(VK_SHADER_STAGE_VERTEX_BIT){} ~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 @@ -117,9 +151,13 @@ public: bool hasFragment()const{return hasShader(VK_SHADER_STAGE_FRAGMENT_BIT);} // bool hasCompute ()const{return hasShader(VK_SHADER_STAGE_COMPUTE_BIT);} + VertexShaderCreater * GetVS(){return vert;} + GeometryShaderCreater * GetGS(){return geom;} + FragmentShaderCreater * GetFS(){return frag;} + public: - MaterialCreater(const uint rc,const uint32 ss) + MaterialCreater(const uint rc,const uint32 ss=VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT) { rt_count=rc; shader_stage=ss; @@ -133,19 +171,12 @@ public: { } - int AddVertexInput(const AnsiString &name,const VertexAttribType &type) - { - if(!vert)return(-1); - - return vert->AddInput(name,type); - } - - bool AddUBOCode(const AnsiString &ubo_typename,const AnsiString &codes) + bool AddUBOStruct(const AnsiString &ubo_typename,const AnsiString &codes) { if(ubo_typename.IsEmpty()||codes.IsEmpty()) return(false); - return MDM.AddUBOCode(ubo_typename,codes); + return MDM.AddUBOStruct(ubo_typename,codes); } bool AddUBO(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const AnsiString &type_name,const AnsiString &name) @@ -153,7 +184,7 @@ public: if(!shader_map.KeyExist(flag_bits)) return(false); - if(!MDM.hasUBOCode(type_name)) + if(!MDM.hasUBOStruct(type_name)) return(false); ShaderCreater *sc=shader_map[flag_bits]; @@ -161,12 +192,26 @@ public: if(!sc) return(false); - UBODescriptor *ubo=new UBODescriptor(); + UBODescriptor *ubo=MDM.GetUBO(name); - ubo->type=type_name; - ubo->name=name; + if(ubo) + { + if(ubo->type!=type_name) + return(false); - return sc->sdm.AddUBO(set_type,MDM.AddUBO(flag_bits,set_type,ubo)); + ubo->stage_flag|=flag_bits; + + return sc->sdm.AddUBO(set_type,ubo); + } + else + { + ubo=new UBODescriptor(); + + ubo->type=type_name; + ubo->name=name; + + return sc->sdm.AddUBO(set_type,MDM.AddUBO(flag_bits,set_type,ubo)); + } } bool AddSampler(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const SamplerType &st,const AnsiString &name) @@ -181,19 +226,85 @@ public: if(!sc) return(false); - SamplerDescriptor *sampler=new SamplerDescriptor(); + SamplerDescriptor *sampler=MDM.GetSampler(name); - sampler->type=GetSamplerTypeName(st); - sampler->name=name; + AnsiString st_name=GetSamplerTypeName(st); - return sc->sdm.AddSampler(set_type,MDM.AddSampler(flag_bits,set_type,sampler)); + if(sampler) + { + if(sampler->type!=st_name) + return(false); + + sampler->stage_flag|=flag_bits; + + return sc->sdm.AddSampler(set_type,sampler); + } + else + { + sampler=new SamplerDescriptor(); + + sampler->type=st_name; + sampler->name=name; + + return sc->sdm.AddSampler(set_type,MDM.AddSampler(flag_bits,set_type,sampler)); + } } };//class MaterialCreater -int main() +#ifdef _DEBUG + +bool PureColorMaterial() { - MaterialCreater mc(1,VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT); + MaterialCreater mc(1); //一个新材质,1个RT输出,默认使用Vertex/Fragment shader + + //vertex部分 + { + VertexShaderCreater *vsc=mc.GetVS(); //获取vertex shader creater + + vsc->AddInput("vec3","Position"); //添加一个vec3类型的position属性输入 + + //以下代码会被合并成 vec3 GetPosition(/**/){return Position;} + vsc->AddFunction("vec3","GetPosition","/**/","return Position;"); + } + + //添加一个名称为ColorMaterial的UBO定义,其内部有一个vec4 color的属性 + //该代码会被展开为 + /* + struct ColorMaterial + { + vec4 color; + }; + */ + mc.AddUBOStruct("ColorMaterial","vec4 color;"); + + //添加一个UBO,该代码会被展开为 + /* + layout(set=SET_PerMI,binding=?) uniform ColorMaterial mtl; + */ + mc.AddUBO( VK_SHADER_STAGE_FRAGMENT_BIT, //这个UBO出现在fragment shader + DescriptorSetType::PerMaterialInstance, //它属于材质实例合集 + "ColorMaterial", //UBO名称为ColorMaterial + "mtl"); //UBO变量名称为mtl + + //fragment部分 + { + FragmentShaderCreater *fsc=mc.GetFS(); //获取fragment shader creater + + //以下代码会被合并成 vec4 GetColor(/**/){return mtl.color;} + fsc->AddFunction("vec4","GetColor","/**/","return mtl.color;"); + + fsc->AddOutput("vec4","Color"); //添加一个vec4类型的color属性输出 + + } + + return(false); +} + +int MaterialCreaterTest() +{ + return 0; } +#endif//_DEBUG SHADERGEN_NAMESPACE_END diff --git a/src/ShaderGen/MaterialDescriptorManager.cpp b/src/ShaderGen/MaterialDescriptorManager.cpp index d16a74d1..f973d3df 100644 --- a/src/ShaderGen/MaterialDescriptorManager.cpp +++ b/src/ShaderGen/MaterialDescriptorManager.cpp @@ -28,7 +28,7 @@ const DescriptorSetType MaterialDescriptorManager::GetSetType(const AnsiString & /** * 添加一个描述符,如果它本身存在,则返回false */ -const ShaderDescriptor *MaterialDescriptorManager::ShaderDescriptorSet::AddDescriptor(VkShaderStageFlagBits ssb,ShaderDescriptor *new_sd) +ShaderDescriptor *MaterialDescriptorManager::ShaderDescriptorSet::AddDescriptor(VkShaderStageFlagBits ssb,ShaderDescriptor *new_sd) { ShaderDescriptor *sd; @@ -58,11 +58,9 @@ const UBODescriptor *MaterialDescriptorManager::AddUBO(VkShaderStageFlagBits ssb ShaderDescriptorSet *sds=desc_set_array+(size_t)set_type; - const ShaderDescriptor *obj=sds->AddDescriptor(ssb,sd); + ShaderDescriptor *obj=sds->AddDescriptor(ssb,sd); - if(!obj)return(nullptr); - - sds->ubo_list.Add((UBODescriptor *)obj); + ubo_map.Add(obj->name,(UBODescriptor *)obj); return((UBODescriptor *)obj); } @@ -73,14 +71,32 @@ const SamplerDescriptor *MaterialDescriptorManager::AddSampler(VkShaderStageFlag ShaderDescriptorSet *sds=desc_set_array+(size_t)set_type; - const ShaderDescriptor *obj=sds->AddDescriptor(ssb,sd); + ShaderDescriptor *obj=sds->AddDescriptor(ssb,sd); - if(!obj)return(nullptr); - - sds->sampler_list.Add((SamplerDescriptor *)obj); + sampler_map.Add(obj->name,(SamplerDescriptor *)obj); return((SamplerDescriptor *)obj); } +UBODescriptor *MaterialDescriptorManager::GetUBO(const AnsiString &name) +{ + UBODescriptor *sd; + + if(ubo_map.Get(name,sd)) + return(sd); + + return(nullptr); +} + +SamplerDescriptor *MaterialDescriptorManager::GetSampler(const AnsiString &name) +{ + SamplerDescriptor *sd; + + if(sampler_map.Get(name,sd)) + return(sd); + + return(nullptr); +} + void MaterialDescriptorManager::Resort() { //重新生成set/binding