use ShaderResource instead ShaderParse

This commit is contained in:
hyzboy 2020-06-09 19:40:08 +08:00
parent 30b5639acc
commit d94e6dee6c
16 changed files with 284 additions and 348 deletions

2
CMCore

@ -1 +1 @@
Subproject commit 6b4feef78efa3d185b6abeda049c6232d2da6a81 Subproject commit 72f2b58e12b0f86ed4f49cb939c18f18bb43e0df

@ -1 +1 @@
Subproject commit 60f82f0042c0b3be19e4eab72376a67db8bb0eab Subproject commit c879515d448d129ada207364e223c59694204b86

View File

@ -11,8 +11,8 @@ using namespace hgl::graph;
bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc);
bool LoadFromFile(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_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=128; constexpr uint32_t SCREEN_HEIGHT=720;
constexpr uint32_t VERTEX_COUNT=3; constexpr uint32_t VERTEX_COUNT=3;

View File

@ -1,12 +1,10 @@
#pragma once #pragma once
#include<hgl/type/BaseString.h> #include<hgl/type/BaseString.h>
#include<hgl/type/List.h> #include<hgl/type/List.h>
#include<vulkan/vulkan.h> #include<hgl/type/StringList.h>
#include<hgl/graph/vulkan/VKNamespace.h>
namespace hgl VK_NAMESPACE_BEGIN
{
namespace graph
{
struct ShaderStage struct ShaderStage
{ {
UTF8String name; UTF8String name;
@ -15,32 +13,65 @@ namespace hgl
};//struct ShaderStage };//struct ShaderStage
using ShaderStageList=ObjectList<ShaderStage>; using ShaderStageList=ObjectList<ShaderStage>;
using ShaderBindingList=List<uint32_t>;
struct ShaderDescriptor struct ShaderDescriptorList
{ {
UTF8String name; UTF8StringList name_list;
uint binding; ShaderBindingList binding_list;
};//struct ShaderDescriptor };
using ShaderDescriptorList=ObjectList<ShaderDescriptor>;
class ShaderResource class ShaderResource
{ {
ShaderStageList is_list; const void *data;
ShaderStageList os_list;
ShaderDescriptorList ubo_list; VkShaderStageFlagBits stage_flag;
ShaderDescriptorList sampler_list;
const void *spv_data;
uint32 spv_size;
ShaderStageList stage_inputs;
ShaderStageList stage_outputs;
ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
public: public:
ShaderStageList &GetInputStages(){return is_list;} ShaderResource(const void *,const VkShaderStageFlagBits &,const void *,const uint32);
ShaderStageList &GetOutputStages(){return os_list;} virtual ~ShaderResource();
ShaderDescriptorList &GetUBO(){return ubo_list;} const VkShaderStageFlagBits GetStage()const{return stage_flag;}
ShaderDescriptorList &GetSampler(){return sampler_list;}
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)
{
if(desc_type<VK_DESCRIPTOR_TYPE_BEGIN_RANGE
||desc_type>VK_DESCRIPTOR_TYPE_END_RANGE)return nullptr;
return descriptor_list+desc_type;
}
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
{
if(desc_type<VK_DESCRIPTOR_TYPE_BEGIN_RANGE
||desc_type>VK_DESCRIPTOR_TYPE_END_RANGE)return nullptr;
return &(descriptor_list[desc_type].binding_list);
}
};//class ShaderResource };//class ShaderResource
ShaderResource *LoadShaderResoruce(const OSString &filename); ShaderResource *LoadShaderResoruce(const OSString &filename);
}//namespace graph VK_NAMESPACE_END
}//namespace hgl

View File

@ -56,7 +56,7 @@ class VertexAttributeBinding;
class Renderable; class Renderable;
enum class ShaderStage enum class ShaderStageBit
{ {
Vertex =VK_SHADER_STAGE_VERTEX_BIT, Vertex =VK_SHADER_STAGE_VERTEX_BIT,
TessControl =VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, TessControl =VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
@ -64,7 +64,7 @@ enum class ShaderStage
Geometry =VK_SHADER_STAGE_GEOMETRY_BIT, Geometry =VK_SHADER_STAGE_GEOMETRY_BIT,
Fragment =VK_SHADER_STAGE_FRAGMENT_BIT, Fragment =VK_SHADER_STAGE_FRAGMENT_BIT,
Compute =VK_SHADER_STAGE_COMPUTE_BIT Compute =VK_SHADER_STAGE_COMPUTE_BIT
};//enum class ShaderStage };//enum class ShaderStageBit
/** /**
* max-lengths: * max-lengths:
@ -80,6 +80,8 @@ struct PushConstant
Vector3f object_size; Vector3f object_size;
}; };
constexpr uint32_t MAX_PUSH_CONSTANT_BYTES=sizeof(PushConstant);
inline void copy(VkExtent3D &e3d,const VkExtent2D &e2d) inline void copy(VkExtent3D &e3d,const VkExtent2D &e2d)
{ {
e3d.width =e2d.width; e3d.width =e2d.width;

View File

@ -113,9 +113,9 @@ public:
return(true); 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);} void PushConstants(const PushConstant *pc){vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0,sizeof(PushConstant),pc);}

View File

@ -1,10 +1,10 @@
#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE #ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE
#define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE #define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE
#include<hgl/graph/vulkan/VKShaderResource.h> #include<hgl/graph/shader/ShaderResource.h>
#include<hgl/type/Set.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class ShaderParse;
/** /**
* Shader模块<br> * Shader模块<br>
@ -20,11 +20,13 @@ private:
VkPipelineShaderStageCreateInfo *stage_create_info; VkPipelineShaderStageCreateInfo *stage_create_info;
ShaderResource resource; protected:
ShaderResource *shader_resource;
public: public:
ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *); ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *);
virtual ~ShaderModule(); virtual ~ShaderModule();
const int GetID()const{return shader_id;} const int GetID()const{return shader_id;}
@ -37,11 +39,12 @@ public:
const VkShaderStageFlagBits GetStage ()const{return stage_create_info->stage;} const VkShaderStageFlagBits GetStage ()const{return stage_create_info->stage;}
const VkPipelineShaderStageCreateInfo * GetCreateInfo ()const{return stage_create_info;} const VkPipelineShaderStageCreateInfo * GetCreateInfo ()const{return stage_create_info;}
const ShaderResource & GetResource ()const{return resource;}
const int GetBinding (VkDescriptorType desc_type,const UTF8String &name)const 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 ShaderModule
class VertexAttributeBinding; class VertexAttributeBinding;
@ -58,19 +61,17 @@ class VertexShaderModule:public ShaderModule
private: private:
Map<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
Set<VertexAttributeBinding *> vab_sets; Set<VertexAttributeBinding *> vab_sets;
public: public:
VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,const ShaderParse *parse); VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr);
virtual ~VertexShaderModule(); virtual ~VertexShaderModule();
/** /**
* binding并非是shader中的binding/locationvkCmdBindVertexBuffer的缓冲区序列号 * binding并非是shader中的binding/locationvkCmdBindVertexBuffer的缓冲区序列号
*/ */
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;} const uint32_t GetAttrCount()const{return attr_count;}

View File

@ -5,6 +5,9 @@
#include<hgl/type/Map.h> #include<hgl/type/Map.h>
#include<hgl/type/BaseString.h> #include<hgl/type/BaseString.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class ShaderResource;
/** /**
* Shader模块管理器<br> * Shader模块管理器<br>
* shader模块均由它创建和释放 * shader模块均由它创建和释放
@ -27,9 +30,9 @@ public:
~ShaderModuleManage(); ~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); 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);} #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(Vertex, VERTEX)
ADD_SHADER_FUNC(Fragment, FRAGMENT) ADD_SHADER_FUNC(Fragment, FRAGMENT)
@ -49,7 +52,7 @@ public:
ADD_NV_SHADER_FUNC(Task, TASK); ADD_NV_SHADER_FUNC(Task, TASK);
ADD_NV_SHADER_FUNC(Mesh, MESH); ADD_NV_SHADER_FUNC(Mesh, MESH);
#undef ADD_NV_SHADER_FUNC #undef ADD_NV_SHADER_FUNC
*/
const ShaderModule *GetShader (int); const ShaderModule *GetShader (int);
bool ReleaseShader (const ShaderModule *); bool ReleaseShader (const ShaderModule *);

View File

@ -13,8 +13,7 @@ SET(VK_DESCRIPTOR_SETS_SOURCE VKDescriptorSets.cpp
VKDescriptorSetLayoutCreater.cpp VKDescriptorSetLayoutCreater.cpp
VKDescriptorSetLayoutCreater.h) VKDescriptorSetLayoutCreater.h)
SET(VK_SHADER_SOURCE VKShaderParse.h SET(VK_SHADER_SOURCE VKShaderModule.cpp
VKShaderModule.cpp
VKShaderModuleManage.cpp) VKShaderModuleManage.cpp)
SET(VK_MATERIAL_SOURCE VKImageView.cpp SET(VK_MATERIAL_SOURCE VKImageView.cpp

View File

@ -88,11 +88,11 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout()
if(vkCreateDescriptorSetLayout(*device,&descriptor_layout,nullptr,&dsl)!=VK_SUCCESS) if(vkCreateDescriptorSetLayout(*device,&descriptor_layout,nullptr,&dsl)!=VK_SUCCESS)
return(false); return(false);
VkPushConstantRange push_constant_rage; VkPushConstantRange push_constant_range;
push_constant_rage.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_constant_rage.size = sizeof(PushConstant); push_constant_range.size = MAX_PUSH_CONSTANT_BYTES;
push_constant_rage.offset = 0; push_constant_range.offset = 0;
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo; VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo;
pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pPipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
@ -101,7 +101,7 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout()
pPipelineLayoutCreateInfo.setLayoutCount = 1; pPipelineLayoutCreateInfo.setLayoutCount = 1;
pPipelineLayoutCreateInfo.pSetLayouts = &dsl; pPipelineLayoutCreateInfo.pSetLayouts = &dsl;
pPipelineLayoutCreateInfo.pushConstantRangeCount = 1; pPipelineLayoutCreateInfo.pushConstantRangeCount = 1;
pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_rage; pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_range;
if(vkCreatePipelineLayout(*device,&pPipelineLayoutCreateInfo,nullptr,&pipeline_layout)!=VK_SUCCESS) if(vkCreatePipelineLayout(*device,&pPipelineLayoutCreateInfo,nullptr,&pipeline_layout)!=VK_SUCCESS)
return(false); return(false);

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include<hgl/graph/vulkan/VKShaderResource.h> #include<hgl/graph/shader/ShaderResource.h>
#include<hgl/type/Map.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class Device; class Device;
class DescriptorSets; class DescriptorSets;
@ -25,13 +26,20 @@ public:
void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits); 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 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 ShaderBindingList &sbl,VkDescriptorType type,VkShaderStageFlagBits stage)
void Bind(const ShaderResource &sr,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++) for(uint32_t i=VK_DESCRIPTOR_TYPE_BEGIN_RANGE;i<=VK_DESCRIPTOR_TYPE_END_RANGE;i++)
{ {
if(sr[i].binding_list.GetCount()>0) if(sdl->binding_list.GetCount()>0)
Bind(sr[i],(VkDescriptorType)i,stage); Bind(sdl->binding_list.GetData(),sdl->binding_list.GetCount(),(VkDescriptorType)i,stage);
++sdl;
} }
} }

View File

@ -32,7 +32,7 @@ Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps)
vsm=(*itp)->right; vsm=(*itp)->right;
memcpy(p,vsm->GetCreateInfo(),sizeof(VkPipelineShaderStageCreateInfo)); memcpy(p,vsm->GetCreateInfo(),sizeof(VkPipelineShaderStageCreateInfo));
dsl_creater->Bind(vsm->GetResource(),vsm->GetStage()); dsl_creater->Bind(vsm->GetDescriptorList(),vsm->GetStage());
++p; ++p;
++itp; ++itp;

View File

@ -1,24 +1,8 @@
#include<hgl/graph/vulkan/VKShaderModule.h> #include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKVertexAttributeBinding.h> #include<hgl/graph/vulkan/VKVertexAttributeBinding.h>
#include"VKShaderParse.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
namespace ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *sci,ShaderResource *sr)
{
void EnumShaderResource(const ShaderParse *parse,ShaderResourceList &sr,const spirv_cross::SmallVector<spirv_cross::Resource> &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)
{ {
device=dev; device=dev;
shader_id=id; shader_id=id;
@ -26,9 +10,7 @@ ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *
stage_create_info=sci; stage_create_info=sci;
EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER],sp->GetUBO()); shader_resource=sr;
EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_STORAGE_BUFFER],sp->GetSSBO());
EnumShaderResource(sp,resource[VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER],sp->GetSampler());
} }
ShaderModule::~ShaderModule() ShaderModule::~ShaderModule()
@ -37,11 +19,11 @@ ShaderModule::~ShaderModule()
delete stage_create_info; 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]; binding_list=new VkVertexInputBindingDescription[attr_count];
attribute_list=new VkVertexInputAttributeDescription[attr_count]; attribute_list=new VkVertexInputAttributeDescription[attr_count];
@ -49,15 +31,13 @@ VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStage
VkVertexInputAttributeDescription *attr=attribute_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;i<attr_count;i++)
{ {
const VkFormat format =parse->GetFormat(si); //注意这个格式有可能会解析不出来(比如各种压缩格式)
const UTF8String & name =parse->GetName(si);
bind->binding =binding_index; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号所以这个数字必须从0开始而且紧密排列。 bind->binding =binding_index; //binding对应在vkCmdBindVertexBuffer中设置的缓冲区的序列号所以这个数字必须从0开始而且紧密排列。
//在VertexInput类中buf_list需要严格按照本此binding为序列号排列 //在VertexInput类中buf_list需要严格按照本此binding为序列号排列
bind->stride =GetStrideByFormat(format); bind->stride =GetStrideByFormat((*si)->format);
bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX; bind->inputRate =VK_VERTEX_INPUT_RATE_VERTEX;
//binding对应的是第几个数据输入流 //binding对应的是第几个数据输入流
@ -66,15 +46,15 @@ VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStage
//但在我们的设计中仅支持一个流传递一个attrib //但在我们的设计中仅支持一个流传递一个attrib
attr->binding =binding_index; attr->binding =binding_index;
attr->location =parse->GetLocation(si); //此值对应shader中的layout(location= attr->location =(*si)->location; //此值对应shader中的layout(location=
attr->format =format; attr->format =(*si)->format;
attr->offset =0; attr->offset =0;
stage_input_locations.Add(name,attr);
++attr; ++attr;
++bind; ++bind;
++binding_index; ++binding_index;
++si;
} }
} }
@ -89,18 +69,6 @@ VertexShaderModule::~VertexShaderModule()
SAFE_CLEAR_ARRAY(attribute_list); 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 *VertexShaderModule::CreateVertexAttributeBinding()
{ {
VertexAttributeBinding *vab=new VertexAttributeBinding(this); VertexAttributeBinding *vab=new VertexAttributeBinding(this);

View File

@ -2,7 +2,7 @@
#include<hgl/graph/vulkan/VKShaderModule.h> #include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKMaterial.h> #include<hgl/graph/vulkan/VKMaterial.h>
#include<hgl/graph/vulkan/VKDevice.h> #include<hgl/graph/vulkan/VKDevice.h>
#include"VKShaderParse.h" #include<hgl/graph/shader/ShaderResource.h>
#include<hgl/filesystem/FileSystem.h> #include<hgl/filesystem/FileSystem.h>
VK_NAMESPACE_BEGIN 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); return(nullptr);
VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo; VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo;
@ -35,28 +35,26 @@ const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits
shader_stage->pNext =nullptr; shader_stage->pNext =nullptr;
shader_stage->pSpecializationInfo =nullptr; shader_stage->pSpecializationInfo =nullptr;
shader_stage->flags =0; shader_stage->flags =0;
shader_stage->stage =shader_stage_bit; shader_stage->stage =sr->GetStage();
shader_stage->pName ="main"; shader_stage->pName ="main";
VkShaderModuleCreateInfo moduleCreateInfo; VkShaderModuleCreateInfo moduleCreateInfo;
moduleCreateInfo.sType =VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; moduleCreateInfo.sType =VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleCreateInfo.pNext =nullptr; moduleCreateInfo.pNext =nullptr;
moduleCreateInfo.flags =0; moduleCreateInfo.flags =0;
moduleCreateInfo.codeSize =spv_size; moduleCreateInfo.codeSize =sr->GetCodeSize();
moduleCreateInfo.pCode =(const uint32_t *)spv_data; moduleCreateInfo.pCode =sr->GetCode();
if(vkCreateShaderModule(*device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS) if(vkCreateShaderModule(*device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS)
return(nullptr); return(nullptr);
ShaderModule *sm; ShaderModule *sm;
ShaderParse *parse=new ShaderParse(spv_data,spv_size);
if(shader_stage_bit==VK_SHADER_STAGE_VERTEX_BIT) if(sr->GetStage()==VK_SHADER_STAGE_VERTEX_BIT)
sm=new VertexShaderModule(*device,shader_count,shader_stage,parse); sm=new VertexShaderModule(*device,shader_count,shader_stage,sr);
else 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_list.Add(shader_count,sm);
++shader_count; ++shader_count;
@ -66,17 +64,11 @@ const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits
const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename) const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename)
{ {
char *spv_data; ShaderResource *shader_resource=LoadShaderResoruce(filename);
int64 spv_size=hgl::filesystem::LoadFileToMemory(filename,(void **)&spv_data);
if(spv_size<=0) if(!shader_resource)return(nullptr);
return(nullptr);
const ShaderModule *sm=CreateShader(shader_stage_bit,spv_data,spv_size); return CreateShader(shader_resource);
delete[] spv_data;
return sm;
} }
const ShaderModule *ShaderModuleManage::GetShader(int id) const ShaderModule *ShaderModuleManage::GetShader(int id)

View File

@ -1,93 +0,0 @@
#pragma once
#include"spirv_cross.hpp"
#include<vulkan/vulkan.h>
#include<hgl/type/BaseString.h>
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<spirv_cross::Resource> &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<Resource> storage_images;
//SmallVector<Resource> atomic_counters;
//SmallVector<Resource> acceleration_structures;
//SmallVector<Resource> push_constant_buffers;
//SmallVector<Resource> separate_images;
//SmallVector<Resource> 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.basetype<spirv_cross::SPIRType::SByte
||type.basetype>spirv_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

View File

@ -2,10 +2,10 @@
#include<hgl/filesystem/FileSystem.h> #include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/vulkan/VKFormat.h> #include<hgl/graph/vulkan/VKFormat.h>
namespace hgl VK_NAMESPACE_BEGIN
{
namespace graph #define AccessByPointer(data,type) *(type *)data;data+=sizeof(type);
{
namespace namespace
{ {
constexpr char SHADER_FILE_HEADER[] ="Shader\x1A"; constexpr char SHADER_FILE_HEADER[] ="Shader\x1A";
@ -25,8 +25,7 @@ namespace hgl
if(count<=0) if(count<=0)
return(data); return(data);
const uint32 total_bytes=*(uint32 *)data; const uint32 total_bytes=AccessByPointer(data,uint32);
data+=sizeof(uint32);
int basetype; int basetype;
int vec_size; int vec_size;
@ -54,10 +53,9 @@ namespace hgl
return data; return data;
} }
const uint8 *LoadShaderDescriptor(ShaderDescriptorList &sd_list,const uint8 *data) const uint8 *LoadShaderDescriptor(ShaderDescriptorList *sd_list,const uint8 *data)
{ {
const uint32 total_bytes=*(uint32 *)data; const uint32 total_bytes=AccessByPointer(data,uint32);
data+=sizeof(uint32);
const uint count=*data++; const uint count=*data++;
@ -65,23 +63,20 @@ namespace hgl
for(uint i=0;i<count;i++) for(uint i=0;i<count;i++)
{ {
ShaderDescriptor *sd=new ShaderDescriptor; sd_list->binding_list.Add(*data++);
sd->binding=*data++;
str_len=*data++; str_len=*data++;
sd->name.SetString((char *)data,str_len); sd_list->name_list.Add(UTF8String((char *)data,str_len));
data+=str_len; data+=str_len;
sd_list.Add(sd);
} }
return data; return data;
} }
}//namespcae }//namespcae
ShaderResource::ShaderResource(const void *fd,const void *sd,const uint32 size) ShaderResource::ShaderResource(const void *fd,const VkShaderStageFlagBits &flag,const void *sd,const uint32 size)
{ {
data=fd; data=fd;
stage_flag=flag;
spv_data=sd; spv_data=sd;
spv_size=size; spv_size=size;
} }
@ -91,6 +86,39 @@ namespace hgl
delete[] data; delete[] data;
} }
const int ShaderResource::GetStageInputBinding(const UTF8String &name)
{
const int count=stage_inputs.GetCount();
ShaderStage **ss=stage_inputs.GetData();
for(int i=0;i<count;i++)
{
if(name==(*ss)->name)
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) ShaderResource *LoadShaderResoruce(const OSString &filename)
{ {
int64 filesize; int64 filesize;
@ -110,29 +138,27 @@ namespace hgl
filedata+=SHADER_FILE_HEADER_BYTES; filedata+=SHADER_FILE_HEADER_BYTES;
const uint8 ver=*filedata; uint8 version;
++filedata; VkShaderStageFlagBits flag;
uint32 spv_size;
uint32 desc_type;
const VkShaderStageFlagBits flag=(const VkShaderStageFlagBits)(*(uint32 *)filedata); version =AccessByPointer(filedata,uint8);
filedata+=sizeof(uint32); flag =(const VkShaderStageFlagBits)AccessByPointer(filedata,uint32);
spv_size=AccessByPointer(filedata,uint32);
const uint32 spv_size=*(uint32 *)filedata; ShaderResource *sr=new ShaderResource(origin_filedata,flag,filedata,spv_size);
filedata+=sizeof(uint32);
ShaderResource *sr=new ShaderResource(origin_filedata,filedata,spv_size);
filedata+=spv_size; filedata+=spv_size;
filedata=LoadShaderStages(sr->GetInputStages(),filedata); filedata=LoadShaderStages(sr->GetStageInputs(),filedata);
filedata=LoadShaderStages(sr->GetOutputStages(),filedata); filedata=LoadShaderStages(sr->GetStageOutputs(),filedata);
while(filedata<file_end) while(filedata<file_end)
{ {
uint32 desc_type=*(uint32 *)filedata; desc_type=AccessByPointer(filedata,uint32);
filedata+=sizeof(uint32);
if(desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER )filedata=LoadShaderDescriptor(sr->GetUBO(), filedata);else filedata=LoadShaderDescriptor(sr->GetDescriptorList((VkDescriptorType)desc_type),filedata);
if(desc_type==VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER )filedata=LoadShaderDescriptor(sr->GetSampler(),filedata);else
{ {
delete sr; delete sr;
return(nullptr); return(nullptr);
@ -141,5 +167,4 @@ namespace hgl
return sr; return sr;
} }
}//namespace graph VK_NAMESPACE_END
}//namespace hgl