Merge pull request #8806 from unknownbrackets/tex-replace

Flag replaced/scaled textures so we don't reuse them on change
This commit is contained in:
Henrik Rydgård 2016-06-08 08:34:46 +02:00
commit 5da0375ee9
4 changed files with 28 additions and 6 deletions

View File

@ -80,7 +80,8 @@ public:
STATUS_CLUT_RECHECK = 0x20, // Another texture with same addr had a hashfail.
STATUS_DEPALETTIZE = 0x40, // Needs to go through a depalettize pass.
STATUS_TO_SCALE = 0x80, // Pending texture scaling in a later frame.
STATUS_FREE_CHANGE = 0x100, // Allow one change before marking "frequent".
STATUS_IS_SCALED = 0x100, // Has been scaled (can't be replaceImages'd.)
STATUS_FREE_CHANGE = 0x200, // Allow one change before marking "frequent".
};
// Status, but int so we can zero initialize.

View File

@ -1235,7 +1235,7 @@ bool TextureCacheDX9::HandleTextureChange(TexCacheEntry *const entry, const char
gpuStats.numTextureInvalidations++;
DEBUG_LOG(G3D, "Texture different or overwritten, reloading at %08x: %s", entry->addr, reason);
if (doDelete) {
if (initialMatch && standardScaleFactor_ == 1) {
if (initialMatch && standardScaleFactor_ == 1 && (entry->status & TexCacheEntry::STATUS_IS_SCALED) == 0) {
// Actually, if size and number of levels match, let's try to avoid deleting and recreating.
// Instead, let's use glTexSubImage to replace the images.
replaceImages = true;
@ -1244,6 +1244,7 @@ bool TextureCacheDX9::HandleTextureChange(TexCacheEntry *const entry, const char
lastBoundTexture = INVALID_TEX;
}
ReleaseTexture(entry);
entry->status &= ~TexCacheEntry::STATUS_IS_SCALED;
}
}
// Clear the reliable bit if set.
@ -1327,8 +1328,14 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry, bool replaceImage
int h = gstate.getTextureHeight(0);
ReplacedTexture &replaced = replacer.FindReplacement(cachekey, entry->fullhash, w, h);
if (replaced.GetSize(0, w, h)) {
if (replaceImages) {
// Since we're replacing the texture, we can't replace the image inside.
ReleaseTexture(entry);
replaceImages = false;
}
// We're replacing, so we won't scale.
scaleFactor = 1;
entry->status |= TexCacheEntry::STATUS_IS_SCALED;
if (g_Config.bMipMap) {
maxLevel = replaced.MaxLevel();
badMipSizes = false;
@ -1350,6 +1357,7 @@ void TextureCacheDX9::BuildTexture(TexCacheEntry *const entry, bool replaceImage
scaleFactor = 1;
} else {
entry->status &= ~TexCacheEntry::STATUS_TO_SCALE;
entry->status |= TexCacheEntry::STATUS_IS_SCALED;
texelsScaledThisFrame_ += w * h;
}
}

View File

@ -1336,7 +1336,7 @@ bool TextureCache::HandleTextureChange(TexCacheEntry *const entry, const char *r
gpuStats.numTextureInvalidations++;
DEBUG_LOG(G3D, "Texture different or overwritten, reloading at %08x: %s", entry->addr, reason);
if (doDelete) {
if (initialMatch && standardScaleFactor_ == 1) {
if (initialMatch && standardScaleFactor_ == 1 && (entry->status & TexCacheEntry::STATUS_IS_SCALED) == 0) {
// Actually, if size and number of levels match, let's try to avoid deleting and recreating.
// Instead, let's use glTexSubImage to replace the images.
replaceImages = true;
@ -1345,6 +1345,7 @@ bool TextureCache::HandleTextureChange(TexCacheEntry *const entry, const char *r
lastBoundTexture = INVALID_TEX;
}
glDeleteTextures(1, &entry->textureName);
entry->status &= ~TexCacheEntry::STATUS_IS_SCALED;
}
}
// Clear the reliable bit if set.
@ -1388,9 +1389,6 @@ void TextureCache::BuildTexture(TexCacheEntry *const entry, bool replaceImages)
return;
}
glBindTexture(GL_TEXTURE_2D, entry->textureName);
lastBoundTexture = entry->textureName;
// Adjust maxLevel to actually present levels..
bool badMipSizes = false;
int maxLevel = entry->maxLevel;
@ -1433,8 +1431,16 @@ void TextureCache::BuildTexture(TexCacheEntry *const entry, bool replaceImages)
int h = gstate.getTextureHeight(0);
ReplacedTexture &replaced = replacer.FindReplacement(cachekey, entry->fullhash, w, h);
if (replaced.GetSize(0, w, h)) {
if (replaceImages) {
// Since we're replacing the texture, we can't replace the image inside.
glDeleteTextures(1, &entry->textureName);
entry->textureName = AllocTextureName();
replaceImages = false;
}
// We're replacing, so we won't scale.
scaleFactor = 1;
entry->status |= TexCacheEntry::STATUS_IS_SCALED;
if (g_Config.bMipMap) {
maxLevel = replaced.MaxLevel();
badMipSizes = false;
@ -1456,10 +1462,14 @@ void TextureCache::BuildTexture(TexCacheEntry *const entry, bool replaceImages)
scaleFactor = 1;
} else {
entry->status &= ~TexCacheEntry::STATUS_TO_SCALE;
entry->status |= TexCacheEntry::STATUS_IS_SCALED;
texelsScaledThisFrame_ += w * h;
}
}
glBindTexture(GL_TEXTURE_2D, entry->textureName);
lastBoundTexture = entry->textureName;
// Disabled this due to issue #6075: https://github.com/hrydgard/ppsspp/issues/6075
// This breaks Dangan Ronpa 2 with mipmapping enabled. Why? No idea, it shouldn't.
// glTexStorage2D probably has few benefits for us anyway.

View File

@ -1209,6 +1209,7 @@ bool TextureCacheVulkan::HandleTextureChange(TexCacheEntry *const entry, const c
}
delete entry->vkTex;
entry->vkTex = nullptr;
entry->status &= ~TexCacheEntry::STATUS_IS_SCALED;
}
// Clear the reliable bit if set.
if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) {
@ -1290,6 +1291,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry,VulkanPushBuffe
if (replaced.GetSize(0, w, h)) {
// We're replacing, so we won't scale.
scaleFactor = 1;
entry->status |= TexCacheEntry::STATUS_IS_SCALED;
if (g_Config.bMipMap) {
maxLevel = replaced.MaxLevel();
badMipSizes = false;
@ -1311,6 +1313,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry,VulkanPushBuffe
scaleFactor = 1;
} else {
entry->status &= ~TexCacheEntry::STATUS_TO_SCALE;
entry->status |= TexCacheEntry::STATUS_IS_SCALED;
texelsScaledThisFrame_ += w * h;
}
}