Remove scaleFactor from struct ReplacedTextureDecodeInfo, instead pass in both unscaled and scaled dimensions

This commit is contained in:
Henrik Rydgård 2023-03-16 10:21:57 +01:00
parent f2a5a5abe7
commit cf6cce0744
4 changed files with 21 additions and 27 deletions

View file

@ -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);
}
}
}

View file

@ -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<u8> saveBuf;

View file

@ -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);

View file

@ -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);
}
}
}