From 0846673dc3dafa4f9fdc1968a859956184077123 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 31 May 2014 22:41:41 -0700 Subject: [PATCH] Track temporary-use FBOs all in FramebufferManager. This way it's easier to manage their lifecycle. --- GPU/GLES/Framebuffer.cpp | 50 +++++++++++++++++++++++---------------- GPU/GLES/Framebuffer.h | 12 +++++++--- GPU/GLES/TextureCache.cpp | 22 +++-------------- GPU/GLES/TextureCache.h | 1 - 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index a27fa8748..18f00cfd3 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -363,8 +363,8 @@ FramebufferManager::~FramebufferManager() { } SetNumExtraFBOs(0); - for (auto it = renderCopies_.begin(), end = renderCopies_.end(); it != end; ++it) { - fbo_destroy(it->second); + for (auto it = tempFBOs_.begin(), end = tempFBOs_.end(); it != end; ++it) { + fbo_destroy(it->second.fbo); } #ifndef USING_GLES2 @@ -1016,6 +1016,22 @@ void FramebufferManager::BindFramebufferDepth(VirtualFramebuffer *sourceframebuf } } +FBO *FramebufferManager::GetTempFBO(u16 w, u16 h, FBOColorDepth depth) { + u32 key = ((u64)depth << 32) | (w << 16) | h; + auto it = tempFBOs_.find(key); + if (it != tempFBOs_.end()) { + it->second.last_frame_used = gpuStats.numFlips; + return it->second.fbo; + } + + FBO *fbo = fbo_create(w, h, 1, false, depth); + if (!fbo) + return fbo; + const TempFBO info = {fbo, gpuStats.numFlips}; + tempFBOs_[key] = info; + return fbo; +} + void FramebufferManager::BindFramebufferColor(VirtualFramebuffer *framebuffer, bool skipCopy) { if (framebuffer == NULL) { framebuffer = currentRenderVfb_; @@ -1031,26 +1047,18 @@ void FramebufferManager::BindFramebufferColor(VirtualFramebuffer *framebuffer, b // Let's just not bother with the copy in that case. if (!skipCopy && currentRenderVfb_ && MaskedEqual(framebuffer->fb_address, gstate.getFrameBufRawAddress())) { // TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size. - FBO *renderCopy = NULL; - std::pair copySize = std::make_pair((int)framebuffer->renderWidth, (int)framebuffer->renderHeight); - for (auto it = renderCopies_.begin(), end = renderCopies_.end(); it != end; ++it) { - if (it->first == copySize) { - renderCopy = it->second; - break; - } - } - if (!renderCopy) { - renderCopy = fbo_create(framebuffer->renderWidth, framebuffer->renderHeight, 1, true, framebuffer->colorDepth); - renderCopies_[copySize] = renderCopy; - } + FBO *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, framebuffer->colorDepth); + if (renderCopy) { + VirtualFramebuffer copyInfo = *framebuffer; + copyInfo.fbo = renderCopy; + BlitFramebuffer_(©Info, 0, 0, framebuffer, 0, 0, framebuffer->width, framebuffer->height, 0, false); - VirtualFramebuffer copyInfo = *framebuffer; - copyInfo.fbo = renderCopy; - BlitFramebuffer_(©Info, 0, 0, framebuffer, 0, 0, framebuffer->width, framebuffer->height, 0, false); - - fbo_bind_as_render_target(currentRenderVfb_->fbo); - fbo_bind_color_as_texture(renderCopy, 0); - glstate.viewport.restore(); + fbo_bind_as_render_target(currentRenderVfb_->fbo); + fbo_bind_color_as_texture(renderCopy, 0); + glstate.viewport.restore(); + } else { + fbo_bind_color_as_texture(framebuffer->fbo, 0); + } } else { fbo_bind_color_as_texture(framebuffer->fbo, 0); } diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 26eee974e..8137c39cf 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -86,7 +86,6 @@ struct VirtualFramebuffer { GEBufferFormat format; // virtual, right now they are all RGBA8888 FBOColorDepth colorDepth; FBO *fbo; - FBO *depalFBO; bool dirtyAfterDisplay; bool reallyDirtyAfterDisplay; // takes frame skipping into account @@ -222,6 +221,8 @@ public: void RebindFramebuffer(); + FBO *GetTempFBO(u16 w, u16 h, FBOColorDepth depth = FBO_8888); + private: void CompileDraw2DProgram(); void DestroyDraw2DProgram(); @@ -283,8 +284,13 @@ private: // The range of PSP memory that may contain FBOs. So we can skip iterating. u32 framebufRangeEnd_; - std::vector bvfbs_; // blitting FBOs - std::map, FBO *> renderCopies_; + struct TempFBO { + FBO *fbo; + int last_frame_used; + }; + + std::vector bvfbs_; // blitting framebuffers (for download) + std::map tempFBOs_; std::set> knownFramebufferRAMCopies_; diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 839a759c7..aae75a796 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -119,9 +119,6 @@ void TextureCache::Decimate() { for (TexCache::iterator iter = cache.begin(); iter != cache.end(); ) { if (iter->second.lastFrame + killAge < gpuStats.numFlips) { glDeleteTextures(1, &iter->second.texture); - if (iter->second.depalFBO) { - fbo_destroy(iter->second.depalFBO); - } cache.erase(iter++); } else { ++iter; @@ -133,9 +130,6 @@ void TextureCache::Decimate() { // In low memory mode, we kill them all. if (lowMemoryMode_ || iter->second.lastFrame + TEXTURE_SECOND_KILL_AGE < gpuStats.numFlips) { glDeleteTextures(1, &iter->second.texture); - if (iter->second.depalFBO) { - fbo_destroy(iter->second.depalFBO); - } secondCache.erase(iter++); } else { ++iter; @@ -899,11 +893,8 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) { } if (program) { GLuint clutTexture = depalShaderCache_->GetClutTexture(clutHash_, clutBuf_); - // TODO: What if the renderWidth or renderHeight changes for the attached FBO? - if (!entry->depalFBO) { - entry->depalFBO = fbo_create(entry->framebuffer->renderWidth, entry->framebuffer->renderHeight, 1, false, FBO_8888); - } - fbo_bind_as_render_target(entry->depalFBO); + FBO *depalFBO = framebufferManager_->GetTempFBO(entry->framebuffer->renderWidth, entry->framebuffer->renderHeight, FBO_8888); + fbo_bind_as_render_target(depalFBO); static const float pos[12] = { -1, -1, -1, 1, -1, -1, @@ -956,7 +947,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) { glDisableVertexAttribArray(a_position); glDisableVertexAttribArray(a_texcoord0); - fbo_bind_color_as_texture(entry->depalFBO, 0); + fbo_bind_color_as_texture(depalFBO, 0); glstate.Restore(); framebufferManager_->RebindFramebuffer(); } else { @@ -1198,12 +1189,6 @@ void TextureCache::SetTexture(bool force) { } } } - - // If we had a depalFBO, get rid of it now. - if (entry->depalFBO) { - fbo_destroy(entry->depalFBO); - entry->depalFBO = 0; - } } } else { VERBOSE_LOG(G3D, "No texture in cache, decoding..."); @@ -1230,7 +1215,6 @@ void TextureCache::SetTexture(bool force) { entry->framebuffer = 0; entry->maxLevel = maxLevel; entry->lodBias = 0.0f; - entry->depalFBO = 0; entry->dim = gstate.getTextureDimension(0); entry->bufw = bufw; diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 4b2bcfd3c..725716931 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -120,7 +120,6 @@ public: u32 addr; u32 hash; VirtualFramebuffer *framebuffer; // if null, not sourced from an FBO. - FBO *depalFBO; u32 sizeInRAM; int lastFrame; int numFrames;