Take widthAlignFactor into account for alignment in mipLevelDesc to fix wrong mip level 2 and above

This commit is contained in:
Lurs
2026-05-27 17:28:00 +02:00
parent 54dbf20480
commit e0de71b5b4
+16 -11
View File
@@ -226,27 +226,28 @@ MipLevelDesc mipLevelDesc(const GtxSurface& s, u32 level, bool isBcn, u32 bpp) {
return d;
}
// Mirror decaf's widthAlignFactor: when one microtile is smaller than
// the pipe interleave (256 B), the demote threshold scales up.
const u32 microTileBytes = (bpp * 64u) / 8u;
const u32 widthAlignFactor = (microTileBytes <= 256u) ? (256u / microTileBytes) : 1u;
if (d.tileMode == addrlib::TileMode::Tiled2DThin1 ||
d.tileMode == addrlib::TileMode::Tiled2BThin1) {
// Mirror decaf's widthAlignFactor: when one microtile is smaller than
// the pipe interleave (256 B), the demote threshold scales up.
const u32 microTileBytes = (bpp * 64) / 8;
const u32 widthAlignFactor = (microTileBytes <= 256) ? 256 / microTileBytes : 1;
const u32 demoteWidth = widthAlignFactor * 32;
const u32 wElem = isBcn ? (d.width + 3) / 4 : d.width;
const u32 hElem = isBcn ? (d.height + 3) / 4 : d.height;
if (wElem < demoteWidth || hElem < 16) {
const u32 demoteWidth = widthAlignFactor * 32u;
const u32 wElem = isBcn ? (d.width + 3u) / 4u : d.width;
const u32 hElem = isBcn ? (d.height + 3u) / 4u : d.height;
if (wElem < demoteWidth || hElem < 16u) {
d.tileMode = addrlib::TileMode::Tiled1DThin1;
}
}
const bool is1D = (d.tileMode == addrlib::TileMode::Tiled1DThin1 ||
d.tileMode == addrlib::TileMode::Tiled1DThick);
const u32 alignment = is1D ? 8u : 32u;
const u32 alignment = is1D ? (8u * widthAlignFactor) : 32u;
const u32 pixelsPerBlock = isBcn ? 4u : 1u;
const u32 widthInBlock = (d.width + pixelsPerBlock - 1) / pixelsPerBlock;
u32 levelPitch = ((widthInBlock + alignment - 1) / alignment) * alignment;
const u32 widthInBlock = (d.width + pixelsPerBlock - 1u) / pixelsPerBlock;
u32 levelPitch = ((widthInBlock + alignment - 1u) / alignment) * alignment;
d.pitch = std::max(1u, levelPitch);
return d;
}
@@ -478,6 +479,8 @@ void registerHdTexturesForArc(std::vector<u8>& arcBytes,
const u8 hdMips = static_cast<u8>(std::clamp<u32>(s.mipCount, 1u, 11u));
timg->mipmapCount = hdMips;
timg->maxLOD = static_cast<s8>((hdMips - 1) * 8);
//timg->maxAnisotropy = 16;
//timg->LODBias = -50;
registerHdSurface(*m, s,
arcBytes.data() + f.dataOffset + btiAbs + newImgOff,
gtx->name, i);
@@ -512,6 +515,8 @@ void registerHdTexturesForArc(std::vector<u8>& arcBytes,
const u8 hdMips = static_cast<u8>(std::clamp<u32>(s.mipCount, 1u, 11u));
timg->mipmapCount = hdMips;
timg->maxLOD = static_cast<s8>((hdMips - 1) * 8);
//timg->maxAnisotropy = 16;
//timg->LODBias = -50;
registerHdSurface(*m, s, arcBytes.data() + f.dataOffset + 0x20,
gtx->name, 0);
++btiReg;