ULRE/src/SceneGraph/Vulkan/VKRenderResourceMaterial.cpp

205 lines
5.3 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/VKMaterialDescriptorManager.h>
#include<hgl/graph/VKVertexInput.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>
#include<hgl/shadergen/ShaderDescriptorInfo.h>
#include<hgl/type/ActiveMemoryBlockManager.h>
2023-10-12 05:55:39 +08:00
#ifdef _DEBUG
#include"VKPipelineLayoutData.h"
#endif//_DEBUG
2023-06-14 16:49:19 +08:00
2023-10-12 05:55:39 +08:00
VK_NAMESPACE_BEGIN
2023-06-14 16:49:19 +08:00
namespace
{
void CreateShaderStageList(List<VkPipelineShaderStageCreateInfo> &shader_stage_list,ShaderModuleMap *shader_maps)
{
const ShaderModule *sm;
const int shader_count=shader_maps->GetCount();
shader_stage_list.SetCount(shader_count);
VkPipelineShaderStageCreateInfo *p=shader_stage_list.GetData();
auto **itp=shader_maps->GetDataList();
for(int i=0;i<shader_count;i++)
{
sm=(*itp)->value;
hgl_cpy(p,sm->GetCreateInfo(),1);
++p;
++itp;
}
}
}//namespace
const ShaderModule *RenderResource::CreateShaderModule(const AnsiString &sm_name,const ShaderCreateInfo *sci)
{
if(!device)return(nullptr);
if(sm_name.IsEmpty())return(nullptr);
const int bit_offset=GetBitOffset((uint32_t)sci->GetShaderStage());
if(bit_offset<0||bit_offset>VK_SHADER_STAGE_TYPE_COUNT)return(nullptr);
ShaderModule *sm;
ShaderModuleMapByName &sm_map=shader_module_by_name[bit_offset];
if(sm_map.Get(sm_name,sm))
return sm;
sm=device->CreateShaderModule(sci->GetShaderStage(),sci->GetSPVData(),sci->GetSPVSize());
if(!sm)
return(nullptr);
sm_map.Add(sm_name,sm);
2022-09-29 18:29:21 +08:00
#ifdef _DEBUG
{
2023-10-13 02:01:57 +08:00
DebugUtils *du=device->GetDebugUtils();
2023-10-13 02:01:57 +08:00
if(du)
du->SetShaderModule(*sm,"Shader:"+sm_name+AnsiString(":")+GetShaderStageName(sci->GetShaderStage()));
2022-09-29 18:29:21 +08:00
}
#endif//_DEBUG
return sm;
}
2023-05-16 02:23:45 +08:00
Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
2023-03-17 21:06:05 +08:00
{
if(!mci)
return(nullptr);
2023-06-14 17:55:06 +08:00
const AnsiString &mtl_name=mci->GetName();
2023-06-14 18:20:23 +08:00
{
Material *mtl;
if(material_by_name.Get(mtl_name,mtl))
return mtl;
}
2023-06-14 16:49:19 +08:00
const ShaderCreateInfoMap &sci_map=mci->GetShaderMap();
const uint sci_count=sci_map.GetCount();
2023-06-14 16:49:19 +08:00
if(sci_count<2)
return(nullptr);
2023-06-14 16:49:19 +08:00
if(!mci->GetFS())
return(nullptr);
AutoDelete<Material> mtl=new Material(mtl_name);
2023-06-14 16:49:19 +08:00
{
const ShaderModule *sm;
2023-06-14 16:49:19 +08:00
auto **sci=sci_map.GetDataList();
2023-06-14 16:49:19 +08:00
for(uint i=0;i<sci_count;i++)
{
sm=CreateShaderModule(mtl_name,(*sci)->value);
2023-06-14 16:49:19 +08:00
if(!sm)
return(nullptr);
2023-03-17 21:06:05 +08:00
mtl->shader_maps->Add(sm);
2023-06-14 16:49:19 +08:00
++sci;
}
2023-06-14 17:55:06 +08:00
}
CreateShaderStageList(mtl->shader_stage_list,mtl->shader_maps);
2023-06-14 17:55:06 +08:00
{
ShaderCreateInfoVertex *vert=mci->GetVS();
2023-06-14 17:55:06 +08:00
if(vert)
2024-05-28 02:21:33 +08:00
mtl->vertex_input=GetVertexInput(vert->sdm->GetShaderStageIO().input);
}
2023-03-17 21:06:05 +08:00
{
const auto &mdi=mci->GetMDI();
if(mdi.GetCount()>0)
mtl->desc_manager=new MaterialDescriptorManager(mci->GetName(),mdi.Get());
}
2023-03-17 21:06:05 +08:00
mtl->pipeline_layout_data=device->CreatePipelineLayoutData(mtl->desc_manager);
2023-10-12 05:55:39 +08:00
#ifdef _DEBUG
2023-10-13 02:01:57 +08:00
DebugUtils *du=device->GetDebugUtils();
2023-10-12 05:55:39 +08:00
2023-10-13 02:01:57 +08:00
if(du)
du->SetPipelineLayout(mtl->GetPipelineLayout(),"PipelineLayout:"+mtl->GetName());
2023-10-12 05:55:39 +08:00
#endif//_DEBUG
if(mtl->desc_manager)
{
2023-06-14 16:49:19 +08:00
ENUM_CLASS_FOR(DescriptorSetType,int,dst)
{
if(mtl->desc_manager->hasSet((DescriptorSetType)dst))
2023-10-12 05:55:39 +08:00
{
mtl->mp_array[dst]=device->CreateMP(mtl->desc_manager,mtl->pipeline_layout_data,(DescriptorSetType)dst);
2023-10-12 05:55:39 +08:00
#ifdef _DEBUG
AnsiString debug_name=mtl->GetName()+AnsiString(":")+GetDescriptorSetTypeName((DescriptorSetType)dst);
2023-10-13 02:01:57 +08:00
if(du)
2023-10-12 05:55:39 +08:00
{
2023-10-13 02:01:57 +08:00
du->SetDescriptorSet(mtl->mp_array[dst]->GetVkDescriptorSet(),"DescSet:"+debug_name);
2023-10-12 05:55:39 +08:00
2023-10-13 02:01:57 +08:00
du->SetDescriptorSetLayout(mtl->pipeline_layout_data->layouts[dst],"DescSetLayout:"+debug_name);
2023-10-12 05:55:39 +08:00
}
#endif//_DEBUG
}
2023-06-14 16:49:19 +08:00
}
}
mtl->mi_data_bytes =mci->GetMIDataBytes();
2023-09-19 21:44:48 +08:00
mtl->mi_max_count =mci->GetMIMaxCount();
if(mtl->mi_data_bytes>0)
{
mtl->mi_data_manager=new ActiveMemoryBlockManager(mtl->mi_data_bytes);
}
2023-06-14 16:49:19 +08:00
Add(mtl);
static_descriptor.Bind(mtl);
global_descriptor.Bind(mtl);
material_by_name.Add(mtl_name,mtl);
return mtl.Finish();
}
namespace mtl
{
MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &, Material2DCreateConfig *);
MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &, Material3DCreateConfig *);
}
Material *RenderResource::LoadMaterial(const AnsiString &mtl_name,mtl::Material2DCreateConfig *cfg)
{
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::LoadMaterialFromFile(mtl_name,cfg);
return this->CreateMaterial(mci);
}
Material *RenderResource::LoadMaterial(const AnsiString &mtl_name,mtl::Material3DCreateConfig *cfg)
{
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::LoadMaterialFromFile(mtl_name,cfg);
return this->CreateMaterial(mci);
}
VK_NAMESPACE_END