diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 9419a0c87a..cbfb7a58a3 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -36,6 +36,7 @@ #include "GPU/Common/PresentationCommon.h" #include "GPU/Common/TextureCacheCommon.h" #include "GPU/Debugger/Record.h" +#include "GPU/Debugger/Stepping.h" #include "GPU/GPUInterface.h" #include "GPU/GPUState.h" @@ -702,6 +703,49 @@ void FramebufferManagerCommon::DrawPixels(VirtualFramebuffer *vfb, int dstX, int } } +bool FramebufferManagerCommon::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { + if (!framebuffer->fbo || !useBufferedRendering_) { + draw_->BindTexture(0, nullptr); + gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; + return false; + } + + // currentRenderVfb_ will always be set when this is called, except from the GE debugger. + // Let's just not bother with the copy in that case. + bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; + if (GPUStepping::IsStepping()) { + skipCopy = true; + } + // Currently rendering to this framebuffer. Need to make a copy. + if (!skipCopy && framebuffer == currentRenderVfb_) { + // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. + Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight); + if (renderCopy) { + VirtualFramebuffer copyInfo = *framebuffer; + copyInfo.fbo = renderCopy; + CopyFramebufferForColorTexture(©Info, framebuffer, flags); + RebindFramebuffer("After BindFramebufferAsColorTexture"); + draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); + } else { + draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); + } + return true; + } else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) { + draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); + return true; + } else { + ERROR_LOG_REPORT_ONCE(vulkanSelfTexture, G3D, "Attempting to texture from target (src=%08x / target=%08x / flags=%d)", framebuffer->fb_address, currentRenderVfb_->fb_address, flags); + // To do this safely in Vulkan, we need to use input attachments. + // Actually if the texture region and render regions don't overlap, this is safe, but we need + // to transition to GENERAL image layout which will take some trickery. + // Badness on D3D11 to bind the currently rendered-to framebuffer as a texture. + draw_->BindTexture(0, nullptr); + gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; + return false; + } + +} + void FramebufferManagerCommon::CopyFramebufferForColorTexture(VirtualFramebuffer *dst, VirtualFramebuffer *src, int flags) { int x = 0; int y = 0; diff --git a/GPU/Common/FramebufferManagerCommon.h b/GPU/Common/FramebufferManagerCommon.h index fd5ce18f7b..26c7e02323 100644 --- a/GPU/Common/FramebufferManagerCommon.h +++ b/GPU/Common/FramebufferManagerCommon.h @@ -233,6 +233,7 @@ public: bool NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); void NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride, int dstX, int dstY, u32 srcBasePtr, int srcStride, int srcX, int srcY, int w, int h, int bpp, u32 skipDrawReason); + bool BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); void ReadFramebufferToMemory(VirtualFramebuffer *vfb, int x, int y, int w, int h); void DownloadFramebufferForClut(u32 fb_address, u32 loadBytes); diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index c4ebb5f450..2538f65edb 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -314,45 +314,6 @@ static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { } } -bool FramebufferManagerD3D11::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { - if (!framebuffer->fbo || !useBufferedRendering_) { - draw_->BindTexture(0, nullptr); - gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; - return false; - } - - // currentRenderVfb_ will always be set when this is called, except from the GE debugger. - // Let's just not bother with the copy in that case. - bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping()) { - skipCopy = true; - } - // Currently rendering to this framebuffer. Need to make a copy. - if (!skipCopy && framebuffer == currentRenderVfb_) { - // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. - Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight); - if (renderCopy) { - VirtualFramebuffer copyInfo = *framebuffer; - copyInfo.fbo = renderCopy; - CopyFramebufferForColorTexture(©Info, framebuffer, flags); - RebindFramebuffer("RebindFramebuffer - BindFramebufferAsColorTexture"); - draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); - } else { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - } - return true; - } else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - return true; - } else { - ERROR_LOG_REPORT_ONCE(d3d11SelfTexture, G3D, "Attempting to texture from target (src=%08x / target=%08x / flags=%d)", framebuffer->fb_address, currentRenderVfb_->fb_address, flags); - // Badness on D3D11 to bind the currently rendered-to framebuffer as a texture. - draw_->BindTexture(0, nullptr); - gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; - return false; - } -} - void FramebufferManagerD3D11::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { // Nothing to do here. } diff --git a/GPU/D3D11/FramebufferManagerD3D11.h b/GPU/D3D11/FramebufferManagerD3D11.h index 497af969a1..ec8f1b00e0 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.h +++ b/GPU/D3D11/FramebufferManagerD3D11.h @@ -44,8 +44,6 @@ public: void EndFrame(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - bool BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; // TODO: Remove diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index b017a59f64..4f0aafb78d 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -336,39 +336,6 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { return offscreen; } - bool FramebufferManagerDX9::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { - if (!framebuffer->fbo || !useBufferedRendering_) { - device_->SetTexture(stage, nullptr); - gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; - return false; - } - - // currentRenderVfb_ will always be set when this is called, except from the GE debugger. - // Let's just not bother with the copy in that case. - bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping()) { - skipCopy = true; - } - if (!skipCopy && framebuffer == currentRenderVfb_) { - // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. - Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight); - if (renderCopy) { - VirtualFramebuffer copyInfo = *framebuffer; - copyInfo.fbo = renderCopy; - - CopyFramebufferForColorTexture(©Info, framebuffer, flags); - RebindFramebuffer("RebindFramebuffer - BindFramebufferAsColorTexture"); - draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); - } else { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - } - return true; - } else { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - return true; - } - } - void FramebufferManagerDX9::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { // Nothing to do here. } diff --git a/GPU/Directx9/FramebufferManagerDX9.h b/GPU/Directx9/FramebufferManagerDX9.h index 99b93c6a62..a35a154265 100644 --- a/GPU/Directx9/FramebufferManagerDX9.h +++ b/GPU/Directx9/FramebufferManagerDX9.h @@ -49,8 +49,6 @@ public: void EndFrame(); void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - bool BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - virtual bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; bool GetFramebuffer(u32 fb_address, int fb_stride, GEBufferFormat format, GPUDebugBuffer &buffer, int maxRes); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index eb742f3370..befbe06177 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -263,38 +263,6 @@ void FramebufferManagerGLES::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GE } } -bool FramebufferManagerGLES::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { - if (!framebuffer->fbo || !useBufferedRendering_) { - render_->BindTexture(stage, nullptr); - gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; - return false; - } - - // currentRenderVfb_ will always be set when this is called, except from the GE debugger. - // Let's just not bother with the copy in that case. - bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping()) { - skipCopy = true; - } - if (!skipCopy && framebuffer == currentRenderVfb_) { - // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. - Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight); - if (renderCopy) { - VirtualFramebuffer copyInfo = *framebuffer; - copyInfo.fbo = renderCopy; - - CopyFramebufferForColorTexture(©Info, framebuffer, flags); - draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); - } else { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - } - return true; - } else { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - return true; - } -} - void FramebufferManagerGLES::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { _assert_msg_(nvfb->fbo, "Expecting a valid nvfb in UpdateDownloadTempBuffer"); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index fc2e5bcbad..56ad6aa307 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -52,9 +52,6 @@ public: void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) override; - // For use when texturing from a framebuffer. May create a duplicate if target. - bool BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; bool GetOutputFramebuffer(GPUDebugBuffer &buffer) override; diff --git a/GPU/Vulkan/FramebufferManagerVulkan.cpp b/GPU/Vulkan/FramebufferManagerVulkan.cpp index 4923da7087..a4e5873f67 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.cpp +++ b/GPU/Vulkan/FramebufferManagerVulkan.cpp @@ -268,48 +268,6 @@ void FramebufferManagerVulkan::ReformatFramebufferFrom(VirtualFramebuffer *vfb, } } -bool FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags) { - if (!framebuffer->fbo || !useBufferedRendering_) { - draw_->BindTexture(0, nullptr); - gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; - return false; - } - - // currentRenderVfb_ will always be set when this is called, except from the GE debugger. - // Let's just not bother with the copy in that case. - bool skipCopy = (flags & BINDFBCOLOR_MAY_COPY) == 0; - if (GPUStepping::IsStepping()) { - skipCopy = true; - } - // Currently rendering to this framebuffer. Need to make a copy. - if (!skipCopy && framebuffer == currentRenderVfb_) { - // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. - Draw::Framebuffer *renderCopy = GetTempFBO(TempFBO::COPY, framebuffer->renderWidth, framebuffer->renderHeight); - if (renderCopy) { - VirtualFramebuffer copyInfo = *framebuffer; - copyInfo.fbo = renderCopy; - CopyFramebufferForColorTexture(©Info, framebuffer, flags); - RebindFramebuffer("RebindFramebuffer - BindFramebufferAsColorTexture"); - draw_->BindFramebufferAsTexture(renderCopy, stage, Draw::FB_COLOR_BIT, 0); - } else { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - } - return true; - } else if (framebuffer != currentRenderVfb_ || (flags & BINDFBCOLOR_FORCE_SELF) != 0) { - draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); - return true; - } else { - ERROR_LOG_REPORT_ONCE(vulkanSelfTexture, G3D, "Attempting to texture from target (src=%08x / target=%08x / flags=%d)", framebuffer->fb_address, currentRenderVfb_->fb_address, flags); - // To do this safely in Vulkan, we need to use input attachments. - // Actually if the texture region and render regions don't overlap, this is safe, but we need - // to transition to GENERAL image layout which will take some trickery. - // Badness on D3D11 to bind the currently rendered-to framebuffer as a texture. - draw_->BindTexture(0, nullptr); - gstate_c.skipDrawReason |= SKIPDRAW_BAD_FB_TEXTURE; - return false; - } -} - void FramebufferManagerVulkan::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) { // Nothing to do here. } diff --git a/GPU/Vulkan/FramebufferManagerVulkan.h b/GPU/Vulkan/FramebufferManagerVulkan.h index 96e6a74569..aaa1d48297 100644 --- a/GPU/Vulkan/FramebufferManagerVulkan.h +++ b/GPU/Vulkan/FramebufferManagerVulkan.h @@ -57,8 +57,6 @@ public: bool NotifyStencilUpload(u32 addr, int size, StencilUpload flags = StencilUpload::NEEDS_CLEAR) override; - bool BindFramebufferAsColorTexture(int stage, VirtualFramebuffer *framebuffer, int flags); - // If within a render pass, this will just issue a regular clear. If beginning a new render pass, // do that. void NotifyClear(bool clearColor, bool clearAlpha, bool clearDepth, uint32_t color, float depth);