diff --git a/CMSceneGraph b/CMSceneGraph index 955cf63c..fe9dc360 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 955cf63c7f911b3a8af2be9a1a0facffdecd34bb +Subproject commit fe9dc360c87179f8a8293f7f78127f366b7f191b diff --git a/example/Vulkan/Atomsphere.cpp b/example/Vulkan/Atomsphere.cpp index 8462bec2..98e624da 100644 --- a/example/Vulkan/Atomsphere.cpp +++ b/example/Vulkan/Atomsphere.cpp @@ -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); diff --git a/example/Vulkan/VulkanAppFramework.h b/example/Vulkan/VulkanAppFramework.h index 8f5831e1..978af423 100644 --- a/example/Vulkan/VulkanAppFramework.h +++ b/example/Vulkan/VulkanAppFramework.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -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(); diff --git a/inc/hgl/graph/shader/ShaderResource.h b/inc/hgl/graph/shader/ShaderResource.h index 1a39091e..d88db702 100644 --- a/inc/hgl/graph/shader/ShaderResource.h +++ b/inc/hgl/graph/shader/ShaderResource.h @@ -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;} diff --git a/inc/hgl/graph/vulkan/ShaderModuleMap.h b/inc/hgl/graph/vulkan/ShaderModuleMap.h index dd7d8f8b..8de04b86 100644 --- a/inc/hgl/graph/vulkan/ShaderModuleMap.h +++ b/inc/hgl/graph/vulkan/ShaderModuleMap.h @@ -3,13 +3,12 @@ #include #include +#include VK_NAMESPACE_BEGIN using namespace hgl; -class ShaderModule; - class ShaderModuleMap:public Map { public: diff --git a/inc/hgl/graph/vulkan/VK.h b/inc/hgl/graph/vulkan/VK.h index b8326eff..0529d47e 100644 --- a/inc/hgl/graph/vulkan/VK.h +++ b/inc/hgl/graph/vulkan/VK.h @@ -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; diff --git a/inc/hgl/graph/vulkan/VKDatabase.h b/inc/hgl/graph/vulkan/VKDatabase.h index 4d04477d..e7abbd14 100644 --- a/inc/hgl/graph/vulkan/VKDatabase.h +++ b/inc/hgl/graph/vulkan/VKDatabase.h @@ -32,7 +32,10 @@ class VertexAttribData; class Database { Device *device; - + + MapObject shader_module_by_name; + Map material_by_name; + IDResManage rm_material; ///<材质合集 IDResManage rm_material_instance; ///<材质实例合集 IDResManage 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 *); diff --git a/inc/hgl/graph/vulkan/VKDescriptorSets.h b/inc/hgl/graph/vulkan/VKDescriptorSets.h index 09907cf8..e4e0e6a3 100644 --- a/inc/hgl/graph/vulkan/VKDescriptorSets.h +++ b/inc/hgl/graph/vulkan/VKDescriptorSets.h @@ -4,12 +4,11 @@ #include #include VK_NAMESPACE_BEGIN -class Device; class Buffer; class DescriptorSets { - Device *device; + VkDevice device; int count; VkDescriptorSet desc_set; const Map *index_by_binding; @@ -23,7 +22,7 @@ private: friend class DescriptorSetLayoutCreater; - DescriptorSets(Device *dev,const int c,VkPipelineLayout pl,VkDescriptorSet ds,const Map *bi):index_by_binding(bi) + DescriptorSets(VkDevice dev,const int c,VkPipelineLayout pl,VkDescriptorSet ds,const Map *bi):index_by_binding(bi) { device=dev; count=c; diff --git a/inc/hgl/graph/vulkan/VKDevice.h b/inc/hgl/graph/vulkan/VKDevice.h index 44168ded..7301ab30 100644 --- a/inc/hgl/graph/vulkan/VKDevice.h +++ b/inc/hgl/graph/vulkan/VKDevice.h @@ -13,6 +13,7 @@ #include #include #include +#include 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字体 diff --git a/inc/hgl/graph/vulkan/VKMaterial.h b/inc/hgl/graph/vulkan/VKMaterial.h index 5c7c300e..85737767 100644 --- a/inc/hgl/graph/vulkan/VKMaterial.h +++ b/inc/hgl/graph/vulkan/VKMaterial.h @@ -4,6 +4,7 @@ #include #include #include +#include VK_NAMESPACE_BEGIN class DescriptorSetLayoutCreater; @@ -13,7 +14,6 @@ class DescriptorSetLayoutCreater; */ class Material { - Device *device; ShaderModuleMap *shader_maps; VertexShaderModule *vertex_sm; List *shader_stage_list; @@ -24,7 +24,7 @@ class Material public: - Material(Device *dev,ShaderModuleMap *smm,List *,DescriptorSetLayoutCreater *dslc); + Material(ShaderModuleMap *smm,List *,DescriptorSetLayoutCreater *dslc); ~Material(); const VertexShaderModule *GetVertexShaderModule()const{return vertex_sm;} diff --git a/inc/hgl/graph/vulkan/VKPipeline.h b/inc/hgl/graph/vulkan/VKPipeline.h index c99a56e3..c582b321 100644 --- a/inc/hgl/graph/vulkan/VKPipeline.h +++ b/inc/hgl/graph/vulkan/VKPipeline.h @@ -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 \ No newline at end of file diff --git a/inc/hgl/graph/vulkan/VKShaderModule.h b/inc/hgl/graph/vulkan/VKShaderModule.h index 589c5062..1f3f899a 100644 --- a/inc/hgl/graph/vulkan/VKShaderModule.h +++ b/inc/hgl/graph/vulkan/VKShaderModule.h @@ -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(); /** diff --git a/inc/hgl/graph/vulkan/VKShaderModuleManage.h b/inc/hgl/graph/vulkan/VKShaderModuleManage.h deleted file mode 100644 index 6f465a69..00000000 --- a/inc/hgl/graph/vulkan/VKShaderModuleManage.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE -#define HGL_GRAPH_VULKAN_SHADER_MODULE_MANAGE_INCLUDE - -#include -#include -#include -VK_NAMESPACE_BEGIN - -class ShaderResource; - -/** - * Shader模块管理器
- * 所有的shader模块均由它创建和释放 - * 该管理器在一个设备下仅有一个,它负责管理所有的shader(仅vs/fs/gs等单个,非组合体) - */ -class ShaderModuleManage -{ - Device *device; - - int shader_count; - Map 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 diff --git a/src/RenderDevice/Vulkan/CMakeLists.txt b/src/RenderDevice/Vulkan/CMakeLists.txt index aaf9444c..05edb4e4 100644 --- a/src/RenderDevice/Vulkan/CMakeLists.txt +++ b/src/RenderDevice/Vulkan/CMakeLists.txt @@ -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 diff --git a/src/RenderDevice/Vulkan/VKDatabase.cpp b/src/RenderDevice/Vulkan/VKDatabase.cpp index 8aff6c71..7fa7ffb9 100644 --- a/src/RenderDevice/Vulkan/VKDatabase.cpp +++ b/src/RenderDevice/Vulkan/VKDatabase.cpp @@ -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); diff --git a/src/RenderDevice/Vulkan/VKDatabaseMaterial.cpp b/src/RenderDevice/Vulkan/VKDatabaseMaterial.cpp new file mode 100644 index 00000000..8cddf608 --- /dev/null +++ b/src/RenderDevice/Vulkan/VKDatabaseMaterial.cpp @@ -0,0 +1,170 @@ +#include +#include +#include +#include +#include +#include +#include + +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 origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".material"),filesize); + + if(filesizeGetStageName()); + + 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 diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp index 6ba4359b..90c07654 100644 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp +++ b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.cpp @@ -3,13 +3,18 @@ #include 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)); diff --git a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h index af65f88d..c3ef1b00 100644 --- a/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h +++ b/src/RenderDevice/Vulkan/VKDescriptorSetLayoutCreater.h @@ -3,7 +3,6 @@ #include #include VK_NAMESPACE_BEGIN -class Device; class DescriptorSets; /** @@ -11,7 +10,8 @@ class DescriptorSets; */ class DescriptorSetLayoutCreater { - Device *device; + VkDevice device; + VkDescriptorPool pool; List 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); diff --git a/src/RenderDevice/Vulkan/VKDescriptorSets.cpp b/src/RenderDevice/Vulkan/VKDescriptorSets.cpp index 61f10754..cbfef913 100644 --- a/src/RenderDevice/Vulkan/VKDescriptorSets.cpp +++ b/src/RenderDevice/Vulkan/VKDescriptorSets.cpp @@ -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 diff --git a/src/RenderDevice/Vulkan/VKDevice.cpp b/src/RenderDevice/Vulkan/VKDevice.cpp index 03f57376..63f10526 100644 --- a/src/RenderDevice/Vulkan/VKDevice.cpp +++ b/src/RenderDevice/Vulkan/VKDevice.cpp @@ -3,11 +3,11 @@ #include #include #include +#include #include //#include #include #include -#include #include 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 diff --git a/src/RenderDevice/Vulkan/VKMaterial.cpp b/src/RenderDevice/Vulkan/VKMaterial.cpp index fb7d2443..1172b837 100644 --- a/src/RenderDevice/Vulkan/VKMaterial.cpp +++ b/src/RenderDevice/Vulkan/VKMaterial.cpp @@ -8,7 +8,7 @@ #include #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 *shader_stage_list=new List; 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 *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 *psci_list,DescriptorSetLayoutCreater *dslc) { - device=dev; shader_maps=smm; shader_stage_list=psci_list; dsl_creater=dslc; diff --git a/src/RenderDevice/Vulkan/VKPipeline.cpp b/src/RenderDevice/Vulkan/VKPipeline.cpp index 11220f6e..b20f6a7f 100644 --- a/src/RenderDevice/Vulkan/VKPipeline.cpp +++ b/src/RenderDevice/Vulkan/VKPipeline.cpp @@ -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 diff --git a/src/RenderDevice/Vulkan/VKShaderModule.cpp b/src/RenderDevice/Vulkan/VKShaderModule.cpp index c96191e3..2d7db7b9 100644 --- a/src/RenderDevice/Vulkan/VKShaderModule.cpp +++ b/src/RenderDevice/Vulkan/VKShaderModule.cpp @@ -1,11 +1,43 @@ #include #include +#include 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(); diff --git a/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp b/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp deleted file mode 100644 index e9ec9b42..00000000 --- a/src/RenderDevice/Vulkan/VKShaderModuleManage.cpp +++ /dev/null @@ -1,281 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -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;iright; - - ++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;iright); - - ++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 origin_filedata=(uint8 *)filesystem::LoadFileToMemory(filename+OS_TEXT(".material"),filesize); - - if(filesizeAdd(sm)) - continue; - } - } - - result=false; - break; - } - - if(result) - return CreateMaterial(smm); - - Free(smm); - return(nullptr); -} -VK_NAMESPACE_END diff --git a/src/SceneGraph/shader/ShaderResource.cpp b/src/SceneGraph/shader/ShaderResource.cpp index 015836f4..b6ca4c7a 100644 --- a/src/SceneGraph/shader/ShaderResource.cpp +++ b/src/SceneGraph/shader/ShaderResource.cpp @@ -1,6 +1,7 @@ #include #include #include +#include VK_NAMESPACE_BEGIN @@ -8,6 +9,8 @@ VK_NAMESPACE_BEGIN namespace { + MapObject 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 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