diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index d248bbe0..2dd2971f 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -54,7 +54,7 @@ protected: protected: GPUDevice * device =nullptr; - RTSwapchain * sc_render_target =nullptr; + SwapchainRenderTarget * sc_render_target =nullptr; protected: @@ -225,8 +225,10 @@ public: { if(!ri)return(false); - return BuildCommandBuffer(sc_render_target->GetRenderCmdBuffer(index), - sc_render_target->GetFramebuffer(index), + IRenderTarget *rt=sc_render_target->GetCurrentFrameRenderTarget(); + + return BuildCommandBuffer(rt->GetRenderCmdBuffer(), + rt->GetFramebuffer(), ri); } @@ -234,7 +236,7 @@ public: { if(!ri)return(false); - for(uint32_t i=0;iGetImageCount();i++) + for(uint32_t i=0;iGetFrameCount();i++) BuildCommandBuffer(i,ri); return(true); @@ -264,7 +266,7 @@ public: void BuildCommandBuffer(RenderList *rl) { - for(uint32_t i=0;iGetImageCount();i++) + for(uint32_t i=0;iGetFrameCount();i++) BuildCommandBuffer(i,rl); } @@ -298,11 +300,9 @@ public: return sc_render_target->AcquireNextImage(); } - virtual void SubmitDraw(int index) + virtual void SubmitDraw() { - VkCommandBuffer cb=*(sc_render_target->GetRenderCmdBuffer(index)); - - sc_render_target->Submit(cb); + sc_render_target->Submit(); sc_render_target->PresentBackbuffer(); sc_render_target->WaitQueue(); sc_render_target->WaitFence(); @@ -312,9 +312,9 @@ public: { int index=AcquireNextImage(); - if(index<0||index>=sc_render_target->GetImageCount())return; + if(index<0||index>=sc_render_target->GetFrameCount())return; - SubmitDraw(index); + SubmitDraw(); } bool Run() @@ -545,7 +545,7 @@ public: BuildCommandBuffer(index); - SubmitDraw(index); + SubmitDraw(); ckc->Update(); cmc->Update(); 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/VKDevice.h b/inc/hgl/graph/VKDevice.h index 278e929d..17ebc139 100644 --- a/inc/hgl/graph/VKDevice.h +++ b/inc/hgl/graph/VKDevice.h @@ -39,9 +39,9 @@ private: DeviceRenderPassManage *render_pass_manage; - RTSwapchain *sc_rt; + SwapchainRenderTarget *sc_rt; - RTSwapchain *CreateSwapchainRenderTarget(); + SwapchainRenderTarget *CreateSwapchainRenderTarget(); void InitRenderPassManage(); void ClearRenderPassManage(); @@ -80,7 +80,7 @@ public: RenderPass * GetRenderPass () {return sc_rt->GetRenderPass();} - RTSwapchain * GetSwapchainRT () {return sc_rt;} + SwapchainRenderTarget * GetSwapchainRT () {return sc_rt;} const VkExtent2D & GetSwapchainSize ()const {return sc_rt->GetExtent();} diff --git a/inc/hgl/graph/VKRenderTarget.h b/inc/hgl/graph/VKRenderTarget.h index c11295a4..42201310 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,61 +6,216 @@ #include #include #include + VK_NAMESPACE_BEGIN /** - * 渲染目标 - */ -class RenderTarget +* RenderTarget 存在几种情况: +* +* 1.正常单帧渲染目标,即只有一帧的数据,每次渲染都是当前帧 +* +* 2.多帧渲染目标,即有多帧数据,每次渲染都是指定帧,典型的是Swapchain +* +* 所以RenderTarget的其实是一个多态类,根据不同的情况,有不同的实现 +*/ + +class IRenderTarget { -protected: - - DeviceQueue *queue; - - Framebuffer *fbo; - VkExtent2D extent; - Semaphore *render_complete_semaphore =nullptr; +public: -protected: + const VkExtent2D &GetExtent ()const{return extent;} - uint32_t color_count; ///<颜色成分数量 - Texture2D **color_textures; ///<颜色成分纹理列表 - Texture2D *depth_texture; ///<深度成分纹理 + 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:public IRenderTarget +{ + RenderTargetData *data; protected: friend class GPUDevice; - RenderTarget(DeviceQueue *,Semaphore *); - RenderTarget(DeviceQueue *,Semaphore *,Framebuffer *_fb,Texture2D **color_texture_list,const uint32_t color_count,Texture2D *depth_texture); + RenderTarget(RenderTargetData *rtd):IRenderTarget(rtd->fbo->GetExtent()) + { + data=rtd; + } public: - virtual ~RenderTarget(); + 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;} - DeviceQueue * GetQueue () {return queue;} - const VkExtent2D & GetExtent ()const {return extent;} - virtual RenderPass * GetRenderPass () {return GetFramebuffer()->GetRenderPass();} - virtual uint32_t GetColorCount () {return GetFramebuffer()->GetColorCount();} + bool hasDepth ()override{return data->depth_texture;} - virtual Framebuffer * GetFramebuffer () {return fbo;} - virtual Texture2D * GetColorTexture (const int index=0){return color_textures[index];} - virtual Texture2D * GetDepthTexture () {return depth_texture;} + Texture2D * GetColorTexture (const int index=0) override{return data->GetColorTexture(index);} + Texture2D * GetDepthTexture () override{return data->depth_texture;} -public: // command buffer +public: // Command Buffer - Semaphore * GetRenderCompleteSemaphore (){return render_complete_semaphore;} - virtual bool Submit (RenderCmdBuffer *,Semaphore *present_complete_semaphore=nullptr); + DeviceQueue * GetQueue ()override{return data->queue;} + Semaphore * GetRenderCompleteSemaphore()override{return data->render_complete_semaphore;} - bool WaitQueue(){return queue->WaitQueue();} - bool WaitFence(){return queue->WaitFence();} + 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: + + uint32_t frame_number; + uint32_t current_frame; + + RenderTarget **rt_list; + +protected: + + friend class GPUDevice; + + MFRenderTarget(const uint32_t fn,RenderTarget **rtl):IRenderTarget(rtl[0]->GetFramebuffer()->GetExtent()) + { + frame_number=fn; + current_frame=0; + + rt_list=rtl; + } + +public: + + virtual ~MFRenderTarget() + { + SAFE_CLEAR_OBJECT_ARRAY_OBJECT(rt_list,frame_number); + } + + virtual void NextFrame() + { + ++current_frame; + + if(current_frame>=frame_number) + current_frame=0; + } + + uint32_t GetCurrentFrameIndices ()const{return current_frame;} + uint32_t GetFrameCount ()const{return frame_number;} + RenderTarget * GetCurrentFrameRenderTarget (){return rt_list[current_frame];} + +public: + + Framebuffer * GetFramebuffer ()override{return rt_list[current_frame]->GetFramebuffer();} + RenderPass * GetRenderPass ()override{return rt_list[current_frame]->GetRenderPass();} + + uint32_t GetColorCount ()override{return rt_list[current_frame]->GetColorCount();} + + 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; @@ -69,47 +223,25 @@ 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 GPUDevice; 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 *); + bool Submit()override + { + return rt_list[current_frame]->Submit(present_complete_semaphore); + } };//class RTSwapchain:public RenderTarget VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_RENDER_TARGET_INCLUDE diff --git a/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp b/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp index e988b1e2..85246aa2 100644 --- a/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceRenderTarget.cpp @@ -1,5 +1,6 @@ #include #include +#include VK_NAMESPACE_BEGIN RenderTarget *GPUDevice::CreateRT(const FramebufferInfo *fbi,RenderPass *rp,const uint32_t fence_count) @@ -34,13 +35,21 @@ RenderTarget *GPUDevice::CreateRT(const FramebufferInfo *fbi,RenderPass *rp,cons if(fb) { - DeviceQueue *q=CreateQueue(fence_count,false); - Semaphore *render_complete_semaphore=CreateGPUSemaphore(); + RenderTargetData *rtd=new RenderTargetData{}; - RenderTarget *rt=new RenderTarget(q,render_complete_semaphore,fb,color_texture_list,color_count,depth_texture); + rtd->fbo =fb; + rtd->queue =CreateQueue(fence_count,false); + rtd->render_complete_semaphore =CreateGPUSemaphore(); + + rtd->cmd_buf =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); @@ -58,23 +67,56 @@ RenderTarget *GPUDevice::CreateRT(const FramebufferInfo *fbi,const uint32_t fenc return CreateRT(fbi,rp,fence_count); } -RTSwapchain *GPUDevice::CreateSwapchainRenderTarget() +namespace +{ + struct SwapchainRenderTargetData:public RenderTargetData + { + void Clear() override + { + delete render_complete_semaphore; + delete queue; + + delete[] color_textures; + } + };// +}//namespace + +SwapchainRenderTarget *GPUDevice::CreateSwapchainRenderTarget() { Swapchain *sc=CreateSwapchain(attr->surface_caps.currentExtent); if(!sc) return(nullptr); - DeviceQueue *q=CreateQueue(sc->image_count,false); - Semaphore *render_complete_semaphore=CreateGPUSemaphore(); - Semaphore *present_complete_semaphore=CreateGPUSemaphore(); + RenderTarget **rt_list=new RenderTarget*[sc->image_count]; - RTSwapchain *srt=new RTSwapchain( attr->device, - sc, - q, - render_complete_semaphore, - present_complete_semaphore - ); + SwapchainImage *sc_image=sc->sc_image; + + for(uint32_t i=0;iimage_count;i++) + { + RenderTargetData *rtd=new SwapchainRenderTargetData{}; + + rtd->fbo =sc_image->fbo; + rtd->queue =CreateQueue(sc->image_count,false); + rtd->render_complete_semaphore =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; + } + + SwapchainRenderTarget *srt=new SwapchainRenderTarget( attr->device, + sc, + CreateGPUSemaphore(), + rt_list + ); return srt; } diff --git a/src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp b/src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp index 43c6aee6..895cf90c 100644 --- a/src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp +++ b/src/SceneGraph/Vulkan/VKDeviceSwapchain.cpp @@ -97,7 +97,6 @@ bool GPUDevice::CreateSwapchainFBO(Swapchain *swapchain) AnsiString num_string; - for(uint32_t i=0;iimage_count;i++) { swapchain->sc_image[i].color=CreateTexture2D(new SwapchainColorTextureCreateInfo(swapchain->surface_format.format,swapchain->extent,sc_images[i])); @@ -105,7 +104,7 @@ bool GPUDevice::CreateSwapchainFBO(Swapchain *swapchain) if(!swapchain->sc_image[i].color) return(false); - swapchain->sc_image[i].depth =CreateTexture2D(new SwapchainDepthTextureCreateInfo(swapchain->depth_format,swapchain->extent)); + swapchain->sc_image[i].depth=CreateTexture2D(new SwapchainDepthTextureCreateInfo(swapchain->depth_format,swapchain->extent)); if(!swapchain->sc_image[i].depth) return(false); 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 cdb194b5..70a47e86 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; @@ -15,31 +15,36 @@ RTSwapchain::RTSwapchain(VkDevice dev,Swapchain *sc,DeviceQueue *q,Semaphore *rc 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