Track temporary-use FBOs all in FramebufferManager.

This way it's easier to manage their lifecycle.
This commit is contained in:
Unknown W. Brackets 2014-05-31 22:41:41 -07:00
parent 4195eac04f
commit 0846673dc3
4 changed files with 41 additions and 44 deletions

View File

@ -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<int, int> 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_(&copyInfo, 0, 0, framebuffer, 0, 0, framebuffer->width, framebuffer->height, 0, false);
VirtualFramebuffer copyInfo = *framebuffer;
copyInfo.fbo = renderCopy;
BlitFramebuffer_(&copyInfo, 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);
}

View File

@ -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<VirtualFramebuffer *> bvfbs_; // blitting FBOs
std::map<std::pair<int, int>, FBO *> renderCopies_;
struct TempFBO {
FBO *fbo;
int last_frame_used;
};
std::vector<VirtualFramebuffer *> bvfbs_; // blitting framebuffers (for download)
std::map<u64, TempFBO> tempFBOs_;
std::set<std::pair<u32, u32>> knownFramebufferRAMCopies_;

View File

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

View File

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