Skip to content

Commit

Permalink
Fix the size calculation when hashing small swizzled textures
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Dec 7, 2023
1 parent 36a2174 commit 443a882
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
6 changes: 4 additions & 2 deletions GPU/Common/TextureCacheCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
14 changes: 12 additions & 2 deletions GPU/Common/TextureCacheCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ class TextureCacheCommon {

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);
}
Expand All @@ -447,7 +447,17 @@ class TextureCacheCommon {
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;
Expand Down

0 comments on commit 443a882

Please sign in to comment.