mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
Merge pull request #8757 from unknownbrackets/gpu-save-decimate
Save FBOs on decimate when a safe size is known
This commit is contained in:
commit
a0ce8025d6
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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) {
|
||||
|
@ -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 @@ public:
|
||||
}
|
||||
}
|
||||
void SetRenderSize(VirtualFramebuffer *vfb);
|
||||
void SetSafeSize(u16 w, u16 h);
|
||||
|
||||
protected:
|
||||
void UpdateSize();
|
||||
|
@ -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();
|
||||
|
@ -885,6 +885,10 @@ rotateVBO:
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
|
||||
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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -981,6 +981,10 @@ rotateVBO:
|
||||
glClearStencil(clearColor >> 24);
|
||||
glClear(target);
|
||||
framebufferManager_->SetColorUpdated(gstate_c.skipDrawReason);
|
||||
|
||||
int scissorX2 = gstate.getScissorX2() + 1;
|
||||
int scissorY2 = gstate.getScissorY2() + 1;
|
||||
framebufferManager_->SetSafeSize(scissorX2, scissorY2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
// 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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
// 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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user