diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index 846e7974..ff0f8e59 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -55,7 +55,7 @@ protected: GPUDevice * device =nullptr; RenderPass * device_render_pass =nullptr; - RTSwapchain * sc_render_target =nullptr; + SwapchainRenderTarget * sc_render_target =nullptr; protected: @@ -617,4 +617,4 @@ template int RunApp(uint w,uint h) while(app.Run()); return 0; -} \ No newline at end of file +} diff --git a/inc/hgl/graph/RenderFramework.h b/inc/hgl/graph/RenderFramework.h index fbc8b68f..fddac536 100644 --- a/inc/hgl/graph/RenderFramework.h +++ b/inc/hgl/graph/RenderFramework.h @@ -55,7 +55,7 @@ public: RenderTargetManager * GetRenderTargetManager (){return rt_manager;} SwapchainModule * GetSwapchainModule (){return sc_module;} - RTSwapchain * GetSwapchainRenderTarget(){return sc_module?sc_module->GetRenderTarget():nullptr;} + SwapchainRenderTarget * GetSwapchainRenderTarget(){return sc_module?sc_module->GetRenderTarget():nullptr;} public: diff --git a/inc/hgl/graph/VK.h b/inc/hgl/graph/VK.h index 469297a7..ffb8ff1d 100644 --- a/inc/hgl/graph/VK.h +++ b/inc/hgl/graph/VK.h @@ -37,7 +37,7 @@ class ImageView; class Framebuffer; struct Swapchain; class RenderTarget; -class RTSwapchain; +class SwapchainRenderTarget; class Texture; class Texture1D; diff --git a/inc/hgl/graph/VKRenderTarget.h b/inc/hgl/graph/VKRenderTarget.h index 5fd19bf1..bc7fba3e 100644 --- a/inc/hgl/graph/VKRenderTarget.h +++ b/inc/hgl/graph/VKRenderTarget.h @@ -1,5 +1,4 @@ -#ifndef HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE -#define HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE +#pragma once #include #include @@ -7,8 +6,9 @@ #include #include #include -VK_NAMESPACE_BEGIN +#include +VK_NAMESPACE_BEGIN /** * RenderTarget 存在几种情况: * @@ -21,67 +21,203 @@ VK_NAMESPACE_BEGIN class IRenderTarget { + VkExtent2D extent; + public: - IRenderTarget(DeviceQueue *,Semaphore *); + const VkExtent2D &GetExtent ()const{return extent;} + virtual uint32_t GetColorCount ()=0; + virtual bool hasDepth ()=0; + +public: + + IRenderTarget(const VkExtent2D &ext){extent=ext;} + virtual ~IRenderTarget()=default; + + virtual Framebuffer * GetFramebuffer ()=0; + virtual RenderPass * GetRenderPass ()=0; + + virtual Texture2D * GetColorTexture (const int index=0)=0; + virtual Texture2D * GetDepthTexture ()=0; + +public: // Command Buffer + + virtual DeviceQueue * GetQueue ()=0; + virtual Semaphore * GetRenderCompleteSemaphore()=0; + + virtual RenderCmdBuffer * GetRenderCmdBuffer ()=0; + + virtual bool Submit (Semaphore *wait_sem)=0; + + virtual bool Submit (){return Submit(nullptr);} + + virtual bool WaitQueue ()=0; + virtual bool WaitFence ()=0; };//class IRenderTarget +struct RenderTargetData +{ + Framebuffer * fbo; + DeviceQueue * queue; + Semaphore * render_complete_semaphore; + + RenderCmdBuffer * cmd_buf; + + uint32_t color_count; ///<颜色成分数量 + Texture2D ** color_textures; ///<颜色成分纹理列表 + Texture2D * depth_texture; ///<深度成分纹理 + +public: + + Texture2D *GetColorTexture(const uint32_t index) + { + if(index>=color_count) + return(nullptr); + + return color_textures[index]; + } + + virtual void Clear(); +};//struct RenderTargetData + /** - * 渲染目标 + * 单帧渲染目标 */ -class RenderTarget +class RenderTarget:public IRenderTarget +{ + RenderTargetData *data; + +protected: + + friend class SwapchainModule; + friend class RenderTargetManager; + + RenderTarget(RenderTargetData *rtd):IRenderTarget(rtd->fbo->GetExtent()) + { + data=rtd; + } + +public: + + virtual ~RenderTarget() + { + if(data) + { + data->Clear(); + delete data; + } + } + + Framebuffer * GetFramebuffer ()override{return data->fbo;} + RenderPass * GetRenderPass ()override{return data->fbo->GetRenderPass();} + + uint32_t GetColorCount ()override{return data->color_count;} + + bool hasDepth ()override{return data->depth_texture;} + + Texture2D * GetColorTexture (const int index=0) override{return data->GetColorTexture(index);} + Texture2D * GetDepthTexture () override{return data->depth_texture;} + +public: // Command Buffer + + DeviceQueue * GetQueue ()override{return data->queue;} + Semaphore * GetRenderCompleteSemaphore()override{return data->render_complete_semaphore;} + + RenderCmdBuffer * GetRenderCmdBuffer ()override{return data->cmd_buf;} + + virtual bool Submit (Semaphore *wait_sem)override + { + if(!data) + return(false); + + return data->queue->Submit(*data->cmd_buf,wait_sem,data->render_complete_semaphore); + } + + bool WaitQueue ()override{return data->queue->WaitQueue();} + bool WaitFence ()override{return data->queue->WaitFence();} +};//class RenderTarget + +/** +* 多帧渲染目标 +*/ +class MFRenderTarget:public IRenderTarget { protected: - DeviceQueue *queue; + uint32_t frame_number; + uint32_t current_frame; - Framebuffer *fbo; - - VkExtent2D extent; - - Semaphore *render_complete_semaphore =nullptr; - -protected: - - uint32_t color_count; - - Texture2D **color_textures; - Texture2D *depth_texture; + RenderTarget **rt_list; protected: friend class RenderTargetManager; - RenderTarget(DeviceQueue *,Semaphore *); - RenderTarget(DeviceQueue *,Semaphore *,Framebuffer *_fb,Texture2D **color_texture_list,const uint32_t color_count,Texture2D *depth_texture); + MFRenderTarget(const uint32_t fn,RenderTarget **rtl):IRenderTarget(rtl[0]->GetFramebuffer()->GetExtent()) + { + frame_number=fn; + current_frame=0; + + rt_list=rtl; + } public: - virtual ~RenderTarget(); + virtual ~MFRenderTarget() + { + SAFE_CLEAR_OBJECT_ARRAY_OBJECT(rt_list,frame_number); + } + + virtual void NextFrame() + { + ++current_frame; + + if(current_frame>=frame_number) + current_frame=0; + } - DeviceQueue * GetQueue () {return queue;} - const VkExtent2D & GetExtent ()const {return extent;} - virtual RenderPass * GetRenderPass () {return GetFramebuffer()->GetRenderPass();} - virtual uint32_t GetColorCount () {return GetFramebuffer()->GetColorCount();} + uint32_t GetCurrentFrameIndices ()const{return current_frame;} + uint32_t GetFrameCount ()const{return frame_number;} + RenderTarget * GetCurrentFrameRenderTarget (){return rt_list[current_frame];} - virtual Framebuffer * GetFramebuffer () {return fbo;} - virtual Texture2D * GetColorTexture (const int index=0){return color_textures[index];} - virtual Texture2D * GetDepthTexture (){return depth_texture;} +public: -public: // command buffer + Framebuffer * GetFramebuffer ()override{return rt_list[current_frame]->GetFramebuffer();} + RenderPass * GetRenderPass ()override{return rt_list[current_frame]->GetRenderPass();} - Semaphore * GetRenderCompleteSemaphore (){return render_complete_semaphore;} - virtual bool Submit (RenderCmdBuffer *,Semaphore *present_complete_semaphore=nullptr); + uint32_t GetColorCount ()override{return rt_list[current_frame]->GetColorCount();} - bool WaitQueue(){return queue->WaitQueue();} - bool WaitFence(){return queue->WaitFence();} -};//class RenderTarget + Texture2D * GetColorTexture (const int index=0) override{return rt_list[current_frame]->GetColorTexture(index);} + Texture2D * GetDepthTexture () override{return rt_list[current_frame]->GetDepthTexture();} + + + bool hasDepth ()override{return rt_list[current_frame]->hasDepth();} + +public: // Command Buffer + + DeviceQueue * GetQueue ()override{return rt_list[current_frame]->GetQueue();} + Semaphore * GetRenderCompleteSemaphore()override{return rt_list[current_frame]->GetRenderCompleteSemaphore();} + RenderCmdBuffer * GetRenderCmdBuffer ()override{return rt_list[current_frame]->GetRenderCmdBuffer();} + + Framebuffer * GetFramebuffer (const uint32_t index){return rt_list[index]->GetFramebuffer();} + RenderCmdBuffer * GetRenderCmdBuffer (const uint32_t index){return rt_list[index]->GetRenderCmdBuffer();} + + virtual bool Submit ()override{return rt_list[current_frame]->Submit(nullptr);} + + virtual bool Submit (Semaphore *wait_sem) override + { + return rt_list[current_frame]->Submit(wait_sem); + } + + bool WaitQueue ()override{return rt_list[current_frame]->WaitQueue();} + bool WaitFence ()override{return rt_list[current_frame]->WaitFence();} +};//class MFRenderTarget /** * 交换链专用渲染目标 */ -class RTSwapchain:public RenderTarget +class SwapchainRenderTarget:public MFRenderTarget { VkDevice device; Swapchain *swapchain; @@ -89,47 +225,26 @@ class RTSwapchain:public RenderTarget Semaphore *present_complete_semaphore=nullptr; - uint32_t current_frame; +private: + + SwapchainRenderTarget(VkDevice dev,Swapchain *sc,Semaphore *pcs,RenderTarget **rtl); + + friend class SwapchainModule; + friend class RenderTargetManager; public: - RTSwapchain(VkDevice dev,Swapchain *sc,DeviceQueue *q,Semaphore *rcs,Semaphore *pcs); - ~RTSwapchain(); - - uint32_t GetColorCount () override {return 1;} - uint32_t GetImageCount ()const {return swapchain->image_count;} - uint32_t GetCurrentFrameIndices ()const {return current_frame;} - - Framebuffer * GetFramebuffer ()override {return swapchain->sc_image[current_frame].fbo;} - Framebuffer * GetFramebuffer (int index) {return swapchain->sc_image[index].fbo;} - - virtual Texture2D * GetColorTexture (const int index=0) override{return swapchain->sc_image[current_frame].color;} - virtual Texture2D * GetDepthTexture () override{return swapchain->sc_image[current_frame].depth;} - - RenderCmdBuffer * GetRenderCmdBuffer (int index) {return swapchain->sc_image[index].cmd_buf;} + ~SwapchainRenderTarget(); public: - Semaphore * GetPresentSemaphore () {return present_complete_semaphore;} + int AcquireNextImage(); ///<获取下一帧的索引 -public: + bool PresentBackbuffer(); ///<推送后台画面到前台 - /** - * 请求下一帧画面的索引 - * @param present_complete_semaphore 推送完成信号 - */ - int AcquireNextImage(); - - /** - * 推送后台画面到前台 - * @param render_complete_semaphore 渲染完成信号 - */ - bool PresentBackbuffer(VkSemaphore *wait_semaphores,const uint32_t wait_semaphore_count); - - bool PresentBackbuffer(); - - bool Submit(VkCommandBuffer); - bool Submit(VkCommandBuffer,Semaphore *); -};//class RTSwapchain:public RenderTarget + bool Submit()override + { + return rt_list[current_frame]->Submit(present_complete_semaphore); + } +};//class SwapchainRenderTarget:public RenderTarget VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE diff --git a/inc/hgl/graph/module/SwapchainModule.h b/inc/hgl/graph/module/SwapchainModule.h index 9f8ac8ff..755adffa 100644 --- a/inc/hgl/graph/module/SwapchainModule.h +++ b/inc/hgl/graph/module/SwapchainModule.h @@ -18,7 +18,7 @@ GRAPH_MODULE_CLASS(SwapchainModule) RenderPass * sc_render_pass =nullptr; - RTSwapchain * sc_render_target=nullptr; + SwapchainRenderTarget * sc_render_target=nullptr; SwapchainImage * current_sc_image=nullptr; @@ -43,11 +43,11 @@ public: public: - RenderPass * GetRenderPass ()const{return sc_render_pass;} + RenderPass * GetRenderPass ()const{return sc_render_pass;} - const VkExtent2D & GetSwapchainSize()const{return sc_render_target->GetExtent();} + const VkExtent2D & GetSwapchainSize()const{return sc_render_target->GetExtent();} - RTSwapchain * GetRenderTarget ()const{return sc_render_target;} + SwapchainRenderTarget * GetRenderTarget ()const{return sc_render_target;} };//class SwapchainModule:public GraphModule VK_NAMESPACE_END diff --git a/src/SceneGraph/Vulkan/VKRenderTarget.cpp b/src/SceneGraph/Vulkan/VKRenderTarget.cpp index 75372d83..d01dc60a 100644 --- a/src/SceneGraph/Vulkan/VKRenderTarget.cpp +++ b/src/SceneGraph/Vulkan/VKRenderTarget.cpp @@ -1,64 +1,17 @@ #include #include -#include -#include #include #include VK_NAMESPACE_BEGIN -RenderTarget::RenderTarget(DeviceQueue *q,Semaphore *s) -{ - queue=q; - fbo=nullptr; - color_count=0; - color_textures=nullptr; - depth_texture=nullptr; - render_complete_semaphore=s; -} - -RenderTarget::RenderTarget(DeviceQueue *q,Semaphore *s,Framebuffer *_fb,Texture2D **ctl,const uint32_t cc,Texture2D *dt) -{ - queue=q; - fbo=_fb; - - depth_texture=dt; - - color_count=cc; - if(color_count>0) - { - color_textures=new Texture2D *[color_count]; - hgl_cpy(color_textures,ctl,color_count); - - extent.width=color_textures[0]->GetWidth(); - extent.height=color_textures[0]->GetHeight(); - } - else - { - color_textures=nullptr; - - if(depth_texture) - { - extent.width=depth_texture->GetWidth(); - extent.height=depth_texture->GetHeight(); - } - } - - render_complete_semaphore=s; -} - -RenderTarget::~RenderTarget() +void RenderTargetData::Clear() { SAFE_CLEAR(queue); - SAFE_CLEAR(depth_texture); - SAFE_CLEAR_OBJECT_ARRAY_OBJECT(color_textures,color_count); - SAFE_CLEAR(render_complete_semaphore); SAFE_CLEAR(fbo); + SAFE_CLEAR_OBJECT_ARRAY_OBJECT(color_textures,color_count); + SAFE_CLEAR(depth_texture); } -bool RenderTarget::Submit(RenderCmdBuffer *command_buffer,Semaphore *present_complete_semaphore) -{ - return queue->Submit(*command_buffer,present_complete_semaphore,render_complete_semaphore); -} VK_NAMESPACE_END \ No newline at end of file diff --git a/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp b/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp index 7b13b803..3b08b638 100644 --- a/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp +++ b/src/SceneGraph/Vulkan/VKSwapchainRenderTarget.cpp @@ -3,7 +3,7 @@ #include VK_NAMESPACE_BEGIN -RTSwapchain::RTSwapchain(VkDevice dev,Swapchain *sc,DeviceQueue *q,Semaphore *rcs,Semaphore *pcs):RenderTarget(q,rcs) +SwapchainRenderTarget::SwapchainRenderTarget(VkDevice dev,Swapchain *sc,Semaphore *pcs,RenderTarget **rtl):MFRenderTarget(sc->image_count,rtl) { device=dev; @@ -14,32 +14,37 @@ RTSwapchain::RTSwapchain(VkDevice dev,Swapchain *sc,DeviceQueue *q,Semaphore *rc present_info.swapchainCount = 1; present_info.pResults = nullptr; present_info.pSwapchains = &(swapchain->swap_chain); - - extent=swapchain->extent; - - current_frame=0; - + present_complete_semaphore=pcs; } -RTSwapchain::~RTSwapchain() +SwapchainRenderTarget::~SwapchainRenderTarget() { delete present_complete_semaphore; delete swapchain; } -int RTSwapchain::AcquireNextImage() +int SwapchainRenderTarget::AcquireNextImage() { - if(vkAcquireNextImageKHR(device,swapchain->swap_chain,UINT64_MAX,*(this->present_complete_semaphore),VK_NULL_HANDLE,¤t_frame)==VK_SUCCESS) + if(vkAcquireNextImageKHR(device, + swapchain->swap_chain, + UINT64_MAX, + *present_complete_semaphore, + VK_NULL_HANDLE, + ¤t_frame)==VK_SUCCESS) return current_frame; return -1; } -bool RTSwapchain::PresentBackbuffer(VkSemaphore *wait_semaphores,const uint32_t count) +bool SwapchainRenderTarget::PresentBackbuffer() { - present_info.waitSemaphoreCount =count; - present_info.pWaitSemaphores =wait_semaphores; + DeviceQueue *queue=GetQueue(); + + VkSemaphore wait_semaphores=*GetRenderCompleteSemaphore(); + + present_info.waitSemaphoreCount =1; + present_info.pWaitSemaphores =&wait_semaphores; present_info.pImageIndices =¤t_frame; VkResult result=queue->Present(&present_info); @@ -55,21 +60,4 @@ bool RTSwapchain::PresentBackbuffer(VkSemaphore *wait_semaphores,const uint32_t return(true); } - -bool RTSwapchain::PresentBackbuffer() -{ - VkSemaphore sem=*render_complete_semaphore; - - return this->PresentBackbuffer(&sem,1); -} - -bool RTSwapchain::Submit(VkCommandBuffer cb) -{ - return queue->Submit(cb,present_complete_semaphore,render_complete_semaphore); -} - -bool RTSwapchain::Submit(VkCommandBuffer cb,Semaphore *pce) -{ - return queue->Submit(cb,pce,render_complete_semaphore); -} VK_NAMESPACE_END diff --git a/src/SceneGraph/module/RenderTargetManager.cpp b/src/SceneGraph/module/RenderTargetManager.cpp index 96a98518..759da6fb 100644 --- a/src/SceneGraph/module/RenderTargetManager.cpp +++ b/src/SceneGraph/module/RenderTargetManager.cpp @@ -15,12 +15,12 @@ RenderTarget *RenderTargetManager::CreateRT(const FramebufferInfo *fbi,RenderPas if(!fbi)return(nullptr); if(!rp)return(nullptr); - const uint32_t image_count=fbi->GetColorCount(); + const uint32_t color_count=fbi->GetColorCount(); const VkExtent2D extent=fbi->GetExtent(); const VkFormat depth_format=fbi->GetDepthFormat(); - AutoDeleteObjectArray color_texture_list(image_count); - AutoDeleteArray color_iv_list(image_count); //iv只是从Texture2D中取出来的,无需一个个delete + AutoDeleteObjectArray color_texture_list(color_count); + AutoDeleteArray color_iv_list(color_count); //iv只是从Texture2D中取出来的,无需一个个delete Texture2D **tp=color_texture_list; ImageView **iv=color_iv_list; @@ -38,19 +38,27 @@ RenderTarget *RenderTargetManager::CreateRT(const FramebufferInfo *fbi,RenderPas Texture2D *depth_texture=(depth_format!=PF_UNDEFINED)?tex_manager->CreateTexture2D(new DepthAttachmentTextureCreateInfo(depth_format,extent)):nullptr; - Framebuffer *fb=CreateFBO(rp,color_iv_list,image_count,depth_texture?depth_texture->GetImageView():nullptr); + Framebuffer *fb=CreateFBO(rp,color_iv_list,color_count,depth_texture?depth_texture->GetImageView():nullptr); if(fb) { - auto *dev=GetDevice(); + RenderTargetData *rtd=new RenderTargetData{}; - DeviceQueue *q=dev->CreateQueue(fence_count,false); - Semaphore *render_complete_semaphore=dev->CreateGPUSemaphore(); + GPUDevice *dev=GetDevice(); - RenderTarget *rt=new RenderTarget(q,render_complete_semaphore,fb,color_texture_list,image_count,depth_texture); + rtd->fbo =fb; + rtd->queue =dev->CreateQueue(fence_count,false); + rtd->render_complete_semaphore =dev->CreateGPUSemaphore(); + + rtd->cmd_buf =dev->CreateRenderCommandBuffer(""); + + rtd->color_count =color_count; + rtd->color_textures =hgl_new_copy(color_texture_list,color_count); + rtd->depth_texture =depth_texture; color_texture_list.DiscardObject(); - return rt; + + return(new RenderTarget(rtd)); } SAFE_CLEAR(depth_texture); @@ -60,7 +68,6 @@ RenderTarget *RenderTargetManager::CreateRT(const FramebufferInfo *fbi,RenderPas RenderTarget *RenderTargetManager::CreateRT(const FramebufferInfo *fbi,const uint32_t fence_count) { if(!fbi)return(nullptr); - if(!rp_manager)return(nullptr); //这个判断理论上不可能成立 RenderPass *rp=rp_manager->AcquireRenderPass(fbi); diff --git a/src/SceneGraph/module/SwapchainModule.cpp b/src/SceneGraph/module/SwapchainModule.cpp index 73eed754..0dc57c11 100644 --- a/src/SceneGraph/module/SwapchainModule.cpp +++ b/src/SceneGraph/module/SwapchainModule.cpp @@ -174,6 +174,20 @@ bool SwapchainModule::CreateSwapchain() return(false); } +namespace +{ + struct SwapchainRenderTargetData:public RenderTargetData + { + void Clear() override + { + delete render_complete_semaphore; + delete queue; + + delete[] color_textures; + } + };// +}//namespace + bool SwapchainModule::CreateSwapchainRenderTarget() { if(!CreateSwapchain()) @@ -181,17 +195,35 @@ bool SwapchainModule::CreateSwapchainRenderTarget() GPUDevice *device=GetDevice(); - DeviceQueue *q=device->CreateQueue(swapchain->image_count,false); - Semaphore *render_complete_semaphore=device->CreateGPUSemaphore(); + RenderTarget **rt_list=new RenderTarget*[swapchain->image_count]; - Semaphore *present_complete_semaphore=device->CreateGPUSemaphore(); + SwapchainImage *sc_image=swapchain->sc_image; - sc_render_target=new RTSwapchain( device->GetDevice(), - swapchain, - q, - render_complete_semaphore, - present_complete_semaphore - ); + for(uint32_t i=0;iimage_count;i++) + { + RenderTargetData *rtd=new SwapchainRenderTargetData{}; + + rtd->fbo =sc_image->fbo; + rtd->queue =device->CreateQueue(swapchain->image_count,false); + rtd->render_complete_semaphore =device->CreateGPUSemaphore(); + + rtd->cmd_buf =sc_image->cmd_buf; + + rtd->color_count =1; + rtd->color_textures =new Texture2D*[1]; + rtd->color_textures[0] =sc_image->color; + rtd->depth_texture =sc_image->depth; + + rt_list[i]=new RenderTarget(rtd); + + ++sc_image; + } + + sc_render_target=new SwapchainRenderTarget( device->GetDevice(), + swapchain, + device->CreateGPUSemaphore(), + rt_list + ); return true; } @@ -255,7 +287,7 @@ void SwapchainModule::EndRender() return; current_sc_image->cmd_buf->End(); - sc_render_target->Submit(*(current_sc_image->cmd_buf)); + sc_render_target->Submit(); sc_render_target->PresentBackbuffer(); sc_render_target->WaitQueue(); sc_render_target->WaitFence();