mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-25 17:19:42 +00:00
Track temporary-use FBOs all in FramebufferManager.
This way it's easier to manage their lifecycle.
This commit is contained in:
parent
4195eac04f
commit
0846673dc3
@ -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_(©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);
|
||||
}
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user