mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
GPU: Force texture invalidation for ZHP minimap.
See #14069, our texture hash misses this change.
This commit is contained in:
parent
5d60fa0d0d
commit
ec3bfe08ae
4 changed files with 35 additions and 10 deletions
|
@ -20,6 +20,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Data/Convert/SmallDataConvert.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/Debugger/Breakpoints.h"
|
||||
|
@ -1053,6 +1054,20 @@ static int Hook_youkosohitsujimura_download_frame() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int Hook_zettai_hero_update_minimap_tex() {
|
||||
const MIPSOpcode storeOffset = Memory::Read_Instruction(currentMIPS->pc + 4, true);
|
||||
const uint32_t texAddr = currentMIPS->r[MIPS_REG_A0] + SignExtend16ToS32(storeOffset);
|
||||
const uint32_t texSize = 64 * 64 * 1;
|
||||
const uint32_t writeAddr = currentMIPS->r[MIPS_REG_V1] + SignExtend16ToS32(storeOffset);
|
||||
if (Memory::IsValidRange(texAddr, texSize) && writeAddr >= texAddr && writeAddr < texAddr + texSize) {
|
||||
const uint8_t currentValue = Memory::Read_U8(writeAddr);
|
||||
if (currentValue != currentMIPS->r[MIPS_REG_A3]) {
|
||||
gpu->InvalidateCache(texAddr, texSize, GPU_INVALIDATE_FORCE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Hook_tonyhawkp8_upload_tutorial_frame() {
|
||||
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
|
||||
if (Memory::IsVRAMAddress(fb_address)) {
|
||||
|
@ -1323,6 +1338,7 @@ static const ReplacementTableEntry entries[] = {
|
|||
{ "photokano_download_frame_2", &Hook_photokano_download_frame_2, 0, REPFLAG_HOOKENTER, },
|
||||
{ "gakuenheaven_download_frame", &Hook_gakuenheaven_download_frame, 0, REPFLAG_HOOKENTER, },
|
||||
{ "youkosohitsujimura_download_frame", &Hook_youkosohitsujimura_download_frame, 0, REPFLAG_HOOKENTER, 0x94 },
|
||||
{ "zettai_hero_update_minimap_tex", &Hook_zettai_hero_update_minimap_tex, 0, REPFLAG_HOOKEXIT, },
|
||||
{ "tonyhawkp8_upload_tutorial_frame", &Hook_tonyhawkp8_upload_tutorial_frame, 0, REPFLAG_HOOKENTER, },
|
||||
{ "sdgundamggenerationportable_download_frame", &Hook_sdgundamggenerationportable_download_frame, 0, REPFLAG_HOOKENTER, 0x34 },
|
||||
{ "atvoffroadfurypro_download_frame", &Hook_atvoffroadfurypro_download_frame, 0, REPFLAG_HOOKENTER, 0xA0 },
|
||||
|
|
|
@ -102,6 +102,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
|
|||
{ 0x030507c9a1f0fc85, 92, "matrix_rot_x", },
|
||||
{ 0x0483fceefa4557ff, 1360, "__udivdi3", },
|
||||
{ 0x0558ad5c5be00ca1, 76, "vtfm_t", },
|
||||
{ 0x05aceb23092fd6a1, 36, "zettai_hero_update_minimap_tex", }, // Zettai Hero Project (US)
|
||||
{ 0x05aedd0c04b451a1, 356, "sqrt", },
|
||||
{ 0x0654fc8adbe16ef7, 28, "vmul_q", },
|
||||
{ 0x06628f6052cda3c1, 1776, "toheart2_download_frame", }, // To Heart 2 Portable
|
||||
|
|
|
@ -1795,7 +1795,7 @@ void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type
|
|||
}
|
||||
|
||||
// If we're hashing every use, without backoff, then this isn't needed.
|
||||
if (!g_Config.bTextureBackoffCache) {
|
||||
if (!g_Config.bTextureBackoffCache && type != GPU_INVALIDATE_FORCE) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1806,28 +1806,34 @@ void TextureCacheCommon::Invalidate(u32 addr, int size, GPUInvalidationType type
|
|||
}
|
||||
|
||||
for (TexCache::iterator iter = cache_.lower_bound(startKey), end = cache_.upper_bound(endKey); iter != end; ++iter) {
|
||||
u32 texAddr = iter->second->addr;
|
||||
u32 texEnd = iter->second->addr + iter->second->sizeInRAM;
|
||||
auto &entry = iter->second;
|
||||
u32 texAddr = entry->addr;
|
||||
u32 texEnd = entry->addr + entry->sizeInRAM;
|
||||
|
||||
// Quick check for overlap. Yes the check is right.
|
||||
if (addr < texEnd && addr_end > texAddr) {
|
||||
if (iter->second->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) {
|
||||
iter->second->SetHashStatus(TexCacheEntry::STATUS_HASHING);
|
||||
if (entry->GetHashStatus() == TexCacheEntry::STATUS_RELIABLE) {
|
||||
entry->SetHashStatus(TexCacheEntry::STATUS_HASHING);
|
||||
}
|
||||
if (type == GPU_INVALIDATE_FORCE) {
|
||||
// Just random values to force the hash not to match.
|
||||
entry->fullhash = (entry->fullhash ^ 0x12345678) + 13;
|
||||
entry->hash = (entry->hash ^ 0x89ABCDEF) + 89;
|
||||
}
|
||||
if (type != GPU_INVALIDATE_ALL) {
|
||||
gpuStats.numTextureInvalidations++;
|
||||
// Start it over from 0 (unless it's safe.)
|
||||
iter->second->numFrames = type == GPU_INVALIDATE_SAFE ? 256 : 0;
|
||||
entry->numFrames = type == GPU_INVALIDATE_SAFE ? 256 : 0;
|
||||
if (type == GPU_INVALIDATE_SAFE) {
|
||||
u32 diff = gpuStats.numFlips - iter->second->lastFrame;
|
||||
u32 diff = gpuStats.numFlips - entry->lastFrame;
|
||||
// We still need to mark if the texture is frequently changing, even if it's safely changing.
|
||||
if (diff < TEXCACHE_FRAME_CHANGE_FREQUENT) {
|
||||
iter->second->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
entry->status |= TexCacheEntry::STATUS_CHANGE_FREQUENT;
|
||||
}
|
||||
}
|
||||
iter->second->framesUntilNextFullHash = 0;
|
||||
entry->framesUntilNextFullHash = 0;
|
||||
} else {
|
||||
iter->second->invalidHint++;
|
||||
entry->invalidHint++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,6 +153,8 @@ enum GPUInvalidationType {
|
|||
GPU_INVALIDATE_HINT,
|
||||
// Reliable invalidation (where any hashing, etc. is unneeded, it'll always invalidate.)
|
||||
GPU_INVALIDATE_SAFE,
|
||||
// Forced invalidation for when the texture hash may not catch changes.
|
||||
GPU_INVALIDATE_FORCE,
|
||||
};
|
||||
|
||||
namespace Draw {
|
||||
|
|
Loading…
Add table
Reference in a new issue