Save FBOs on decimate when they have a safe size.

Fixes #7695.
This commit is contained in:
Unknown W. Brackets 2016-05-19 21:23:22 -07:00
parent eee98966f4
commit f08c873a4b
9 changed files with 47 additions and 20 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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();
}