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 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;

View File

@ -1,46 +1,77 @@
#pragma once
#include<hgl/type/BaseString.h>
#include<hgl/type/List.h>
#include<vulkan/vulkan.h>
#include<hgl/type/StringList.h>
#include<hgl/graph/vulkan/VKNamespace.h>
namespace hgl
{
namespace graph
VK_NAMESPACE_BEGIN
struct ShaderStage
{
struct ShaderStage
UTF8String name;
uint location;
VkFormat format;
};//struct ShaderStage
using ShaderStageList=ObjectList<ShaderStage>;
using ShaderBindingList=List<uint32_t>;
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_type<VK_DESCRIPTOR_TYPE_BEGIN_RANGE
||desc_type>VK_DESCRIPTOR_TYPE_END_RANGE)return nullptr;
using ShaderStageList=ObjectList<ShaderStage>;
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_type<VK_DESCRIPTOR_TYPE_BEGIN_RANGE
||desc_type>VK_DESCRIPTOR_TYPE_END_RANGE)return nullptr;
using ShaderDescriptorList=ObjectList<ShaderDescriptor>;
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

View File

@ -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;

View File

@ -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);}

View File

@ -1,10 +1,10 @@
#ifndef 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
class ShaderParse;
/**
* Shader模块<br>
@ -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<UTF8String,VkVertexInputAttributeDescription *> stage_input_locations;
Set<VertexAttributeBinding *> 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/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;}

View File

@ -5,6 +5,9 @@
#include<hgl/type/Map.h>
#include<hgl/type/BaseString.h>
VK_NAMESPACE_BEGIN
class ShaderResource;
/**
* Shader模块管理器<br>
* 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 *);

View File

@ -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

View File

@ -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);

View File

@ -1,6 +1,7 @@
#pragma once
#include<hgl/graph/vulkan/VKShaderResource.h>
#include<hgl/graph/shader/ShaderResource.h>
#include<hgl/type/Map.h>
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;
}
}

View File

@ -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;

View File

@ -1,24 +1,8 @@
#include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKVertexAttributeBinding.h>
#include"VKShaderParse.h"
VK_NAMESPACE_BEGIN
namespace
{
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)
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;i<attr_count;i++)
{
const VkFormat format =parse->GetFormat(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);

View File

@ -2,7 +2,7 @@
#include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKMaterial.h>
#include<hgl/graph/vulkan/VKDevice.h>
#include"VKShaderParse.h"
#include<hgl/graph/shader/ShaderResource.h>
#include<hgl/filesystem/FileSystem.h>
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)

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,144 +2,169 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/vulkan/VKFormat.h>
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;i<count;i++)
{
const uint count=*data++;
ss=new ShaderStage;
if(count<=0)
return(data);
ss->location=*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;i<count;i++)
{
ss=new ShaderStage;
ss->location=*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;i<count;i++)
{
ShaderDescriptor *sd=new ShaderDescriptor;
sd->binding=*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(filesize<SHADER_FILE_MIN_SIZE
||memcmp(origin_filedata,SHADER_FILE_HEADER,SHADER_FILE_HEADER_BYTES))
for(uint i=0;i<count;i++)
{
delete[] origin_filedata;
return(false);
sd_list->binding_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(filedata<file_end)
{
uint32 desc_type=*(uint32 *)filedata;
filedata+=sizeof(uint32);
if(desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER )filedata=LoadShaderDescriptor(sr->GetUBO(), 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;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)
{
int64 filesize;
uint8 *origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename,filesize);
if(!origin_filedata)return(nullptr);
if(filesize<SHADER_FILE_MIN_SIZE
||memcmp(origin_filedata,SHADER_FILE_HEADER,SHADER_FILE_HEADER_BYTES))
{
delete[] origin_filedata;
return(false);
}
const uint8 *filedata=origin_filedata;
const uint8 *file_end=filedata+filesize;
filedata+=SHADER_FILE_HEADER_BYTES;
uint8 version;
VkShaderStageFlagBits flag;
uint32 spv_size;
uint32 desc_type;
version =AccessByPointer(filedata,uint8);
flag =(const VkShaderStageFlagBits)AccessByPointer(filedata,uint32);
spv_size=AccessByPointer(filedata,uint32);
ShaderResource *sr=new ShaderResource(origin_filedata,flag,filedata,spv_size);
filedata+=spv_size;
filedata=LoadShaderStages(sr->GetStageInputs(),filedata);
filedata=LoadShaderStages(sr->GetStageOutputs(),filedata);
while(filedata<file_end)
{
desc_type=AccessByPointer(filedata,uint32);
filedata=LoadShaderDescriptor(sr->GetDescriptorList((VkDescriptorType)desc_type),filedata);
{
delete sr;
return(nullptr);
}
}
return sr;
}
VK_NAMESPACE_END