optimized Material and ShaderModule,Pipeline,Database codes.

This commit is contained in:
hyzboy 2020-09-19 23:49:32 +08:00
parent 5d08717c21
commit 2b9152d602
25 changed files with 417 additions and 469 deletions

@ -1 +1 @@
Subproject commit 955cf63c7f911b3a8af2be9a1a0facffdecd34bb Subproject commit fe9dc360c87179f8a8293f7f78127f366b7f191b

View File

@ -14,12 +14,21 @@ using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=128; constexpr uint32_t SCREEN_WIDTH=128;
constexpr uint32_t SCREEN_HEIGHT=128; constexpr uint32_t SCREEN_HEIGHT=128;
struct AtomsphereData struct AtmosphereData
{ {
Vector3f position; Vector3f position;
float intensity; float intensity;
float scattering_direction; float scattering_direction;
};//
public:
AtmosphereData()
{
position.Set(0,0.1f,-1.0f);
intensity=22.0f;
scattering_direction=0.758f;
}
};//struct AtmosphereData
class TestApp:public CameraAppFramework class TestApp:public CameraAppFramework
{ {
@ -28,82 +37,48 @@ private:
SceneNode render_root; SceneNode render_root;
RenderList render_list; RenderList render_list;
vulkan::Material * material =nullptr;
vulkan::MaterialInstance * material_instance =nullptr; vulkan::MaterialInstance * material_instance =nullptr;
vulkan::Renderable * ro_sphere =nullptr;
vulkan::Pipeline * pipeline_solid =nullptr; vulkan::Pipeline * pipeline_solid =nullptr;
vulkan::Buffer * ubo_atomsphere =nullptr; vulkan::Buffer * ubo_atomsphere =nullptr;
AtomsphereData atomsphere_data; AtmosphereData atomsphere_data;
vulkan::Renderable * ro_sphere =nullptr;
private: private:
bool InitMaterial() bool InitMaterial()
{ {
material=shader_manage->CreateMaterial(OS_TEXT("res/material/Atmosphere")); //不需要写.material的扩展名 material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Atmosphere")); //不需要优先创建Material也不需要写扩展名
if(!material) if(!material_instance)return(false);
return(false);
material_instance=material->CreateInstance(); pipeline_solid=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/sky"));
if(!pipeline_solid)return(false);
db->Add(material);
db->Add(material_instance);
return(true); return(true);
} }
void CreateRenderObject()
{
ro_sphere=CreateRenderableSphere(db,material,128);
}
bool InitAtomsphereUBO(vulkan::MaterialInstance *mi,const AnsiString &sun_node_name)
{
atomsphere_data.position.Set(0,0.1f,-1.0f);
atomsphere_data.intensity=22.0f;
atomsphere_data.scattering_direction=0.758f;
ubo_atomsphere=db->CreateUBO(sizeof(AtomsphereData),&atomsphere_data);
if(!ubo_atomsphere)
return(false);
return mi->BindUBO(sun_node_name,ubo_atomsphere);
}
bool InitUBO() bool InitUBO()
{ {
if(!material_instance->BindUBO("world",GetCameraMatrixBuffer())) if(!material_instance->BindUBO("world",GetCameraMatrixBuffer()))
return(false); return(false);
if(!InitAtomsphereUBO(material_instance,"sun")) ubo_atomsphere=db->CreateUBO(sizeof(AtmosphereData),&atomsphere_data);
if(!ubo_atomsphere)
return(false);
if(!material_instance->BindUBO("sun",ubo_atomsphere))
return(false); return(false);
material_instance->Update(); material_instance->Update();
return(true); return(true);
} }
bool InitPipeline()
{
vulkan::PipelineData pd;
if(!vulkan::LoadFromFile(OS_TEXT("res/pipeline/sky.pipeline"),&pd))
return(false);
pd.Set(Prim::Triangles);
pipeline_solid=CreatePipeline(device,&pd,material,sc_render_target);
if(!pipeline_solid)
return(false);
db->Add(pipeline_solid);
return(true);
}
bool InitScene() bool InitScene()
{ {
ro_sphere=CreateRenderableSphere(db,material_instance->GetMaterial(),128);
render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_sphere),scale(100)); render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_sphere),scale(100));
render_root.RefreshMatrix(); render_root.RefreshMatrix();
@ -122,14 +97,9 @@ public:
if(!InitMaterial()) if(!InitMaterial())
return(false); return(false);
CreateRenderObject();
if(!InitUBO()) if(!InitUBO())
return(false); return(false);
if(!InitPipeline())
return(false);
if(!InitScene()) if(!InitScene())
return(false); return(false);

View File

@ -6,7 +6,6 @@
#include<hgl/graph/vulkan/VKSemaphore.h> #include<hgl/graph/vulkan/VKSemaphore.h>
#include<hgl/graph/vulkan/VKBuffer.h> #include<hgl/graph/vulkan/VKBuffer.h>
#include<hgl/graph/vulkan/VKShaderModule.h> #include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
#include<hgl/graph/vulkan/VKImageView.h> #include<hgl/graph/vulkan/VKImageView.h>
#include<hgl/graph/vulkan/VKRenderable.h> #include<hgl/graph/vulkan/VKRenderable.h>
#include<hgl/graph/vulkan/VKDescriptorSets.h> #include<hgl/graph/vulkan/VKDescriptorSets.h>
@ -53,8 +52,6 @@ protected:
vulkan::Semaphore * present_complete_semaphore =nullptr, vulkan::Semaphore * present_complete_semaphore =nullptr,
* render_complete_semaphore =nullptr; * render_complete_semaphore =nullptr;
vulkan::ShaderModuleManage * shader_manage =nullptr;
protected: protected:
int32_t swap_chain_count =0; int32_t swap_chain_count =0;
@ -77,7 +74,6 @@ public:
SAFE_CLEAR(db); SAFE_CLEAR(db);
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
SAFE_CLEAR(shader_manage);
SAFE_CLEAR(device); SAFE_CLEAR(device);
SAFE_CLEAR(win); SAFE_CLEAR(win);
SAFE_CLEAR(inst); SAFE_CLEAR(inst);
@ -126,7 +122,6 @@ public:
present_complete_semaphore =device->CreateSem(); present_complete_semaphore =device->CreateSem();
render_complete_semaphore =device->CreateSem(); render_complete_semaphore =device->CreateSem();
shader_manage=device->CreateShaderModuleManage();
db=new vulkan::Database(device); db=new vulkan::Database(device);
InitCommandBuffer(); InitCommandBuffer();

View File

@ -57,6 +57,7 @@ public:
virtual ~ShaderResource()=default; virtual ~ShaderResource()=default;
const VkShaderStageFlagBits GetStage ()const {return stage_flag;} const VkShaderStageFlagBits GetStage ()const {return stage_flag;}
const os_char * GetStageName ()const;
const uint32_t * GetCode ()const {return (uint32_t *)spv_data;} const uint32_t * GetCode ()const {return (uint32_t *)spv_data;}
const uint32_t GetCodeSize ()const {return spv_size;} const uint32_t GetCodeSize ()const {return spv_size;}

View File

@ -3,13 +3,12 @@
#include<hgl/type/Map.h> #include<hgl/type/Map.h>
#include<hgl/graph/vulkan/VKNamespace.h> #include<hgl/graph/vulkan/VKNamespace.h>
#include<hgl/graph/vulkan/VKShaderModule.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
using namespace hgl; using namespace hgl;
class ShaderModule;
class ShaderModuleMap:public Map<VkShaderStageFlagBits,const ShaderModule *> class ShaderModuleMap:public Map<VkShaderStageFlagBits,const ShaderModule *>
{ {
public: public:

View File

@ -47,15 +47,17 @@ class RenderPass;
class Fence; class Fence;
class Semaphore; class Semaphore;
class DescriptorSetLayoutCreater;
struct ShaderStage; struct ShaderStage;
class ShaderModuleMap; class ShaderResource;
class ShaderModule; class ShaderModule;
class ShaderModuleManage;
class VertexShaderModule; class VertexShaderModule;
class Material; class Material;
class MaterialInstance; class MaterialInstance;
class PipelineLayout; class PipelineLayout;
struct PipelineData;
class Pipeline; class Pipeline;
class DescriptorSets; class DescriptorSets;
class VertexAttributeBinding; class VertexAttributeBinding;

View File

@ -33,6 +33,9 @@ class Database
{ {
Device *device; Device *device;
MapObject<OSString,ShaderModule> shader_module_by_name;
Map<OSString,Material *> material_by_name;
IDResManage<MaterialID, Material> rm_material; ///<材质合集 IDResManage<MaterialID, Material> rm_material; ///<材质合集
IDResManage<MaterialInstanceID, MaterialInstance> rm_material_instance; ///<材质实例合集 IDResManage<MaterialInstanceID, MaterialInstance> rm_material_instance; ///<材质实例合集
IDResManage<PipelineID, Pipeline> rm_pipeline; ///<管线合集 IDResManage<PipelineID, Pipeline> rm_pipeline; ///<管线合集
@ -60,7 +63,7 @@ public: //Add
TextureID Add(Texture * t ){return rm_textures.Add(t);} TextureID Add(Texture * t ){return rm_textures.Add(t);}
RenderableInstanceID Add(RenderableInstance *ri ){return rm_renderable_instances.Add(ri);} RenderableInstanceID Add(RenderableInstance *ri ){return rm_renderable_instances.Add(ri);}
public: //Create public: // VBO/VAO
VAB *CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sm=SharingMode::Exclusive); VAB *CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sm=SharingMode::Exclusive);
VAB *CreateVAB(VkFormat format,uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateVAB(format,count,nullptr,sm);} VAB *CreateVAB(VkFormat format,uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateVAB(format,count,nullptr,sm);}
@ -83,7 +86,21 @@ public: //Create
IndexBuffer *CreateIBO16(uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,nullptr,sm);} IndexBuffer *CreateIBO16(uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U16,count,nullptr,sm);}
IndexBuffer *CreateIBO32(uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,nullptr,sm);} IndexBuffer *CreateIBO32(uint32_t count,SharingMode sm=SharingMode::Exclusive){return CreateIBO(IndexType::U32,count,nullptr,sm);}
public: //Material
const ShaderModule *CreateShaderModule(const OSString &filename,ShaderResource *shader_resource);
const ShaderModule *CreateShaderModule(const OSString &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);
Material * CreateMaterial(const OSString &);
MaterialInstance * CreateMaterialInstance(Material *); MaterialInstance * CreateMaterialInstance(Material *);
MaterialInstance * CreateMaterialInstance(const OSString &);
Pipeline * CreatePipeline(Material *,RenderTarget *,const OSString &,const Prim &prim=Prim::Triangles,const bool prim_restart=false);
Pipeline * CreatePipeline(MaterialInstance *,RenderTarget *,const OSString &,const Prim &prim=Prim::Triangles,const bool prim_restart=false);
Renderable * CreateRenderable(Material *,const uint32_t vertex_count=0); Renderable * CreateRenderable(Material *,const uint32_t vertex_count=0);
TextRenderable * CreateTextRenderable(Material *); TextRenderable * CreateTextRenderable(Material *);

View File

@ -4,12 +4,11 @@
#include<hgl/graph/vulkan/VK.h> #include<hgl/graph/vulkan/VK.h>
#include<hgl/type/Map.h> #include<hgl/type/Map.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class Device;
class Buffer; class Buffer;
class DescriptorSets class DescriptorSets
{ {
Device *device; VkDevice device;
int count; int count;
VkDescriptorSet desc_set; VkDescriptorSet desc_set;
const Map<uint32_t,int> *index_by_binding; const Map<uint32_t,int> *index_by_binding;
@ -23,7 +22,7 @@ private:
friend class DescriptorSetLayoutCreater; friend class DescriptorSetLayoutCreater;
DescriptorSets(Device *dev,const int c,VkPipelineLayout pl,VkDescriptorSet ds,const Map<uint32_t,int> *bi):index_by_binding(bi) DescriptorSets(VkDevice dev,const int c,VkPipelineLayout pl,VkDescriptorSet ds,const Map<uint32_t,int> *bi):index_by_binding(bi)
{ {
device=dev; device=dev;
count=c; count=c;

View File

@ -13,6 +13,7 @@
#include<hgl/graph/vulkan/VKSwapchain.h> #include<hgl/graph/vulkan/VKSwapchain.h>
#include<hgl/graph/vulkan/VKRenderTarget.h> #include<hgl/graph/vulkan/VKRenderTarget.h>
#include<hgl/graph/VertexAttribData.h> #include<hgl/graph/VertexAttribData.h>
#include<hgl/graph/vulkan/ShaderModuleMap.h>
namespace hgl namespace hgl
{ {
@ -217,7 +218,15 @@ public: //
Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr); Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr);
ShaderModuleManage *CreateShaderModuleManage(); public: //shader & material
DescriptorSetLayoutCreater *CreateDescriptorSetLayoutCreater();
ShaderModule *CreateShaderModule(ShaderResource *);
Material *CreateMaterial(ShaderModuleMap *shader_maps);
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);
public: //Command Buffer 相关 public: //Command Buffer 相关
@ -264,6 +273,8 @@ public:
RenderTarget *CreateRenderTarget(Framebuffer *); RenderTarget *CreateRenderTarget(Framebuffer *);
Pipeline *CreatePipeline(PipelineData *,const Material *,const RenderTarget *);
TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集 TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集
TileFont *CreateTileFont(FontSource *fs,int limit_count=-1); ///<创建一个Tile字体 TileFont *CreateTileFont(FontSource *fs,int limit_count=-1); ///<创建一个Tile字体

View File

@ -4,6 +4,7 @@
#include<hgl/graph/vulkan/VK.h> #include<hgl/graph/vulkan/VK.h>
#include<hgl/type/Map.h> #include<hgl/type/Map.h>
#include<hgl/type/String.h> #include<hgl/type/String.h>
#include<hgl/graph/vulkan/ShaderModuleMap.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class DescriptorSetLayoutCreater; class DescriptorSetLayoutCreater;
@ -13,7 +14,6 @@ class DescriptorSetLayoutCreater;
*/ */
class Material class Material
{ {
Device *device;
ShaderModuleMap *shader_maps; ShaderModuleMap *shader_maps;
VertexShaderModule *vertex_sm; VertexShaderModule *vertex_sm;
List<VkPipelineShaderStageCreateInfo> *shader_stage_list; List<VkPipelineShaderStageCreateInfo> *shader_stage_list;
@ -24,7 +24,7 @@ class Material
public: public:
Material(Device *dev,ShaderModuleMap *smm,List<VkPipelineShaderStageCreateInfo> *,DescriptorSetLayoutCreater *dslc); Material(ShaderModuleMap *smm,List<VkPipelineShaderStageCreateInfo> *,DescriptorSetLayoutCreater *dslc);
~Material(); ~Material();
const VertexShaderModule *GetVertexShaderModule()const{return vertex_sm;} const VertexShaderModule *GetVertexShaderModule()const{return vertex_sm;}

View File

@ -26,8 +26,6 @@ public:
const bool IsAlphaTest()const{return data->alpha_test>0;} const bool IsAlphaTest()const{return data->alpha_test>0;}
const bool IsAlphaBlend()const{return data->alpha_blend;} const bool IsAlphaBlend()const{return data->alpha_blend;}
};//class GraphicsPipeline };//class GraphicsPipeline
Pipeline *CreatePipeline(Device *,PipelineData *,const Material *,const RenderTarget *);
VK_NAMESPACE_END VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_PIPELINE_INCLUDE #endif//HGL_GRAPH_VULKAN_PIPELINE_INCLUDE

View File

@ -13,7 +13,6 @@ VK_NAMESPACE_BEGIN
class ShaderModule class ShaderModule
{ {
VkDevice device; VkDevice device;
int shader_id;
int ref_count; int ref_count;
private: private:
@ -26,11 +25,9 @@ protected:
public: public:
ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *); ShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *);
virtual ~ShaderModule(); virtual ~ShaderModule();
const int GetID()const{return shader_id;}
const int IncRef(){return ++ref_count;} const int IncRef(){return ++ref_count;}
const int DecRef(){return --ref_count;} const int DecRef(){return --ref_count;}
@ -75,7 +72,7 @@ private:
public: public:
VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr); VertexShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr);
virtual ~VertexShaderModule(); virtual ~VertexShaderModule();
/** /**

View File

@ -1,73 +0,0 @@
#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE
#define HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE
#include<hgl/graph/vulkan/VK.h>
#include<hgl/type/Map.h>
#include<hgl/type/String.h>
VK_NAMESPACE_BEGIN
class ShaderResource;
/**
* Shader模块管理器<br>
* shader模块均由它创建和释放
* shader(vs/fs/gs等单个)
*/
class ShaderModuleManage
{
Device *device;
int shader_count;
Map<int,ShaderModule *> shader_list;
protected:
void Free(ShaderModuleMap *);
Material *CreateMaterial(ShaderModuleMap *);
public:
ShaderModuleManage(Device *dev)
{
device=dev;
shader_count=0;
}
~ShaderModuleManage();
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)
ADD_SHADER_FUNC(Geometry, GEOMETRY)
ADD_SHADER_FUNC(TessCtrl, TESSELLATION_CONTROL)
ADD_SHADER_FUNC(TessEval, TESSELLATION_EVALUATION)
ADD_SHADER_FUNC(Compute, COMPUTE)
#undef ADD_SHADER_FUNC
#define ADD_NV_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_NV,spv_data,spv_size);}
ADD_NV_SHADER_FUNC(Raygen, RAYGEN);
ADD_NV_SHADER_FUNC(AnyHit, ANY_HIT);
ADD_NV_SHADER_FUNC(ClosestHit, CLOSEST_HIT);
ADD_NV_SHADER_FUNC(MissBit, MISS);
ADD_NV_SHADER_FUNC(Intersection,INTERSECTION);
ADD_NV_SHADER_FUNC(Callable, CALLABLE);
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 *);
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);
Material *CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename);
Material *CreateMaterial(const OSString &filename);
};//class ShaderModuleManage
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE

View File

@ -1,7 +1,8 @@
set(RD_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph/vulkan) set(RD_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph/vulkan)
SET(VK_DB_SOURCE ${RD_INCLUDE_PATH}/VKDatabase.h SET(VK_DB_SOURCE ${RD_INCLUDE_PATH}/VKDatabase.h
VKDatabase.cpp) VKDatabase.cpp
VKDatabaseMaterial.cpp)
SOURCE_GROUP("Database" FILES ${VK_DB_SOURCE}) SOURCE_GROUP("Database" FILES ${VK_DB_SOURCE})
@ -45,11 +46,9 @@ SET(VK_DESCRIPTOR_SETS_SOURCE ${RD_INCLUDE_PATH}/VKDescriptorSets.h
SOURCE_GROUP("Descriptor Sets" FILES ${VK_DESCRIPTOR_SETS_SOURCE}) SOURCE_GROUP("Descriptor Sets" FILES ${VK_DESCRIPTOR_SETS_SOURCE})
SET(VK_SHADER_SOURCE ${RD_INCLUDE_PATH}/VKShaderModule.h SET(VK_SHADER_SOURCE ${RD_INCLUDE_PATH}/VKShaderModule.h
${RD_INCLUDE_PATH}/VKShaderModuleManage.h
${RD_INCLUDE_PATH}/ShaderModuleMap.h ${RD_INCLUDE_PATH}/ShaderModuleMap.h
ShaderModuleMap.cpp ShaderModuleMap.cpp
VKShaderModule.cpp VKShaderModule.cpp)
VKShaderModuleManage.cpp)
SET(VK_TEXTURE_SOURCE ${RD_INCLUDE_PATH}/VKImageView.h SET(VK_TEXTURE_SOURCE ${RD_INCLUDE_PATH}/VKImageView.h
${RD_INCLUDE_PATH}/VKTexture.h ${RD_INCLUDE_PATH}/VKTexture.h

View File

@ -60,6 +60,37 @@ MaterialInstance *Database::CreateMaterialInstance(Material *mtl)
return mi; return mi;
} }
MaterialInstance *Database::CreateMaterialInstance(const OSString &mtl_filename)
{
Material *mtl=this->CreateMaterial(mtl_filename);
if(!mtl)
return(nullptr);
return CreateMaterialInstance(mtl);
}
Pipeline *Database::CreatePipeline(Material *mtl,RenderTarget *rt,const OSString &pipeline_filename,const Prim &prim,const bool prim_restart)
{
PipelineData *pd=vulkan::GetPipelineData(pipeline_filename);
if(!pd)return(nullptr);
pd->Set(prim,prim_restart);
Pipeline *p=device->CreatePipeline(pd,mtl,rt);
if(p)
Add(p);
return(p);
}
Pipeline *Database::CreatePipeline(MaterialInstance *mi,RenderTarget *rt,const OSString &filename,const Prim &prim,const bool prim_restart)
{
return CreatePipeline(mi->GetMaterial(),rt,filename,prim,prim_restart);
}
Renderable *Database::CreateRenderable(Material *mtl,const uint32_t vertex_count) Renderable *Database::CreateRenderable(Material *mtl,const uint32_t vertex_count)
{ {
if(!mtl)return(nullptr); if(!mtl)return(nullptr);

View File

@ -0,0 +1,170 @@
#include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKMaterial.h>
#include<hgl/graph/vulkan/VKDevice.h>
#include<hgl/graph/vulkan/ShaderModuleMap.h>
#include<hgl/graph/shader/ShaderResource.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/vulkan/VKDatabase.h>
VK_NAMESPACE_BEGIN
const ShaderModule *Database::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);
return sm;
}
const ShaderModule *Database::CreateShaderModule(const OSString &filename)
{
ShaderModule *sm;
if(shader_module_by_name.Get(filename,sm))
return sm;
ShaderResource *shader_resource=LoadShaderResoruce(filename);
if(!shader_resource)return(nullptr);
sm=device->CreateShaderModule(shader_resource);
shader_module_by_name.Add(filename,sm);
return sm;
}
Material *Database::CreateMaterial(const OSString &vertex_shader_filename,const OSString &fragment_shader_filename)
{
const ShaderModule *vs=CreateShaderModule(vertex_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *fs=CreateShaderModule(fragment_shader_filename);
if(!fs)
return(nullptr);
return(device->CreateMaterial((VertexShaderModule *)vs,fs));
}
Material *Database::CreateMaterial(const OSString &vertex_shader_filename,const OSString &geometry_shader_filename,const OSString &fragment_shader_filename)
{
const ShaderModule *vs=CreateShaderModule(vertex_shader_filename);
if(!vs)
return(nullptr);
const ShaderModule *gs=CreateShaderModule(geometry_shader_filename);
if(!gs)
return(nullptr);
const ShaderModule *fs=CreateShaderModule(fragment_shader_filename);
if(!fs)
return(nullptr);
return(device->CreateMaterial((VertexShaderModule *)vs,gs,fs));
}
Material *Database::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;
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;
if(ver!=1)
return(nullptr);
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;
OSString shader_name;
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)
{
shader_name=filename+OS_TEXT("?")+OSString(sr->GetStageName());
sm=CreateShaderModule(shader_name,sr);
if(sm)
{
if(smm->Add(sm))
continue;
}
}
result=false;
break;
}
if(result)
{
mtl=device->CreateMaterial(smm);
Add(mtl);
}
else
{
delete smm;
mtl=nullptr;
}
material_by_name.Add(filename,mtl);
return(mtl);
}
VK_NAMESPACE_END

View File

@ -3,13 +3,18 @@
#include<hgl/graph/vulkan/VKDevice.h> #include<hgl/graph/vulkan/VKDevice.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
DescriptorSetLayoutCreater *Device::CreateDescriptorSetLayoutCreater()
{
return(new DescriptorSetLayoutCreater(attr->device,attr->desc_pool));
}
DescriptorSetLayoutCreater::~DescriptorSetLayoutCreater() DescriptorSetLayoutCreater::~DescriptorSetLayoutCreater()
{ {
if(pipeline_layout) if(pipeline_layout)
vkDestroyPipelineLayout(*device,pipeline_layout,nullptr); vkDestroyPipelineLayout(device,pipeline_layout,nullptr);
if(dsl) if(dsl)
vkDestroyDescriptorSetLayout(*device,dsl,nullptr); vkDestroyDescriptorSetLayout(device,dsl,nullptr);
} }
void DescriptorSetLayoutCreater::Bind(const uint32_t binding,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags) void DescriptorSetLayoutCreater::Bind(const uint32_t binding,VkDescriptorType desc_type,VkShaderStageFlagBits stageFlags)
@ -83,9 +88,9 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout()
descriptor_layout.pBindings = layout_binding_list.GetData(); descriptor_layout.pBindings = layout_binding_list.GetData();
if(dsl) if(dsl)
vkDestroyDescriptorSetLayout(*device,dsl,nullptr); vkDestroyDescriptorSetLayout(device,dsl,nullptr);
if(vkCreateDescriptorSetLayout(*device,&descriptor_layout,nullptr,&dsl)!=VK_SUCCESS) if(vkCreateDescriptorSetLayout(device,&descriptor_layout,nullptr,&dsl)!=VK_SUCCESS)
return(false); return(false);
VkPushConstantRange push_constant_range; VkPushConstantRange push_constant_range;
@ -103,7 +108,7 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout()
pPipelineLayoutCreateInfo.pushConstantRangeCount = 1; pPipelineLayoutCreateInfo.pushConstantRangeCount = 1;
pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_range; pPipelineLayoutCreateInfo.pPushConstantRanges = &push_constant_range;
if(vkCreatePipelineLayout(*device,&pPipelineLayoutCreateInfo,nullptr,&pipeline_layout)!=VK_SUCCESS) if(vkCreatePipelineLayout(device,&pPipelineLayoutCreateInfo,nullptr,&pipeline_layout)!=VK_SUCCESS)
return(false); return(false);
return(true); return(true);
@ -122,13 +127,13 @@ DescriptorSets *DescriptorSetLayoutCreater::Create()
VkDescriptorSetAllocateInfo alloc_info; VkDescriptorSetAllocateInfo alloc_info;
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.pNext = nullptr; alloc_info.pNext = nullptr;
alloc_info.descriptorPool = device->GetDescriptorPool(); alloc_info.descriptorPool = pool;
alloc_info.descriptorSetCount = 1; alloc_info.descriptorSetCount = 1;
alloc_info.pSetLayouts = &dsl; alloc_info.pSetLayouts = &dsl;
VkDescriptorSet desc_set; VkDescriptorSet desc_set;
if(vkAllocateDescriptorSets(*device,&alloc_info,&desc_set)!=VK_SUCCESS) if(vkAllocateDescriptorSets(device,&alloc_info,&desc_set)!=VK_SUCCESS)
return(nullptr); return(nullptr);
return(new DescriptorSets(device,count,pipeline_layout,desc_set,&index_by_binding)); return(new DescriptorSets(device,count,pipeline_layout,desc_set,&index_by_binding));

View File

@ -3,7 +3,6 @@
#include<hgl/graph/shader/ShaderResource.h> #include<hgl/graph/shader/ShaderResource.h>
#include<hgl/type/Map.h> #include<hgl/type/Map.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
class Device;
class DescriptorSets; class DescriptorSets;
/** /**
@ -11,7 +10,8 @@ class DescriptorSets;
*/ */
class DescriptorSetLayoutCreater class DescriptorSetLayoutCreater
{ {
Device *device; VkDevice device;
VkDescriptorPool pool;
List<VkDescriptorSetLayoutBinding> layout_binding_list; List<VkDescriptorSetLayoutBinding> layout_binding_list;
VkDescriptorSetLayout dsl=VK_NULL_HANDLE; VkDescriptorSetLayout dsl=VK_NULL_HANDLE;
@ -21,7 +21,7 @@ class DescriptorSetLayoutCreater
public: public:
DescriptorSetLayoutCreater(Device *dev):device(dev){} DescriptorSetLayoutCreater(VkDevice dev,VkDescriptorPool dp){device=dev;pool=dp;}
~DescriptorSetLayoutCreater(); ~DescriptorSetLayoutCreater();
void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits); void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits);

View File

@ -87,6 +87,6 @@ bool DescriptorSets::BindSampler(const int binding,Texture *tex,Sampler *sampler
void DescriptorSets::Update() void DescriptorSets::Update()
{ {
vkUpdateDescriptorSets(*device,wds_list.GetCount(),wds_list.GetData(),0,nullptr); vkUpdateDescriptorSets(device,wds_list.GetCount(),wds_list.GetData(),0,nullptr);
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -3,11 +3,11 @@
#include<hgl/graph/vulkan/VKSemaphore.h> #include<hgl/graph/vulkan/VKSemaphore.h>
#include<hgl/graph/vulkan/VKTexture.h> #include<hgl/graph/vulkan/VKTexture.h>
#include<hgl/graph/vulkan/VKImageView.h> #include<hgl/graph/vulkan/VKImageView.h>
#include<hgl/graph/vulkan/VKPipeline.h>
#include<hgl/graph/vulkan/VKCommandBuffer.h> #include<hgl/graph/vulkan/VKCommandBuffer.h>
//#include<hgl/graph/vulkan/VKDescriptorSet.h> //#include<hgl/graph/vulkan/VKDescriptorSet.h>
#include<hgl/graph/vulkan/VKRenderPass.h> #include<hgl/graph/vulkan/VKRenderPass.h>
#include<hgl/graph/vulkan/VKFramebuffer.h> #include<hgl/graph/vulkan/VKFramebuffer.h>
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
#include<hgl/graph/vulkan/VKDescriptorSets.h> #include<hgl/graph/vulkan/VKDescriptorSets.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
@ -110,13 +110,15 @@ vulkan::Semaphore *Device::CreateSem()
return(new vulkan::Semaphore(attr->device,sem)); return(new vulkan::Semaphore(attr->device,sem));
} }
ShaderModuleManage *Device::CreateShaderModuleManage()
{
return(new ShaderModuleManage(this));
}
RenderTarget *Device::CreateRenderTarget(Framebuffer *fb) RenderTarget *Device::CreateRenderTarget(Framebuffer *fb)
{ {
return(new RenderTarget(this,fb)); return(new RenderTarget(this,fb));
} }
Pipeline *CreatePipeline(VkDevice device,VkPipelineCache pipeline_cache,PipelineData *data,const Material *material,const RenderTarget *rt);
Pipeline *Device::CreatePipeline(PipelineData *pd,const Material *mtl,const RenderTarget *rt)
{
return VK_NAMESPACE::CreatePipeline(attr->device,attr->pipeline_cache,pd,mtl,rt);
}
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -8,7 +8,7 @@
#include<hgl/graph/vulkan/VKBuffer.h> #include<hgl/graph/vulkan/VKBuffer.h>
#include"VKDescriptorSetLayoutCreater.h" #include"VKDescriptorSetLayoutCreater.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps) Material *Device::CreateMaterial(ShaderModuleMap *shader_maps)
{ {
const int shader_count=shader_maps->GetCount(); const int shader_count=shader_maps->GetCount();
@ -20,7 +20,7 @@ Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps)
if(!shader_maps->Get(VK_SHADER_STAGE_VERTEX_BIT,sm)) if(!shader_maps->Get(VK_SHADER_STAGE_VERTEX_BIT,sm))
return(nullptr); return(nullptr);
DescriptorSetLayoutCreater *dsl_creater=new DescriptorSetLayoutCreater(dev); DescriptorSetLayoutCreater *dsl_creater=CreateDescriptorSetLayoutCreater();
List<VkPipelineShaderStageCreateInfo> *shader_stage_list=new List<VkPipelineShaderStageCreateInfo>; List<VkPipelineShaderStageCreateInfo> *shader_stage_list=new List<VkPipelineShaderStageCreateInfo>;
shader_stage_list->SetCount(shader_count); shader_stage_list->SetCount(shader_count);
@ -47,12 +47,47 @@ Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps)
return(nullptr); return(nullptr);
} }
return(new Material(dev,shader_maps,shader_stage_list,dsl_creater)); return(new Material(shader_maps,shader_stage_list,dsl_creater));
} }
Material::Material(Device *dev,ShaderModuleMap *smm,List<VkPipelineShaderStageCreateInfo> *psci_list,DescriptorSetLayoutCreater *dslc) Material *Device::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *fragment_shader_module)
{
if(!vertex_shader_module||!fragment_shader_module)
return(nullptr);
if(!vertex_shader_module->IsVertex())return(nullptr);
if(!fragment_shader_module->IsFragment())return(nullptr);
ShaderModuleMap *smm=new ShaderModuleMap;
smm->Add(vertex_shader_module);
smm->Add(fragment_shader_module);
return CreateMaterial(smm);
}
Material *Device::CreateMaterial(const VertexShaderModule *vertex_shader_module,const ShaderModule *geometry_shader_module,const ShaderModule *fragment_shader_module)
{
if(!vertex_shader_module
||!geometry_shader_module
||!fragment_shader_module)
return(nullptr);
if(!vertex_shader_module->IsVertex())return(nullptr);
if(!geometry_shader_module->IsGeometry())return(nullptr);
if(!fragment_shader_module->IsFragment())return(nullptr);
ShaderModuleMap *smm=new ShaderModuleMap;
smm->Add(vertex_shader_module);
smm->Add(geometry_shader_module);
smm->Add(fragment_shader_module);
return CreateMaterial(smm);
}
Material::Material(ShaderModuleMap *smm,List<VkPipelineShaderStageCreateInfo> *psci_list,DescriptorSetLayoutCreater *dslc)
{ {
device=dev;
shader_maps=smm; shader_maps=smm;
shader_stage_list=psci_list; shader_stage_list=psci_list;
dsl_creater=dslc; dsl_creater=dslc;

View File

@ -11,7 +11,7 @@ Pipeline::~Pipeline()
vkDestroyPipeline(device,pipeline,nullptr); vkDestroyPipeline(device,pipeline,nullptr);
} }
Pipeline *CreatePipeline(Device *dev,PipelineData *data,const Material *material,const RenderTarget *rt) Pipeline *CreatePipeline(VkDevice device,VkPipelineCache pipeline_cache,PipelineData *data,const Material *material,const RenderTarget *rt)
{ {
VkPipeline graphicsPipeline; VkPipeline graphicsPipeline;
@ -28,13 +28,13 @@ Pipeline *CreatePipeline(Device *dev,PipelineData *data,const Material *material
data->pipeline_info.subpass = 0; //subpass由于还不知道有什么用所以暂时写0待知道功用后需改进 data->pipeline_info.subpass = 0; //subpass由于还不知道有什么用所以暂时写0待知道功用后需改进
} }
if (vkCreateGraphicsPipelines( dev->GetDevice(), if (vkCreateGraphicsPipelines( device,
dev->GetPipelineCache(), pipeline_cache,
1,&data->pipeline_info, 1,&data->pipeline_info,
nullptr, nullptr,
&graphicsPipeline) != VK_SUCCESS) &graphicsPipeline) != VK_SUCCESS)
return(nullptr); return(nullptr);
return(new Pipeline(dev->GetDevice(),graphicsPipeline,data)); return(new Pipeline(device,graphicsPipeline,data));
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -1,11 +1,43 @@
#include<hgl/graph/vulkan/VKShaderModule.h> #include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKVertexAttributeBinding.h> #include<hgl/graph/vulkan/VKVertexAttributeBinding.h>
#include<hgl/graph/vulkan/VKDevice.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
ShaderModule::ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *sci,ShaderResource *sr) ShaderModule *Device::CreateShaderModule(ShaderResource *sr)
{
if(!sr)return(nullptr);
VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo;
shader_stage->sType =VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stage->pNext =nullptr;
shader_stage->pSpecializationInfo =nullptr;
shader_stage->flags =0;
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 =sr->GetCodeSize();
moduleCreateInfo.pCode =sr->GetCode();
if(vkCreateShaderModule(attr->device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS)
return(nullptr);
ShaderModule *sm;
if(sr->GetStage()==VK_SHADER_STAGE_VERTEX_BIT)
sm=new VertexShaderModule(attr->device,shader_stage,sr);
else
sm=new ShaderModule(attr->device,shader_stage,sr);
return sm;
}
ShaderModule::ShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *sci,ShaderResource *sr)
{ {
device=dev; device=dev;
shader_id=id;
ref_count=0; ref_count=0;
stage_create_info=sci; stage_create_info=sci;
@ -19,7 +51,7 @@ ShaderModule::~ShaderModule()
delete stage_create_info; delete stage_create_info;
} }
VertexShaderModule::VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr):ShaderModule(dev,id,pssci,sr) VertexShaderModule::VertexShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr):ShaderModule(dev,pssci,sr)
{ {
const ShaderStageList &stage_inputs=sr->GetStageInputs(); const ShaderStageList &stage_inputs=sr->GetStageInputs();

View File

@ -1,281 +0,0 @@
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
#include<hgl/graph/vulkan/VKShaderModule.h>
#include<hgl/graph/vulkan/VKMaterial.h>
#include<hgl/graph/vulkan/VKDevice.h>
#include<hgl/graph/vulkan/ShaderModuleMap.h>
#include<hgl/graph/shader/ShaderResource.h>
#include<hgl/filesystem/FileSystem.h>
VK_NAMESPACE_BEGIN
Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps);
ShaderModuleManage::~ShaderModuleManage()
{
const int count=shader_list.GetCount();
if(count>0)
{
auto **p=shader_list.GetDataList();
for(int i=0;i<count;i++)
{
delete (*p)->right;
++p;
}
}
}
const ShaderModule *ShaderModuleManage::CreateShader(ShaderResource *sr)
{
if(!sr)
return(nullptr);
VkPipelineShaderStageCreateInfo *shader_stage=new VkPipelineShaderStageCreateInfo;
shader_stage->sType =VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader_stage->pNext =nullptr;
shader_stage->pSpecializationInfo =nullptr;
shader_stage->flags =0;
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 =sr->GetCodeSize();
moduleCreateInfo.pCode =sr->GetCode();
if(vkCreateShaderModule(*device,&moduleCreateInfo,nullptr,&(shader_stage->module))!=VK_SUCCESS)
return(nullptr);
ShaderModule *sm;
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,sr);
shader_list.Add(shader_count,sm);
++shader_count;
return sm;
}
const ShaderModule *ShaderModuleManage::CreateShader(const VkShaderStageFlagBits shader_stage_bit,const OSString &filename)
{
ShaderResource *shader_resource=LoadShaderResoruce(filename);
if(!shader_resource)return(nullptr);
return CreateShader(shader_resource);
}
const ShaderModule *ShaderModuleManage::GetShader(int id)
{
ShaderModule *sm;
if(!shader_list.Get(id,sm))
return nullptr;
sm->IncRef();
return sm;
}
bool ShaderModuleManage::ReleaseShader(const ShaderModule *const_sm)
{
if(!const_sm)
return(false);
ShaderModule *sm;
if(!shader_list.Get(const_sm->GetID(),sm))
return(false);
if(sm!=const_sm)
return(false);
sm->DecRef();
return(true);
}
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);
if(!vertex_shader_module->IsVertex())return(nullptr);
if(!fragment_shader_module->IsFragment())return(nullptr);
ShaderModuleMap *smm=new ShaderModuleMap;
smm->Add(vertex_shader_module);
smm->Add(fragment_shader_module);
return CreateMaterial(smm);
}
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
||!fragment_shader_module)
return(nullptr);
if(!vertex_shader_module->IsVertex())return(nullptr);
if(!geometry_shader_module->IsGeometry())return(nullptr);
if(!fragment_shader_module->IsFragment())return(nullptr);
ShaderModuleMap *smm=new ShaderModuleMap;
smm->Add(vertex_shader_module);
smm->Add(geometry_shader_module);
smm->Add(fragment_shader_module);
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;
if(ver!=1)
return(nullptr);
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

@ -1,6 +1,7 @@
#include<hgl/graph/shader/ShaderResource.h> #include<hgl/graph/shader/ShaderResource.h>
#include<hgl/filesystem/FileSystem.h> #include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/vulkan/VKFormat.h> #include<hgl/graph/vulkan/VKFormat.h>
#include<hgl/type/Map.h>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
@ -8,6 +9,8 @@ VK_NAMESPACE_BEGIN
namespace namespace
{ {
MapObject<OSString,ShaderResource> shader_resource_by_filename;
constexpr char SHADER_FILE_HEADER[] ="Shader\x1A"; constexpr char SHADER_FILE_HEADER[] ="Shader\x1A";
constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1; constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1;
@ -88,6 +91,34 @@ VK_NAMESPACE_BEGIN
spv_size=size; 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 const ShaderStage *ShaderResource::GetStageInput(const AnsiString &name) const
{ {
const int count=stage_inputs.GetCount(); const int count=stage_inputs.GetCount();
@ -184,9 +215,17 @@ VK_NAMESPACE_BEGIN
ShaderResource *LoadShaderResoruce(const OSString &filename) ShaderResource *LoadShaderResoruce(const OSString &filename)
{ {
ShaderResource *sr;
if(shader_resource_by_filename.Get(filename,sr))
return sr;
int64 filesize; int64 filesize;
AutoDeleteArray<uint8> origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".shader"),filesize); AutoDeleteArray<uint8> origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".shader"),filesize);
return LoadShaderResource(origin_filedata,filesize,true); sr=LoadShaderResource(origin_filedata,filesize,true);
shader_resource_by_filename.Add(filename,sr);
return sr;
} }
VK_NAMESPACE_END VK_NAMESPACE_END