ULRE/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp

205 lines
5.1 KiB
C++
Raw Normal View History

#include<hgl/graph/VKShaderModule.h>
#include<hgl/graph/VKMaterial.h>
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKShaderModuleMap.h>
2021-09-13 20:39:25 +08:00
#include<hgl/graph/VKShaderResource.h>
#include<hgl/graph/VKMaterialDescriptorSets.h>
#include<hgl/filesystem/FileSystem.h>
2020-10-21 12:39:22 +08:00
#include<hgl/graph/VKRenderResource.h>
2023-02-23 19:01:01 +08:00
#include<hgl/io/ConstBufferReader.h>
2023-03-17 21:06:05 +08:00
#include<hgl/shadergen/MaterialCreateInfo.h>
VK_NAMESPACE_BEGIN
2020-10-21 12:39:22 +08:00
const ShaderModule *RenderResource::CreateShaderModule(const OSString &filename,ShaderResource *shader_resource)
{
if(!device)return(nullptr);
if(filename.IsEmpty())return(nullptr);
if(!shader_resource)return(nullptr);
ShaderModule *sm;
if(shader_module_by_name.Get(filename,sm))
return sm;
sm=device->CreateShaderModule(shader_resource);
shader_module_by_name.Add(filename,sm);
2022-09-29 18:29:21 +08:00
#ifdef _DEBUG
{
auto da=device->GetDeviceAttribute();
const UTF8String sn=ToUTF8String(filename);
if(da->debug_maker)
da->debug_maker->SetShaderModule(*sm,sn);
if(da->debug_utils)
da->debug_utils->SetShaderModule(*sm,sn);
}
#endif//_DEBUG
return sm;
}
2023-02-23 19:01:01 +08:00
void LoadShaderDescriptor(io::ConstBufferReader &cbr,ShaderDescriptor *sd_list,const uint count,const uint8 ver)
2021-09-13 20:39:25 +08:00
{
ShaderDescriptor *sd=sd_list;
for(uint i=0;i<count;i++)
{
2023-02-23 19:01:01 +08:00
cbr.CastRead<uint8>(sd->desc_type);
cbr.ReadTinyString(sd->name);
2023-02-22 21:50:18 +08:00
if(ver==3)
2023-02-23 19:01:01 +08:00
cbr.CastRead<uint8>(sd->set_type);
2023-02-22 21:50:18 +08:00
else
if(ver==2) //以下是旧的,未来不用了,现仅保证能运行
{
if(sd->name[0]=='g')sd->set_type=DescriptorSetType::Global;else
if(sd->name[0]=='m')sd->set_type=DescriptorSetType::PerMaterial;else
if(sd->name[0]=='r')sd->set_type=DescriptorSetType::PerObject;else
sd->set_type=DescriptorSetType::PerFrame;
2023-02-22 21:50:18 +08:00
}
2023-02-23 19:01:01 +08:00
cbr.Read(sd->set);
cbr.Read(sd->binding);
cbr.Read(sd->stage_flag);
if(sd->set_type==DescriptorSetType::PerObject)
{
2021-09-13 20:39:25 +08:00
if(sd->desc_type==VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;else
if(sd->desc_type==VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)sd->desc_type=VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
}
++sd;
}
}
ShaderResource *LoadShaderResource(io::ConstBufferReader &cbr);
2020-10-21 12:39:22 +08:00
Material *RenderResource::CreateMaterial(const OSString &filename)
{
Material *mtl;
if(material_by_name.Get(filename,mtl))
return mtl;
constexpr char MaterialFileHeader[]=u8"Material\x1A";
constexpr uint MaterialFileHeaderLength=sizeof(MaterialFileHeader)-1;
int64 filesize;
2020-10-24 19:12:32 +08:00
uint8 *filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".material"),filesize);
if(!filedata)
{
material_by_name.Add(filename,nullptr);
return(nullptr);
}
AutoDeleteArray<uint8> origin_filedata(filedata,filesize);
if(filesize<MaterialFileHeaderLength)
return(nullptr);
2023-02-23 19:01:01 +08:00
io::ConstBufferReader cbr(filedata,filesize);
2023-02-23 19:01:01 +08:00
if(memcmp(cbr.CurPointer(),MaterialFileHeader,MaterialFileHeaderLength)!=0)
return(nullptr);
2023-02-23 19:01:01 +08:00
cbr.Skip(MaterialFileHeaderLength);
2023-02-23 19:01:01 +08:00
uint8 ver;
cbr.Read(ver);
2023-02-22 21:50:18 +08:00
if(ver<2||ver>3)
return(nullptr);
2023-02-23 19:01:01 +08:00
uint32_t shader_bits;
cbr.Read(shader_bits);
const uint count=GetShaderCountByBits(shader_bits);
uint32_t size;
ShaderResource *sr;
const ShaderModule *sm;
bool result=true;
ShaderModuleMap *smm=new ShaderModuleMap;
OSString shader_name;
for(uint i=0;i<count;i++)
{
2023-02-23 19:01:01 +08:00
cbr.Read(size);
2023-02-23 19:01:01 +08:00
sr=LoadShaderResource(io::ConstBufferReader(cbr,size)); //有一个stage output没读放弃了所以不能直接用上一级的cbr
cbr.Skip(size);
if(sr)
{
2023-03-17 16:21:12 +08:00
shader_name=filename+OS_TEXT("?")+ToOSString(sr->GetStageName());
sm=CreateShaderModule(shader_name,sr);
if(sm)
{
if(smm->Add(sm))
continue;
}
}
result=false;
break;
}
2021-09-27 20:56:50 +08:00
const UTF8String mtl_name=ToUTF8String(filename);
2021-09-13 20:39:25 +08:00
MaterialDescriptorSets *mds=nullptr;
{
2023-02-23 19:01:01 +08:00
uint8 count;
cbr.Read(count);
2021-09-13 20:39:25 +08:00
if(count>0)
{
2023-02-23 13:25:05 +08:00
ShaderDescriptor *sd_list=new ShaderDescriptor[count];
2021-09-13 20:39:25 +08:00
2023-02-23 19:01:01 +08:00
LoadShaderDescriptor(cbr,sd_list,count,ver);
2021-09-13 20:39:25 +08:00
2021-09-27 20:56:50 +08:00
mds=new MaterialDescriptorSets(mtl_name,sd_list,count);
2021-09-13 20:39:25 +08:00
}
}
if(result)
{
2021-09-27 20:56:50 +08:00
mtl=device->CreateMaterial(mtl_name,smm,mds);
Add(mtl);
}
else
{
2021-09-14 20:31:15 +08:00
SAFE_CLEAR(mds);
delete smm;
mtl=nullptr;
}
material_by_name.Add(filename,mtl);
return(mtl);
2023-03-17 21:06:05 +08:00
}
Material *RenderResource::CreateMaterial(const hgl::shadergen::MaterialCreateInfo *mci)
{
SHADERGEN_NAMESPACE_USING
if(!mci)
return(nullptr);
const uint count=GetShaderCountByBits(mci->GetShaderStage());
ShaderModuleMap *smm=new ShaderModuleMap;
}
VK_NAMESPACE_END