From d94e6dee6c316dcd694f6282586add850a651a00 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Tue, 9 Jun 2020 19:40:08 +0800 Subject: [PATCH] use ShaderResource instead ShaderParse --- CMCore | 2 +- CMSceneGraph | 2 +- example/Vulkan/first_triangle.cpp | 4 +- inc/hgl/graph/shader/ShaderResource.h | 101 ++++--- inc/hgl/graph/vulkan/VK.h | 6 +- inc/hgl/graph/vulkan/VKCommandBuffer.h | 4 +- inc/hgl/graph/vulkan/VKShaderModule.h | 21 +- inc/hgl/graph/vulkan/VKShaderModuleManage.h | 9 +- src/RenderDevice/Vulkan/CMakeLists.txt | 3 +- .../Vulkan/VKDescriptorSetLayoutCreater.cpp | 10 +- .../Vulkan/VKDescriptorSetLayoutCreater.h | 18 +- src/RenderDevice/Vulkan/VKMaterial.cpp | 2 +- src/RenderDevice/Vulkan/VKShaderModule.cpp | 58 +--- .../Vulkan/VKShaderModuleManage.cpp | 32 +-- src/RenderDevice/Vulkan/VKShaderParse.h | 93 ------ src/SceneGraph/shader/ShaderResource.cpp | 267 ++++++++++-------- 16 files changed, 284 insertions(+), 348 deletions(-) delete mode 100644 src/RenderDevice/Vulkan/VKShaderParse.h diff --git a/CMCore b/CMCore index 6b4feef7..72f2b58e 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 6b4feef78efa3d185b6abeda049c6232d2da6a81 +Subproject commit 72f2b58e12b0f86ed4f49cb939c18f18bb43e0df diff --git a/CMSceneGraph b/CMSceneGraph index 60f82f00..c879515d 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 60f82f0042c0b3be19e4eab72376a67db8bb0eab +Subproject commit c879515d448d129ada207364e223c59694204b86 diff --git a/example/Vulkan/first_triangle.cpp b/example/Vulkan/first_triangle.cpp index 85b03af3..b3005f73 100644 --- a/example/Vulkan/first_triangle.cpp +++ b/example/Vulkan/first_triangle.cpp @@ -11,8 +11,8 @@ using namespace hgl::graph; bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); -constexpr uint32_t SCREEN_WIDTH=128; -constexpr uint32_t SCREEN_HEIGHT=128; +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; constexpr uint32_t VERTEX_COUNT=3; diff --git a/inc/hgl/graph/shader/ShaderResource.h b/inc/hgl/graph/shader/ShaderResource.h index 4906ac58..6a658576 100644 --- a/inc/hgl/graph/shader/ShaderResource.h +++ b/inc/hgl/graph/shader/ShaderResource.h @@ -1,46 +1,77 @@ #pragma once #include #include -#include +#include +#include -namespace hgl -{ - namespace graph +VK_NAMESPACE_BEGIN + struct ShaderStage { - struct ShaderStage + UTF8String name; + uint location; + VkFormat format; + };//struct ShaderStage + + using ShaderStageList=ObjectList; + using ShaderBindingList=List; + + struct ShaderDescriptorList + { + UTF8StringList name_list; + ShaderBindingList binding_list; + }; + + class ShaderResource + { + const void *data; + + VkShaderStageFlagBits stage_flag; + + const void *spv_data; + uint32 spv_size; + + ShaderStageList stage_inputs; + ShaderStageList stage_outputs; + + ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; + + public: + + ShaderResource(const void *,const VkShaderStageFlagBits &,const void *,const uint32); + virtual ~ShaderResource(); + + const VkShaderStageFlagBits GetStage()const{return stage_flag;} + + 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 int GetStageInputBinding(const UTF8String &); + + const ShaderDescriptorList *GetDescriptorList()const{return descriptor_list;} + ShaderDescriptorList *GetDescriptorList(VkDescriptorType desc_type) { - UTF8String name; - uint location; - VkFormat format; - };//struct ShaderStage + if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; - using ShaderStageList=ObjectList; + return descriptor_list+desc_type; + } - struct ShaderDescriptor + ShaderDescriptorList &GetUBO(){return descriptor_list[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER];} + ShaderDescriptorList &GetSSBO(){return descriptor_list[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER];} + ShaderDescriptorList &GetSampler(){return descriptor_list[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER];} + + const int GetBinding (VkDescriptorType desc_type,const UTF8String &name)const; + const ShaderBindingList * GetBindingList (VkDescriptorType desc_type)const { - UTF8String name; - uint binding; - };//struct ShaderDescriptor + if(desc_typeVK_DESCRIPTOR_TYPE_END_RANGE)return nullptr; - using ShaderDescriptorList=ObjectList; + return &(descriptor_list[desc_type].binding_list); + } + };//class ShaderResource - class ShaderResource - { - ShaderStageList is_list; - ShaderStageList os_list; - - ShaderDescriptorList ubo_list; - ShaderDescriptorList sampler_list; - - public: - - ShaderStageList &GetInputStages(){return is_list;} - ShaderStageList &GetOutputStages(){return os_list;} - - ShaderDescriptorList &GetUBO(){return ubo_list;} - ShaderDescriptorList &GetSampler(){return sampler_list;} - };//class ShaderResource - - ShaderResource *LoadShaderResoruce(const OSString &filename); - }//namespace graph -}//namespace hgl + ShaderResource *LoadShaderResoruce(const OSString &filename); +VK_NAMESPACE_END \ No newline at end of file diff --git a/inc/hgl/graph/vulkan/VK.h b/inc/hgl/graph/vulkan/VK.h index 0d09c6e5..9c27723f 100644 --- a/inc/hgl/graph/vulkan/VK.h +++ b/inc/hgl/graph/vulkan/VK.h @@ -56,7 +56,7 @@ class VertexAttributeBinding; class Renderable; -enum class ShaderStage +enum class ShaderStageBit { Vertex =VK_SHADER_STAGE_VERTEX_BIT, TessControl =VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, @@ -64,7 +64,7 @@ enum class ShaderStage Geometry =VK_SHADER_STAGE_GEOMETRY_BIT, Fragment =VK_SHADER_STAGE_FRAGMENT_BIT, Compute =VK_SHADER_STAGE_COMPUTE_BIT -};//enum class ShaderStage +};//enum class ShaderStageBit /** * max-lengths: @@ -80,6 +80,8 @@ struct PushConstant Vector3f object_size; }; +constexpr uint32_t MAX_PUSH_CONSTANT_BYTES=sizeof(PushConstant); + inline void copy(VkExtent3D &e3d,const VkExtent2D &e2d) { e3d.width =e2d.width; diff --git a/inc/hgl/graph/vulkan/VKCommandBuffer.h b/inc/hgl/graph/vulkan/VKCommandBuffer.h index f0585b31..849cdae9 100644 --- a/inc/hgl/graph/vulkan/VKCommandBuffer.h +++ b/inc/hgl/graph/vulkan/VKCommandBuffer.h @@ -113,9 +113,9 @@ public: return(true); } - void PushConstants(ShaderStage shader_stage,uint32_t offset,uint32_t size,const void *pValues) + void PushConstants(ShaderStageBit shader_stage_bit,uint32_t offset,uint32_t size,const void *pValues) { - vkCmdPushConstants(cmd_buf,pipeline_layout,(VkShaderStageFlagBits)shader_stage,offset,size,pValues); + vkCmdPushConstants(cmd_buf,pipeline_layout,(VkShaderStageFlagBits)shader_stage_bit,offset,size,pValues); } void PushConstants(const PushConstant *pc){vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0,sizeof(PushConstant),pc);} diff --git a/inc/hgl/graph/vulkan/VKShaderModule.h b/inc/hgl/graph/vulkan/VKShaderModule.h index 02f32f40..61bf2b7f 100644 --- a/inc/hgl/graph/vulkan/VKShaderModule.h +++ b/inc/hgl/graph/vulkan/VKShaderModule.h @@ -1,10 +1,10 @@ #ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE #define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE -#include +#include +#include VK_NAMESPACE_BEGIN -class ShaderParse; /** * Shader模块
@@ -20,11 +20,13 @@ private: VkPipelineShaderStageCreateInfo *stage_create_info; - ShaderResource resource; +protected: + + ShaderResource *shader_resource; public: - ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *); + ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *); virtual ~ShaderModule(); const int GetID()const{return shader_id;} @@ -37,11 +39,12 @@ public: const VkShaderStageFlagBits GetStage ()const{return stage_create_info->stage;} const VkPipelineShaderStageCreateInfo * GetCreateInfo ()const{return stage_create_info;} - const ShaderResource & GetResource ()const{return resource;} const int GetBinding (VkDescriptorType desc_type,const UTF8String &name)const { - return resource[desc_type].GetBinding(name); + return shader_resource->GetBinding(desc_type,name); } + + const ShaderDescriptorList * GetDescriptorList()const{return shader_resource->GetDescriptorList();} };//class ShaderModule class VertexAttributeBinding; @@ -58,19 +61,17 @@ class VertexShaderModule:public ShaderModule private: - Map stage_input_locations; - Set vab_sets; public: - VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *parse); + VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr); virtual ~VertexShaderModule(); /** * 获取输入流绑定点,需要注意的时,这里获取的binding并非是shader中的binding/location,而是绑定顺序的序列号。对应vkCmdBindVertexBuffer的缓冲区序列号 */ - const int GetStageInputBinding(const UTF8String &)const; + const int GetStageInputBinding(const UTF8String &name)const{return shader_resource->GetStageInputBinding(name);} const uint32_t GetAttrCount()const{return attr_count;} diff --git a/inc/hgl/graph/vulkan/VKShaderModuleManage.h b/inc/hgl/graph/vulkan/VKShaderModuleManage.h index e1177b94..3db7dc15 100644 --- a/inc/hgl/graph/vulkan/VKShaderModuleManage.h +++ b/inc/hgl/graph/vulkan/VKShaderModuleManage.h @@ -5,6 +5,9 @@ #include #include VK_NAMESPACE_BEGIN + +class ShaderResource; + /** * Shader模块管理器
* 所有的shader模块均由它创建和释放 @@ -27,9 +30,9 @@ public: ~ShaderModuleManage(); - const ShaderModule *CreateShader(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size); + const ShaderModule *CreateShader(ShaderResource *); const ShaderModule *CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename); - +/* #define ADD_SHADER_FUNC(sn,vk_name) const ShaderModule *Create##sn##Shader(const void *spv_data,const uint32_t spv_size){return CreateShader(VK_SHADER_STAGE_##vk_name##_BIT,spv_data,spv_size);} ADD_SHADER_FUNC(Vertex, VERTEX) ADD_SHADER_FUNC(Fragment, FRAGMENT) @@ -49,7 +52,7 @@ public: ADD_NV_SHADER_FUNC(Task, TASK); ADD_NV_SHADER_FUNC(Mesh, MESH); #undef ADD_NV_SHADER_FUNC - +*/ const ShaderModule *GetShader (int); bool ReleaseShader (const ShaderModule *); diff --git a/src/RenderDevice/Vulkan/CMakeLists.txt b/src/RenderDevice/Vulkan/CMakeLists.txt index 9b15dfd7..6f9b7f8b 100644 --- a/src/RenderDevice/Vulkan/CMakeLists.txt +++ b/src/RenderDevice/Vulkan/CMakeLists.txt @@ -13,8 +13,7 @@ SET(VK_DESCRIPTOR_SETS_SOURCE VKDescriptorSets.cpp VKDescriptorSetLayoutCreater.cpp VKDescriptorSetLayoutCreater.h) -SET(VK_SHADER_SOURCE VKShaderParse.h - VKShaderModule.cpp +SET(VK_SHADER_SOURCE VKShaderModule.cpp VKShaderModuleManage.cpp) SET(VK_MATERIAL_SOURCE VKImageView.cpp diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp index 9d7af084..6ba4359b 100644 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp +++ b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp @@ -88,11 +88,11 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout() if(vkCreateDescriptorSetLayout(*device,&descriptor_layout,nullptr,&dsl)!=VK_SUCCESS) return(false); - VkPushConstantRange push_constant_rage; + VkPushConstantRange push_constant_range; - push_constant_rage.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - push_constant_rage.size = sizeof(PushConstant); - push_constant_rage.offset = 0; + push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + push_constant_range.size = MAX_PUSH_CONSTANT_BYTES; + push_constant_range.offset = 0; VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo; pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; @@ -101,7 +101,7 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout() pPipelineLayoutCreateInfo.setLayoutCount = 1; pPipelineLayoutCreateInfo.pSetLayouts = &dsl; pPipelineLayoutCreateInfo.pushConstantRangeCount = 1; - pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_rage; + pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_range; if(vkCreatePipelineLayout(*device,&pPipelineLayoutCreateInfo,nullptr,&pipeline_layout)!=VK_SUCCESS) return(false); diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h index 6f8a12e8..652d2b39 100644 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h +++ b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include VK_NAMESPACE_BEGIN class Device; class DescriptorSets; @@ -25,13 +26,20 @@ public: void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits); void Bind(const uint32_t *binding,const uint32_t count,VkDescriptorType type,VkShaderStageFlagBits stage); - void Bind(const ShaderResourceList &srl,VkDescriptorType type,VkShaderStageFlagBits stage){if(srl.binding_list.GetCount()>0)Bind(srl.binding_list.GetData(),srl.binding_list.GetCount(),type,stage);} - void Bind(const ShaderResource &sr,VkShaderStageFlagBits stage) + void Bind(const ShaderBindingList &sbl,VkDescriptorType type,VkShaderStageFlagBits stage) + { + if(sbl.GetCount()>0) + Bind(sbl.GetData(),sbl.GetCount(),type,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(sr[i].binding_list.GetCount()>0) - Bind(sr[i],(VkDescriptorType)i,stage); + if(sdl->binding_list.GetCount()>0) + Bind(sdl->binding_list.GetData(),sdl->binding_list.GetCount(),(VkDescriptorType)i,stage); + + ++sdl; } } diff --git a/src/RenderDevice/Vulkan/VKMaterial.cpp b/src/RenderDevice/Vulkan/VKMaterial.cpp index 4825ed0c..c2efd0aa 100644 --- a/src/RenderDevice/Vulkan/VKMaterial.cpp +++ b/src/RenderDevice/Vulkan/VKMaterial.cpp @@ -32,7 +32,7 @@ Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps) vsm=(*itp)->right; memcpy(p,vsm->GetCreateInfo(),sizeof(VkPipelineShaderStageCreateInfo)); - dsl_creater->Bind(vsm->GetResource(),vsm->GetStage()); + dsl_creater->Bind(vsm->GetDescriptorList(),vsm->GetStage()); ++p; ++itp; diff --git a/src/RenderDevice/Vulkan/VKShaderModule.cpp b/src/RenderDevice/Vulkan/VKShaderModule.cpp index 3d9de9e3..a70219f1 100644 --- a/src/RenderDevice/Vulkan/VKShaderModule.cpp +++ b/src/RenderDevice/Vulkan/VKShaderModule.cpp @@ -1,24 +1,8 @@ #include #include -#include"VKShaderParse.h" VK_NAMESPACE_BEGIN -namespace -{ - void EnumShaderResource(const ShaderParse *parse,ShaderResourceList &sr,const spirv_cross::SmallVector &res) - { - for(const auto &obj:res) - { - const UTF8String & name =parse->GetName(obj); - const uint binding =parse->GetBinding(obj); - - sr.binding_by_name.Add(name,binding); - sr.binding_list.Add(binding); - } - } -}//namespace - -ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *sci,const ShaderParse *sp) +ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *sci,ShaderResource *sr) { device=dev; shader_id=id; @@ -26,9 +10,7 @@ ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo * stage_create_info=sci; - EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER],sp->GetUBO()); - EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER],sp->GetSSBO()); - EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER],sp->GetSampler()); + shader_resource=sr; } ShaderModule::~ShaderModule() @@ -37,27 +19,25 @@ ShaderModule::~ShaderModule() delete stage_create_info; } -VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *parse):ShaderModule(dev,id,pssci,parse) +VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr):ShaderModule(dev,id,pssci,sr) { - const auto &stage_inputs=parse->GetStageInputs(); + const ShaderStageList &stage_inputs=sr->GetStageInputs(); - attr_count=(uint32_t)stage_inputs.size(); + attr_count=stage_inputs.GetCount(); binding_list=new VkVertexInputBindingDescription[attr_count]; attribute_list=new VkVertexInputAttributeDescription[attr_count]; VkVertexInputBindingDescription *bind=binding_list; VkVertexInputAttributeDescription *attr=attribute_list; - uint32_t binding_index=0; + uint32_t binding_index=0; + ShaderStage **si=stage_inputs.GetData(); - for(const auto &si:stage_inputs) + for(uint i=0;iGetFormat(si); //注意这个格式有可能会解析不出来(比如各种压缩格式) - const UTF8String & name =parse->GetName(si); - bind->binding =binding_index; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号,所以这个数字必须从0开始,而且紧密排列。 //在VertexInput类中,buf_list需要严格按照本此binding为序列号排列 - bind->stride =GetStrideByFormat(format); + bind->stride =GetStrideByFormat((*si)->format); bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX; //binding对应的是第几个数据输入流 @@ -66,15 +46,15 @@ VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStage //但在我们的设计中,仅支持一个流传递一个attrib attr->binding =binding_index; - attr->location =parse->GetLocation(si); //此值对应shader中的layout(location= - attr->format =format; + attr->location =(*si)->location; //此值对应shader中的layout(location= + attr->format =(*si)->format; attr->offset =0; - stage_input_locations.Add(name,attr); - ++attr; ++bind; ++binding_index; + + ++si; } } @@ -89,18 +69,6 @@ VertexShaderModule::~VertexShaderModule() SAFE_CLEAR_ARRAY(attribute_list); } -const int VertexShaderModule::GetStageInputBinding(const UTF8String &name)const -{ - if(name.IsEmpty())return -1; - - VkVertexInputAttributeDescription *attr; - - if(!stage_input_locations.Get(name,attr)) - return -1; - - return attr->binding; -} - VertexAttributeBinding *VertexShaderModule::CreateVertexAttributeBinding() { VertexAttributeBinding *vab=new VertexAttributeBinding(this); diff --git a/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp b/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp index 901fc98b..85ff70b2 100644 --- a/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp +++ b/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp @@ -2,7 +2,7 @@ #include #include #include -#include"VKShaderParse.h" +#include #include VK_NAMESPACE_BEGIN @@ -25,9 +25,9 @@ ShaderModuleManage::~ShaderModuleManage() } } -const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size) +const ShaderModule *ShaderModuleManage::CreateShader(ShaderResource *sr) { - if(!spv_data||spv_size<=0) + if(!sr) return(nullptr); VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo; @@ -35,28 +35,26 @@ const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage->pNext =nullptr; shader_stage->pSpecializationInfo =nullptr; shader_stage->flags =0; - shader_stage->stage =shader_stage_bit; + shader_stage->stage =sr->GetStage(); shader_stage->pName ="main"; VkShaderModuleCreateInfo moduleCreateInfo; moduleCreateInfo.sType =VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.pNext =nullptr; moduleCreateInfo.flags =0; - moduleCreateInfo.codeSize =spv_size; - moduleCreateInfo.pCode =(const uint32_t *)spv_data; + moduleCreateInfo.codeSize =sr->GetCodeSize(); + moduleCreateInfo.pCode =sr->GetCode(); if(vkCreateShaderModule(*device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS) return(nullptr); ShaderModule *sm; - ShaderParse *parse=new ShaderParse(spv_data,spv_size); - if(shader_stage_bit==VK_SHADER_STAGE_VERTEX_BIT) - sm=new VertexShaderModule(*device,shader_count,shader_stage,parse); + if(sr->GetStage()==VK_SHADER_STAGE_VERTEX_BIT) + sm=new VertexShaderModule(*device,shader_count,shader_stage,sr); else - sm=new ShaderModule(*device,shader_count,shader_stage,parse); + sm=new ShaderModule(*device,shader_count,shader_stage,sr); - delete parse; shader_list.Add(shader_count,sm); ++shader_count; @@ -66,17 +64,11 @@ const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename) { - char *spv_data; - int64 spv_size=hgl::filesystem::LoadFileToMemory(filename,(void **)&spv_data); + ShaderResource *shader_resource=LoadShaderResoruce(filename); - if(spv_size<=0) - return(nullptr); + if(!shader_resource)return(nullptr); - const ShaderModule *sm=CreateShader(shader_stage_bit,spv_data,spv_size); - - delete[] spv_data; - - return sm; + return CreateShader(shader_resource); } const ShaderModule *ShaderModuleManage::GetShader(int id) diff --git a/src/RenderDevice/Vulkan/VKShaderParse.h b/src/RenderDevice/Vulkan/VKShaderParse.h deleted file mode 100644 index 95f73422..00000000 --- a/src/RenderDevice/Vulkan/VKShaderParse.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once -#include"spirv_cross.hpp" -#include -#include - -using namespace hgl; - -VK_NAMESPACE_BEGIN -class ShaderParse -{ - spirv_cross::Compiler *compiler; - spirv_cross::ShaderResources resource; - -public: - - ShaderParse(const void *spv_data,const uint32_t spv_size) - { - compiler=new spirv_cross::Compiler((const uint32_t *)spv_data,spv_size/sizeof(uint32_t)); - - resource=compiler->get_shader_resources(); - } - - ~ShaderParse() - { - delete compiler; - } - -#define SHADER_PARSE_GET_RESOURCE(name,buf_name) const spirv_cross::SmallVector &Get##name()const{return resource.buf_name;} - - SHADER_PARSE_GET_RESOURCE(UBO, uniform_buffers) - SHADER_PARSE_GET_RESOURCE(SSBO, storage_buffers) - SHADER_PARSE_GET_RESOURCE(StageInputs, stage_inputs) - SHADER_PARSE_GET_RESOURCE(StageOutputs, stage_outputs) - SHADER_PARSE_GET_RESOURCE(Sampler, sampled_images) - SHADER_PARSE_GET_RESOURCE(Subpass, subpass_inputs) - - //SmallVector storage_images; - //SmallVector atomic_counters; - //SmallVector acceleration_structures; - //SmallVector push_constant_buffers; - //SmallVector separate_images; - //SmallVector separate_samplers; - -#undef SHADER_PARSE_GET_RESOURCE - -public: - - const UTF8String GetName(const spirv_cross::Resource &res)const - { - return UTF8String(compiler->get_name(res.id).c_str()); - } - - const uint32_t GetBinding(const spirv_cross::Resource &res)const - { - return compiler->get_decoration(res.id,spv::DecorationBinding); - } - - const uint32_t GetLocation(const spirv_cross::Resource &res)const - { - return compiler->get_decoration(res.id,spv::DecorationLocation); - } - - const VkFormat GetFormat(const spirv_cross::Resource &res)const - { - const spirv_cross::SPIRType &type=compiler->get_type(res.type_id); - - constexpr VkFormat format[][4]= - { - {FMT_R8I,FMT_RG8I,VK_FORMAT_UNDEFINED,FMT_RGBA8I}, //sbyte - {FMT_R8U,FMT_RG8U,VK_FORMAT_UNDEFINED,FMT_RGBA8U}, //ubyte - {FMT_R16I,FMT_RG16I,VK_FORMAT_UNDEFINED,FMT_RGBA16I},//short - {FMT_R16U,FMT_RG16U,VK_FORMAT_UNDEFINED,FMT_RGBA16U},//ushort - {FMT_R32I,FMT_RG32I,FMT_RGB32I,FMT_RGBA32I},//int - {FMT_R32U,FMT_RG32U,FMT_RGB32U,FMT_RGBA32U},//uint - {FMT_R64I,FMT_RG64I,FMT_RGB64I,FMT_RGBA64I},//int64 - {FMT_R64U,FMT_RG64U,FMT_RGB64U,FMT_RGBA64U},//uint64 - {}, //atomic - {FMT_R16F,FMT_RG16F,VK_FORMAT_UNDEFINED,FMT_RGBA16F},//half - {FMT_R32F,FMT_RG32F,FMT_RGB32F,FMT_RGBA32F},//float - {FMT_R64F,FMT_RG64F,FMT_RGB64F,FMT_RGBA64F} //double - }; - - if(type.basetypespirv_cross::SPIRType::Double - ||type.basetype==spirv_cross::SPIRType::AtomicCounter - ||type.vecsize<1 - ||type.vecsize>4) - return VK_FORMAT_UNDEFINED; - - return format[type.basetype-spirv_cross::SPIRType::SByte][type.vecsize-1]; - } -};//class ShaderParse -VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/shader/ShaderResource.cpp b/src/SceneGraph/shader/ShaderResource.cpp index 64901661..8e7a8a10 100644 --- a/src/SceneGraph/shader/ShaderResource.cpp +++ b/src/SceneGraph/shader/ShaderResource.cpp @@ -2,144 +2,169 @@ #include #include -namespace hgl -{ - namespace graph +VK_NAMESPACE_BEGIN + + #define AccessByPointer(data,type) *(type *)data;data+=sizeof(type); + + namespace { - namespace + 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) { - constexpr char SHADER_FILE_HEADER[] ="Shader\x1A"; - constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1; + const uint count=*data++; - 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 + if(count<=0) + return(data); - const uint8 *LoadShaderStages(ShaderStageList &ss_list,const uint8 *data) + const uint32 total_bytes=AccessByPointer(data,uint32); + + int basetype; + int vec_size; + int str_len; + + ShaderStage *ss; + + for(uint i=0;ilocation=*data++; + basetype=*data++; + vec_size=*data++; - const uint32 total_bytes=*(uint32 *)data; - data+=sizeof(uint32); + ss->format=VK_NAMESPACE::GetVulkanFormat(basetype,vec_size); - int basetype; - int vec_size; - int str_len; + str_len=*data++; + ss->name.SetString((char *)data,str_len); + data+=str_len; - ShaderStage *ss; - - for(uint i=0;ilocation=*data++; - basetype=*data++; - vec_size=*data++; - - ss->format=VK_NAMESPACE::GetVulkanFormat(basetype,vec_size); - - str_len=*data++; - ss->name.SetString((char *)data,str_len); - data+=str_len; - - ss_list.Add(ss); - } - - return data; + ss_list.Add(ss); } - const uint8 *LoadShaderDescriptor(ShaderDescriptorList &sd_list,const uint8 *data) - { - const uint32 total_bytes=*(uint32 *)data; - data+=sizeof(uint32); - - const uint count=*data++; - - uint str_len; - - for(uint i=0;ibinding=*data++; - str_len=*data++; - sd->name.SetString((char *)data,str_len); - data+=str_len; - - sd_list.Add(sd); - } - - return data; - } - }//namespcae - - ShaderResource::ShaderResource(const void *fd,const void *sd,const uint32 size) - { - data=fd; - spv_data=sd; - spv_size=size; + return data; } - ShaderResource::~ShaderResource() - { - delete[] data; - } + const uint8 *LoadShaderDescriptor(ShaderDescriptorList *sd_list,const uint8 *data) + { + const uint32 total_bytes=AccessByPointer(data,uint32); - ShaderResource *LoadShaderResoruce(const OSString &filename) - { - int64 filesize; - uint8 *origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename,filesize); + const uint count=*data++; - if(!origin_filedata)return(nullptr); + uint str_len; - if(filesizebinding_list.Add(*data++); + str_len=*data++; + sd_list->name_list.Add(UTF8String((char *)data,str_len)); + data+=str_len; } - const uint8 *filedata=origin_filedata; - const uint8 *file_end=filedata+filesize; - - filedata+=SHADER_FILE_HEADER_BYTES; - - const uint8 ver=*filedata; - ++filedata; - - const VkShaderStageFlagBits flag=(const VkShaderStageFlagBits)(*(uint32 *)filedata); - filedata+=sizeof(uint32); - - const uint32 spv_size=*(uint32 *)filedata; - filedata+=sizeof(uint32); - - ShaderResource *sr=new ShaderResource(origin_filedata,filedata,spv_size); - - filedata+=spv_size; - - filedata=LoadShaderStages(sr->GetInputStages(),filedata); - filedata=LoadShaderStages(sr->GetOutputStages(),filedata); - - while(filedataGetUBO(), filedata);else - if(desc_type==VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER )filedata=LoadShaderDescriptor(sr->GetSampler(),filedata);else - { - delete sr; - return(nullptr); - } - } - - return sr; + return data; } - }//namespace graph -}//namespace hgl + }//namespcae + + ShaderResource::ShaderResource(const void *fd,const VkShaderStageFlagBits &flag,const void *sd,const uint32 size) + { + data=fd; + stage_flag=flag; + spv_data=sd; + spv_size=size; + } + + ShaderResource::~ShaderResource() + { + delete[] data; + } + + const int ShaderResource::GetStageInputBinding(const UTF8String &name) + { + const int count=stage_inputs.GetCount(); + ShaderStage **ss=stage_inputs.GetData(); + + for(int i=0;iname) + return (*ss)->location; + + ++ss; + } + + return -1; + } + + const int ShaderResource::GetBinding(VkDescriptorType desc_type,const UTF8String &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; + + const int index=sdl->name_list.Find(name); + + uint binding; + + if(sdl->binding_list.Get(index,binding)) + return binding; + else + return -1; + } + + ShaderResource *LoadShaderResoruce(const OSString &filename) + { + int64 filesize; + uint8 *origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename,filesize); + + if(!origin_filedata)return(nullptr); + + if(filesizeGetStageInputs(),filedata); + filedata=LoadShaderStages(sr->GetStageOutputs(),filedata); + + while(filedataGetDescriptorList((VkDescriptorType)desc_type),filedata); + { + delete sr; + return(nullptr); + } + } + + return sr; + } +VK_NAMESPACE_END \ No newline at end of file