support .material file

This commit is contained in:
hyzboy 2020-09-17 21:49:23 +08:00
parent 8f68b3935d
commit 37ffb5dc8c
8 changed files with 271 additions and 150 deletions

2
CMCore

@ -1 +1 @@
Subproject commit 7c69cfff60cceb41760513ea4c5fbf78053012e3
Subproject commit 6f1249263e97c2c88fb69d0c277e24d887fd32cb

View File

@ -42,8 +42,7 @@ private:
bool InitMaterial()
{
material=shader_manage->CreateMaterial(OS_TEXT("res/shader/Atomsphere.vert"),
OS_TEXT("res/shader/Atomsphere.frag"));
material=shader_manage->CreateMaterial(OS_TEXT("res/material/Atmosphere"));
if(!material)
return(false);

View File

@ -5,95 +5,94 @@
#include<hgl/graph/vulkan/VKFormat.h>
VK_NAMESPACE_BEGIN
struct ShaderStage
{
AnsiString name;
uint location;
struct ShaderStage
{
AnsiString name;
uint location;
VertexAttribType type; ///<成份数量(如vec4中的4)
VkFormat format; ///<对应的Vulkan格式(如vec4对应的FMT_RGBA32F)
VertexAttribType type; ///<成份数量(如vec4中的4)
VkFormat format; ///<对应的Vulkan格式(如vec4对应的FMT_RGBA32F)
uint binding;
};//struct ShaderStage
uint binding;
};//struct ShaderStage
using ShaderStageList =ObjectList<ShaderStage>;
using DescriptorSetList =List<uint32_t>;
using DescriptorBindingList =List<uint32_t>;
using ShaderStageList =ObjectList<ShaderStage>;
using DescriptorSetList =List<uint32_t>;
using DescriptorBindingList =List<uint32_t>;
struct ShaderDescriptorList
{
AnsiStringList name_list;
DescriptorSetList set_list;
DescriptorBindingList binding_list;
};
struct ShaderDescriptorList
{
AnsiStringList name_list;
DescriptorSetList set_list;
DescriptorBindingList binding_list;
};
#ifndef VK_DESCRIPTOR_TYPE_BEGIN_RANGE
constexpr size_t VK_DESCRIPTOR_TYPE_BEGIN_RANGE=VK_DESCRIPTOR_TYPE_SAMPLER;
#endif//VK_DESCRIPTOR_TYPE_BEGIN_RANGE
#ifndef VK_DESCRIPTOR_TYPE_BEGIN_RANGE
constexpr size_t VK_DESCRIPTOR_TYPE_BEGIN_RANGE=VK_DESCRIPTOR_TYPE_SAMPLER;
#endif//VK_DESCRIPTOR_TYPE_BEGIN_RANGE
#ifndef VK_DESCRIPTOR_TYPE_END_RANGE
constexpr size_t VK_DESCRIPTOR_TYPE_END_RANGE=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
#endif//VK_DESCRIPTOR_TYPE_END_RANGE
#ifndef VK_DESCRIPTOR_TYPE_END_RANGE
constexpr size_t VK_DESCRIPTOR_TYPE_END_RANGE=VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
#endif//VK_DESCRIPTOR_TYPE_END_RANGE
#ifndef VK_DESCRIPTOR_TYPE_RANGE_SIZE
constexpr size_t VK_DESCRIPTOR_TYPE_RANGE_SIZE=VK_DESCRIPTOR_TYPE_END_RANGE-VK_DESCRIPTOR_TYPE_BEGIN_RANGE+1;
#endif//VK_DESCRIPTOR_TYPE_RANGE_SIZE
#ifndef VK_DESCRIPTOR_TYPE_RANGE_SIZE
constexpr size_t VK_DESCRIPTOR_TYPE_RANGE_SIZE=VK_DESCRIPTOR_TYPE_END_RANGE-VK_DESCRIPTOR_TYPE_BEGIN_RANGE+1;
#endif//VK_DESCRIPTOR_TYPE_RANGE_SIZE
class ShaderResource
class ShaderResource
{
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 VkShaderStageFlagBits &,const void *,const uint32);
virtual ~ShaderResource()=default;
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 uint GetStageInputCount ()const {return stage_inputs.GetCount();}
const uint GetStageOutputCount ()const {return stage_outputs.GetCount();}
const ShaderStage * GetStageInput (const AnsiString &)const;
const int GetStageInputBinding(const AnsiString &)const;
const ShaderDescriptorList * GetDescriptorList ()const {return descriptor_list;}
ShaderDescriptorList * GetDescriptorList (VkDescriptorType desc_type)
{
const uint8 *data;
if(desc_type<VK_DESCRIPTOR_TYPE_BEGIN_RANGE
||desc_type>VK_DESCRIPTOR_TYPE_END_RANGE)return nullptr;
VkShaderStageFlagBits stage_flag;
return descriptor_list+desc_type;
}
const void *spv_data;
uint32 spv_size;
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];}
ShaderStageList stage_inputs;
ShaderStageList stage_outputs;
const int GetBinding (VkDescriptorType desc_type,const AnsiString &name)const;
const DescriptorBindingList * GetBindingList (VkDescriptorType desc_type)const
{
if(desc_type<VK_DESCRIPTOR_TYPE_BEGIN_RANGE
||desc_type>VK_DESCRIPTOR_TYPE_END_RANGE)return nullptr;
ShaderDescriptorList descriptor_list[VK_DESCRIPTOR_TYPE_RANGE_SIZE];
return &(descriptor_list[desc_type].binding_list);
}
};//class ShaderResource
public:
ShaderResource(const uint8 *,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 uint GetStageInputCount ()const {return stage_inputs.GetCount();}
const uint GetStageOutputCount ()const {return stage_outputs.GetCount();}
const ShaderStage * GetStageInput (const AnsiString &)const;
const int GetStageInputBinding(const AnsiString &)const;
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 AnsiString &name)const;
const DescriptorBindingList * 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
ShaderResource *LoadShaderResoruce(const OSString &filename);
ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize,bool include_file_header);
ShaderResource *LoadShaderResoruce(const OSString &filename);
VK_NAMESPACE_END

View File

@ -92,6 +92,22 @@ enum class ShaderStageBit
Compute =VK_SHADER_STAGE_COMPUTE_BIT
};//enum class ShaderStageBit
inline const uint GetShaderCountByBits(const uint32_t bits)
{
uint comp=(uint)VK_SHADER_STAGE_VERTEX_BIT;
uint result=0;
for(uint i=0;i<6;i++)
{
if(bits&comp)
++result;
comp<<=1;
}
return result;
}
/**
* max-lengths:
*

View File

@ -20,6 +20,11 @@ class ShaderModuleManage
int shader_count;
Map<int,ShaderModule *> shader_list;
protected:
void Free(ShaderModuleMap *);
Material *CreateMaterial(ShaderModuleMap *);
public:
ShaderModuleManage(Device *dev)
@ -56,53 +61,13 @@ public:
const ShaderModule *GetShader (int);
bool ReleaseShader (const ShaderModule *);
Material * CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module)const;
Material * CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module)const;
Material *CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module);
Material *CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module);
Material * CreateMaterial(const OSString &vertex_shader_filename,const OSString &fragment_shader_filename)
{
const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename);
Material *CreateMaterial(const OSString &vertex_shader_filename,const OSString &fragment_shader_filename);
Material *CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename);
if(!fs)
{
ReleaseShader(vs);
return(nullptr);
}
return(CreateMaterial((VertexShaderModule *)vs,fs));
}
Material * CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename)
{
const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *gs=CreateShader(VK_SHADER_STAGE_GEOMETRY_BIT,geometry_shader_filename);
if(!gs)
{
ReleaseShader(vs);
return(nullptr);
}
const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename);
if(!fs)
{
ReleaseShader(gs);
ReleaseShader(vs);
return(nullptr);
}
return(CreateMaterial((VertexShaderModule *)vs,gs,fs));
}
Material *CreateMaterial(const OSString &filename);
};//class ShaderModuleManage
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE

2
res

@ -1 +1 @@
Subproject commit 7f2ffa2e7c7cfb308d5eb20019faee68d4652181
Subproject commit 6e4f4a9329b440787eb0a92eaa691e989497e9bd

View File

@ -100,7 +100,33 @@ bool ShaderModuleManage::ReleaseShader(const ShaderModule *const_sm)
return(true);
}
Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module)const
void ShaderModuleManage::Free(ShaderModuleMap *smm)
{
const int count=smm->GetCount();
auto **it=smm->GetDataList();
for(int i=0;i<count;i++)
{
ReleaseShader((*it)->right);
++it;
}
delete smm;
}
Material *ShaderModuleManage::CreateMaterial(ShaderModuleMap *smm)
{
Material *mtl=VK_NAMESPACE::CreateMaterial(device,smm);
if(mtl)return(mtl);
Free(smm);
return(nullptr);
}
Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module)
{
if(!vertex_shader_module||!fragment_shader_module)
return(nullptr);
@ -113,10 +139,10 @@ Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_sh
smm->Add(vertex_shader_module);
smm->Add(fragment_shader_module);
return(VK_NAMESPACE::CreateMaterial(device,smm));
return CreateMaterial(smm);
}
Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module)const
Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module)
{
if(!vertex_shader_module
||!geometry_shader_module
@ -133,6 +159,120 @@ Material *ShaderModuleManage::CreateMaterial(const VertexShaderModule *vertex_sh
smm->Add(geometry_shader_module);
smm->Add(fragment_shader_module);
return(VK_NAMESPACE::CreateMaterial(device,smm));
return CreateMaterial(smm);
}
Material *ShaderModuleManage::CreateMaterial(const OSString &vertex_shader_filename,const OSString &fragment_shader_filename)
{
const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename);
if(!fs)
{
ReleaseShader(vs);
return(nullptr);
}
return(CreateMaterial((VertexShaderModule *)vs,fs));
}
Material *ShaderModuleManage::CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename)
{
const ShaderModule *vs=CreateShader(VK_SHADER_STAGE_VERTEX_BIT,vertex_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *gs=CreateShader(VK_SHADER_STAGE_GEOMETRY_BIT,geometry_shader_filename);
if(!gs)
{
ReleaseShader(vs);
return(nullptr);
}
const ShaderModule *fs=CreateShader(VK_SHADER_STAGE_FRAGMENT_BIT,fragment_shader_filename);
if(!fs)
{
ReleaseShader(gs);
ReleaseShader(vs);
return(nullptr);
}
return(CreateMaterial((VertexShaderModule *)vs,gs,fs));
}
Material *ShaderModuleManage::CreateMaterial(const OSString &filename)
{
constexpr char MaterialFileHeader[]=u8"Material\x1A";
constexpr uint MaterialFileHeaderLength=sizeof(MaterialFileHeader)-1;
int64 filesize;
AutoDeleteArray<uint8> origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".material"),filesize);
if(filesize<MaterialFileHeaderLength)
return(nullptr);
const uint8 *sp=origin_filedata;
int64 left=filesize;
if(memcmp(sp,MaterialFileHeader,MaterialFileHeaderLength)!=0)
return(nullptr);
sp+=MaterialFileHeaderLength;
left-=MaterialFileHeaderLength;
const uint8 ver=*sp;
++sp;
--left;
const uint32_t shader_bits=*(uint32_t *)sp;
sp+=sizeof(uint32_t);
left-=sizeof(uint32_t);
const uint count=GetShaderCountByBits(shader_bits);
uint32_t size;
ShaderResource *sr;
const ShaderModule *sm;
bool result=true;
ShaderModuleMap *smm=new ShaderModuleMap;
for(uint i=0;i<count;i++)
{
size=*(uint32_t *)sp;
sp+=sizeof(uint32_t);
left-=sizeof(uint32_t);
sr=LoadShaderResource(sp,size,false);
sp+=size;
left-=size;
if(sr)
{
sm=CreateShader(sr);
if(sm)
{
if(smm->Add(sm))
continue;
}
}
result=false;
break;
}
if(result)
return CreateMaterial(smm);
Free(smm);
return(nullptr);
}
VK_NAMESPACE_END

View File

@ -81,19 +81,13 @@ VK_NAMESPACE_BEGIN
}
}//namespcae
ShaderResource::ShaderResource(const uint8 *fd,const VkShaderStageFlagBits &flag,const void *sd,const uint32 size)
ShaderResource::ShaderResource(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 ShaderStage *ShaderResource::GetStageInput(const AnsiString &name) const
{
const int count=stage_inputs.GetCount();
@ -143,24 +137,24 @@ VK_NAMESPACE_BEGIN
return -1;
}
ShaderResource *LoadShaderResoruce(const OSString &filename)
ShaderResource *LoadShaderResource(const uint8 *origin_filedata,const int64 filesize,bool include_file_header)
{
int64 filesize;
uint8 *origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".shader"),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(nullptr);
}
const uint8 *filedata=origin_filedata;
const uint8 *file_end=filedata+filesize;
filedata+=SHADER_FILE_HEADER_BYTES;
if(include_file_header)
{
if(filesize<SHADER_FILE_MIN_SIZE
||memcmp(origin_filedata,SHADER_FILE_HEADER,SHADER_FILE_HEADER_BYTES))
{
delete[] origin_filedata;
return(nullptr);
}
filedata+=SHADER_FILE_HEADER_BYTES;
}
uint8 version;
VkShaderStageFlagBits flag;
@ -171,7 +165,7 @@ VK_NAMESPACE_BEGIN
flag =(const VkShaderStageFlagBits)AccessByPointer(filedata,uint32);
spv_size=AccessByPointer(filedata,uint32);
ShaderResource *sr=new ShaderResource(origin_filedata,flag,filedata,spv_size);
ShaderResource *sr=new ShaderResource(flag,filedata,spv_size);
filedata+=spv_size;
@ -187,4 +181,12 @@ VK_NAMESPACE_BEGIN
return sr;
}
ShaderResource *LoadShaderResoruce(const OSString &filename)
{
int64 filesize;
AutoDeleteArray<uint8> origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".shader"),filesize);
return LoadShaderResource(origin_filedata,filesize,true);
}
VK_NAMESPACE_END