TexCache: Force recreate texture on detach.

We could have multiple detaches, and we delete the texture on attach, so
we really must make sure we recreate.

Fixes #13320.
This commit is contained in:
Unknown W. Brackets 2020-08-23 21:29:15 -07:00
parent 3b11b09621
commit f44717c4f5
3 changed files with 17 additions and 3 deletions

View file

@ -407,6 +407,12 @@ void TextureCacheCommon::SetTexture(bool force) {
rehash = false;
}
// Do we need to recreate?
if (entry->status & TexCacheEntry::STATUS_FORCE_REBUILD) {
match = false;
entry->status &= ~TexCacheEntry::STATUS_FORCE_REBUILD;
}
if (match) {
if (entry->lastFrame != gpuStats.numFlips) {
u32 diff = gpuStats.numFlips - entry->lastFrame;
@ -749,11 +755,12 @@ void TextureCacheCommon::DetachFramebuffer(TexCacheEntry *entry, u32 address, Vi
const u64 cachekey = entry->CacheKey();
cacheSizeEstimate_ += EstimateTexMemoryUsage(entry);
entry->framebuffer = nullptr;
// Force the hash to change in case we had one before.
// Force recreate the texture in case we had one before and the hash matches.
// Otherwise we never recreate the texture.
entry->hash ^= 1;
entry->status |= TexCacheEntry::STATUS_FORCE_REBUILD;
fbTexInfo_.erase(cachekey);
GPUDebug::NotifyTextureAttachment(entry->addr);
InvalidateLastTexture(entry);
}
}

View file

@ -126,6 +126,7 @@ struct TexCacheEntry {
STATUS_BAD_MIPS = 0x400, // Has bad or unusable mipmap levels.
STATUS_DEPTH = 0x800,
STATUS_FORCE_REBUILD = 0x1000,
};
// Status, but int so we can zero initialize.

View file

@ -825,8 +825,10 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level)
}
SetTexture(true);
if (!nextTexture_)
if (!nextTexture_) {
ERROR_LOG(G3D, "Failed to get debug texture: no texture set");
return false;
}
// Apply texture may need to rebuild the texture if we're about to render, or bind a framebuffer.
TexCacheEntry *entry = nextTexture_;
@ -844,6 +846,8 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level)
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE);
// We may have blitted to a temp FBO.
framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug");
if (!retval)
ERROR_LOG(G3D, "Failed to get debug texture: copy to memory failed");
return retval;
}
@ -862,6 +866,8 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level)
if (result) {
buffer.Allocate(w, h, GE_FORMAT_8888, false);
renderManager->CopyImageToMemorySync(entry->textureName, level, 0, 0, w, h, Draw::DataFormat::R8G8B8A8_UNORM, (uint8_t *)buffer.GetData(), w, "GetCurrentTextureDebug");
} else {
ERROR_LOG(G3D, "Failed to get debug texture: texture is null");
}
gstate_c.Dirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
framebufferManager_->RebindFramebuffer("RebindFramebuffer - GetCurrentTextureDebug");