diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index e13d7275c01d..d01fb17df6b1 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -383,18 +383,15 @@ void DoState(PointerWrap &p) p.DoMarker("ScratchPad"); } -void Shutdown() -{ +void Shutdown() { lock_guard guard(g_shutdownLock); u32 flags = 0; - MemoryMap_Shutdown(flags); - base = NULL; + base = nullptr; DEBUG_LOG(MEMMAP, "Memory system shut down."); } -void Clear() -{ +void Clear() { if (m_pRAM) memset(GetPointerUnchecked(PSP_GetKernelMemoryBase()), 0, g_MemorySize); if (m_pScratchPad) @@ -403,6 +400,10 @@ void Clear() memset(m_pVRAM, 0, VRAM_SIZE); } +bool IsActive() { + return base != nullptr; +} + // Wanting to avoid include pollution, MemMap.h is included a lot. MemoryInitedLock::MemoryInitedLock() { diff --git a/Core/MemMap.h b/Core/MemMap.h index c2b4ad3b12a6..b397781c3742 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -130,6 +130,8 @@ void Init(); void Shutdown(); void DoState(PointerWrap &p); void Clear(); +// False when shutdown has already been called. +bool IsActive(); class MemoryInitedLock { diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index fa8011231030..20dd23a2664e 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -355,6 +355,9 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame needsRecreate = needsRecreate || vfb->newHeight > vfb->bufferHeight || vfb->newHeight * 2 < vfb->bufferHeight; if (needsRecreate) { ResizeFramebufFBO(vfb, vfb->width, vfb->height, true); + // Let's discard this information, might be wrong now. + vfb->safeWidth = 0; + vfb->safeHeight = 0; } else { // Even though we won't resize it, let's at least change the size params. vfb->width = drawing_width; @@ -378,7 +381,8 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame // None found? Create one. if (!vfb) { vfb = new VirtualFramebuffer(); - vfb->fbo = 0; + memset(vfb, 0, sizeof(VirtualFramebuffer)); + vfb->fbo = nullptr; vfb->fb_address = params.fb_address; vfb->fb_stride = params.fb_stride; vfb->z_address = params.z_address; @@ -393,8 +397,6 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame vfb->bufferWidth = drawing_width; vfb->bufferHeight = drawing_height; vfb->format = params.fmt; - vfb->drawnWidth = 0; - vfb->drawnHeight = 0; vfb->drawnFormat = params.fmt; vfb->usageFlags = FB_USAGE_RENDERTARGET; SetColorUpdated(vfb, skipDrawReason); @@ -412,10 +414,6 @@ VirtualFramebuffer *FramebufferManagerCommon::DoSetRenderFrameBuffer(const Frame INFO_LOG(SCEGE, "Creating FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format); vfb->last_frame_render = gpuStats.numFlips; - vfb->last_frame_used = 0; - vfb->last_frame_attached = 0; - vfb->last_frame_displayed = 0; - vfb->last_frame_clut = 0; frameLastFramebufUsed_ = gpuStats.numFlips; vfbs_.push_back(vfb); currentRenderVfb_ = vfb; @@ -771,6 +769,7 @@ VirtualFramebuffer *FramebufferManagerCommon::FindDownloadTempBuffer(VirtualFram // Create a new fbo if none was found for the size if (!nvfb) { nvfb = new VirtualFramebuffer(); + memset(nvfb, 0, sizeof(VirtualFramebuffer)); nvfb->fbo = nullptr; nvfb->fb_address = vfb->fb_address; nvfb->fb_stride = vfb->fb_stride; @@ -964,16 +963,27 @@ void FramebufferManagerCommon::SetRenderSize(VirtualFramebuffer *vfb) { break; } + if (hackForce04154000Download_ && vfb->fb_address == 0x00154000) { + force1x = true; + } + if (force1x && g_Config.iInternalResolution != 1) { vfb->renderWidth = vfb->bufferWidth; vfb->renderHeight = vfb->bufferHeight; - } - else { + } else { vfb->renderWidth = (u16)(vfb->bufferWidth * renderWidthFactor); vfb->renderHeight = (u16)(vfb->bufferHeight * renderHeightFactor); } } +void FramebufferManagerCommon::SetSafeSize(u16 w, u16 h) { + VirtualFramebuffer *vfb = currentRenderVfb_; + if (vfb) { + vfb->safeWidth = std::max(vfb->safeWidth, w); + vfb->safeHeight = std::max(vfb->safeHeight, h); + } +} + void FramebufferManagerCommon::UpdateFramebufUsage(VirtualFramebuffer *vfb) { auto checkFlag = [&](u16 flag, int last_frame) { if (vfb->usageFlags & flag) { diff --git a/GPU/Common/FramebufferCommon.h b/GPU/Common/FramebufferCommon.h index b8464ee3ccac..9fe53073e282 100644 --- a/GPU/Common/FramebufferCommon.h +++ b/GPU/Common/FramebufferCommon.h @@ -99,6 +99,8 @@ struct VirtualFramebuffer { u16 drawnWidth; u16 drawnHeight; GEBufferFormat drawnFormat; + u16 safeWidth; + u16 safeHeight; bool dirtyAfterDisplay; bool reallyDirtyAfterDisplay; // takes frame skipping into account @@ -224,6 +226,7 @@ class FramebufferManagerCommon { } } void SetRenderSize(VirtualFramebuffer *vfb); + void SetSafeSize(u16 w, u16 h); protected: void UpdateSize(); diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index 685976115f0f..5466f4826daa 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -92,7 +92,7 @@ static void RotateUVThrough(TransformedVertex v[4]) { // Clears on the PSP are best done by drawing a series of vertical strips // in clear mode. This tries to detect that. -static bool IsReallyAClear(const TransformedVertex *transformed, int numVerts) { +static bool IsReallyAClear(const TransformedVertex *transformed, int numVerts, float x2, float y2) { if (transformed[0].x != 0.0f || transformed[0].y != 0.0f) return false; @@ -100,21 +100,18 @@ static bool IsReallyAClear(const TransformedVertex *transformed, int numVerts) { u32 matchcolor = transformed[1].color0_32; float matchz = transformed[1].z; - int bufW = gstate_c.curRTWidth; - int bufH = gstate_c.curRTHeight; - for (int i = 1; i < numVerts; i++) { if ((i & 1) == 0) { // Top left of a rectangle - if (transformed[i].y != 0) + if (transformed[i].y != 0.0f) return false; if (i > 0 && transformed[i].x != transformed[i - 1].x) return false; } else { - if ((i & 1) && (transformed[i].color0_32 != matchcolor || transformed[i].z != matchz)) + if (transformed[i].color0_32 != matchcolor || transformed[i].z != matchz) return false; // Bottom right - if (transformed[i].y != bufH) + if (transformed[i].y < y2) return false; if (transformed[i].x <= transformed[i - 1].x) return false; @@ -122,7 +119,7 @@ static bool IsReallyAClear(const TransformedVertex *transformed, int numVerts) { } // The last vertical strip often extends outside the drawing area. - if (transformed[numVerts - 1].x < bufW) + if (transformed[numVerts - 1].x < x2) return false; return true; @@ -411,7 +408,13 @@ void SoftwareTransform( // rectangle out of many. Quite a small optimization though. // Experiment: Disable on PowerVR (see issue #6290) // TODO: This bleeds outside the play area in non-buffered mode. Big deal? Probably not. - if (maxIndex > 1 && gstate.isModeClear() && prim == GE_PRIM_RECTANGLES && IsReallyAClear(transformed, maxIndex) && gl_extensions.gpuVendor != GPU_VENDOR_POWERVR) { // && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) { + bool reallyAClear = false; + if (maxIndex > 1 && prim == GE_PRIM_RECTANGLES && gstate.isModeClear()) { + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; + reallyAClear = IsReallyAClear(transformed, maxIndex, scissorX2, scissorY2); + } + if (reallyAClear && gl_extensions.gpuVendor != GPU_VENDOR_POWERVR) { // && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE) { // If alpha is not allowed to be separate, it must match for both depth/stencil and color. Vulkan requires this. bool alphaMatchesColor = gstate.isClearModeColorMask() == gstate.isClearModeAlphaMask(); bool depthMatchesStencil = gstate.isClearModeAlphaMask() == gstate.isClearModeDepthMask(); diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 75f4cedfc665..5a312ce05b9a 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -885,6 +885,10 @@ void DrawEngineDX9::DoFlush() { dxstate.colorMask.set((mask & D3DCLEAR_TARGET) != 0, (mask & D3DCLEAR_TARGET) != 0, (mask & D3DCLEAR_TARGET) != 0, (mask & D3DCLEAR_STENCIL) != 0); pD3Ddevice->Clear(0, NULL, mask, clearColor, clearDepth, clearColor >> 24); + + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; + framebufferManager_->SetSafeSize(scissorX2, scissorY2); } } diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 63ec3533f99f..66af073c10bb 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -1140,7 +1140,7 @@ namespace DX9 { void FramebufferManagerDX9::EndFrame() { if (resized_) { - DestroyAllFBOs(); + DestroyAllFBOs(false); // Actually, auto mode should be more granular... // Round up to a zoom factor for the render size. int zoom = g_Config.iInternalResolution; @@ -1173,7 +1173,7 @@ namespace DX9 { } void FramebufferManagerDX9::DeviceLost() { - DestroyAllFBOs(); + DestroyAllFBOs(false); resized_ = false; } @@ -1218,6 +1218,9 @@ namespace DX9 { if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) { if (age > FBO_OLD_AGE) { INFO_LOG(SCEGE, "Decimating FBO for %08x (%i x %i x %i), age %i", vfb->fb_address, vfb->width, vfb->height, vfb->format, age); + if (!g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) { + ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + } DestroyFramebuf(vfb); vfbs_.erase(vfbs_.begin() + i--); } @@ -1256,7 +1259,7 @@ namespace DX9 { } } - void FramebufferManagerDX9::DestroyAllFBOs() { + void FramebufferManagerDX9::DestroyAllFBOs(bool forceDelete) { fbo_unbind(); currentRenderVfb_ = 0; displayFramebuf_ = 0; @@ -1266,6 +1269,12 @@ namespace DX9 { for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; INFO_LOG(SCEGE, "Destroying FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format); + if (!forceDelete && !g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) { + // But also let's check if Memory is shut down already. + if (Memory::IsActive()) { + ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + } + } DestroyFramebuf(vfb); } vfbs_.clear(); diff --git a/GPU/Directx9/FramebufferDX9.h b/GPU/Directx9/FramebufferDX9.h index 0063107981a4..3c8eec8aeee3 100644 --- a/GPU/Directx9/FramebufferDX9.h +++ b/GPU/Directx9/FramebufferDX9.h @@ -60,7 +60,7 @@ class FramebufferManagerDX9 : public FramebufferManagerCommon { void DrawActiveTexture(LPDIRECT3DTEXTURE9 texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation); - void DestroyAllFBOs(); + void DestroyAllFBOs(bool forceDelete); void EndFrame(); void Resized(); diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 9e29ad3dd8db..62cab89c22f1 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -511,7 +511,7 @@ void GPU_DX9::CheckGPUFeatures() { } GPU_DX9::~GPU_DX9() { - framebufferManager_.DestroyAllFBOs(); + framebufferManager_.DestroyAllFBOs(true); shaderManager_->ClearCache(true); delete shaderManager_; } @@ -2137,7 +2137,7 @@ void GPU_DX9::DoState(PointerWrap &p) { drawEngine_.ClearTrackedVertexArrays(); gstate_c.textureChanged = TEXCHANGE_UPDATED; - framebufferManager_.DestroyAllFBOs(); + framebufferManager_.DestroyAllFBOs(true); shaderManager_->ClearCache(true); } } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index c71387189de7..f13b061dc01c 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -981,6 +981,10 @@ void DrawEngineGLES::DoFlush() { glClearStencil(clearColor >> 24); glClear(target); framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason); + + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; + framebufferManager_->SetSafeSize(scissorX2, scissorY2); } } diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 8ecce9e131ef..1f09773f5e5c 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -1784,7 +1784,7 @@ void FramebufferManager::PackDepthbuffer(VirtualFramebuffer *vfb, int x, int y, void FramebufferManager::EndFrame() { if (resized_) { // TODO: Only do this if the new size actually changed the renderwidth/height. - DestroyAllFBOs(); + DestroyAllFBOs(false); // Probably not necessary glstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); @@ -1854,7 +1854,7 @@ void FramebufferManager::EndFrame() { } void FramebufferManager::DeviceLost() { - DestroyAllFBOs(); + DestroyAllFBOs(false); DestroyDraw2DProgram(); resized_ = false; } @@ -1897,6 +1897,9 @@ void FramebufferManager::DecimateFBOs() { if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) { if (age > FBO_OLD_AGE) { INFO_LOG(SCEGE, "Decimating FBO for %08x (%i x %i x %i), age %i", vfb->fb_address, vfb->width, vfb->height, vfb->format, age); + if (!g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) { + ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + } DestroyFramebuf(vfb); vfbs_.erase(vfbs_.begin() + i--); } @@ -1925,7 +1928,7 @@ void FramebufferManager::DecimateFBOs() { } } -void FramebufferManager::DestroyAllFBOs() { +void FramebufferManager::DestroyAllFBOs(bool forceDelete) { fbo_unbind(); currentRenderVfb_ = 0; displayFramebuf_ = 0; @@ -1935,6 +1938,12 @@ void FramebufferManager::DestroyAllFBOs() { for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; INFO_LOG(SCEGE, "Destroying FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format); + if (!forceDelete && !g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) { + // But also let's check if Memory is shut down already. + if (Memory::IsActive()) { + ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + } + } DestroyFramebuf(vfb); } vfbs_.clear(); diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 64e9390f982e..5efe76a67a9f 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -82,7 +82,7 @@ class FramebufferManager : public FramebufferManagerCommon { // x,y,w,h are relative to destW, destH which fill out the target completely. void DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation); - void DestroyAllFBOs(); + void DestroyAllFBOs(bool forceDelete); virtual void Init() override; void EndFrame(); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index b542631a0a12..9b1034fa9bda 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -469,7 +469,7 @@ GPU_GLES::GPU_GLES(GraphicsContext *ctx) } GPU_GLES::~GPU_GLES() { - framebufferManager_.DestroyAllFBOs(); + framebufferManager_.DestroyAllFBOs(true); shaderManager_->ClearCache(true); depalShaderCache_.Clear(); fragmentTestCache_.Clear(); @@ -660,7 +660,7 @@ void GPU_GLES::Reinitialize() { void GPU_GLES::ReinitializeInternal() { textureCache_.Clear(true); depalShaderCache_.Clear(); - framebufferManager_.DestroyAllFBOs(); + framebufferManager_.DestroyAllFBOs(true); framebufferManager_.Resized(); } @@ -2401,7 +2401,7 @@ void GPU_GLES::DoState(PointerWrap &p) { drawEngine_.ClearTrackedVertexArrays(); gstate_c.textureChanged = TEXCHANGE_UPDATED; - framebufferManager_.DestroyAllFBOs(); + framebufferManager_.DestroyAllFBOs(true); shaderManager_->ClearCache(true); } } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 6c8b56cc565a..95638f624787 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -826,6 +826,10 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { // We let the framebuffer manager handle the clear. It can use renderpasses to optimize on tilers. framebufferManager_->NotifyClear(gstate.isClearModeColorMask(), gstate.isClearModeAlphaMask(), gstate.isClearModeDepthMask(), result.color, result.depth); + + int scissorX2 = gstate.getScissorX2() + 1; + int scissorY2 = gstate.getScissorY2() + 1; + framebufferManager_->SetSafeSize(scissorX2, scissorY2); } } diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index bef4600ff616..b16a90eab7e3 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -1456,7 +1456,7 @@ void FramebufferManagerVulkan::BeginFrameVulkan() { void FramebufferManagerVulkan::EndFrame() { if (resized_) { // TODO: Only do this if the new size actually changed the renderwidth/height. - DestroyAllFBOs(); + DestroyAllFBOs(false); // Check if postprocessing shader is doing upscaling as it requires native resolution const ShaderInfo *shaderInfo = 0; @@ -1512,7 +1512,7 @@ void FramebufferManagerVulkan::EndFrame() { } void FramebufferManagerVulkan::DeviceLost() { - DestroyAllFBOs(); + DestroyAllFBOs(false); resized_ = false; } @@ -1553,6 +1553,9 @@ void FramebufferManagerVulkan::DecimateFBOs() { if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) { if (age > FBO_OLD_AGE) { INFO_LOG(SCEGE, "Decimating FBO for %08x (%i x %i x %i), age %i", vfb->fb_address, vfb->width, vfb->height, vfb->format, age); + if (!g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) { + ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + } DestroyFramebuf(vfb); vfbs_.erase(vfbs_.begin() + i--); } @@ -1560,7 +1563,7 @@ void FramebufferManagerVulkan::DecimateFBOs() { } } -void FramebufferManagerVulkan::DestroyAllFBOs() { +void FramebufferManagerVulkan::DestroyAllFBOs(bool forceDelete) { currentRenderVfb_ = 0; displayFramebuf_ = 0; prevDisplayFramebuf_ = 0; @@ -1569,6 +1572,12 @@ void FramebufferManagerVulkan::DestroyAllFBOs() { for (size_t i = 0; i < vfbs_.size(); ++i) { VirtualFramebuffer *vfb = vfbs_[i]; INFO_LOG(SCEGE, "Destroying FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format); + if (!forceDelete && !g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) { + // But also let's check if Memory is shut down already. + if (Memory::IsActive()) { + ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight); + } + } DestroyFramebuf(vfb); } vfbs_.clear(); diff --git a/GPU/Vulkan/FramebufferVulkan.h b/GPU/Vulkan/FramebufferVulkan.h index 9093375625cb..c6dd64864b2b 100644 --- a/GPU/Vulkan/FramebufferVulkan.h +++ b/GPU/Vulkan/FramebufferVulkan.h @@ -95,7 +95,7 @@ class FramebufferManagerVulkan : public FramebufferManagerCommon { // x,y,w,h are relative to destW, destH which fill out the target completely. void DrawTexture(VulkanTexture *texture, float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, VkPipeline pipeline, int uvRotation); - void DestroyAllFBOs(); + void DestroyAllFBOs(bool forceDelete); virtual void Init() override; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 6f91e2ec7c22..97922f20c76d 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -455,7 +455,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *ctx) } GPU_Vulkan::~GPU_Vulkan() { - framebufferManager_->DestroyAllFBOs(); + framebufferManager_->DestroyAllFBOs(true); depalShaderCache_.Clear(); delete framebufferManager_; delete pipelineManager_; @@ -614,7 +614,7 @@ void GPU_Vulkan::Reinitialize() { void GPU_Vulkan::ReinitializeInternal() { textureCache_.Clear(true); depalShaderCache_.Clear(); - framebufferManager_->DestroyAllFBOs(); + framebufferManager_->DestroyAllFBOs(true); framebufferManager_->Resized(); } @@ -2236,7 +2236,7 @@ void GPU_Vulkan::DoState(PointerWrap &p) { depalShaderCache_.Clear(); gstate_c.textureChanged = TEXCHANGE_UPDATED; - framebufferManager_->DestroyAllFBOs(); + framebufferManager_->DestroyAllFBOs(true); shaderManager_->ClearShaders(); pipelineManager_->Clear(); }