From 2ac91b80ac3af2087f28700e21930f554a102093 Mon Sep 17 00:00:00 2001 From: "HuYingzhuo(hugo/hyzboy)" Date: Wed, 8 Mar 2023 14:02:51 +0800 Subject: [PATCH] added GLSLCompiler.cpp/.h --- CMCore | 2 +- example/MaterialCreaterTest.cpp | 6 +- inc/hgl/shadergen/MaterialCreater.h | 8 +- inc/hgl/shadergen/ShaderCreater.h | 2 +- inc/hgl/shadergen/ShaderDescriptorManager.h | 10 -- src/ShaderGen/CMakeLists.txt | 6 + src/ShaderGen/GLSLCompiler.cpp | 184 ++++++++++++++++++++ src/ShaderGen/GLSLCompiler.h | 111 ++++++++++++ src/ShaderGen/MaterialCreater.cpp | 84 +++++++-- src/ShaderGen/ShaderCreater.cpp | 4 + src/ShaderGen/ShaderCreaterFragment.cpp | 14 +- 11 files changed, 393 insertions(+), 38 deletions(-) create mode 100644 src/ShaderGen/GLSLCompiler.cpp create mode 100644 src/ShaderGen/GLSLCompiler.h diff --git a/CMCore b/CMCore index 643773c9..3e8f45a3 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 643773c93d97de2c1834cc05a10fb8cfbe76124c +Subproject commit 3e8f45a35e551f6202fb10d0b090c10619f354c9 diff --git a/example/MaterialCreaterTest.cpp b/example/MaterialCreaterTest.cpp index a957c412..1bb82450 100644 --- a/example/MaterialCreaterTest.cpp +++ b/example/MaterialCreaterTest.cpp @@ -23,8 +23,6 @@ void main() { gl_Position=vec4(Position,0,1); })"); - - vsc->CompileToSPV(); } //添加一个名称为ColorMaterial的UBO定义,其内部有一个vec4 color的属性 @@ -63,12 +61,12 @@ void main() })"); } + mc.CompileShader(); + return(false); } int MaterialCreaterTest() { - - return 0; } diff --git a/inc/hgl/shadergen/MaterialCreater.h b/inc/hgl/shadergen/MaterialCreater.h index 221153dc..eb6a03a1 100644 --- a/inc/hgl/shadergen/MaterialCreater.h +++ b/inc/hgl/shadergen/MaterialCreater.h @@ -14,7 +14,7 @@ class MaterialCreater uint32_t shader_stage; ///<着色器阶段 - MaterialDescriptorManager MDM; ///<材质描述符管理器 + MaterialDescriptorManager mdm; ///<材质描述符管理器 ShaderCreaterMap shader_map; ///<着色器列表 @@ -22,6 +22,10 @@ class MaterialCreater ShaderCreaterGeometry *geom; ShaderCreaterFragment *frag; +private: + + void SetContext(); + public: bool hasShader(const VkShaderStageFlagBits ss)const{return shader_stage&ss;} @@ -46,5 +50,7 @@ public: bool AddUBO(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const AnsiString &type_name,const AnsiString &name); bool AddSampler(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const SamplerType &st,const AnsiString &name); + + bool CompileShader(); };//class MaterialCreater SHADERGEN_NAMESPACE_END \ No newline at end of file diff --git a/inc/hgl/shadergen/ShaderCreater.h b/inc/hgl/shadergen/ShaderCreater.h index c9cf1398..bed17221 100644 --- a/inc/hgl/shadergen/ShaderCreater.h +++ b/inc/hgl/shadergen/ShaderCreater.h @@ -32,7 +32,7 @@ public: void SetShaderCodes(const AnsiString &str) { - shader_codes; + shader_codes=str; } bool CompileToSPV(); diff --git a/inc/hgl/shadergen/ShaderDescriptorManager.h b/inc/hgl/shadergen/ShaderDescriptorManager.h index 90328107..305a8dec 100644 --- a/inc/hgl/shadergen/ShaderDescriptorManager.h +++ b/inc/hgl/shadergen/ShaderDescriptorManager.h @@ -27,8 +27,6 @@ class ShaderDescriptorManager ShaderPushConstant push_constant; - AnsiString source_codes; - public: ShaderDescriptorManager(VkShaderStageFlagBits); @@ -50,8 +48,6 @@ public: const ObjectList & GetConstList()const{return const_value_list;} const ObjectList & GetSubpassInputList()const { return subpass_input; } - - const AnsiString &GetSources()const{return source_codes;} public: @@ -66,12 +62,6 @@ public: 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 diff --git a/src/ShaderGen/CMakeLists.txt b/src/ShaderGen/CMakeLists.txt index 96ab5540..214a23f9 100644 --- a/src/ShaderGen/CMakeLists.txt +++ b/src/ShaderGen/CMakeLists.txt @@ -32,6 +32,11 @@ SET(SHADERGEN_SOURCE_FILES MaterialDescriptorManager.cpp ) +SET(GLSL_COMPILER_SOURCE GLSLCompiler.h + GLSLCompiler.cpp) + +SOURCE_GROUP("GLSL Compiler" FILES ${GLSL_COMPILER_SOURCE}) + #SOURCE_GROUP("Pixel Material Components" FILES ${SHADERGEN_HEADER_FILES} # ${SHADERGEN_SOURCE_FILES}) @@ -41,4 +46,5 @@ add_cm_library(ULRE.ShaderGen "ULRE" ${SHADERGEN_HEADER_FILES} ${MATERIAL_CREATER_SOURCE_FILES} ${SHADER_CREATER_HEADER_FILES} ${SHADER_CREATER_SOURCE_FILES} + ${GLSL_COMPILER_SOURCE} ) diff --git a/src/ShaderGen/GLSLCompiler.cpp b/src/ShaderGen/GLSLCompiler.cpp new file mode 100644 index 00000000..16c7952b --- /dev/null +++ b/src/ShaderGen/GLSLCompiler.cpp @@ -0,0 +1,184 @@ +#include"GLSLCompiler.h" +#include +#include +#include + +using namespace hgl; +using namespace hgl::io; + +namespace glsl_compiler +{ + enum class ShaderLanguageType + { + GLSL=0, + HLSL, + + MAX=0xff + };//enum class ShaderType + + struct CompileInfo + { + ShaderLanguageType shader_type = ShaderLanguageType::GLSL; + const char * entrypoint = nullptr; //it only used in HLSL + + uint32_t includes_count = 0; + const char ** includes = nullptr; + + const char * preamble = nullptr; + }; + + UTF8StringList include_list; + CompileInfo compile_info; + + struct GLSLCompilerInterface + { + bool (*Init)(); + void (*Close)(); + + bool (*GetLimit)(void *,const int); + bool (*SetLimit)(void *,const int); + + uint32_t (*GetType)(const char *ext_name); + SPVData * (*Compile)(const uint32_t stage,const char *shader_source, const CompileInfo *compile_info); + SPVData * (*CompileFromPath)(const uint32_t stage,const char *shader_filename, const CompileInfo *compile_info); + + void (*Free)(SPVData *); + }; + + ExternalModule *gsi_module=nullptr; + + static GLSLCompilerInterface *gsi=nullptr; + + typedef GLSLCompilerInterface *(*GetInterfaceFUNC)(); + + bool Init() + { + compile_info.includes=nullptr; + compile_info.includes_count=0; + + if(gsi)return(true); + + OSString cur_path; + OSString glsl_compiler_fullname; + + if(!filesystem::GetCurrentPath(cur_path)) + return(false); + glsl_compiler_fullname=filesystem::MergeFilename(cur_path,OS_TEXT("GLSLCompiler") HGL_PLUGIN_EXTNAME); + + gsi_module=LoadExternalModule(glsl_compiler_fullname); + + if(!gsi_module)return(false); + + GetInterfaceFUNC get_func; + + get_func=GetInterfaceFUNC(gsi_module->GetFunc("GetInterface")); + + if(get_func) + { + gsi=get_func(); + if(gsi) + { + if(gsi->Init()) + return(true); + } + } + + delete gsi_module; + gsi_module=nullptr; + return(false); + } + + void Close() + { + delete[] compile_info.includes; + compile_info.includes=nullptr; + + if(gsi) + { + gsi->Close(); + gsi=nullptr; + } + + if(gsi_module) + { + delete gsi_module; + gsi_module=nullptr; + } + } + + void AddGLSLIncludePath(const char *path) + { + if(include_list.Find(path)==-1) + include_list.Add(path); + } + + const char PreambleString[]="#extension GL_GOOGLE_include_directive : require\n"; + + void RebuildGLSLIncludePath() + { + delete[] compile_info.includes; + + compile_info.includes_count=include_list.GetCount(); + compile_info.includes=new const char *[compile_info.includes_count]; + + for(uint32_t i=0;i0) + compile_info.preamble=PreambleString; + } + + uint32_t GetType (const char *ext_name) + { + if(gsi) + return gsi->GetType(ext_name); + + return 0; + } + + void Free (SPVData *spv_data) + { + if(gsi) + gsi->Free(spv_data); + } + + SPVData *Compile(const uint32_t type,const char *source) + { + if(!gsi) + return(nullptr); + + ByteOrderMask bom=CheckBOM(source); + + if(bom==ByteOrderMask::UTF8) + source+=3; + else + if(bom!=ByteOrderMask::NONE) + { + std::cerr<<"GLSLCompiler does not support BOMHeader outside of UTF8"<Compile(type,source,&compile_info); + + if(!spv)return(nullptr); + + const bool result=spv->result; + + if(!result) + { + std::cerr<<"glsl compile failed."<log) + std::cerr<<"info: "<log<debug_log) + std::cerr<<"debug info: "<debug_log<spv_length<<" bytes."< +#include +#include + +namespace hgl +{ + namespace io + { + class MemoryOutputStream; + class DataOutputStream; + } +} + +namespace glsl_compiler +{ + using namespace hgl; + + enum class DescriptorType //等同VkDescriptorType + { + SAMPLER = 0, + COMBINED_IMAGE_SAMPLER, + SAMPLED_IMAGE, + STORAGE_IMAGE, + UNIFORM_TEXEL_BUFFER, + STORAGE_TEXEL_BUFFER, + UNIFORM_BUFFER, + STORAGE_BUFFER, + UNIFORM_BUFFER_DYNAMIC, + STORAGE_BUFFER_DYNAMIC, + INPUT_ATTACHMENT, + + ENUM_CLASS_RANGE(SAMPLER,INPUT_ATTACHMENT) + }; + + constexpr size_t SHADER_RESOURCE_NAME_MAX_LENGTH=32; + + struct ShaderStage + { + char name[SHADER_RESOURCE_NAME_MAX_LENGTH]; + uint8_t location; + uint8_t basetype; //现在改对应hgl/graph/VertexAttrib.h中的enum class VertexAttribType::BaseType + uint8_t vec_size; + };// + + struct ShaderStageData + { + uint32_t count; + ShaderStage *items; + }; + + struct Descriptor + { + char name[SHADER_RESOURCE_NAME_MAX_LENGTH]; + uint8_t set; + uint8_t binding; + }; + + struct PushConstant + { + char name[SHADER_RESOURCE_NAME_MAX_LENGTH]; + uint8_t offset; + uint8_t size; + }; + + struct SubpassInput + { + char name[SHADER_RESOURCE_NAME_MAX_LENGTH]; + uint8_t input_attachment_index; + uint8_t binding; + }; + + template + struct ShaderResourceData + { + uint32_t count; + T *items; + }; + + using ShaderDescriptorResource=ShaderResourceData[size_t(DescriptorType::RANGE_SIZE)]; + + struct SPVData + { + bool result; + char *log; + char *debug_log; + + uint32_t *spv_data; + uint32_t spv_length; + + ShaderStageData input, + output; + ShaderDescriptorResource resource; + ShaderResourceData push_constant; + ShaderResourceData subpass_input; + }; + + bool Init(); + void Close(); + + void AddGLSLIncludePath(const char *); + void RebuildGLSLIncludePath(); + + uint32_t GetType (const char *ext_name); + + SPVData * Compile (const uint32_t type,const char *source); + void Free (SPVData *spv_data); +}//namespace glsl_compiler +#endif//HGL_GLSL_COMPILER_INCLUDE diff --git a/src/ShaderGen/MaterialCreater.cpp b/src/ShaderGen/MaterialCreater.cpp index e424da44..d0078e60 100644 --- a/src/ShaderGen/MaterialCreater.cpp +++ b/src/ShaderGen/MaterialCreater.cpp @@ -19,30 +19,30 @@ bool MaterialCreater::AddUBOStruct(const AnsiString &ubo_typename,const AnsiStri if(ubo_typename.IsEmpty()||codes.IsEmpty()) return(false); - return MDM.AddUBOStruct(ubo_typename,codes); + return mdm.AddUBOStruct(ubo_typename,codes); } -bool MaterialCreater::AddUBO(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const AnsiString &type_name,const AnsiString &name) +bool MaterialCreater::AddUBO(const VkShaderStageFlagBits flag_bit,const DescriptorSetType set_type,const AnsiString &type_name,const AnsiString &name) { - if(!shader_map.KeyExist(flag_bits)) + if(!shader_map.KeyExist(flag_bit)) return(false); - if(!MDM.hasUBOStruct(type_name)) + if(!mdm.hasUBOStruct(type_name)) return(false); - ShaderCreater *sc=shader_map[flag_bits]; + ShaderCreater *sc=shader_map[flag_bit]; if(!sc) return(false); - UBODescriptor *ubo=MDM.GetUBO(name); + UBODescriptor *ubo=mdm.GetUBO(name); if(ubo) { if(ubo->type!=type_name) return(false); - ubo->stage_flag|=flag_bits; + ubo->stage_flag|=flag_bit; return sc->sdm.AddUBO(set_type,ubo); } @@ -53,23 +53,23 @@ bool MaterialCreater::AddUBO(const VkShaderStageFlagBits flag_bits,const Descrip ubo->type=type_name; ubo->name=name; - return sc->sdm.AddUBO(set_type,MDM.AddUBO(flag_bits,set_type,ubo)); + return sc->sdm.AddUBO(set_type,mdm.AddUBO(flag_bit,set_type,ubo)); } } -bool MaterialCreater::AddSampler(const VkShaderStageFlagBits flag_bits,const DescriptorSetType set_type,const SamplerType &st,const AnsiString &name) +bool MaterialCreater::AddSampler(const VkShaderStageFlagBits flag_bit,const DescriptorSetType set_type,const SamplerType &st,const AnsiString &name) { - if(!shader_map.KeyExist(flag_bits)) + if(!shader_map.KeyExist(flag_bit)) return(false); RANGE_CHECK_RETURN_FALSE(st); - ShaderCreater *sc=shader_map[flag_bits]; + ShaderCreater *sc=shader_map[flag_bit]; if(!sc) return(false); - SamplerDescriptor *sampler=MDM.GetSampler(name); + SamplerDescriptor *sampler=mdm.GetSampler(name); AnsiString st_name=GetSamplerTypeName(st); @@ -78,7 +78,7 @@ bool MaterialCreater::AddSampler(const VkShaderStageFlagBits flag_bits,const Des if(sampler->type!=st_name) return(false); - sampler->stage_flag|=flag_bits; + sampler->stage_flag|=flag_bit; return sc->sdm.AddSampler(set_type,sampler); } @@ -89,7 +89,63 @@ bool MaterialCreater::AddSampler(const VkShaderStageFlagBits flag_bits,const Des sampler->type=st_name; sampler->name=name; - return sc->sdm.AddSampler(set_type,MDM.AddSampler(flag_bits,set_type,sampler)); + return sc->sdm.AddSampler(set_type,mdm.AddSampler(flag_bit,set_type,sampler)); } } + +void MaterialCreater::SetContext() +{ + //ShaderMap使用ObjectMap保存,ObjectMap本质附带排序功能,所以这里无需再排序,直接设定prev,next即可 + + LOG_INFO("Resort Shader."); + + ShaderCreater *prev,*cur,*next; + + auto *it=shader_map.GetDataList(); + + const int count=shader_map.GetCount(); + + for(int i=0; iright; + ++it; + + if(i>0) + cur->sdm.SetPrevShader(prev->GetShaderStage()); + + if(iright; + cur->sdm.SetNextShader(next->GetShaderStage()); + } + +#ifdef _DEBUG + cur->sdm.DebugOutput(i); +#endif//_DEBUG + + prev=cur; + } +} + +bool MaterialCreater::CompileShader() +{ + if(shader_map.IsEmpty()) + return(false); + + SetContext(); //设定上下文 + + ShaderCreater *sc; + + for(int i=0;iCompileToSPV()) + return(false); + } + + return(true); + +} SHADERGEN_NAMESPACE_END diff --git a/src/ShaderGen/ShaderCreater.cpp b/src/ShaderGen/ShaderCreater.cpp index 0e248c49..5dd7a382 100644 --- a/src/ShaderGen/ShaderCreater.cpp +++ b/src/ShaderGen/ShaderCreater.cpp @@ -25,5 +25,9 @@ int ShaderCreater::AddOutput(const AnsiString &type,const AnsiString &name) bool ShaderCreater::CompileToSPV() { + if(shader_codes.IsEmpty()) + return(false); + + } SHADERGEN_NAMESPACE_END diff --git a/src/ShaderGen/ShaderCreaterFragment.cpp b/src/ShaderGen/ShaderCreaterFragment.cpp index 6dd2461a..78f7405f 100644 --- a/src/ShaderGen/ShaderCreaterFragment.cpp +++ b/src/ShaderGen/ShaderCreaterFragment.cpp @@ -4,20 +4,20 @@ SHADERGEN_NAMESPACE_BEGIN void ShaderCreaterFragment::UseDefaultMain() { - main_codes="void main()\n{\n"; + shader_codes="void main()\n{\n"; const auto &output_list=sdm.GetShaderStageIO().output; const uint count=output_list.GetCount(); for(uint i=0;iname; - main_codes+="=Get"; - main_codes+=output_list[i]->name; - main_codes+="();\n"; + shader_codes+="\t"; + shader_codes+=output_list[i]->name; + shader_codes+="=Get"; + shader_codes+=output_list[i]->name; + shader_codes+="();\n"; } - main_codes+="}"; + shader_codes+="}"; } SHADERGEN_NAMESPACE_END \ No newline at end of file