diff --git a/example/Vulkan/Deferred.cpp b/example/Vulkan/Deferred.cpp index 9b97bf9d..c9a58614 100644 --- a/example/Vulkan/Deferred.cpp +++ b/example/Vulkan/Deferred.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include using namespace hgl; using namespace hgl::graph; @@ -21,6 +24,8 @@ struct AtomsphereData float scattering_direction; };// +using Texture2DPointer=vulkan::Texture2D *; + class TestApp:public CameraAppFramework { private: @@ -28,6 +33,38 @@ private: SceneNode render_root; RenderList render_list; + struct DeferredGBuffer + { + uint32_t width,height; + vulkan::Framebuffer *framebuffer; + vulkan::RenderPass *renderpass; + + union + { + struct + { + Texture2DPointer position,normal,albedo,depth; + }; + + Texture2DPointer texture_list[4]; + }; + + List color_format_list; + List image_view_list; + + struct + { + List desc_list; + List ref_list; + }attachment; + + struct + { + List desc; + List dependency; + }subpass; + }gbuffer;// + struct SubpassParam { vulkan::Material * material; @@ -42,6 +79,53 @@ private: private: + bool InitGBuffer() + { + gbuffer.width=power_to_2(SCREEN_WIDTH); + gbuffer.height=power_to_2(SCREEN_HEIGHT); + + gbuffer.position=device->CreateTexture2DColor(FMT_RGB32F, gbuffer.width,gbuffer.height); + gbuffer.normal =device->CreateTexture2DColor(FMT_RGB32F, gbuffer.width,gbuffer.height); + gbuffer.albedo =device->CreateTexture2DColor(FMT_RGB32F, gbuffer.width,gbuffer.height); + gbuffer.depth =device->CreateTexture2DDepth(FMT_D32F, gbuffer.width,gbuffer.height); + + for(uint i=0;i<3;i++) + { + gbuffer.color_format_list.Add(gbuffer.texture_list[i]->GetFormat()); + gbuffer.image_view_list.Add(gbuffer.texture_list[i]->GetImageView()); + } + + if(!device->CreateAttachment( gbuffer.attachment.ref_list, + gbuffer.attachment.desc_list, + gbuffer.color_format_list, + gbuffer.depth->GetFormat())) + return(false); + + VkSubpassDescription desc; + + device->CreateSubpassDescription(desc,gbuffer.attachment.ref_list); + + gbuffer.subpass.desc.Add(desc); + + device->CreateSubpassDependency(gbuffer.subpass.dependency,2); + + gbuffer.renderpass=device->CreateRenderPass(gbuffer.attachment.desc_list, + gbuffer.subpass.desc, + gbuffer.subpass.dependency, + gbuffer.color_format_list, + gbuffer.depth->GetFormat()); + + if(!gbuffer.renderpass) + return(false); + + gbuffer.framebuffer=vulkan::CreateFramebuffer(device,gbuffer.renderpass,gbuffer.image_view_list); + + if(!gbuffer.framebuffer) + return(false); + + return(true); + } + bool InitSubpass(SubpassParam *sp,const OSString &vs,const OSString &fs) { sp->material=shader_manage->CreateMaterial(vs,fs); @@ -58,7 +142,7 @@ private: bool InitGBufferPipeline(SubpassParam *sp) { - vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,sp->material,device->GetMainRenderPass(),device->GetExtent()); + vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,sp->material,gbuffer.renderpass,device->GetExtent()); pipeline_creater->SetDepthTest(true); pipeline_creater->SetDepthWrite(true); pipeline_creater->SetCullMode(VK_CULL_MODE_BACK_BIT); diff --git a/inc/hgl/graph/vulkan/VKDevice.h b/inc/hgl/graph/vulkan/VKDevice.h index 3cd00c99..e9d5aa31 100644 --- a/inc/hgl/graph/vulkan/VKDevice.h +++ b/inc/hgl/graph/vulkan/VKDevice.h @@ -166,17 +166,18 @@ public: //Command Buffer 相关 CommandBuffer * CreateCommandBuffer(); - void CreateSubpassDependency(List &dependency,const uint32_t count); - bool CreateAttachment( List &ref_list, List &desc_list, const List &color_format, const VkFormat depth_format, const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; - bool CreateColorAttachment( List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - bool CreateDepthAttachment( List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + bool CreateColorAttachment( List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)const; + bool CreateDepthAttachment( List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; + + void CreateSubpassDependency(List &dependency,const uint32_t count)const; + void CreateSubpassDescription(VkSubpassDescription &,const List &)const; RenderPass * CreateRenderPass( const List &desc_list, const List &subpass, @@ -184,12 +185,12 @@ public: //Command Buffer 相关 const List &color_format, const VkFormat depth_format, const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; RenderPass * CreateRenderPass( const VkFormat color_format, const VkFormat depth_format, const VkImageLayout color_final_layout=VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + const VkImageLayout depth_final_layout=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)const; Fence * CreateFence(bool); Semaphore * CreateSem(); diff --git a/inc/hgl/graph/vulkan/VKFramebuffer.h b/inc/hgl/graph/vulkan/VKFramebuffer.h index 600324d1..7b38a2c4 100644 --- a/inc/hgl/graph/vulkan/VKFramebuffer.h +++ b/inc/hgl/graph/vulkan/VKFramebuffer.h @@ -26,7 +26,8 @@ public: operator VkFramebuffer(){return frame_buffer;} };//class Framebuffer -Framebuffer *CreateFramebuffer(Device *,RenderPass *,List color,ImageView *depth=nullptr); +Framebuffer *CreateFramebuffer(Device *,RenderPass *,List &color,ImageView *depth); +Framebuffer *CreateFramebuffer(Device *,RenderPass *,List &image_view_list); Framebuffer *CreateFramebuffer(Device *,RenderPass *,ImageView *color,ImageView *depth=nullptr); Framebuffer *CreateFramebuffer(Device *,RenderPass *,ImageView *depth); VK_NAMESPACE_END diff --git a/inc/hgl/graph/vulkan/VKTexture.h b/inc/hgl/graph/vulkan/VKTexture.h index 1a24293a..9a4ce6b4 100644 --- a/inc/hgl/graph/vulkan/VKTexture.h +++ b/inc/hgl/graph/vulkan/VKTexture.h @@ -37,6 +37,8 @@ public: operator Memory * (){return data?data->memory:nullptr;} operator ImageView * (){return data?data->image_view:nullptr;} + ImageView * GetImageView(){return data?data->image_view:nullptr;} + const uint32 GetMipLevels()const{return data?data->mip_levels:0;} const bool IsLinear ()const{return data?data->linear:false;} diff --git a/inc/hgl/type/List.h b/inc/hgl/type/List.h index 8b324d1d..874cb18b 100644 --- a/inc/hgl/type/List.h +++ b/inc/hgl/type/List.h @@ -62,7 +62,12 @@ namespace hgl virtual void operator << (const T &obj){Add(obj);} ///<操作符重载添加一个数据 virtual void operator -= (const T &obj){DeleteByValue(obj);} ///<操作符重载删除一个数据 - T * GetPointer(const int index) ///<取得指定序列号数据的索引 + T * GetPointer(const int index) ///<取得指定序列号数据的索引 + { + return(index>=count?nullptr:items+index); + } + + const T * GetPointer(const int index) const ///<取得指定序列号数据的索引 { return(index>=count?nullptr:items+index); } diff --git a/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp b/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp index aad795a6..a9de3e80 100644 --- a/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp +++ b/src/RenderDevice/Vulkan/VKDeviceRenderPass.cpp @@ -3,7 +3,7 @@ #include VK_NAMESPACE_BEGIN -void Device::CreateSubpassDependency(List &subpass_dependency_list,const uint32_t count) +void Device::CreateSubpassDependency(List &subpass_dependency_list,const uint32_t count) const { if(count==1) { @@ -62,7 +62,7 @@ void Device::CreateSubpassDependency(List &subpass_dependen } } -bool Device::CreateAttachment(List &ref_list,List &desc_list,const List &color_format,const VkFormat depth_format,VkImageLayout color_final_layout,VkImageLayout depth_final_layout) +bool Device::CreateAttachment(List &ref_list,List &desc_list,const List &color_format,const VkFormat depth_format,VkImageLayout color_final_layout,VkImageLayout depth_final_layout) const { uint atta_count=color_format.GetCount(); @@ -84,7 +84,7 @@ bool Device::CreateAttachment(List &ref_list,List &ref_list,List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout) +bool Device::CreateColorAttachment( List &ref_list,List &desc_list,const List &color_format,const VkImageLayout color_final_layout) const { const VkFormat *cf=color_format.GetData(); - for(uint i=0;iphysical_device->IsColorAttachmentOptimal(*cf)) return(false); @@ -121,7 +121,7 @@ bool Device::CreateColorAttachment( List &ref_list,Listflags = 0; desc->samples = VK_SAMPLE_COUNT_1_BIT; @@ -141,7 +141,7 @@ bool Device::CreateColorAttachment( List &ref_list,List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout) +bool Device::CreateDepthAttachment( List &ref_list,List &desc_list,const VkFormat &depth_format,const VkImageLayout depth_final_layout) const { if(!attr->physical_device->IsDepthAttachmentOptimal(depth_format)) return(false); @@ -171,18 +171,37 @@ bool Device::CreateDepthAttachment( List &ref_list,List &ref_list) const +{ + const VkAttachmentReference *end_ref=ref_list.GetPointer(ref_list.GetCount()-1); + + if(end_ref->layout==VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) //最后一个是深度 + { + sd.colorAttachmentCount =ref_list.GetCount()-1; + sd.pDepthStencilAttachment =end_ref; + } + else + { + sd.colorAttachmentCount =ref_list.GetCount(); + sd.pDepthStencilAttachment =nullptr; + } + + sd.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + sd.pColorAttachments = ref_list.GetData(); +} + RenderPass *Device::CreateRenderPass( const List &desc_list, const List &subpass, const List &dependency, const List &color_format, const VkFormat depth_format, const VkImageLayout color_final_layout, - const VkImageLayout depth_final_layout) + const VkImageLayout depth_final_layout) const { { const VkFormat *cf=color_format.GetData(); - for(uint i=0;iphysical_device->IsColorAttachmentOptimal(*cf)) return(false); @@ -212,7 +231,7 @@ RenderPass *Device::CreateRenderPass( const List &des return(new RenderPass(attr->device,render_pass,color_format,depth_format)); } -RenderPass *Device::CreateRenderPass(VkFormat color_format,VkFormat depth_format,VkImageLayout color_final_layout,VkImageLayout depth_final_layout) +RenderPass *Device::CreateRenderPass(VkFormat color_format,VkFormat depth_format,VkImageLayout color_final_layout,VkImageLayout depth_final_layout) const { if(!attr->physical_device->IsColorAttachmentOptimal(color_format)) return(false); diff --git a/src/RenderDevice/Vulkan/VKFramebuffer.cpp b/src/RenderDevice/Vulkan/VKFramebuffer.cpp index 5b7d7685..bbd187be 100644 --- a/src/RenderDevice/Vulkan/VKFramebuffer.cpp +++ b/src/RenderDevice/Vulkan/VKFramebuffer.cpp @@ -65,7 +65,7 @@ Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,ImageView **color_list return(new Framebuffer(dev->GetDevice(),fb)); } -Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,List color,ImageView *depth) +Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,List &color,ImageView *depth) { if(!dev)return(nullptr); if(!rp)return(nullptr); @@ -77,6 +77,18 @@ Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,List colo return CreateFramebuffer(dev,rp,color.GetData(),color.GetCount(),depth); } +Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,List image_view_list) +{ + const int count=image_view_list.GetCount(); + + ImageView *last_iv=*(image_view_list.GetData()+count-1); + + if(last_iv->GetAspectFlags()&VK_IMAGE_ASPECT_DEPTH_BIT) + return CreateFramebuffer(dev,rp,image_view_list.GetData(),count-1,last_iv); + else + return CreateFramebuffer(dev,rp,image_view_list.GetData(),count,nullptr); +} + Framebuffer *CreateFramebuffer(Device *dev,RenderPass *rp,ImageView *color,ImageView *depth) { if(!dev)return(nullptr);