Merge pull request #4274 from unknownbrackets/fb-minor

Detach framebuffers when texcache match fails, properly
This commit is contained in:
Henrik Rydgård 2013-10-27 00:53:44 -07:00
commit 5408a06e6c
2 changed files with 23 additions and 12 deletions

View file

@ -312,7 +312,9 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, GEBufferFormat pixelForm
} }
// TODO: We can just change the texture format and flip some bits around instead of this. // TODO: We can just change the texture format and flip some bits around instead of this.
bool useConvBuf = false;
if (pixelFormat != GE_FORMAT_8888 || linesize != 512) { if (pixelFormat != GE_FORMAT_8888 || linesize != 512) {
useConvBuf = true;
if (!convBuf) { if (!convBuf) {
convBuf = new u8[512 * 272 * 4]; convBuf = new u8[512 * 272 * 4];
} }
@ -385,7 +387,7 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, GEBufferFormat pixelForm
if (g_Config.iTexFiltering == LINEAR || (g_Config.iTexFiltering == LINEARFMV && g_iNumVideos)) { if (g_Config.iTexFiltering == LINEAR || (g_Config.iTexFiltering == LINEARFMV && g_iNumVideos)) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} }
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,272, GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat == GE_FORMAT_8888 ? framebuf : convBuf); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 512, 272, GL_RGBA, GL_UNSIGNED_BYTE, useConvBuf ? convBuf : framebuf);
// This draws directly at the backbuffer so if there's a post shader, we need to apply it here. Should try to unify this path // This draws directly at the backbuffer so if there's a post shader, we need to apply it here. Should try to unify this path
// with the regular path somehow, but this simple solution works for most of the post shaders (it always runs at output resolution so FXAA may look odd). // with the regular path somehow, but this simple solution works for most of the post shaders (it always runs at output resolution so FXAA may look odd).

View file

@ -135,7 +135,7 @@ void TextureCache::Invalidate(u32 addr, int size, GPUInvalidationType type) {
// Start it over from 0 (unless it's safe.) // Start it over from 0 (unless it's safe.)
iter->second.numFrames = type == GPU_INVALIDATE_SAFE ? 256 : 0; iter->second.numFrames = type == GPU_INVALIDATE_SAFE ? 256 : 0;
iter->second.framesUntilNextFullHash = 0; iter->second.framesUntilNextFullHash = 0;
} else { } else if (!iter->second.framebuffer) {
iter->second.invalidHint++; iter->second.invalidHint++;
} }
} }
@ -148,7 +148,9 @@ void TextureCache::InvalidateAll(GPUInvalidationType /*unused*/) {
// Clear status -> STATUS_HASHING. // Clear status -> STATUS_HASHING.
iter->second.status &= ~TexCacheEntry::STATUS_MASK; iter->second.status &= ~TexCacheEntry::STATUS_MASK;
} }
iter->second.invalidHint++; if (!iter->second.framebuffer) {
iter->second.invalidHint++;
}
} }
} }
@ -850,11 +852,17 @@ void TextureCache::SetTexture(bool force) {
#endif #endif
// Check for FBO - slow! // Check for FBO - slow!
if (entry->framebuffer && match) { if (entry->framebuffer) {
SetTextureFramebuffer(entry); if (match) {
lastBoundTexture = -1; SetTextureFramebuffer(entry);
entry->lastFrame = gpuStats.numFlips; lastBoundTexture = -1;
return; entry->lastFrame = gpuStats.numFlips;
return;
} else {
// Make sure we re-evaluate framebuffers.
DetachFramebuffer(entry, texaddr, entry->framebuffer);
match = false;
}
} }
bool rehash = (entry->status & TexCacheEntry::STATUS_MASK) == TexCacheEntry::STATUS_UNRELIABLE; bool rehash = (entry->status & TexCacheEntry::STATUS_MASK) == TexCacheEntry::STATUS_UNRELIABLE;
@ -1000,6 +1008,11 @@ void TextureCache::SetTexture(bool force) {
gstate_c.curTextureWidth = w; gstate_c.curTextureWidth = w;
gstate_c.curTextureHeight = h; gstate_c.curTextureHeight = h;
// Always generate a texture name, we might need it if the texture is replaced later.
if (!replaceImages) {
glGenTextures(1, &entry->texture);
}
// Before we go reading the texture from memory, let's check for render-to-texture. // Before we go reading the texture from memory, let's check for render-to-texture.
for (size_t i = 0, n = fbCache_.size(); i < n; ++i) { for (size_t i = 0, n = fbCache_.size(); i < n; ++i) {
auto framebuffer = fbCache_[i]; auto framebuffer = fbCache_[i];
@ -1024,10 +1037,6 @@ void TextureCache::SetTexture(bool force) {
entry->lastFrame = gpuStats.numFlips; entry->lastFrame = gpuStats.numFlips;
return; return;
} }
if (!replaceImages) {
glGenTextures(1, &entry->texture);
}
glBindTexture(GL_TEXTURE_2D, entry->texture); glBindTexture(GL_TEXTURE_2D, entry->texture);
lastBoundTexture = entry->texture; lastBoundTexture = entry->texture;