diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index bb2b1d2b..7f5ac11f 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -20,6 +20,8 @@ SET(VULKAN_TEST_SOURCE_FILES main.cpp VKPipelineLayout.cpp VKRenderPass.cpp VKShader.cpp + VKShaderModule.cpp + VKShaderModuleManage.cpp VKVertexAttributeBinding.cpp VKVertexInput.cpp VKPipeline.cpp @@ -44,6 +46,8 @@ SET(VULKAN_TEST_HEADER_FILES VK.h VKPipelineLayout.h VKRenderPass.h VKShader.h + VKShaderModule.h + VKShaderModuleManage.h VKVertexInput.h VKVertexAttributeBinding.h VKSemaphore.h diff --git a/example/Vulkan/VKDevice.cpp b/example/Vulkan/VKDevice.cpp index a60ab90f..d7a095bf 100644 --- a/example/Vulkan/VKDevice.cpp +++ b/example/Vulkan/VKDevice.cpp @@ -8,6 +8,7 @@ #include"VKFramebuffer.h" #include"VKFence.h" #include"VKSemaphore.h" +#include"VKShader.h" #include"VKMaterial.h" #include"VKDescriptorSets.h" @@ -299,6 +300,29 @@ Semaphore *Device::CreateSem() return(new Semaphore(attr->device,sem)); } +ShaderModule *Device::CreateShaderModule(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size) +{ + VkPipelineShaderStageCreateInfo shader_stage; + shader_stage.sType=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage.pNext=nullptr; + shader_stage.pSpecializationInfo=nullptr; + shader_stage.flags=0; + shader_stage.stage=shader_stage_bit; + 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; + + if(vkCreateShaderModule(attr->device,&moduleCreateInfo,nullptr,&shader_stage.module)!=VK_SUCCESS) + return(nullptr); + + return(new ShaderModule(device,shader_stage)); +} + bool Device::AcquireNextImage() { return(vkAcquireNextImageKHR(attr->device,attr->swap_chain,UINT64_MAX,*image_acquired_semaphore,VK_NULL_HANDLE,¤t_frame)==VK_SUCCESS); diff --git a/example/Vulkan/VKDevice.h b/example/Vulkan/VKDevice.h index d189922a..9428e05c 100644 --- a/example/Vulkan/VKDevice.h +++ b/example/Vulkan/VKDevice.h @@ -16,8 +16,8 @@ class CommandBuffer; class RenderPass; class Fence; class Semaphore; +class ShaderModule; class Material; -class Shader; #define MAX_FRAMES_IN_FLIGHT 2 @@ -91,6 +91,8 @@ public: #undef CREATE_BUFFER_OBJECT + ShaderModule * CreateShaderModule(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size); + Material * CreateMaterial(Shader *); CommandBuffer * CreateCommandBuffer(); diff --git a/example/Vulkan/VKMaterial.h b/example/Vulkan/VKMaterial.h index e642094c..12b76470 100644 --- a/example/Vulkan/VKMaterial.h +++ b/example/Vulkan/VKMaterial.h @@ -17,12 +17,12 @@ class VertexAttributeBinding; class Material { Device *device; - Shader *shader; + ShaderModule *shader_modules; DescriptorSetLayoutCreater *dsl_creater; public: - Material(Device *dev,Shader *s); + Material(Device *dev,); ~Material(); MaterialInstance *CreateInstance(); diff --git a/example/Vulkan/VKShader.h b/example/Vulkan/VKShader.h index abe37d88..3091b2f7 100644 --- a/example/Vulkan/VKShader.h +++ b/example/Vulkan/VKShader.h @@ -17,12 +17,7 @@ class Shader private: - uint32_t attr_count; - VkVertexInputBindingDescription *binding_list; - VkVertexInputAttributeDescription *attribute_list; - Map stage_input_locations; - Map ubo_list; Set vab_sets; @@ -35,50 +30,14 @@ public: Shader(VkDevice); ~Shader(); - bool Add(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size); - -#define ADD_SHADER_FUNC(sn,vk_name) bool Add##sn##Shader(const void *spv_data,const uint32_t spv_size){return Add(VK_SHADER_STAGE_##vk_name##_BIT,spv_data,spv_size);} - ADD_SHADER_FUNC(Vertex, VERTEX) - ADD_SHADER_FUNC(Fragment, FRAGMENT) - ADD_SHADER_FUNC(Geometry, GEOMETRY) - ADD_SHADER_FUNC(TessCtrl, TESSELLATION_CONTROL) - ADD_SHADER_FUNC(TessEval, TESSELLATION_EVALUATION) - ADD_SHADER_FUNC(Compute, COMPUTE) -#undef ADD_SHADER_FUNC - -#define ADD_NV_SHADER_FUNC(sn,vk_name) bool Add##sn##Shader(const void *spv_data,const uint32_t spv_size) { return Add(VK_SHADER_STAGE_##vk_name##_BIT_NV,spv_data,spv_size); } - ADD_NV_SHADER_FUNC(Raygen, RAYGEN); - ADD_NV_SHADER_FUNC(AnyHit, ANY_HIT); - ADD_NV_SHADER_FUNC(ClosestHit, CLOSEST_HIT); - ADD_NV_SHADER_FUNC(MissBit, MISS); - ADD_NV_SHADER_FUNC(Intersection,INTERSECTION); - ADD_NV_SHADER_FUNC(Callable, CALLABLE); - ADD_NV_SHADER_FUNC(Task, TASK); - ADD_NV_SHADER_FUNC(Mesh, MESH); -#undef ADD_NV_SHADER_FUNC public: //shader部分 - const uint32_t GetStageCount ()const{return shader_stage_list.GetCount();} - const VkPipelineShaderStageCreateInfo * GetShaderStages ()const{return shader_stage_list.GetData();} - - const int GetUBO(const UTF8String &name)const{int binding;if(ubo_list.Get(name,binding))return binding;else return -1;} - public: //Vertex Input部分 VertexAttributeBinding * CreateVertexAttributeBinding(); bool Release(VertexAttributeBinding *); const uint32_t GetInstanceCount()const{return vab_sets.GetCount();} - const uint32_t GetAttrCount()const{return attr_count;} - - const int GetLocation (const UTF8String &)const; - const int GetBinding (const UTF8String &)const; - - const VkVertexInputBindingDescription * GetDescList ()const{return binding_list;} - const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list;} - - const VkVertexInputBindingDescription * GetDesc (const uint32_t index)const{return (index>=attr_count?nullptr:binding_list+index);} - const VkVertexInputAttributeDescription * GetAttr (const uint32_t index)const{return (index>=attr_count?nullptr:attribute_list+index);} };//class ShaderCreater VK_NAMESPACE_END diff --git a/example/Vulkan/VKShaderModule.cpp b/example/Vulkan/VKShaderModule.cpp new file mode 100644 index 00000000..646623c2 --- /dev/null +++ b/example/Vulkan/VKShaderModule.cpp @@ -0,0 +1,16 @@ +#include"VKShaderModule.h" + +VK_NAMESPACE_BEGIN +ShaderModule::ShaderModule(int id,VkPipelineShaderStageCreateInfo *sci) +{ + shader_id=id; + ref_count=0; + + stage_create_info=sci; +} + +ShaderModule::~ShaderModule() +{ + delete stage_create_info; +} +VK_NAMESPACE_END diff --git a/example/Vulkan/VKShaderModule.h b/example/Vulkan/VKShaderModule.h new file mode 100644 index 00000000..1f75ad5c --- /dev/null +++ b/example/Vulkan/VKShaderModule.h @@ -0,0 +1,68 @@ +#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE +#define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE + +#include"VK.h" +#include +#include +VK_NAMESPACE_BEGIN +/** + * ShaderÄ£¿é
+ * ¸ÃÄ£¿éÌṩµÄÊÇԭʼµÄshaderÊý¾ÝºÍÐÅÏ¢£¬²»¿É±»Ð޸ģ¬Ö»ÄÜͨ¹ýShaderModuleManage´´½¨ºÍɾ³ý + */ +class ShaderModule +{ + int shader_id; + + int ref_count; + +private: + + VkPipelineShaderStageCreateInfo *stage_create_info; + + uint32_t attr_count; + VkVertexInputBindingDescription *binding_list; + VkVertexInputAttributeDescription *attribute_list; + +private: + + Map stage_input_locations; + Map ubo_list; + +public: + + ShaderModule(int id,VkPipelineShaderStageCreateInfo *); + ~ShaderModule(); + + const int GetID()const{return shader_id;} + + const int IncRef(){return ++ref_count;} + const int DecRef(){return --ref_count;} + +public: + + const VkShaderStageFlagBits GetStage ()const{return stage_create_info->stage;} + const VkPipelineShaderStageCreateInfo * GetCreateInfo ()const{return stage_create_info;} + + const int GetUBO (const UTF8String &name)const + { + int binding; + + if(ubo_list.Get(name,binding)) + return binding; + else + return -1; + } + + const uint32_t GetAttrCount()const{return attr_count;} + + const int GetLocation (const UTF8String &)const; + const int GetBinding (const UTF8String &)const; + + const VkVertexInputBindingDescription * GetDescList ()const{return binding_list;} + const VkVertexInputAttributeDescription * GetAttrList ()const{return attribute_list;} + + const VkVertexInputBindingDescription * GetDesc (const uint32_t index)const{return (index>=attr_count?nullptr:binding_list+index);} + const VkVertexInputAttributeDescription * GetAttr (const uint32_t index)const{return (index>=attr_count?nullptr:attribute_list+index);} +};//class ShaderModule +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE diff --git a/example/Vulkan/VKShaderModuleManage.cpp b/example/Vulkan/VKShaderModuleManage.cpp new file mode 100644 index 00000000..51be222b --- /dev/null +++ b/example/Vulkan/VKShaderModuleManage.cpp @@ -0,0 +1,58 @@ +#include"VKShaderModuleManage.h" +#include"VKShaderModule.h" + +VK_NAMESPACE_BEGIN +int ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size) +{ + VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo; + shader_stage->sType=VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shader_stage->pNext=nullptr; + shader_stage->pSpecializationInfo=nullptr; + shader_stage->flags=0; + shader_stage->stage=shader_stage_bit; + 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; + + if(vkCreateShaderModule(device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS) + return(-1); + + ShaderModule *sm=new ShaderModule(shader_count,shader_stage); + + shader_list.Add(shader_count,sm); + + return shader_count++; +} + +const ShaderModule *ShaderModuleManage::GetShader(int id) +{ + ShaderModule *sm; + + if(!shader_list.Get(id,sm)) + return nullptr; + + sm->IncRef(); + return sm; +} + +bool ShaderModuleManage::ReleaseShader(const ShaderModule *const_sm) +{ + if(!const_sm)return; + + ShaderModule *sm; + + if(!shader_list.Get(const_sm->GetID(),sm)) + return nullptr; + + if(sm!=const_sm) + return(false); + + sm->DecRef(); + return(true); +} +VK_NAMESPACE_END diff --git a/example/Vulkan/VKShaderModuleManage.h b/example/Vulkan/VKShaderModuleManage.h new file mode 100644 index 00000000..e0fd776b --- /dev/null +++ b/example/Vulkan/VKShaderModuleManage.h @@ -0,0 +1,57 @@ +#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE +#define HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE + +#include"VK.h" +#include +VK_NAMESPACE_BEGIN +class ShaderModule; + +/** + * ShaderÄ£¿é¹ÜÀíÆ÷
+ * ËùÓеÄshaderÄ£¿é¾ùÓÉËü´´½¨ºÍÊÍ·Å + * ¸Ã¹ÜÀíÆ÷ÔÚÒ»¸öÉ豸ϽöÓÐÒ»¸ö£¬Ëü¸ºÔð¹ÜÀíËùÓеÄshader(½övs/fs/gsµÈµ¥¸ö£¬·Ç×éºÏÌå) + */ +class ShaderModuleManage +{ + VkDevice device; + + int shader_count; + Map shader_list; + +public: + + ShaderModuleManage(VkDevice dev) + { + device=dev; + shader_count=0; + } + + ~ShaderModuleManage(); + + int CreateShader(const VkShaderStageFlagBits shader_stage_bit,const void *spv_data,const uint32_t spv_size); + +#define ADD_SHADER_FUNC(sn,vk_name) int 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) + ADD_SHADER_FUNC(Geometry, GEOMETRY) + ADD_SHADER_FUNC(TessCtrl, TESSELLATION_CONTROL) + ADD_SHADER_FUNC(TessEval, TESSELLATION_EVALUATION) + ADD_SHADER_FUNC(Compute, COMPUTE) +#undef ADD_SHADER_FUNC + +#define ADD_NV_SHADER_FUNC(sn,vk_name) int Create##sn##Shader(const void *spv_data,const uint32_t spv_size){return CreateShader(VK_SHADER_STAGE_##vk_name##_BIT_NV,spv_data,spv_size);} + ADD_NV_SHADER_FUNC(Raygen, RAYGEN); + ADD_NV_SHADER_FUNC(AnyHit, ANY_HIT); + ADD_NV_SHADER_FUNC(ClosestHit, CLOSEST_HIT); + ADD_NV_SHADER_FUNC(MissBit, MISS); + ADD_NV_SHADER_FUNC(Intersection,INTERSECTION); + ADD_NV_SHADER_FUNC(Callable, CALLABLE); + 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 *); +};//class ShaderModuleManage +VK_NAMESPACE_END +#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE