diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 44162893bf..5776bc4919 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -469,6 +469,26 @@ void FramebufferManagerCommon::DestroyFramebuf(VirtualFramebuffer *v) { delete v; } +void FramebufferManagerCommon::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { + bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; + bool matchingSize = src->width == dst->width && src->height == dst->height; + + // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. + if (matchingDepthBuffer && matchingSize) { + int w = std::min(src->renderWidth, dst->renderWidth); + int h = std::min(src->renderHeight, dst->renderHeight); + // Let's only do this if not clearing depth. + if (gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { + draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } else if (gstate_c.Supports(GPU_SUPPORTS_COPY_IMAGE)) { + draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); + RebindFramebuffer("BlitFramebufferDepth"); + } + dst->last_frame_depth_updated = gpuStats.numFlips; + } +} + void FramebufferManagerCommon::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) { if (!useBufferedRendering_) { // Let's ignore rendering to targets that have not (yet) been displayed. diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index ff43f6d504..05a2a787b6 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -339,7 +339,7 @@ protected: void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth); virtual void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) = 0; - virtual void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) = 0; + void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst); void ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, int h, bool force = false, bool skipCopy = false); void ShowScreenResolution(); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 93648cbcbb..4440ebf4b3 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -315,19 +315,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { } } -void FramebufferManagerD3D11::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - void FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { ID3D11ShaderResourceView *view = nullptr; diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index a1683c299c..e951e277a1 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -45,8 +45,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 3575ed82e9..be7f751eda 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -305,19 +305,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { } } - void FramebufferManagerDX9::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - // Should use StretchRect here? Note: should only copy depth and ideally NOT copy stencil. See #9740. - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - RebindFramebuffer("RebindFramebuffer - BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } - } - LPDIRECT3DSURFACE9 FramebufferManagerDX9::GetOffscreenSurface(LPDIRECT3DSURFACE9 similarSurface, VirtualFramebuffer *vfb) { D3DSURFACE_DESC desc = {}; HRESULT hr = similarSurface->GetDesc(&desc); diff --git a/GPU/Directx9/FramebufferManagerDX9.h b/GPU/Directx9/FramebufferManagerDX9.h index b164a9b0e7..3a8578599a 100644 --- a/GPU/Directx9/FramebufferManagerDX9.h +++ b/GPU/Directx9/FramebufferManagerDX9.h @@ -50,8 +50,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index e030effb22..f2709663cf 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -263,21 +263,6 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE } } -void FramebufferManagerGLES::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - - // Note: we don't use CopyFramebufferImage here, because it would copy depth AND stencil. See #9740. - if (matchingDepthBuffer && matchingSize && gstate_c.Supports(GPU_SUPPORTS_FRAMEBUFFER_BLIT)) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // Let's only do this if not clearing depth. - draw_->BlitFramebuffer(src->fbo, 0, 0, w, h, dst->fbo, 0, 0, w, h, Draw::FB_DEPTH_BIT, Draw::FB_BLIT_NEAREST, "BlitFramebufferDepth"); - RebindFramebuffer("BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - void FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { render_->BindTexture(stage, nullptr); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 12a3eb85c5..9177b62767 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -49,8 +49,6 @@ public: void DeviceLost(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - // For use when texturing from a framebuffer. May create a duplicate if target. void BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 8a39fdc85e..293ff77be5 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -269,19 +269,6 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, } } -// Except for a missing rebind and silly scissor enables, identical copy of the same function in GPU_GLES - tricky parts are in thin3d. -void FramebufferManagerVulkan::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) { - bool matchingDepthBuffer = src->z_address == dst->z_address && src->z_stride != 0 && dst->z_stride != 0; - bool matchingSize = src->width == dst->width && src->height == dst->height; - if (matchingDepthBuffer && matchingSize) { - int w = std::min(src->renderWidth, dst->renderWidth); - int h = std::min(src->renderHeight, dst->renderHeight); - // TODO: Currently, this copies depth AND stencil, which is a problem. See #9740. - draw_->CopyFramebufferImage(src->fbo, 0, 0, 0, 0, dst->fbo, 0, 0, 0, 0, w, h, 1, Draw::FB_DEPTH_BIT, "BlitFramebufferDepth"); - dst->last_frame_depth_updated = gpuStats.numFlips; - } -} - VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { if (!framebuffer->fbo || !useBufferedRendering_) { gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index b66eeb6033..a09f6ef755 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -54,8 +54,6 @@ public: int GetLineWidth(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) override; - bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; VkImageView BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags);