diff --git a/example/Vulkan/HQFilterTexture.cpp b/example/Vulkan/HQFilterTexture.cpp index fd21041c..692c2669 100644 --- a/example/Vulkan/HQFilterTexture.cpp +++ b/example/Vulkan/HQFilterTexture.cpp @@ -46,18 +46,19 @@ class TestApp:public VulkanApplicationFramework private: vulkan::PipelineData * pipeline_data =nullptr;; + vulkan::Renderable * render_obj =nullptr; struct MP { vulkan::Material * material =nullptr; vulkan::Pipeline * pipeline =nullptr; - vulkan::Renderable * render_obj =nullptr; }mp_normal,mp_hq; struct MIR { MP * mp =nullptr; vulkan::MaterialInstance * material_instance =nullptr; + vulkan::RenderableInstance *renderable_instance =nullptr; }mir_nearest,mir_linear,mir_nearest_hq,mir_linear_hq; vulkan::Texture2D * texture =nullptr; @@ -99,6 +100,18 @@ private: return(true); } + bool InitRenderObject() + { + render_obj=db->CreateRenderable(VERTEX_COUNT); + if(!render_obj)return(false); + + render_obj->Set(VAN::Position,vertex_buffer); + render_obj->Set(VAN::TexCoord,tex_coord_buffer); + render_obj->Set(index_buffer); + + return(true); + } + vulkan::Sampler *InitSampler(VkFilter filter) { VkSamplerCreateInfo sampler_create_info; @@ -139,11 +152,6 @@ private: mp->pipeline=CreatePipeline(mp->material,pipeline_data); if(!mp->pipeline)return(false); - mp->render_obj=db->CreateRenderable(mp->material,VERTEX_COUNT); - mp->render_obj->Set(VAN::Position,vertex_buffer); - mp->render_obj->Set(VAN::TexCoord,tex_coord_buffer); - mp->render_obj->Set(index_buffer); - return(true); } @@ -168,18 +176,17 @@ private: mir->mp=mp; + mir->renderable_instance=db->CreateRenderableInstance(render_obj,mir->material_instance,mp->pipeline); + + if(!mir->renderable_instance) + return(false); + return(true); } bool Add(struct MIR *mir,const Matrix4f &offset) { - RenderableInstance *ri=db->CreateRenderableInstance(mir->mp->pipeline, - mir->material_instance, - mir->mp->render_obj); - - if(!ri)return(false); - - render_root.Add(ri,offset); + render_root.Add(mir->renderable_instance,offset); return(true); } @@ -207,6 +214,9 @@ public: if(!InitVBO()) return(false); + if(!InitRenderObject()) + return(false); + if(!InitTexture()) return(false); diff --git a/example/Vulkan/VulkanAppFramework.h b/example/Vulkan/VulkanAppFramework.h index 3b2309ad..56225295 100644 --- a/example/Vulkan/VulkanAppFramework.h +++ b/example/Vulkan/VulkanAppFramework.h @@ -173,39 +173,39 @@ public: } } - void BuildCommandBuffer(uint32_t index,vulkan::Pipeline *p,vulkan::MaterialInstance *mi,vulkan::Renderable *r) + void BuildCommandBuffer(uint32_t index,vulkan::RenderableInstance *ri) { - if(!p||!mi||!r) + if(!ri) return; - const vulkan::IndexBuffer *ib=r->GetIndexBuffer(); + const vulkan::IndexBuffer *ib=ri->GetIndexBuffer(); vulkan::CommandBuffer *cb=cmd_buf[index]; cb->Begin(); - cb->BeginRenderPass(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); - cb->Bind(p); - cb->Bind(mi->GetDescriptorSets()); - cb->Bind(r); + cb->BeginRenderPass(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index)); + cb->BindPipeline(ri->GetPipeline()); + cb->BindDescriptorSets(ri->GetDescriptorSets()); + cb->BindVAB(ri); - if (ib) - cb->DrawIndexed(ib->GetCount()); - else - cb->Draw(r->GetDrawCount()); + if (ib) + cb->DrawIndexed(ib->GetCount()); + else + cb->Draw(ri->GetDrawCount()); - cb->EndRenderPass(); + cb->EndRenderPass(); cb->End(); } - void BuildCommandBuffer(vulkan::Pipeline *p,vulkan::MaterialInstance *mi,vulkan::Renderable *r) + void BuildCommandBuffer(vulkan::RenderableInstance *ri) { for(int32_t i=0;iGetCurrentFrameIndices(),p,mi,r); + BuildCommandBuffer(sc_render_target->GetCurrentFrameIndices(),ri); } void BuildCommandBuffer(uint32_t index,RenderList *rl) diff --git a/inc/hgl/graph/RenderList.h b/inc/hgl/graph/RenderList.h index c574e7c6..2332a368 100644 --- a/inc/hgl/graph/RenderList.h +++ b/inc/hgl/graph/RenderList.h @@ -9,8 +9,6 @@ namespace hgl { namespace graph { - class RenderableInstance; - class RenderList { vulkan::CommandBuffer *cmd_buf; @@ -22,10 +20,10 @@ namespace hgl vulkan::PushConstant * last_pc; vulkan::Pipeline * last_pipeline; vulkan::MaterialInstance * last_mat_inst; - vulkan::Renderable * last_renderable; + vulkan::RenderableInstance *last_ri; - void Render(SceneNode *,RenderableInstance *); - void Render(SceneNode *,List &); + void Render(SceneNode *,vulkan::RenderableInstance *); + void Render(SceneNode *,List &); public: @@ -35,7 +33,7 @@ namespace hgl last_pc=nullptr; last_pipeline=nullptr; last_mat_inst=nullptr; - last_renderable=nullptr; + last_ri=nullptr; } ~RenderList()=default; diff --git a/inc/hgl/graph/RenderableInstance.h b/inc/hgl/graph/RenderableInstance.h deleted file mode 100644 index 9194be33..00000000 --- a/inc/hgl/graph/RenderableInstance.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE -#define HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE - -#include -#include -#include -namespace hgl -{ - namespace graph - { - /** - * 可渲染对象节点 - */ - class RenderableInstance - { - vulkan::Pipeline * pipeline; - vulkan::MaterialInstance *mat_inst; - vulkan::Renderable * render_obj; - - public: - - RenderableInstance(vulkan::Pipeline *p,vulkan::MaterialInstance *mi,vulkan::Renderable *r):pipeline(p),mat_inst(mi),render_obj(r){} - virtual ~RenderableInstance() - { - //需要在这里添加删除pipeline/desc_sets/render_obj引用计数的代码 - } - - vulkan::Pipeline * GetPipeline (){return pipeline;} - vulkan::MaterialInstance * GetMaterialInstance (){return mat_inst;} - vulkan::Renderable * GetRenderable (){return render_obj;} - const AABB & GetBoundingBox ()const{return render_obj->GetBoundingBox();} - - const int Comp(const RenderableInstance *ri)const - { - //绘制顺序: - - // ARM Mali GPU : 不透明、AlphaTest、半透明 - // Adreno/NV/AMD: AlphaTest、不透明、半透明 - // PowerVR: 同Adreno/NV/AMD,但不透明部分可以不排序 - - if(pipeline->IsAlphaBlend()) - { - if(!ri->pipeline->IsAlphaBlend()) - return 1; - } - else - { - if(ri->pipeline->IsAlphaBlend()) - return -1; - } - - if(pipeline->IsAlphaTest()) - { - if(!ri->pipeline->IsAlphaTest()) - return 1; - } - else - { - if(ri->pipeline->IsAlphaTest()) - return -1; - } - - if(pipeline!=ri->pipeline) - return pipeline-ri->pipeline; - - if(mat_inst!=ri->mat_inst) - return int64(mat_inst)-int64(ri->mat_inst); - - return render_obj-ri->render_obj; - } - - CompOperator(const RenderableInstance *,Comp) - };//class RenderableInstance - }//namespace graph -}//namespace hgl -#endif//HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index 3a6336cd..b4c11644 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -11,7 +11,6 @@ namespace hgl class SceneNode; struct Camera; class RenderList; - class RenderableInstance; using RenderListCompFunc=float (*)(Camera *,SceneNode *,SceneNode *); ///<渲染列表排序比较函数 @@ -41,7 +40,7 @@ namespace hgl ObjectList SubNode; ///<子节点 - List renderable_instances; ///<可渲染实例 + List renderable_instances; ///<可渲染实例 public: @@ -75,9 +74,9 @@ namespace hgl void Add(SceneNode *n){if(n)SubNode.Add(n);} ///<增加一个子节点 void ClearSubNode(){SubNode.ClearData();} ///<清除子节点 - void Add(RenderableInstance *ri){if(ri)renderable_instances.Add(ri);} ///<增加渲染实例 + void Add(vulkan::RenderableInstance *ri){if(ri)renderable_instances.Add(ri);} ///<增加渲染实例 - void Add(RenderableInstance *ri,const Matrix4f &mat) + void Add(vulkan::RenderableInstance *ri,const Matrix4f &mat) { SceneNode *sn=new SceneNode(mat); diff --git a/inc/hgl/graph/VertexAttribDataAccess.h b/inc/hgl/graph/VertexAttribDataAccess.h index ea493a0e..3c5c9c83 100644 --- a/inc/hgl/graph/VertexAttribDataAccess.h +++ b/inc/hgl/graph/VertexAttribDataAccess.h @@ -60,7 +60,7 @@ namespace hgl { if(!data||offset>=count) { - LOG_HINT(OS_TEXT("VertexAttribBuffer::Get() out,offset:")+OSString::valueOf(offset)); + LOG_HINT(OS_TEXT("VertexAttribDataAccess::Get() out,offset:")+OSString::valueOf(offset)); return(nullptr); } @@ -76,7 +76,7 @@ namespace hgl { if(access) { - LOG_HINT(OS_TEXT("VertexAttribBuffer::Begin() access!=0,offset:")+OSString::valueOf(offset)); + LOG_HINT(OS_TEXT("VertexAttribDataAccess::Begin() access!=0,offset:")+OSString::valueOf(offset)); return(nullptr); } @@ -106,7 +106,7 @@ namespace hgl { if(!this->access||this->access+C*number>this->data_end) { - LOG_HINT(OS_TEXT("VertexAttribBuffer::Write(const T *,number) out,number:")+OSString::valueOf(number)); + LOG_HINT(OS_TEXT("VertexAttribDataAccess::Write(const T *,number) out,number:")+OSString::valueOf(number)); return(false); } @@ -116,7 +116,7 @@ namespace hgl return(true); } - };//class VertexAttribBuffer + };//class VertexAttribDataAccess /** * 一元数据缓冲区 diff --git a/inc/hgl/graph/vulkan/VK.h b/inc/hgl/graph/vulkan/VK.h index 0529d47e..ce9d4fd4 100644 --- a/inc/hgl/graph/vulkan/VK.h +++ b/inc/hgl/graph/vulkan/VK.h @@ -63,6 +63,7 @@ class DescriptorSets; class VertexAttributeBinding; class Renderable; +class RenderableInstance; class Database; diff --git a/inc/hgl/graph/vulkan/VKCommandBuffer.h b/inc/hgl/graph/vulkan/VKCommandBuffer.h index 1a64efb2..67498b84 100644 --- a/inc/hgl/graph/vulkan/VKCommandBuffer.h +++ b/inc/hgl/graph/vulkan/VKCommandBuffer.h @@ -98,7 +98,7 @@ public: bool BeginRenderPass(VkRenderPass rp,VkFramebuffer fb); bool BeginRenderPass(RenderTarget *rt); - bool Bind(Pipeline *p) + bool BindPipeline(Pipeline *p) { if(!p)return(false); @@ -106,7 +106,7 @@ public: return(true); } - bool Bind(DescriptorSets *dsl) + bool BindDescriptorSets(DescriptorSets *dsl) { if(!dsl)return(false); @@ -124,7 +124,7 @@ public: void PushConstants(const void *data,const uint32_t size){vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0,size,data);} - bool Bind(Renderable *); + bool BindVAB(RenderableInstance *); void SetViewport (uint32_t first,uint32_t count,const VkViewport *vp) {vkCmdSetViewport(cmd_buf,first,count,vp);} void SetScissor (uint32_t first,uint32_t count,const VkRect2D *sci) {vkCmdSetScissor(cmd_buf,first,count,sci);} diff --git a/inc/hgl/graph/vulkan/VKDatabase.h b/inc/hgl/graph/vulkan/VKDatabase.h index ad700a66..aca440cb 100644 --- a/inc/hgl/graph/vulkan/VKDatabase.h +++ b/inc/hgl/graph/vulkan/VKDatabase.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include VK_NAMESPACE_BEGIN @@ -103,11 +103,10 @@ public: //Material 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(MaterialInstance *,const uint32_t vertex_count=0); + Renderable * CreateRenderable(const uint32_t vertex_count=0); TextRenderable * CreateTextRenderable(Material *); - RenderableInstance *CreateRenderableInstance(Pipeline *p,MaterialInstance *mi,Renderable *r); + RenderableInstance *CreateRenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p); Sampler * CreateSampler(VkSamplerCreateInfo *sci=nullptr); diff --git a/inc/hgl/graph/vulkan/VKMaterial.h b/inc/hgl/graph/vulkan/VKMaterial.h index cafadc69..d9639dff 100644 --- a/inc/hgl/graph/vulkan/VKMaterial.h +++ b/inc/hgl/graph/vulkan/VKMaterial.h @@ -62,7 +62,6 @@ public: public: - Renderable * CreateRenderable (const uint32_t draw_count=0); MaterialInstance * CreateInstance (); };//class Material VK_NAMESPACE_END diff --git a/inc/hgl/graph/vulkan/VKRenderable.h b/inc/hgl/graph/vulkan/VKRenderable.h index e343c266..dfbff3ab 100644 --- a/inc/hgl/graph/vulkan/VKRenderable.h +++ b/inc/hgl/graph/vulkan/VKRenderable.h @@ -3,6 +3,7 @@ #include #include +#include #include #include VK_NAMESPACE_BEGIN @@ -13,12 +14,18 @@ VK_NAMESPACE_BEGIN */ class Renderable { - const VertexShaderModule *vertex_sm; + struct BufferData + { + VAB *buf; + VkDeviceSize offset; - int buf_count; - VkBuffer *buf_list=nullptr; - VkDeviceSize *buf_offset=nullptr; + public: + CompOperatorMemcmp(const BufferData &); + }; + + Map buffer_list; + protected: uint32_t draw_count; @@ -41,16 +48,15 @@ protected: public: - Renderable(const VertexShaderModule *,const uint32_t dc=0); - virtual ~Renderable(); + Renderable(const uint32_t dc=0):draw_count(dc){} + virtual ~Renderable()=default; const uint GetRefCount()const{return ref_count;} void SetBoundingBox(const AABB &aabb){BoundingBox=aabb;} const AABB &GetBoundingBox()const {return BoundingBox;} - bool Set(const int stage_input_binding, VAB *vb,VkDeviceSize offset=0); - bool Set(const AnsiString &name, VAB *vb,VkDeviceSize offset=0); + bool Set(const UTF8String &name,VAB *vb,VkDeviceSize offset=0); bool Set(IndexBuffer *ib,VkDeviceSize offset=0) { @@ -72,12 +78,12 @@ public: return draw_count; } - const int GetBufferCount ()const{return buf_count;} - const VkBuffer * GetBuffer ()const{return buf_list;} - const VkDeviceSize * GetOffset ()const{return buf_offset;} + VAB * GetVAB(const UTF8String &,VkDeviceSize *); + VkBuffer GetBuffer(const UTF8String &,VkDeviceSize *); + const int GetBufferCount()const{return buffer_list.GetCount();} - IndexBuffer * GetIndexBuffer() {return indices_buffer;} - const VkDeviceSize GetIndexOffset()const{return indices_offset;} + IndexBuffer * GetIndexBuffer() {return indices_buffer;} + const VkDeviceSize GetIndexBufferOffset()const {return indices_offset;} };//class Renderable VK_NAMESPACE_END #endif//HGL_GRAPH_VULKAN_RENDERABLE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKRenderableInstance.h b/inc/hgl/graph/vulkan/VKRenderableInstance.h new file mode 100644 index 00000000..fd117ab1 --- /dev/null +++ b/inc/hgl/graph/vulkan/VKRenderableInstance.h @@ -0,0 +1,92 @@ +#ifndef HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE +#define HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE + +#include +#include +#include +#include +VK_NAMESPACE_BEGIN +/** +* 可渲染对象节点 +*/ +class RenderableInstance +{ + Pipeline * pipeline; + MaterialInstance *mat_inst; + Renderable * render_obj; + + uint32_t buffer_count; + VkBuffer *buffer_list; + VkDeviceSize *buffer_size; + +private: + + friend RenderableInstance *CreateRenderableInstance(Renderable *,MaterialInstance *,Pipeline *); + + RenderableInstance(Renderable *,MaterialInstance *,Pipeline *,const uint32_t,VkBuffer *,VkDeviceSize *); + +public: + + virtual ~RenderableInstance(); + + vulkan::Pipeline * GetPipeline (){return pipeline;} + vulkan::MaterialInstance * GetMaterialInstance (){return mat_inst;} + vulkan::Renderable * GetRenderable (){return render_obj;} + const AABB & GetBoundingBox ()const{return render_obj->GetBoundingBox();} + + const uint32_t GetBufferCount ()const{return buffer_count;} + VkBuffer * GetBuffer ()const{return buffer_list;} + VkDeviceSize * GetBufferSize ()const{return buffer_size;} + IndexBuffer * GetIndexBuffer ()const{return render_obj->GetIndexBuffer();} + const uint32_t GetIndexBufferOffset ()const{return render_obj->GetIndexBufferOffset();} + const uint32_t GetDrawCount ()const{return render_obj->GetDrawCount();} + + DescriptorSets *GetDescriptorSets ()const{return mat_inst->GetDescriptorSets();} + +public: + + const int Comp(const RenderableInstance *ri)const + { + //绘制顺序: + + // ARM Mali GPU : 不透明、AlphaTest、半透明 + // Adreno/NV/AMD: AlphaTest、不透明、半透明 + // PowerVR: 同Adreno/NV/AMD,但不透明部分可以不排序 + + if(pipeline->IsAlphaBlend()) + { + if(!ri->pipeline->IsAlphaBlend()) + return 1; + } + else + { + if(ri->pipeline->IsAlphaBlend()) + return -1; + } + + if(pipeline->IsAlphaTest()) + { + if(!ri->pipeline->IsAlphaTest()) + return 1; + } + else + { + if(ri->pipeline->IsAlphaTest()) + return -1; + } + + if(pipeline!=ri->pipeline) + return pipeline-ri->pipeline; + + if(mat_inst!=ri->mat_inst) + return int64(mat_inst)-int64(ri->mat_inst); + + return render_obj-ri->render_obj; + } + + CompOperator(const RenderableInstance *,Comp) +};//class RenderableInstance + +RenderableInstance *CreateRenderableInstance(Renderable *,MaterialInstance *,Pipeline *); +VK_NAMESPACE_END +#endif//HGL_GRAPH_RENDERABLE_INSTANCE_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKShaderModule.h b/inc/hgl/graph/vulkan/VKShaderModule.h index 15dc8804..b623a4c1 100644 --- a/inc/hgl/graph/vulkan/VKShaderModule.h +++ b/inc/hgl/graph/vulkan/VKShaderModule.h @@ -80,7 +80,8 @@ public: */ const int GetStageInputBinding(const AnsiString &name)const{return shader_resource->GetStageInputBinding(name);} const ShaderStage * GetStageInput (const AnsiString &name)const{return shader_resource->GetStageInput(name);} - const uint GetStageInputCount () const{return shader_resource->GetStageInputCount();} + const uint GetStageInputCount () const{return shader_resource->GetStageInputCount();} + const ShaderStageList & GetStageInputs () const{return shader_resource->GetStageInputs();} const uint32_t GetAttrCount()const{return attr_count;} diff --git a/src/RenderDevice/Vulkan/CMakeLists.txt b/src/RenderDevice/Vulkan/CMakeLists.txt index 05edb4e4..862ade24 100644 --- a/src/RenderDevice/Vulkan/CMakeLists.txt +++ b/src/RenderDevice/Vulkan/CMakeLists.txt @@ -88,8 +88,10 @@ SOURCE_GROUP("Render Pass" FILES ${VK_RENDER_PASS_SOURCE}) SET(VK_RENDERABLE_SOURCE ${RD_INCLUDE_PATH}/VKVertexAttributeBinding.h ${RD_INCLUDE_PATH}/VKRenderable.h + ${RD_INCLUDE_PATH}/VKRenderableInstance.h VKVertexAttributeBinding.cpp VKRenderable.cpp + VKRenderableInstance.cpp VKTileData.cpp VKTileFont.cpp) diff --git a/src/RenderDevice/Vulkan/VKCommandBuffer.cpp b/src/RenderDevice/Vulkan/VKCommandBuffer.cpp index 1ea208ca..f0feffdc 100644 --- a/src/RenderDevice/Vulkan/VKCommandBuffer.cpp +++ b/src/RenderDevice/Vulkan/VKCommandBuffer.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include VK_NAMESPACE_BEGIN @@ -102,22 +103,22 @@ bool CommandBuffer::BeginRenderPass(RenderTarget *rt) return BeginRenderPass(rt->GetRenderPass(),rt->GetFramebuffer()); } -bool CommandBuffer::Bind(Renderable *render_obj) +bool CommandBuffer::BindVAB(RenderableInstance *ri) { - if(!render_obj) + if(!ri) return(false); - const uint count=render_obj->GetBufferCount(); + const uint count=ri->GetBufferCount(); if(count<=0) return(false); - vkCmdBindVertexBuffers(cmd_buf,0,count,render_obj->GetBuffer(),render_obj->GetOffset()); + vkCmdBindVertexBuffers(cmd_buf,0,count,ri->GetBuffer(),ri->GetBufferSize()); - IndexBuffer *indices_buffer=render_obj->GetIndexBuffer(); + IndexBuffer *indices_buffer=ri->GetIndexBuffer(); if(indices_buffer) - vkCmdBindIndexBuffer(cmd_buf,indices_buffer->GetBuffer(),render_obj->GetIndexOffset(),VkIndexType(indices_buffer->GetType())); + vkCmdBindIndexBuffer(cmd_buf,indices_buffer->GetBuffer(),ri->GetIndexBufferOffset(),VkIndexType(indices_buffer->GetType())); return(true); } diff --git a/src/RenderDevice/Vulkan/VKDatabase.cpp b/src/RenderDevice/Vulkan/VKDatabase.cpp index 29436547..ab160087 100644 --- a/src/RenderDevice/Vulkan/VKDatabase.cpp +++ b/src/RenderDevice/Vulkan/VKDatabase.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include VK_NAMESPACE_BEGIN VAB *Database::CreateVAB(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode) @@ -101,11 +101,11 @@ Pipeline *Database::CreatePipeline(MaterialInstance *mi,RenderTarget *rt,const O return CreatePipeline(mi->GetMaterial(),rt,filename,prim,prim_restart); } -Renderable *Database::CreateRenderable(Material *mtl,const uint32_t vertex_count) +Renderable *Database::CreateRenderable(const uint32_t vertex_count) { - if(!mtl)return(nullptr); + if(!vertex_count)return(nullptr); - Renderable *ro=mtl->CreateRenderable(vertex_count); + Renderable *ro=new Renderable(vertex_count); if(ro) Add(ro); @@ -113,13 +113,6 @@ Renderable *Database::CreateRenderable(Material *mtl,const uint32_t vertex_count return ro; } -Renderable *Database::CreateRenderable(MaterialInstance *mi,const uint32_t vertex_count) -{ - if(!mi)return(nullptr); - - return CreateRenderable(mi->GetMaterial(),vertex_count); -} - TextRenderable *Database::CreateTextRenderable(Material *mtl) { if(!mtl)return(nullptr); @@ -132,12 +125,12 @@ TextRenderable *Database::CreateTextRenderable(Material *mtl) return tr; } -RenderableInstance *Database::CreateRenderableInstance(Pipeline *p,MaterialInstance *mi,Renderable *r) +RenderableInstance *Database::CreateRenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p) { if(!p||!mi||!r) return(nullptr); - RenderableInstance *ri=new RenderableInstance(p,mi,r); + RenderableInstance *ri=VK_NAMESPACE::CreateRenderableInstance(r,mi,p); if(ri) Add(ri); diff --git a/src/RenderDevice/Vulkan/VKMaterial.cpp b/src/RenderDevice/Vulkan/VKMaterial.cpp index c1b06279..c118c942 100644 --- a/src/RenderDevice/Vulkan/VKMaterial.cpp +++ b/src/RenderDevice/Vulkan/VKMaterial.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include"VKDescriptorSetLayoutCreater.h" VK_NAMESPACE_BEGIN @@ -154,9 +153,4 @@ DescriptorSets *Material::CreateDescriptorSets()const { return dsl_creater->Create(); } - -Renderable *Material::CreateRenderable(const uint32_t draw_count) -{ - return(new Renderable(vertex_sm,draw_count)); -} VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKRenderable.cpp b/src/RenderDevice/Vulkan/VKRenderable.cpp index 7aebc97f..3387634f 100644 --- a/src/RenderDevice/Vulkan/VKRenderable.cpp +++ b/src/RenderDevice/Vulkan/VKRenderable.cpp @@ -3,43 +3,60 @@ #include VK_NAMESPACE_BEGIN -Renderable::Renderable(const VertexShaderModule *vsm,const uint32_t dc) +//bool Renderable::Set(const int stage_input_binding,VAB *vab,VkDeviceSize offset) +//{ +// if(stage_input_binding<0||stage_input_binding>=buf_count||!vab)return(false); +// +// const VkVertexInputBindingDescription *desc=vertex_sm->GetDesc(stage_input_binding); +// const VkVertexInputAttributeDescription *attr=vertex_sm->GetAttr(stage_input_binding); +// +// if(vab->GetFormat()!=attr->format)return(false); +// if(vab->GetStride()!=desc->stride)return(false); +// +// //format信息来自于shader,实际中可以不一样。但那样需要为每一个格式产生一个同样shader的material instance,不同的格式又需要不同的pipeline,我们不支持这种行为 +// +// buf_list[stage_input_binding]=vab->GetBuffer(); +// buf_offset[stage_input_binding]=offset; +// +// return(true); +//} + +bool Renderable::Set(const UTF8String &name,VAB *vab,VkDeviceSize offset) { - vertex_sm=vsm; - draw_count=dc; + if(!vab)return(false); + if(buffer_list.KeyExist(name))return(false); - buf_count=vertex_sm->GetAttrCount(); - - buf_list=hgl_zero_new(buf_count); - buf_offset=hgl_zero_new(buf_count); -} - -Renderable::~Renderable() -{ - delete[] buf_offset; - delete[] buf_list; -} - -bool Renderable::Set(const int stage_input_binding,VAB *vab,VkDeviceSize offset) -{ - if(stage_input_binding<0||stage_input_binding>=buf_count||!vab)return(false); - - const VkVertexInputBindingDescription *desc=vertex_sm->GetDesc(stage_input_binding); - const VkVertexInputAttributeDescription *attr=vertex_sm->GetAttr(stage_input_binding); - - if(vab->GetFormat()!=attr->format)return(false); - if(vab->GetStride()!=desc->stride)return(false); - - //format信息来自于shader,实际中可以不一样。但那样需要为每一个格式产生一个同样shader的material instance,不同的格式又需要不同的pipeline,我们不支持这种行为 - - buf_list[stage_input_binding]=vab->GetBuffer(); - buf_offset[stage_input_binding]=offset; + BufferData bd; + + bd.buf=vab; + bd.offset=offset; + buffer_list.Add(name,bd); return(true); } -bool Renderable::Set(const AnsiString &name,VAB *vab,VkDeviceSize offset) +VAB *Renderable::GetVAB(const UTF8String &name,VkDeviceSize *offset) { - return Set(vertex_sm->GetStageInputBinding(name),vab,offset); + if(!offset)return(nullptr); + if(name.IsEmpty())return(nullptr); + + BufferData bd; + + if(buffer_list.Get(name,bd)) + { + *offset=bd.offset; + return bd.buf; + } + + return(nullptr); +} + +VkBuffer Renderable::GetBuffer(const UTF8String &name,VkDeviceSize *offset) +{ + VAB *vab=GetVAB(name,offset); + + if(vab)return vab->GetBuffer(); + + return(VK_NULL_HANDLE); } VK_NAMESPACE_END diff --git a/src/RenderDevice/Vulkan/VKRenderableInstance.cpp b/src/RenderDevice/Vulkan/VKRenderableInstance.cpp new file mode 100644 index 00000000..6f85f17b --- /dev/null +++ b/src/RenderDevice/Vulkan/VKRenderableInstance.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +VK_NAMESPACE_BEGIN +RenderableInstance::RenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p,const uint32_t count,VkBuffer *bl,VkDeviceSize *bs) +{ + render_obj=r; + mat_inst=mi; + pipeline=p; + + buffer_count=count; + buffer_list=bl; + buffer_size=bs; +} + +RenderableInstance::~RenderableInstance() +{ + //需要在这里添加删除pipeline/desc_sets/render_obj引用计数的代码 + + delete[] buffer_list; + delete[] buffer_size; +} + +RenderableInstance *CreateRenderableInstance(Renderable *r,MaterialInstance *mi,Pipeline *p) +{ + if(!r||!mi||!p)return(nullptr); + + Material *mtl=mi->GetMaterial(); + + if(!mtl)return(nullptr); + + const VertexShaderModule *vsm=mtl->GetVertexShaderModule(); + const ShaderStageList &ssl=vsm->GetStageInputs(); + const int input_count=ssl.GetCount(); + + if(r->GetBufferCount() buffer_list=new VkBuffer[input_count]; + AutoDeleteArray buffer_size=new VkDeviceSize[input_count]; + + ShaderStage **ss=ssl.GetData(); + + VAB *vab; + const VkVertexInputBindingDescription *desc; + const VkVertexInputAttributeDescription *attr; + + for(uint i=0;iGetDesc(i); + attr=vsm->GetAttr(i); + + vab=r->GetVAB((*ss)->name,buffer_size+i); + + if(!vab)return(nullptr); + + if(vab->GetFormat()!=attr->format)return(nullptr); + if(vab->GetStride()!=desc->stride)return(nullptr); + + buffer_list[i]=vab->GetBuffer(); + + ++ss; + } + + RenderableInstance *ri=new RenderableInstance(r,mi,p,input_count,buffer_list,buffer_size); + buffer_list.Discard(); + buffer_size.Discard(); + return ri; +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 7cd4babf..357acab3 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -29,7 +29,6 @@ SOURCE_GROUP("Tile" FILES ${TILE_SOURCE}) SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h - ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableInstance.h ${ROOT_INCLUDE_PATH}/hgl/graph/RenderList.h ${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h #${ROOT_INCLUDE_PATH}/hgl/graph/Mesh.h diff --git a/src/SceneGraph/RenderList.cpp b/src/SceneGraph/RenderList.cpp index c510b90e..cc6bcc16 100644 --- a/src/SceneGraph/RenderList.cpp +++ b/src/SceneGraph/RenderList.cpp @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include namespace hgl { @@ -27,13 +27,13 @@ namespace hgl // return (((Frustum *)fc)->BoxIn(node->GetWorldBoundingBox())!=Frustum::OUTSIDE); //} - void RenderList::Render(SceneNode *node,RenderableInstance *ri) + void RenderList::Render(SceneNode *node,vulkan::RenderableInstance *ri) { if(last_pipeline!=ri->GetPipeline()) { last_pipeline=ri->GetPipeline(); - cmd_buf->Bind(last_pipeline); + cmd_buf->BindPipeline(last_pipeline); last_mat_inst=nullptr; } @@ -42,7 +42,7 @@ namespace hgl { last_mat_inst=ri->GetMaterialInstance(); - cmd_buf->Bind(last_mat_inst->GetDescriptorSets()); + cmd_buf->BindDescriptorSets(last_mat_inst->GetDescriptorSets()); } if(last_pc!=node->GetPushConstant()) @@ -54,16 +54,14 @@ namespace hgl //更新fin_mvp - vulkan::Renderable *obj=ri->GetRenderable(); - - if(obj!=last_renderable) + if(ri!=last_ri) { - cmd_buf->Bind(obj); + cmd_buf->BindVAB(ri); - last_renderable=obj; + last_ri=ri; } - const vulkan::IndexBuffer *ib=obj->GetIndexBuffer(); + const vulkan::IndexBuffer *ib=ri->GetIndexBuffer(); if(ib) { @@ -71,14 +69,14 @@ namespace hgl } else { - cmd_buf->Draw(obj->GetDrawCount()); + cmd_buf->Draw(ri->GetDrawCount()); } } - void RenderList::Render(SceneNode *node,List &ri_list) + void RenderList::Render(SceneNode *node,List &ri_list) { const int count=ri_list.GetCount(); - RenderableInstance **ri=ri_list.GetData(); + vulkan::RenderableInstance **ri=ri_list.GetData(); for(int i=0;iCreateRenderable(vertices_number); + vulkan::Renderable *render_obj=db->CreateRenderable(vertices_number); const auto *sp=vab_maps.GetDataList(); for(uint i=0;iright->vab) - render_obj->Set((*sp)->right->binding,(*sp)->right->vab); + render_obj->Set((*sp)->left,(*sp)->right->vab); else - render_obj->Set((*sp)->right->binding,db->CreateVAB((*sp)->right->data)); + render_obj->Set((*sp)->left,db->CreateVAB((*sp)->right->data)); ++sp; } diff --git a/src/SceneGraph/font/TextRenderable.cpp b/src/SceneGraph/font/TextRenderable.cpp index e71e7df2..877b2e06 100644 --- a/src/SceneGraph/font/TextRenderable.cpp +++ b/src/SceneGraph/font/TextRenderable.cpp @@ -6,7 +6,7 @@ namespace hgl { namespace graph { - TextRenderable::TextRenderable(vulkan::Device *dev,vulkan::Material *m,uint mc):vulkan::Renderable(m->GetVertexShaderModule(),mc) + TextRenderable::TextRenderable(vulkan::Device *dev,vulkan::Material *m,uint mc):vulkan::Renderable(mc) { device=dev; mtl=m;