diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index c2007df6bb..61fa27eeb0 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -1162,7 +1162,10 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, u16 w, BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min(vfb->bufferWidth, vfb->width), std::min(vfb->height, vfb->bufferHeight), 0); } } - delete old.fbo; + delete old.fbo; + if (needGLESRebinds_) { + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP }); + } } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }); } diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index 11f339073c..0530e6480a 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -375,6 +375,7 @@ protected: // Used by post-processing shaders std::vector extraFBOs_; + bool needGLESRebinds_ = false; struct TempFBO { Draw::Framebuffer *fbo; diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 3d2cdf774f..b5423dc9dc 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -490,10 +490,9 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G // The best way to do this may ultimately be to create a new FBO (combine with any resize?) // and blit with a shader to that, then replace the FBO on vfb. Stencil would still be complex // to exactly reproduce in 4444 and 8888 formats. - - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP }); - if (old == GE_FORMAT_565) { + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::KEEP }); + // TODO: There's no way this does anything useful :( context_->OMSetDepthStencilState(stockD3D11.depthDisabledStencilWrite, 0xFF); context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0], nullptr, 0xFFFFFFFF); diff --git a/GPU/D3D11/TextureCacheD3D11.cpp b/GPU/D3D11/TextureCacheD3D11.cpp index 8ceec37249..344fc10a1e 100644 --- a/GPU/D3D11/TextureCacheD3D11.cpp +++ b/GPU/D3D11/TextureCacheD3D11.cpp @@ -434,7 +434,7 @@ void TextureCacheD3D11::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFra context_->PSSetShaderResources(1, 1, &clutTexture); framebufferManagerD3D11_->BindFramebufferAsColorTexture(0, framebuffer, BINDFBCOLOR_SKIP_COPY); context_->PSSetSamplers(0, 1, &stockD3D11.samplerPoint2DWrap); - draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(depalFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); shaderApply.Shade(); framebufferManagerD3D11_->RebindFramebuffer(); diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 14d37ceb9b..4af5f74d07 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -93,11 +93,6 @@ void FramebufferManagerGLES::ClearBuffer(bool keepState) { #endif glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); if (keepState) { - glstate.scissorTest.force(false); - glstate.depthWrite.force(GL_TRUE); - glstate.colorMask.force(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glstate.stencilFunc.force(GL_ALWAYS, 0, 0); - glstate.stencilMask.force(0xFF); glstate.scissorTest.restore(); glstate.depthWrite.restore(); glstate.colorMask.restore(); @@ -239,6 +234,7 @@ FramebufferManagerGLES::FramebufferManagerGLES(Draw::DrawContext *draw) : currentPBO_(0) { needBackBufferYSwap_ = true; + needGLESRebinds_ = true; } void FramebufferManagerGLES::Init() { diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index a595bb19bc..ba5d34a3fa 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -183,9 +183,9 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe Draw::Framebuffer *blitFBO = nullptr; if (useBlit) { blitFBO = GetTempFBO(w, h, Draw::FBO_8888); - draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::CLEAR, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(blitFBO, { Draw::RPAction::DONT_CARE, Draw::RPAction::DONT_CARE }); } else if (dstBuffer->fbo) { - draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::DONT_CARE }); + draw_->BindFramebufferAsRenderTarget(dstBuffer->fbo, { Draw::RPAction::KEEP, Draw::RPAction::CLEAR }); } glViewport(0, 0, w, h); diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index 7c19ad7c7e..2fa7c96208 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -176,6 +176,8 @@ void FramebufferManagerVulkan::NotifyClear(bool clearColor, bool clearAlpha, boo CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); int mask = 0; + // The Clear detection takes care of doing a regular draw instead if separate masking + // of color and alpha is needed, so we can just treat them as the same. if (clearColor || clearAlpha) mask |= Draw::FBChannel::FB_COLOR_BIT; if (clearDepth) @@ -481,8 +483,8 @@ VkImageView FramebufferManagerVulkan::BindFramebufferAsColorTexture(int stage, V draw_->BindFramebufferAsTexture(framebuffer->fbo, stage, Draw::FB_COLOR_BIT, 0); return (VkImageView)draw_->GetNativeObject(Draw::NativeObject::BOUND_TEXTURE_IMAGEVIEW); } else { - ERROR_LOG_REPORT_ONCE(d3d11SelfTexture, G3D, "Attempting to texture to target"); - // Badness on D3D11 to bind the currently rendered-to framebuffer as a texture. + ERROR_LOG_REPORT_ONCE(vulkanSelfTexture, G3D, "Attempting to texture from target"); + // To do this safely in Vulkan, we need to use input attachments. return VK_NULL_HANDLE; } } @@ -1144,4 +1146,5 @@ bool FramebufferManagerVulkan::GetStencilbuffer(u32 fb_address, int fb_stride, G void FramebufferManagerVulkan::ClearBuffer(bool keepState) { // TODO: Ideally, this should never be called. + // assert(false); }