diff --git a/example/Vulkan/VKShader.cpp b/example/Vulkan/VKShader.cpp index dd6bbdcc..e4a77fcd 100644 --- a/example/Vulkan/VKShader.cpp +++ b/example/Vulkan/VKShader.cpp @@ -1,53 +1,90 @@ #include"VKShader.h" +#include"VKVertexInput.h" #include"spirv_cross.hpp" VK_NAMESPACE_BEGIN +const VkFormat GetVecFormat(const spirv_cross::SPIRType &type) +{ + if(type.basetype==spirv_cross::SPIRType::Float) + { + constexpr VkFormat format[4]={FMT_R32F,FMT_RG32F,FMT_RGB32F,FMT_RGB32F}; -void shader_dump(const void *spv_data,const uint32_t spv_size) + return format[type.vecsize-1]; + } + else + if(type.basetype==spirv_cross::SPIRType::Half) + { + constexpr VkFormat format[4]={FMT_R16F,FMT_RG16F,FMT_RGB16F,FMT_RGB16F}; + + return format[type.vecsize-1]; + } + else + if(type.basetype==spirv_cross::SPIRType::UInt) + { + constexpr VkFormat format[4]={FMT_R32U,FMT_RG32U,FMT_RGB32U,FMT_RGB32U}; + + return format[type.vecsize-1]; + } + else + if(type.basetype==spirv_cross::SPIRType::Int) + { + constexpr VkFormat format[4]={FMT_R32I,FMT_RG32I,FMT_RGB32I,FMT_RGB32I}; + + return format[type.vecsize-1]; + } + else + if(type.basetype==spirv_cross::SPIRType::UShort) + { + constexpr VkFormat format[4]={FMT_R16U,FMT_RG16U,FMT_RGB16U,FMT_RGB16U}; + + return format[type.vecsize-1]; + } + else + if(type.basetype==spirv_cross::SPIRType::Short) + { + constexpr VkFormat format[4]={FMT_R16I,FMT_RG16I,FMT_RGB16I,FMT_RGB16I}; + + return format[type.vecsize-1]; + } + + return VK_FORMAT_UNDEFINED; +} + +bool Shader::CreateVIS(const void *spv_data,const uint32_t spv_size) { spirv_cross::Compiler comp((const uint32_t *)spv_data,spv_size/sizeof(uint32_t)); spirv_cross::ShaderResources res=comp.get_shader_resources(); - for(auto &ref:res.sampled_images) + for(auto &si:res.stage_inputs) { - unsigned set=comp.get_decoration(ref.id,spv::DecorationDescriptorSet); - unsigned binding=comp.get_decoration(ref.id,spv::DecorationBinding); - const std::string name=comp.get_name(ref.id); + const spirv_cross::SPIRType & type =comp.get_type(si.type_id); + const VkFormat format =GetVecFormat(type); + + if(format==VK_FORMAT_UNDEFINED) + return(false); + + const uint32_t location=comp.get_decoration(si.id,spv::DecorationLocation); + const UTF8String & name =comp.get_name(si.id).c_str(); + + const int binding=vertex_input_state->Add(name,location,format); - std::cout<<"sampled image ["<0) @@ -63,7 +100,8 @@ Shader::~Shader() bool Shader::Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size) { - shader_dump(spv_data,spv_size); + if(shader_stage_bit==VK_SHADER_STAGE_VERTEX_BIT) + CreateVIS(spv_data,spv_size); VkPipelineShaderStageCreateInfo shader_stage; shader_stage.sType=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -87,4 +125,10 @@ bool Shader::Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_da return(true); } + +void Shader::Clear() +{ + shader_stage_list.Clear(); + vertex_input_state->Clear(); +} VK_NAMESPACE_END diff --git a/example/Vulkan/VKShader.h b/example/Vulkan/VKShader.h index c8b55d11..44c79093 100644 --- a/example/Vulkan/VKShader.h +++ b/example/Vulkan/VKShader.h @@ -2,6 +2,9 @@ #include"VK.h" VK_NAMESPACE_BEGIN + +class VertexInputState; + /** * Shader ´´½¨Æ÷ */ @@ -11,9 +14,15 @@ class Shader List shader_stage_list; + VertexInputState *vertex_input_state=nullptr; + +private: + + bool CreateVIS(const void *,const uint32_t); + public: - Shader(VkDevice dev):device(dev){} + Shader(VkDevice); ~Shader(); bool Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size); @@ -38,12 +47,11 @@ public: ADD_NV_SHADER_FUNC(Mesh, MESH); #undef ADD_NV_SHADER_FUNC - void Clear() - { - shader_stage_list.Clear(); - } + void Clear(); const uint32_t GetCount ()const{return shader_stage_list.GetCount();} const VkPipelineShaderStageCreateInfo * GetStages ()const{return shader_stage_list.GetData();} + + VertexInputState *GetVIS(){return vertex_input_state;} };//class ShaderCreater VK_NAMESPACE_END diff --git a/example/Vulkan/VKVertexInput.cpp b/example/Vulkan/VKVertexInput.cpp index bc6f214f..6231f49d 100644 --- a/example/Vulkan/VKVertexInput.cpp +++ b/example/Vulkan/VKVertexInput.cpp @@ -3,7 +3,7 @@ VK_NAMESPACE_BEGIN -void VertexInputState::Add(const uint32_t shader_location,const VkFormat format,uint32_t offset,bool instance) +int VertexInputState::Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset,bool instance) { const int binding_index=binding_list.GetCount(); //å‚考opengl vab,binding_index必须从0开始,紧密排列。对应在vkCmdBindVertexBuffer中的缓冲区索引 @@ -25,7 +25,35 @@ void VertexInputState::Add(const uint32_t shader_location,const VkFormat format, attrib->binding=binding_index; attrib->location=shader_location; attrib->format=format; - attrib->offset=offset; + attrib->offset=offset; + + stage_input_locations.Add(name,StageInput(binding_index,shader_location,format)); + + return binding_index; +} + +const int VertexInputState::GetLocation(const UTF8String &name)const +{ + if(name.IsEmpty())return -1; + + StageInput si; + + if(!stage_input_locations.Get(name,si)) + return -1; + + return si.location; +} + +const int VertexInputState::GetBinding(const UTF8String &name)const +{ + if(name.IsEmpty())return -1; + + StageInput si; + + if(!stage_input_locations.Get(name,si)) + return -1; + + return si.binding; } void VertexInputState::Write(VkPipelineVertexInputStateCreateInfo &vis) const @@ -58,7 +86,7 @@ VertexInput::~VertexInput() delete[] buf_list; } -bool VertexInput::Set(uint32_t index,VertexBuffer *buf,VkDeviceSize offset) +bool VertexInput::Set(int index,VertexBuffer *buf,VkDeviceSize offset) { if(index<0||index>=buf_count)return(false); diff --git a/example/Vulkan/VKVertexInput.h b/example/Vulkan/VKVertexInput.h index 3098c782..3d96e476 100644 --- a/example/Vulkan/VKVertexInput.h +++ b/example/Vulkan/VKVertexInput.h @@ -2,6 +2,8 @@ #define HGL_GRAPH_VULKAN_VERTEX_INPUT_INCLUDE #include"VK.h" +#include +#include VK_NAMESPACE_BEGIN class VertexBuffer; class IndexBuffer; @@ -15,17 +17,48 @@ class VertexInputState List binding_list; List attribute_list; + struct StageInput + { + int binding; + VkFormat format; + + uint32_t location; + + public: + + StageInput(){} + StageInput(const int b,const uint32_t l,const VkFormat f) + { + binding=b; + location=l; + format=f; + } + + CompOperatorMemcmp(const StageInput &); + };//struct StageInput + + Map stage_input_locations; public: VertexInputState()=default; ~VertexInputState()=default; - void Add(const uint32_t shader_location,const VkFormat format,uint32_t offset=0,bool instance=false); + int Add(const UTF8String &name,const uint32_t shader_location,const VkFormat format,uint32_t offset=0,bool instance=false); public: + void Clear() + { + binding_list.Clear(); + attribute_list.Clear(); + } + const uint32_t GetCount()const{return binding_list.GetCount();} + + const int GetLocation (const UTF8String &)const; + const int GetBinding (const UTF8String &)const; + VkVertexInputBindingDescription * GetDesc(const int index){return (index<0||index>=binding_list.GetCount()?nullptr:binding_list.GetData()+index);} VkVertexInputAttributeDescription * GetAttr(const int index){return (index<0||index>=attribute_list.GetCount()?nullptr:attribute_list.GetData()+index);} @@ -40,7 +73,7 @@ class VertexInput { VertexInputState *vis; - uint32_t buf_count=0; + int buf_count=0; VkBuffer *buf_list=nullptr; VkDeviceSize *buf_offset=nullptr; @@ -52,7 +85,9 @@ public: VertexInput(VertexInputState *); virtual ~VertexInput(); - bool Set(uint32_t index,VertexBuffer *,VkDeviceSize offset=0); + bool Set(int binding,VertexBuffer *,VkDeviceSize offset=0); + bool Set(const UTF8String &name,VertexBuffer *vb,VkDeviceSize offset=0){return Set(vis->GetBinding(name),vb,offset);} + bool Set(IndexBuffer *ib,VkDeviceSize offset=0) { if(!ib)return(false); @@ -64,7 +99,7 @@ public: public: - const uint32_t GetCount ()const{return buf_count;} + const int GetCount ()const{return buf_count;} const VkBuffer * GetBuffer ()const{return buf_list;} const VkDeviceSize * GetOffset ()const{return buf_offset;} diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index 334041d4..d61fd107 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -102,9 +102,6 @@ vulkan::Buffer *CreateUBO(vulkan::Device *dev) return ubo; } -constexpr uint32_t SHADER_LOCATION_POSITION =0; //对应shader中的layout(locaiton=0,暂时这样写 -constexpr uint32_t SHADER_LOCATION_COLOR =1; - constexpr float vertex_data[]= { SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25, @@ -113,16 +110,6 @@ constexpr float vertex_data[]= }; constexpr float color_data[]={1,0,0, 0,1,0, 0,0,1 }; -vulkan::VertexInputState *InitVertexInput() -{ - vulkan::VertexInputState *vis=new vulkan::VertexInputState(); - - vis->Add(SHADER_LOCATION_POSITION, FMT_RG32F); - vis->Add(SHADER_LOCATION_COLOR, FMT_RGB32F); - - return vis; -} - vulkan::VertexBuffer *vertex_buffer=nullptr; vulkan::VertexBuffer *color_buffer=nullptr; @@ -133,8 +120,8 @@ vulkan::VertexInput *CreateVertexBuffer(vulkan::Device *dev,vulkan::VertexInputS vulkan::VertexInput *vi=new vulkan::VertexInput(vis); - vi->Set(SHADER_LOCATION_POSITION, vertex_buffer); - vi->Set(SHADER_LOCATION_COLOR, color_buffer); + vi->Set("Vertex", vertex_buffer); + vi->Set("Color", color_buffer); return vi; } @@ -201,7 +188,7 @@ int main(int,char **) vulkan::Buffer *ubo=CreateUBO(device); - vulkan::VertexInputState *vis=InitVertexInput(); + vulkan::VertexInputState *vis=shader->GetVIS(); vulkan::VertexInput *vi=CreateVertexBuffer(device,vis); @@ -259,7 +246,6 @@ int main(int,char **) delete dsl; delete vi; - delete vis; delete ubo; delete shader;