ULRE/src/SceneGraph/shader/ShaderResource.cpp

174 lines
5.3 KiB
C++
Raw Normal View History

2020-06-06 19:45:38 +08:00
#include<hgl/graph/shader/ShaderResource.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/VKFormat.h>
#include<hgl/type/Map.h>
2020-06-06 19:45:38 +08:00
2020-06-09 19:40:08 +08:00
VK_NAMESPACE_BEGIN
2020-06-08 19:12:29 +08:00
const DescriptorSetType CheckDescriptorSetType(const char *str)
{
if(str[1]=='_')
{
if(str[0]=='m')return DescriptorSetType::Material;
if(str[0]=='g')return DescriptorSetType::Global;
if(str[0]=='r')return DescriptorSetType::Renderable;
}
return DescriptorSetType::Value;
}
2020-06-09 19:40:08 +08:00
#define AccessByPointer(data,type) *(type *)data;data+=sizeof(type);
2020-06-09 14:05:20 +08:00
2020-06-09 19:40:08 +08:00
namespace
{
MapObject<OSString,ShaderResource> shader_resource_by_filename;
2020-06-09 19:40:08 +08:00
constexpr char SHADER_FILE_HEADER[] ="Shader\x1A";
constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
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
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
const uint8 *LoadShaderStages(ShaderStageList &ss_list,const uint8 *data)
{
const uint count=*data++;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
if(count<=0)
return(data);
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
int str_len;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
ShaderStage *ss;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
for(uint i=0;i<count;i++)
{
ss=new ShaderStage;
2020-06-08 19:12:29 +08:00
ss->location =*data++;
ss->type.basetype =(VertexAttribBaseType)*data++;
ss->type.vec_size =*data++;
2020-06-08 19:12:29 +08:00
ss->format =VK_NAMESPACE::GetVulkanFormat(&(ss->type));
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
str_len=*data++;
ss->name.SetString((char *)data,str_len);
data+=str_len;
2020-06-08 19:12:29 +08:00
2020-07-16 17:01:33 +08:00
ss->binding=i;
2020-06-09 19:40:08 +08:00
ss_list.Add(ss);
}
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
return data;
}
}//namespcae
2020-09-17 21:49:23 +08:00
ShaderResource::ShaderResource(const VkShaderStageFlagBits &flag,const void *sd,const uint32 size)
2020-06-09 19:40:08 +08:00
{
stage_flag=flag;
spv_data=sd;
spv_size=size;
}
const os_char *ShaderStageName[]=
{
OS_TEXT("vert"),
OS_TEXT("tesc"),
OS_TEXT("tese"),
OS_TEXT("geom"),
OS_TEXT("frag"),
OS_TEXT("comp"),
OS_TEXT("task"),
OS_TEXT("mesh")
};
const os_char *ShaderResource::GetStageName() const
{
switch(stage_flag)
{
case VK_SHADER_STAGE_VERTEX_BIT: return ShaderStageName[0];
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return ShaderStageName[1];
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return ShaderStageName[2];
case VK_SHADER_STAGE_GEOMETRY_BIT: return ShaderStageName[3];
case VK_SHADER_STAGE_FRAGMENT_BIT: return ShaderStageName[4];
case VK_SHADER_STAGE_COMPUTE_BIT: return ShaderStageName[5];
case VK_SHADER_STAGE_TASK_BIT_NV: return ShaderStageName[6];
case VK_SHADER_STAGE_MESH_BIT_NV: return ShaderStageName[7];
default: return nullptr;
}
}
const ShaderStage *ShaderResource::GetStageInput(const AnsiString &name) const
2020-07-09 20:37:34 +08:00
{
const int count=stage_inputs.GetCount();
ShaderStage **ss=stage_inputs.GetData();
for(int i=0;i<count;i++)
{
if(name==(*ss)->name)
return *ss;
++ss;
}
return nullptr;
}
const int ShaderResource::GetStageInputBinding(const AnsiString &name) const
2020-06-09 19:40:08 +08:00
{
const int count=stage_inputs.GetCount();
ShaderStage **ss=stage_inputs.GetData();
2020-06-09 14:05:20 +08:00
2020-06-09 19:40:08 +08:00
for(int i=0;i<count;i++)
2020-06-09 14:05:20 +08:00
{
2020-06-09 19:40:08 +08:00
if(name==(*ss)->name)
return i;
2020-06-09 19:40:08 +08:00
++ss;
2020-06-09 14:05:20 +08:00
}
2020-06-09 19:40:08 +08:00
return -1;
}
2020-07-07 19:16:23 +08:00
const int ShaderResource::GetBinding(VkDescriptorType desc_type,const AnsiString &name)const
2020-06-09 19:40:08 +08:00
{
if(desc_type>=VK_DESCRIPTOR_TYPE_RANGE_SIZE)return -1;
if(name.IsEmpty())return -1;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
const ShaderDescriptorList *sdl=descriptor_list+(size_t)desc_type;
2020-06-06 19:45:38 +08:00
2021-06-15 17:43:06 +08:00
for(const ShaderDescriptor &sd:*sdl)
if(name==sd.name)
return sd.binding;
2020-06-06 19:45:38 +08:00
2021-06-15 17:43:06 +08:00
return -1;
2020-06-09 19:40:08 +08:00
}
2020-06-08 19:12:29 +08:00
ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize)
2020-06-09 19:40:08 +08:00
{
if(!origin_filedata)return(nullptr);
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
const uint8 *filedata=origin_filedata;
const uint8 *file_end=filedata+filesize;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
VkShaderStageFlagBits flag;
uint32 spv_size;
2020-06-08 19:12:29 +08:00
2020-06-09 19:40:08 +08:00
flag =(const VkShaderStageFlagBits)AccessByPointer(filedata,uint32);
spv_size=AccessByPointer(filedata,uint32);
2020-09-17 21:49:23 +08:00
ShaderResource *sr=new ShaderResource(flag,filedata,spv_size);
2020-06-09 19:40:08 +08:00
filedata+=spv_size;
filedata=LoadShaderStages(sr->GetStageInputs(),filedata);
filedata=LoadShaderStages(sr->GetStageOutputs(),filedata);
return sr;
2020-09-17 21:49:23 +08:00
}
2020-09-11 17:11:32 +08:00
VK_NAMESPACE_END