From 5a81928c80f8748efaa1762ad347f5588c0d4188 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sun, 23 Aug 2020 18:18:38 +0800 Subject: [PATCH] add ShaderParse --- CMakeLists.txt | 2 +- VKShaderParse.h | 17 +++--- glsl2spv.cpp | 143 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 153 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index edabb76..214765c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,6 @@ set(VULKAN_SPIRV_LIBS GenericCodeGen SPIRV-Tools-opt spirv-cross-core) -add_library(GLSLCompiler SHARED glsl2spv.cpp) +add_library(GLSLCompiler SHARED glsl2spv.cpp VKShaderParse.h) target_link_libraries(GLSLCompiler PRIVATE ${VULKAN_SPIRV_LIBS} ${Vulkan_LIBRARY}) diff --git a/VKShaderParse.h b/VKShaderParse.h index f2fa7ce..2b62591 100644 --- a/VKShaderParse.h +++ b/VKShaderParse.h @@ -1,8 +1,6 @@ #pragma once -#include -#include - -using namespace hgl; +#include"SPIRV-Cross/spirv_cross.hpp" +#include using SPVResVector=spirv_cross::SmallVector; @@ -45,9 +43,14 @@ class ShaderParse public: - const AnsiString GetName(const spirv_cross::Resource &res)const + const std::string &GetName(const spirv_cross::Resource &res)const + { + return compiler->get_name(res.id); + } + + const uint32_t GetSet(const spirv_cross::Resource &res)const { - return AnsiString(compiler->get_name(res.id).c_str()); + return compiler->get_decoration(res.id,spv::DecorationDescriptorSet); } const uint32_t GetBinding(const spirv_cross::Resource &res)const @@ -60,7 +63,7 @@ class ShaderParse return compiler->get_decoration(res.id,spv::DecorationLocation); } - void GetFormat(const spirv_cross::Resource &res,spirv_cross::SPIRType::BaseType *base_type,uint8 *vecsize) + void GetFormat(const spirv_cross::Resource &res,spirv_cross::SPIRType::BaseType *base_type,uint8_t *vecsize) { const spirv_cross::SPIRType &type=compiler->get_type(res.type_id); diff --git a/glsl2spv.cpp b/glsl2spv.cpp index 0c81d97..56a5b0c 100644 --- a/glsl2spv.cpp +++ b/glsl2spv.cpp @@ -1,5 +1,7 @@ #include #include +#include"SPIRV-Cross/spirv_common.hpp" +#include"VKShaderParse.h" #include #include @@ -29,6 +31,28 @@ typedef enum VkShaderStageFlagBits { VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkShaderStageFlagBits; +typedef enum VkDescriptorType { + VK_DESCRIPTOR_TYPE_SAMPLER = 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000165000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorType; + +constexpr uint32_t VK_DESCRIPTOR_TYPE_COUNT =VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + -VK_DESCRIPTOR_TYPE_SAMPLER + +1; + static TBuiltInResource default_build_in_resource; void init_default_build_in_resource() @@ -183,6 +207,34 @@ extern "C" glslang::FinalizeProcess(); } + struct ShaderStage + { + char name[128]; + uint8_t location; + uint8_t base_type; + uint8_t vec_size; + };// + + struct ShaderStageData + { + uint32_t count; + ShaderStage *items; + }; + + struct ShaderResource + { + char name[128]; + + uint8_t set; + uint8_t binding; + }; + + struct ShaderResourceData + { + uint32_t count; + ShaderResource *items; + }; + struct SPVData { bool result; @@ -192,6 +244,26 @@ extern "C" uint32_t *spv_data; uint32_t spv_length; + ShaderStageData input,output; + ShaderResourceData resource[VK_DESCRIPTOR_TYPE_COUNT]; + + void Init() + { + memset(&input,0,sizeof(ShaderStageData)); + memset(&output,0,sizeof(ShaderStageData)); + + memset(&resource,0,sizeof(resource)); + } + + void Clear() + { + for(uint32_t i=0;i &spirv) @@ -217,10 +291,14 @@ extern "C" spv_length=spirv.size(); spv_data=new uint32_t[spv_length]; memcpy(spv_data,spirv.data(),spv_length*sizeof(uint32_t)); + + Init(); } ~SPVData() { + Clear(); + delete[] log; delete[] debug_log; delete[] spv_data; @@ -232,6 +310,56 @@ extern "C" delete spv; } + void OutputShaderStage(ShaderStageData *ssd,ShaderParse *sp,const SPVResVector &stages) + { + size_t attr_count=stages.size(); + + ssd->count=attr_count; + + if(attr_count<=0)return; + + spirv_cross::SPIRType::BaseType base_type; + uint8_t vec_size; + uint32_t location; + std::string name; + + ssd->items=new ShaderStage[attr_count]; + ShaderStage *ss=ssd->items; + + for(const spirv_cross::Resource &si:stages) + { + sp->GetFormat(si,&base_type,&vec_size); + + ss->base_type =(uint8_t)base_type; + ss->vec_size =vec_size; + ss->location =sp->GetLocation(si); + + strcpy(ss->name,sp->GetName(si).c_str()); + + ++ss; + } + } + + void OutputShaderResource(ShaderResourceData *ssd,ShaderParse *sp,const SPVResVector &res) + { + size_t count=res.size(); + + if(count<=0)return; + + ssd->count=count; + ssd->items=new ShaderResource[count]; + ShaderResource *sr=ssd->items; + + for(const spirv_cross::Resource &obj:res) + { + strcpy(sr->name,sp->GetName(obj).c_str()); + sr->binding=sp->GetBinding(obj); + sr->set=sp->GetSet(obj); + + ++sr; + } + } + SPVData *GLSL2SPV(const uint32_t shader_type,const char *shader_source) { EShLanguage stage = FindLanguage((VkShaderStageFlagBits)shader_type); @@ -266,8 +394,21 @@ extern "C" std::vector spirv; glslang::GlslangToSpv(*program.getIntermediate(stage),spirv); + + SPVData *spv=new SPVData(spirv); - return(new SPVData(spirv)); + { + ShaderParse sp(spirv.data(),spirv.size()*sizeof(uint32_t)); + + OutputShaderStage(&(spv->input),&sp,sp.GetStageInputs()); + OutputShaderStage(&(spv->output),&sp,sp.GetStageOutputs()); + + OutputShaderResource(spv->resource+VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &sp,sp.GetSampler()); + OutputShaderResource(spv->resource+VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &sp,sp.GetUBO()); + OutputShaderResource(spv->resource+VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &sp,sp.GetSSBO()); + } + + return(spv); } uint32_t GetShaderStageFlagByExtName(const char *ext_name)