Fix the size calculation when hashing small swizzled textures

This commit is contained in:
Henrik Rydgård 2023-12-07 10:45:31 +01:00
parent 36a2174ac0
commit 443a882041
2 changed files with 16 additions and 4 deletions

View File

@ -2115,7 +2115,8 @@ void TextureCacheCommon::ApplyTexture() {
// Update the hash on the texture.
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
entry->fullhash = QuickTexHash(replacer_, entry->addr, entry->bufw, w, h, GETextureFormat(entry->format), entry);
bool swizzled = gstate.isTextureSwizzled();
entry->fullhash = QuickTexHash(replacer_, entry->addr, entry->bufw, w, h, swizzled, GETextureFormat(entry->format), entry);
// TODO: Here we could check the secondary cache; maybe the texture is in there?
// We would need to abort the build if so.
@ -2536,6 +2537,7 @@ bool TextureCacheCommon::CheckFullHash(TexCacheEntry *entry, bool &doDelete) {
int w = gstate.getTextureWidth(0);
int h = gstate.getTextureHeight(0);
bool isVideo = IsVideo(entry->addr);
bool swizzled = gstate.isTextureSwizzled();
// Don't even check the texture, just assume it has changed.
if (isVideo && g_Config.bTextureBackoffCache) {
@ -2547,7 +2549,7 @@ bool TextureCacheCommon::CheckFullHash(TexCacheEntry *entry, bool &doDelete) {
u32 fullhash;
{
PROFILE_THIS_SCOPE("texhash");
fullhash = QuickTexHash(replacer_, entry->addr, entry->bufw, w, h, GETextureFormat(entry->format), entry);
fullhash = QuickTexHash(replacer_, entry->addr, entry->bufw, w, h, swizzled, GETextureFormat(entry->format), entry);
}
if (fullhash == entry->fullhash) {

View File

@ -438,7 +438,7 @@ protected:
static CheckAlphaResult CheckCLUTAlpha(const uint8_t *pixelData, GEPaletteFormat clutFmt, int w);
inline u32 QuickTexHash(TextureReplacer &replacer, u32 addr, int bufw, int w, int h, GETextureFormat format, const TexCacheEntry *entry) const {
static inline u32 QuickTexHash(TextureReplacer &replacer, u32 addr, int bufw, int w, int h, bool swizzled, GETextureFormat format, const TexCacheEntry *entry) {
if (replacer.Enabled()) {
return replacer.ComputeHash(addr, bufw, w, h, format, entry->maxSeenV);
}
@ -447,7 +447,17 @@ protected:
h = (int)entry->maxSeenV;
}
const u32 sizeInRAM = (textureBitsPerPixel[format] * bufw * h) / 8;
u32 sizeInRAM;
if (swizzled) {
// In swizzle mode, textures are stored in rectangular blocks with the height 8.
// That means that for a 64x4 texture, like in issue #9308, we would only hash half of the texture!
// In theory, we should make sure to only hash half of each block, but in reality it's not likely that
// games are using that memory for anything else. So we'll just make sure to compute the full size to hash.
// To do that, we just use the same calculation but round the height upwards to the nearest multiple of 8.
sizeInRAM = (textureBitsPerPixel[format] * bufw * ((h + 7) & ~7)) >> 3;
} else {
sizeInRAM = (textureBitsPerPixel[format] * bufw * h) >> 3;
}
const u32 *checkp = (const u32 *)Memory::GetPointer(addr);
gpuStats.numTextureDataBytesHashed += sizeInRAM;