mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
Merge pull request #18484 from hrydgard/mlb-fix
Fix frozen pitch meters in MLB series games - we were not hashing enough texture data
This commit is contained in:
commit
8dab823936
@ -14,7 +14,7 @@
|
||||
#include "Core/KeyMap.h"
|
||||
|
||||
void Screen::focusChanged(ScreenFocusChange focusChange) {
|
||||
char *eventName = "";
|
||||
const char *eventName = "";
|
||||
switch (focusChange) {
|
||||
case ScreenFocusChange::FOCUS_LOST_TOP: eventName = "FOCUS_LOST_TOP"; break;
|
||||
case ScreenFocusChange::FOCUS_BECAME_TOP: eventName = "FOCUS_BECAME_TOP"; break;
|
||||
|
@ -494,6 +494,7 @@ TexCacheEntry *TextureCacheCommon::SetTexture() {
|
||||
// Exponential backoff up to 512 frames. Textures are often reused.
|
||||
if (entry->numFrames > 32) {
|
||||
// Also, try to add some "randomness" to avoid rehashing several textures the same frame.
|
||||
// textureName is unioned with texturePtr and vkTex so will work for the other backends.
|
||||
entry->framesUntilNextFullHash = std::min(512, entry->numFrames) + (((intptr_t)(entry->textureName) >> 12) & 15);
|
||||
} else {
|
||||
entry->framesUntilNextFullHash = entry->numFrames;
|
||||
@ -2114,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.
|
||||
@ -2535,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) {
|
||||
@ -2546,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) {
|
||||
|
@ -438,16 +438,26 @@ 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);
|
||||
return replacer.ComputeHash(addr, bufw, w, h, swizzled, format, entry->maxSeenV);
|
||||
}
|
||||
|
||||
if (h == 512 && entry->maxSeenV < 512 && entry->maxSeenV != 0) {
|
||||
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;
|
||||
|
@ -457,9 +457,12 @@ void TextureReplacer::ParseReduceHashRange(const std::string& key, const std::st
|
||||
reducehashranges_[reducerangeKey] = rhashvalue;
|
||||
}
|
||||
|
||||
u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, GETextureFormat fmt, u16 maxSeenV) {
|
||||
u32 TextureReplacer::ComputeHash(u32 addr, int bufw, int w, int h, bool swizzled, GETextureFormat fmt, u16 maxSeenV) {
|
||||
_dbg_assert_msg_(enabled_, "Replacement not enabled");
|
||||
|
||||
// TODO: Take swizzled into account, like in QuickTexHash().
|
||||
// Note: Currently, only the MLB games are known to need this.
|
||||
|
||||
if (!LookupHashRange(addr, w, h, &w, &h)) {
|
||||
// There wasn't any hash range, let's fall back to maxSeenV logic.
|
||||
if (h == 512 && maxSeenV < 512 && maxSeenV != 0) {
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
bool Enabled() const { return enabled_; }
|
||||
bool AllowVideo() const { return allowVideo_; }
|
||||
|
||||
u32 ComputeHash(u32 addr, int bufw, int w, int h, GETextureFormat fmt, u16 maxSeenV);
|
||||
u32 ComputeHash(u32 addr, int bufw, int w, int h, bool swizzled, GETextureFormat fmt, u16 maxSeenV);
|
||||
|
||||
// Returns nullptr if not found.
|
||||
ReplacedTexture *FindReplacement(u64 cachekey, u32 hash, int w, int h);
|
||||
|
@ -503,11 +503,11 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
|
||||
case VULKAN_4444_FORMAT: mapping = &VULKAN_4444_SWIZZLE; break;
|
||||
case VULKAN_1555_FORMAT: mapping = &VULKAN_1555_SWIZZLE; break;
|
||||
case VULKAN_565_FORMAT: mapping = &VULKAN_565_SWIZZLE; break;
|
||||
default: mapping = &VULKAN_8888_SWIZZLE; break; // no swizzle
|
||||
default: mapping = &VULKAN_8888_SWIZZLE; break; // no channel swizzle
|
||||
}
|
||||
|
||||
char texName[64]{};
|
||||
snprintf(texName, sizeof(texName), "tex_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format, gstate.getClutPaletteFormat()));
|
||||
char texName[64];
|
||||
snprintf(texName, sizeof(texName), "tex_%08x_%s_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format, gstate.getClutPaletteFormat()), gstate.isTextureSwizzled() ? "swz" : "lin");
|
||||
entry->vkTex = new VulkanTexture(vulkan, texName);
|
||||
VulkanTexture *image = entry->vkTex;
|
||||
bool allocSuccess = image->CreateDirect(cmdInit, plan.createW, plan.createH, plan.depth, plan.levelsToCreate, actualFmt, imageLayout, usage, mapping);
|
||||
|
Loading…
Reference in New Issue
Block a user