From cf6cce0744a351af81d5355359214fbce042aa2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 16 Mar 2023 10:21:57 +0100 Subject: [PATCH] Remove scaleFactor from struct ReplacedTextureDecodeInfo, instead pass in both unscaled and scaled dimensions --- GPU/Common/TextureCacheCommon.cpp | 15 +++++++-------- GPU/Common/TextureReplacer.cpp | 24 +++++++++++------------- GPU/Common/TextureReplacer.h | 5 ++--- GPU/Vulkan/TextureCacheVulkan.cpp | 4 +--- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 09fc10023e..02c8016fdc 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -2847,7 +2847,6 @@ bool TextureCacheCommon::PrepareBuildTexture(BuildTexturePlan &plan, TexCacheEnt replacedInfo.hash = entry->fullhash; replacedInfo.addr = entry->addr; replacedInfo.isFinal = (entry->status & TexCacheEntry::STATUS_TO_SCALE) == 0; - replacedInfo.scaleFactor = plan.scaleFactor; replacedInfo.isVideo = plan.isVideo; replacedInfo.fmt = Draw::DataFormat::R8G8B8A8_UNORM; plan.saveTexture = replacer_.WillSave(replacedInfo); @@ -2899,7 +2898,7 @@ void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, i GETextureFormat tfmt = (GETextureFormat)entry.format; GEPaletteFormat clutformat = gstate.getClutPaletteFormat(); u32 texaddr = gstate.getTextureAddress(srcLevel); - int bufw = GetTextureBufw(srcLevel, texaddr, tfmt); + const int bufw = GetTextureBufw(srcLevel, texaddr, tfmt); u32 *pixelData; int decPitch; if (plan.scaleFactor > 1) { @@ -2922,19 +2921,20 @@ void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, i CheckAlphaResult alphaResult = DecodeTextureLevel((u8 *)pixelData, decPitch, tfmt, clutformat, texaddr, srcLevel, bufw, texDecFlags); entry.SetAlphaStatus(alphaResult, srcLevel); + int scaledW = w, scaledH = h; if (plan.scaleFactor > 1) { // Note that this updates w and h! - scaler_.ScaleAlways((u32 *)data, pixelData, w, h, &w, &h, plan.scaleFactor); + scaler_.ScaleAlways((u32 *)data, pixelData, w, h, &scaledW, &scaledH, plan.scaleFactor); pixelData = (u32 *)data; - decPitch = w * 4; + decPitch = scaledW * sizeof(u32); if (decPitch != stride) { // Rearrange in place to match the requested pitch. // (it can only be larger than w * bpp, and a match is likely.) // Note! This is bad because it reads the mapped memory! TODO: Look into if DX9 does this right. - for (int y = h - 1; y >= 0; --y) { - memcpy((u8 *)data + stride * y, (u8 *)data + decPitch * y, w * 4); + for (int y = scaledH - 1; y >= 0; --y) { + memcpy((u8 *)data + stride * y, (u8 *)data + decPitch * y, scaledW *4); } decPitch = stride; } @@ -2947,11 +2947,10 @@ void TextureCacheCommon::LoadTextureLevel(TexCacheEntry &entry, uint8_t *data, i replacedInfo.addr = entry.addr; replacedInfo.isVideo = IsVideo(entry.addr); replacedInfo.isFinal = (entry.status & TexCacheEntry::STATUS_TO_SCALE) == 0; - replacedInfo.scaleFactor = plan.scaleFactor; replacedInfo.fmt = dstFmt; // NOTE: Reading the decoded texture here may be very slow, if we just wrote it to write-combined memory. - replacer_.NotifyTextureDecoded(replacedInfo, pixelData, decPitch, srcLevel, w, h); + replacer_.NotifyTextureDecoded(replacedInfo, pixelData, decPitch, srcLevel, w, h, scaledW, scaledH); } } } diff --git a/GPU/Common/TextureReplacer.cpp b/GPU/Common/TextureReplacer.cpp index 2dbfe03053..446ebe6d27 100644 --- a/GPU/Common/TextureReplacer.cpp +++ b/GPU/Common/TextureReplacer.cpp @@ -631,7 +631,7 @@ bool TextureReplacer::WillSave(const ReplacedTextureDecodeInfo &replacedInfo) { return true; } -void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &replacedInfo, const void *data, int pitch, int level, int w, int h) { +void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &replacedInfo, const void *data, int pitch, int level, int origW, int origH, int scaledW, int scaledH) { _assert_msg_(enabled_, "Replacement not enabled"); if (!WillSave(replacedInfo)) { // Ignore. @@ -663,23 +663,21 @@ void TextureReplacer::NotifyTextureDecoded(const ReplacedTextureDecodeInfo &repl bool skipIfExists = false; double now = time_now_d(); if (it != savedCache_.end()) { - // We've already saved this texture. Let's only save if it's bigger (e.g. scaled now.) - // This check isn't backwards, it's just to check if we should *skip* saving, a bit confusing. - if (it->second.levelW[level] >= w && it->second.levelH[level] >= h) { - // If it's been more than 5 seconds, we'll check again. Maybe they deleted. - double age = now - it->second.lastTimeSaved; - if (age < 5.0) - return; - skipIfExists = true; - } + // We've already saved this texture. Ignore it. + // We don't really care about changing the scale factor during runtime, only confusing. + return; } + // Width/height of the image to save. + int w = scaledW; + int h = scaledH; + // Only save the hashed portion of the PNG. int lookupW; int lookupH; - if (LookupHashRange(replacedInfo.addr, w / replacedInfo.scaleFactor, h / replacedInfo.scaleFactor, &lookupW, &lookupH)) { - w = lookupW * replacedInfo.scaleFactor; - h = lookupH * replacedInfo.scaleFactor; + if (LookupHashRange(replacedInfo.addr, origW, origH, &lookupW, &lookupH)) { + w = lookupW * (scaledW / origW); + h = lookupH * (scaledH / origH); } std::vector saveBuf; diff --git a/GPU/Common/TextureReplacer.h b/GPU/Common/TextureReplacer.h index e85e3e5901..e73a35150c 100644 --- a/GPU/Common/TextureReplacer.h +++ b/GPU/Common/TextureReplacer.h @@ -81,7 +81,6 @@ struct ReplacedTextureDecodeInfo { u32 addr; bool isVideo; bool isFinal; - int scaleFactor; Draw::DataFormat fmt; }; @@ -112,8 +111,8 @@ public: // Check if a NotifyTextureDecoded for this texture is desired (used to avoid reads from write-combined memory.) bool WillSave(const ReplacedTextureDecodeInfo &replacedInfo); - // Notify that a new texture was decoded. May already be upscaled, saves the data passed. - void NotifyTextureDecoded(const ReplacedTextureDecodeInfo &replacedInfo, const void *data, int pitch, int level, int w, int h); + // Notify that a new texture was decoded. May already be upscaled, saves the data passed. + void NotifyTextureDecoded(const ReplacedTextureDecodeInfo &replacedInfo, const void *data, int pitch, int level, int origW, int origH, int scaledW, int scaledH); void Decimate(ReplacerDecimateMode mode); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 425905dd8f..61b8033daa 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -647,10 +647,8 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) { replacedInfo.addr = entry->addr; replacedInfo.isVideo = IsVideo(entry->addr); replacedInfo.isFinal = (entry->status & TexCacheEntry::STATUS_TO_SCALE) == 0; - replacedInfo.scaleFactor = plan.scaleFactor; replacedInfo.fmt = FromVulkanFormat(actualFmt); - - replacer_.NotifyTextureDecoded(replacedInfo, data, byteStride, plan.baseLevelSrc + i, w, h); + replacer_.NotifyTextureDecoded(replacedInfo, data, byteStride, plan.baseLevelSrc + i, mipUnscaledWidth, mipUnscaledHeight, w, h); } } }