optimized Material and ShaderModule,Pipeline,Database codes.
This commit is contained in:
parent
5d08717c21
commit
2b9152d602
@ -1 +1 @@
|
||||
Subproject commit 955cf63c7f911b3a8af2be9a1a0facffdecd34bb
|
||||
Subproject commit fe9dc360c87179f8a8293f7f78127f366b7f191b
|
@ -14,12 +14,21 @@ using namespace hgl::graph;
|
||||
constexpr uint32_t SCREEN_WIDTH=128;
|
||||
constexpr uint32_t SCREEN_HEIGHT=128;
|
||||
|
||||
struct AtomsphereData
|
||||
struct AtmosphereData
|
||||
{
|
||||
Vector3f position;
|
||||
float intensity;
|
||||
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
|
||||
{
|
||||
@ -28,82 +37,48 @@ private:
|
||||
SceneNode render_root;
|
||||
RenderList render_list;
|
||||
|
||||
vulkan::Material * material =nullptr;
|
||||
vulkan::MaterialInstance * material_instance =nullptr;
|
||||
|
||||
vulkan::Renderable * ro_sphere =nullptr;
|
||||
|
||||
vulkan::Pipeline * pipeline_solid =nullptr;
|
||||
|
||||
vulkan::Buffer * ubo_atomsphere =nullptr;
|
||||
AtomsphereData atomsphere_data;
|
||||
AtmosphereData atomsphere_data;
|
||||
|
||||
vulkan::Renderable * ro_sphere =nullptr;
|
||||
|
||||
private:
|
||||
|
||||
bool InitMaterial()
|
||||
{
|
||||
material=shader_manage->CreateMaterial(OS_TEXT("res/material/Atmosphere")); //不需要写.material的扩展名
|
||||
if(!material)
|
||||
return(false);
|
||||
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Atmosphere")); //不需要优先创建Material,也不需要写扩展名
|
||||
if(!material_instance)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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if(!material_instance->BindUBO("world",GetCameraMatrixBuffer()))
|
||||
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);
|
||||
|
||||
material_instance->Update();
|
||||
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()
|
||||
{
|
||||
ro_sphere=CreateRenderableSphere(db,material_instance->GetMaterial(),128);
|
||||
|
||||
render_root.Add(db->CreateRenderableInstance(pipeline_solid,material_instance,ro_sphere),scale(100));
|
||||
|
||||
render_root.RefreshMatrix();
|
||||
@ -122,14 +97,9 @@ public:
|
||||
if(!InitMaterial())
|
||||
return(false);
|
||||
|
||||
CreateRenderObject();
|
||||
|
||||
if(!InitUBO())
|
||||
return(false);
|
||||
|
||||
if(!InitPipeline())
|
||||
return(false);
|
||||
|
||||
if(!InitScene())
|
||||
return(false);
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include<hgl/graph/vulkan/VKSemaphore.h>
|
||||
#include<hgl/graph/vulkan/VKBuffer.h>
|
||||
#include<hgl/graph/vulkan/VKShaderModule.h>
|
||||
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
|
||||
#include<hgl/graph/vulkan/VKImageView.h>
|
||||
#include<hgl/graph/vulkan/VKRenderable.h>
|
||||
#include<hgl/graph/vulkan/VKDescriptorSets.h>
|
||||
@ -53,8 +52,6 @@ protected:
|
||||
vulkan::Semaphore * present_complete_semaphore =nullptr,
|
||||
* render_complete_semaphore =nullptr;
|
||||
|
||||
vulkan::ShaderModuleManage * shader_manage =nullptr;
|
||||
|
||||
protected:
|
||||
|
||||
int32_t swap_chain_count =0;
|
||||
@ -77,7 +74,6 @@ public:
|
||||
SAFE_CLEAR(db);
|
||||
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
|
||||
|
||||
SAFE_CLEAR(shader_manage);
|
||||
SAFE_CLEAR(device);
|
||||
SAFE_CLEAR(win);
|
||||
SAFE_CLEAR(inst);
|
||||
@ -126,7 +122,6 @@ public:
|
||||
present_complete_semaphore =device->CreateSem();
|
||||
render_complete_semaphore =device->CreateSem();
|
||||
|
||||
shader_manage=device->CreateShaderModuleManage();
|
||||
db=new vulkan::Database(device);
|
||||
|
||||
InitCommandBuffer();
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
virtual ~ShaderResource()=default;
|
||||
|
||||
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 GetCodeSize ()const {return spv_size;}
|
||||
|
@ -3,13 +3,12 @@
|
||||
|
||||
#include<hgl/type/Map.h>
|
||||
#include<hgl/graph/vulkan/VKNamespace.h>
|
||||
#include<hgl/graph/vulkan/VKShaderModule.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
using namespace hgl;
|
||||
|
||||
class ShaderModule;
|
||||
|
||||
class ShaderModuleMap:public Map<VkShaderStageFlagBits,const ShaderModule *>
|
||||
{
|
||||
public:
|
||||
|
@ -47,15 +47,17 @@ class RenderPass;
|
||||
class Fence;
|
||||
class Semaphore;
|
||||
|
||||
class DescriptorSetLayoutCreater;
|
||||
|
||||
struct ShaderStage;
|
||||
|
||||
class ShaderModuleMap;
|
||||
class ShaderResource;
|
||||
class ShaderModule;
|
||||
class ShaderModuleManage;
|
||||
class VertexShaderModule;
|
||||
class Material;
|
||||
class MaterialInstance;
|
||||
class PipelineLayout;
|
||||
struct PipelineData;
|
||||
class Pipeline;
|
||||
class DescriptorSets;
|
||||
class VertexAttributeBinding;
|
||||
|
@ -33,6 +33,9 @@ class Database
|
||||
{
|
||||
Device *device;
|
||||
|
||||
MapObject<OSString,ShaderModule> shader_module_by_name;
|
||||
Map<OSString,Material *> material_by_name;
|
||||
|
||||
IDResManage<MaterialID, Material> rm_material; ///<材质合集
|
||||
IDResManage<MaterialInstanceID, MaterialInstance> rm_material_instance; ///<材质实例合集
|
||||
IDResManage<PipelineID, Pipeline> rm_pipeline; ///<管线合集
|
||||
@ -60,7 +63,7 @@ public: //Add
|
||||
TextureID Add(Texture * t ){return rm_textures.Add(t);}
|
||||
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,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 *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(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);
|
||||
TextRenderable * CreateTextRenderable(Material *);
|
||||
|
||||
|
@ -4,12 +4,11 @@
|
||||
#include<hgl/graph/vulkan/VK.h>
|
||||
#include<hgl/type/Map.h>
|
||||
VK_NAMESPACE_BEGIN
|
||||
class Device;
|
||||
class Buffer;
|
||||
|
||||
class DescriptorSets
|
||||
{
|
||||
Device *device;
|
||||
VkDevice device;
|
||||
int count;
|
||||
VkDescriptorSet desc_set;
|
||||
const Map<uint32_t,int> *index_by_binding;
|
||||
@ -23,7 +22,7 @@ private:
|
||||
|
||||
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;
|
||||
count=c;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include<hgl/graph/vulkan/VKSwapchain.h>
|
||||
#include<hgl/graph/vulkan/VKRenderTarget.h>
|
||||
#include<hgl/graph/VertexAttribData.h>
|
||||
#include<hgl/graph/vulkan/ShaderModuleMap.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
@ -217,7 +218,15 @@ public: //
|
||||
|
||||
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 相关
|
||||
|
||||
@ -264,6 +273,8 @@ public:
|
||||
|
||||
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数据集
|
||||
|
||||
TileFont *CreateTileFont(FontSource *fs,int limit_count=-1); ///<创建一个Tile字体
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include<hgl/graph/vulkan/VK.h>
|
||||
#include<hgl/type/Map.h>
|
||||
#include<hgl/type/String.h>
|
||||
#include<hgl/graph/vulkan/ShaderModuleMap.h>
|
||||
VK_NAMESPACE_BEGIN
|
||||
class DescriptorSetLayoutCreater;
|
||||
|
||||
@ -13,7 +14,6 @@ class DescriptorSetLayoutCreater;
|
||||
*/
|
||||
class Material
|
||||
{
|
||||
Device *device;
|
||||
ShaderModuleMap *shader_maps;
|
||||
VertexShaderModule *vertex_sm;
|
||||
List<VkPipelineShaderStageCreateInfo> *shader_stage_list;
|
||||
@ -24,7 +24,7 @@ class Material
|
||||
|
||||
public:
|
||||
|
||||
Material(Device *dev,ShaderModuleMap *smm,List<VkPipelineShaderStageCreateInfo> *,DescriptorSetLayoutCreater *dslc);
|
||||
Material(ShaderModuleMap *smm,List<VkPipelineShaderStageCreateInfo> *,DescriptorSetLayoutCreater *dslc);
|
||||
~Material();
|
||||
|
||||
const VertexShaderModule *GetVertexShaderModule()const{return vertex_sm;}
|
||||
|
@ -26,8 +26,6 @@ public:
|
||||
const bool IsAlphaTest()const{return data->alpha_test>0;}
|
||||
const bool IsAlphaBlend()const{return data->alpha_blend;}
|
||||
};//class GraphicsPipeline
|
||||
|
||||
Pipeline *CreatePipeline(Device *,PipelineData *,const Material *,const RenderTarget *);
|
||||
VK_NAMESPACE_END
|
||||
#endif//HGL_GRAPH_VULKAN_PIPELINE_INCLUDE
|
||||
|
@ -13,7 +13,6 @@ VK_NAMESPACE_BEGIN
|
||||
class ShaderModule
|
||||
{
|
||||
VkDevice device;
|
||||
int shader_id;
|
||||
int ref_count;
|
||||
|
||||
private:
|
||||
@ -26,11 +25,9 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
ShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *);
|
||||
ShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *);
|
||||
virtual ~ShaderModule();
|
||||
|
||||
const int GetID()const{return shader_id;}
|
||||
|
||||
const int IncRef(){return ++ref_count;}
|
||||
const int DecRef(){return --ref_count;}
|
||||
|
||||
@ -75,7 +72,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
VertexShaderModule(VkDevice dev,int id,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr);
|
||||
VertexShaderModule(VkDevice dev,VkPipelineShaderStageCreateInfo *pssci,ShaderResource *sr);
|
||||
virtual ~VertexShaderModule();
|
||||
|
||||
/**
|
||||
|
@ -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
|
@ -1,7 +1,8 @@
|
||||
set(RD_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph/vulkan)
|
||||
|
||||
SET(VK_DB_SOURCE ${RD_INCLUDE_PATH}/VKDatabase.h
|
||||
VKDatabase.cpp)
|
||||
VKDatabase.cpp
|
||||
VKDatabaseMaterial.cpp)
|
||||
|
||||
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})
|
||||
|
||||
SET(VK_SHADER_SOURCE ${RD_INCLUDE_PATH}/VKShaderModule.h
|
||||
${RD_INCLUDE_PATH}/VKShaderModuleManage.h
|
||||
${RD_INCLUDE_PATH}/ShaderModuleMap.h
|
||||
ShaderModuleMap.cpp
|
||||
VKShaderModule.cpp
|
||||
VKShaderModuleManage.cpp)
|
||||
VKShaderModule.cpp)
|
||||
|
||||
SET(VK_TEXTURE_SOURCE ${RD_INCLUDE_PATH}/VKImageView.h
|
||||
${RD_INCLUDE_PATH}/VKTexture.h
|
||||
|
@ -60,6 +60,37 @@ MaterialInstance *Database::CreateMaterialInstance(Material *mtl)
|
||||
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)
|
||||
{
|
||||
if(!mtl)return(nullptr);
|
||||
|
170
src/RenderDevice/Vulkan/VKDatabaseMaterial.cpp
Normal file
170
src/RenderDevice/Vulkan/VKDatabaseMaterial.cpp
Normal 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
|
@ -3,13 +3,18 @@
|
||||
#include<hgl/graph/vulkan/VKDevice.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
DescriptorSetLayoutCreater *Device::CreateDescriptorSetLayoutCreater()
|
||||
{
|
||||
return(new DescriptorSetLayoutCreater(attr->device,attr->desc_pool));
|
||||
}
|
||||
|
||||
DescriptorSetLayoutCreater::~DescriptorSetLayoutCreater()
|
||||
{
|
||||
if(pipeline_layout)
|
||||
vkDestroyPipelineLayout(*device,pipeline_layout,nullptr);
|
||||
vkDestroyPipelineLayout(device,pipeline_layout,nullptr);
|
||||
|
||||
if(dsl)
|
||||
vkDestroyDescriptorSetLayout(*device,dsl,nullptr);
|
||||
vkDestroyDescriptorSetLayout(device,dsl,nullptr);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
VkPushConstantRange push_constant_range;
|
||||
@ -103,7 +108,7 @@ bool DescriptorSetLayoutCreater::CreatePipelineLayout()
|
||||
pPipelineLayoutCreateInfo.pushConstantRangeCount = 1;
|
||||
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(true);
|
||||
@ -122,13 +127,13 @@ DescriptorSets *DescriptorSetLayoutCreater::Create()
|
||||
VkDescriptorSetAllocateInfo alloc_info;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
alloc_info.pNext = nullptr;
|
||||
alloc_info.descriptorPool = device->GetDescriptorPool();
|
||||
alloc_info.descriptorPool = pool;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &dsl;
|
||||
|
||||
VkDescriptorSet desc_set;
|
||||
|
||||
if(vkAllocateDescriptorSets(*device,&alloc_info,&desc_set)!=VK_SUCCESS)
|
||||
if(vkAllocateDescriptorSets(device,&alloc_info,&desc_set)!=VK_SUCCESS)
|
||||
return(nullptr);
|
||||
|
||||
return(new DescriptorSets(device,count,pipeline_layout,desc_set,&index_by_binding));
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include<hgl/graph/shader/ShaderResource.h>
|
||||
#include<hgl/type/Map.h>
|
||||
VK_NAMESPACE_BEGIN
|
||||
class Device;
|
||||
class DescriptorSets;
|
||||
|
||||
/**
|
||||
@ -11,7 +10,8 @@ class DescriptorSets;
|
||||
*/
|
||||
class DescriptorSetLayoutCreater
|
||||
{
|
||||
Device *device;
|
||||
VkDevice device;
|
||||
VkDescriptorPool pool;
|
||||
|
||||
List<VkDescriptorSetLayoutBinding> layout_binding_list;
|
||||
VkDescriptorSetLayout dsl=VK_NULL_HANDLE;
|
||||
@ -21,7 +21,7 @@ class DescriptorSetLayoutCreater
|
||||
|
||||
public:
|
||||
|
||||
DescriptorSetLayoutCreater(Device *dev):device(dev){}
|
||||
DescriptorSetLayoutCreater(VkDevice dev,VkDescriptorPool dp){device=dev;pool=dp;}
|
||||
~DescriptorSetLayoutCreater();
|
||||
|
||||
void Bind(const uint32_t binding,VkDescriptorType,VkShaderStageFlagBits);
|
||||
|
@ -87,6 +87,6 @@ bool DescriptorSets::BindSampler(const int binding,Texture *tex,Sampler *sampler
|
||||
|
||||
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
|
||||
|
@ -3,11 +3,11 @@
|
||||
#include<hgl/graph/vulkan/VKSemaphore.h>
|
||||
#include<hgl/graph/vulkan/VKTexture.h>
|
||||
#include<hgl/graph/vulkan/VKImageView.h>
|
||||
#include<hgl/graph/vulkan/VKPipeline.h>
|
||||
#include<hgl/graph/vulkan/VKCommandBuffer.h>
|
||||
//#include<hgl/graph/vulkan/VKDescriptorSet.h>
|
||||
#include<hgl/graph/vulkan/VKRenderPass.h>
|
||||
#include<hgl/graph/vulkan/VKFramebuffer.h>
|
||||
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
|
||||
#include<hgl/graph/vulkan/VKDescriptorSets.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
@ -110,13 +110,15 @@ vulkan::Semaphore *Device::CreateSem()
|
||||
return(new vulkan::Semaphore(attr->device,sem));
|
||||
}
|
||||
|
||||
ShaderModuleManage *Device::CreateShaderModuleManage()
|
||||
{
|
||||
return(new ShaderModuleManage(this));
|
||||
}
|
||||
|
||||
RenderTarget *Device::CreateRenderTarget(Framebuffer *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
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include<hgl/graph/vulkan/VKBuffer.h>
|
||||
#include"VKDescriptorSetLayoutCreater.h"
|
||||
VK_NAMESPACE_BEGIN
|
||||
Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps)
|
||||
Material *Device::CreateMaterial(ShaderModuleMap *shader_maps)
|
||||
{
|
||||
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))
|
||||
return(nullptr);
|
||||
|
||||
DescriptorSetLayoutCreater *dsl_creater=new DescriptorSetLayoutCreater(dev);
|
||||
DescriptorSetLayoutCreater *dsl_creater=CreateDescriptorSetLayoutCreater();
|
||||
List<VkPipelineShaderStageCreateInfo> *shader_stage_list=new List<VkPipelineShaderStageCreateInfo>;
|
||||
|
||||
shader_stage_list->SetCount(shader_count);
|
||||
@ -47,12 +47,47 @@ Material *CreateMaterial(Device *dev,ShaderModuleMap *shader_maps)
|
||||
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_stage_list=psci_list;
|
||||
dsl_creater=dslc;
|
||||
|
@ -11,7 +11,7 @@ Pipeline::~Pipeline()
|
||||
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;
|
||||
|
||||
@ -28,13 +28,13 @@ Pipeline *CreatePipeline(Device *dev,PipelineData *data,const Material *material
|
||||
data->pipeline_info.subpass = 0; //subpass由于还不知道有什么用,所以暂时写0,待知道功用后,需改进
|
||||
}
|
||||
|
||||
if (vkCreateGraphicsPipelines( dev->GetDevice(),
|
||||
dev->GetPipelineCache(),
|
||||
if (vkCreateGraphicsPipelines( device,
|
||||
pipeline_cache,
|
||||
1,&data->pipeline_info,
|
||||
nullptr,
|
||||
&graphicsPipeline) != VK_SUCCESS)
|
||||
return(nullptr);
|
||||
|
||||
return(new Pipeline(dev->GetDevice(),graphicsPipeline,data));
|
||||
return(new Pipeline(device,graphicsPipeline,data));
|
||||
}
|
||||
VK_NAMESPACE_END
|
||||
|
@ -1,11 +1,43 @@
|
||||
#include<hgl/graph/vulkan/VKShaderModule.h>
|
||||
#include<hgl/graph/vulkan/VKVertexAttributeBinding.h>
|
||||
#include<hgl/graph/vulkan/VKDevice.h>
|
||||
|
||||
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;
|
||||
shader_id=id;
|
||||
ref_count=0;
|
||||
|
||||
stage_create_info=sci;
|
||||
@ -19,7 +51,7 @@ ShaderModule::~ShaderModule()
|
||||
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();
|
||||
|
||||
|
@ -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
|
@ -1,6 +1,7 @@
|
||||
#include<hgl/graph/shader/ShaderResource.h>
|
||||
#include<hgl/filesystem/FileSystem.h>
|
||||
#include<hgl/graph/vulkan/VKFormat.h>
|
||||
#include<hgl/type/Map.h>
|
||||
|
||||
VK_NAMESPACE_BEGIN
|
||||
|
||||
@ -8,6 +9,8 @@ VK_NAMESPACE_BEGIN
|
||||
|
||||
namespace
|
||||
{
|
||||
MapObject<OSString,ShaderResource> shader_resource_by_filename;
|
||||
|
||||
constexpr char SHADER_FILE_HEADER[] ="Shader\x1A";
|
||||
constexpr uint SHADER_FILE_HEADER_BYTES=sizeof(SHADER_FILE_HEADER)-1;
|
||||
|
||||
@ -88,6 +91,34 @@ VK_NAMESPACE_BEGIN
|
||||
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 int count=stage_inputs.GetCount();
|
||||
@ -184,9 +215,17 @@ VK_NAMESPACE_BEGIN
|
||||
|
||||
ShaderResource *LoadShaderResoruce(const OSString &filename)
|
||||
{
|
||||
ShaderResource *sr;
|
||||
|
||||
if(shader_resource_by_filename.Get(filename,sr))
|
||||
return sr;
|
||||
|
||||
int64 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user