From 44dc3555adb41595c526b79c83e2b1dfac60a5dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 8 Dec 2021 21:57:32 +0100 Subject: [PATCH] FramebufferManagerCommon: Fix some issues where currentRenderVfb_ could get out of sync. It would get out of sync with draw_->GetCurrentFramebuffer(), which led to checks for self-texturing not working, hitting an assert. This caused problems when turning off "slow effects", and who knows what else. Fixes #15208 --- GPU/Common/FramebufferManagerCommon.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 90b19fe286..cdc6517a55 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -989,9 +989,8 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G { (uint8_t *)srcPixels }, generateTexture, }; - // TODO: On Vulkan, use a custom allocator? Important to use an allocator: - // Hot Shot Golf (#12355) does tons of these in a frame in some situations! So actually, - // we do use an allocator. In fact, I've now banned allocator-less textures. + // Hot Shots Golf (#12355) does tons of these in a frame in some situations! So creating textures + // better be fast. Draw::Texture *tex = draw_->CreateTexture(desc); if (!tex) ERROR_LOG(G3D, "Failed to create drawpixels texture"); @@ -1053,8 +1052,6 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { DownloadFramebufferOnSwitch(currentRenderVfb_); shaderManager_->DirtyLastShader(); - currentRenderVfb_ = nullptr; - if (displayFramebufPtr_ == 0) { if (Core_IsStepping()) VERBOSE_LOG(FRAMEBUF, "Display disabled, displaying only black"); @@ -1187,6 +1184,7 @@ void FramebufferManagerCommon::CopyDisplayToOutput(bool reallyDirty) { // This may get called mid-draw if the game uses an immediate flip. // PresentationCommon sets all kinds of state, we can't rely on anything. gstate_c.Dirty(DIRTY_ALL); + currentRenderVfb_ = nullptr; } void FramebufferManagerCommon::DecimateFBOs() { @@ -1326,16 +1324,17 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w, // TODO: Swap the order of the below? That way we can avoid the needGLESRebinds_ check below I think. draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); if (!skipCopy) { + // TODO: In this case, it'll nearly always be better to draw the old framebuffer to the new one than to do an actual blit. + // Usually hardly a performance issue though. BlitFramebuffer(vfb, 0, 0, &old, 0, 0, std::min((u16)oldWidth, std::min(vfb->bufferWidth, vfb->width)), std::min((u16)oldHeight, std::min(vfb->height, vfb->bufferHeight)), 0, "Blit_ResizeFramebufFBO"); } } fbosToDelete_.push_back(old.fbo); - if (needGLESRebinds_) { - draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "ResizeFramebufFBO"); - } + draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "ResizeFramebufFBO"); } else { draw_->BindFramebufferAsRenderTarget(vfb->fbo, { Draw::RPAction::CLEAR, Draw::RPAction::CLEAR, Draw::RPAction::CLEAR }, "ResizeFramebufFBO"); } + currentRenderVfb_ = vfb; if (!vfb->fbo) { ERROR_LOG(FRAMEBUF, "Error creating FBO during resize! %dx%d", vfb->renderWidth, vfb->renderHeight);