rend: fix hash of vq textures

Do correct hashing of VQ textures to avoid hash conflicts. Keep previous
hash for backward-compatibility.
Issue #1291
This commit is contained in:
Flyinghead 2023-11-11 18:57:16 +01:00
parent 41723a831f
commit 535fbe29f8
3 changed files with 31 additions and 9 deletions

View File

@ -63,10 +63,10 @@ void CustomTexture::LoaderThread()
{
int width, height;
u8 *image_data = LoadCustomTexture(texture->texture_hash, width, height);
if (image_data == nullptr && texture->old_vqtexture_hash != 0)
image_data = LoadCustomTexture(texture->old_vqtexture_hash, width, height);
if (image_data == nullptr)
{
image_data = LoadCustomTexture(texture->old_texture_hash, width, height);
}
if (image_data != nullptr)
{
texture->custom_width = width;

View File

@ -554,6 +554,8 @@ BaseTextureCacheData::BaseTextureCacheData(TSP tsp, TCW tcw)
void BaseTextureCacheData::ComputeHash()
{
// Include everything but texaddr, reserved and stride. Palette textures don't have ScanOrder
const u32 tcwMask = IsPaletted() ? 0xF8000000 : 0xFC000000;
u32 hashSize = size;
if (tcw.VQ_Comp)
{
@ -561,14 +563,33 @@ void BaseTextureCacheData::ComputeHash()
// We use the old size to compute the hash for backward-compatibility
// with existing custom texture packs.
hashSize = size - 256 * 8;
old_vqtexture_hash = XXH32(&vram[sa], hashSize, 7);
if (IsPaletted())
old_vqtexture_hash ^= palette_hash;
old_texture_hash = old_vqtexture_hash;
old_vqtexture_hash ^= tcw.full & tcwMask;
// New hash
XXH32_state_t *state = XXH32_createState();
XXH32_reset(state, 7);
// hash vq codebook
XXH32_update(state, &vram[sa_tex], 256 * 8);
// hash texture
XXH32_update(state, &vram[sa + 256 * 8], hashSize);
texture_hash = XXH32_digest(state);
XXH32_freeState(state);
if (IsPaletted())
texture_hash ^= palette_hash;
texture_hash ^= tcw.full & tcwMask;
}
else
{
old_vqtexture_hash = 0;
texture_hash = XXH32(&vram[sa], hashSize, 7);
if (IsPaletted())
texture_hash ^= palette_hash;
old_texture_hash = texture_hash;
texture_hash ^= tcw.full & tcwMask;
}
texture_hash = XXH32(&vram[sa], hashSize, 7);
if (IsPaletted())
texture_hash ^= palette_hash;
old_texture_hash = texture_hash;
// Include everything but texaddr, reserved and stride. Palette textures don't have ScanOrder
const u32 tcwMask = IsPaletted() ? 0xF8000000 : 0xFC000000;
texture_hash ^= tcw.full & tcwMask;
}
bool BaseTextureCacheData::Update()

View File

@ -624,6 +624,7 @@ public:
//used for palette updates
u32 palette_hash; // Palette hash at time of last update
u32 texture_hash; // xxhash of texture data, used for custom textures
u32 old_vqtexture_hash; // legacy hash for vq textures
u32 old_texture_hash; // legacy hash
u8* custom_image_data; // loaded custom image data
u32 custom_width;