GS: Only reload Auto MIPs on TEX base change

This commit is contained in:
refractionpcsx2 2021-11-10 22:18:11 +00:00
parent a396b50610
commit 512064f1b5
2 changed files with 34 additions and 16 deletions

View File

@ -134,6 +134,7 @@ GSState::GSState()
PRIM = &m_env.PRIM;
//CSR->rREV = 0x20;
m_env.PRMODECONT.AC = 1;
tex_flushed = true;
Reset();
@ -899,6 +900,10 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
GIFRegTEX0 TEX0 = r->TEX0;
bool MTBA_reload = false;
if ((m_env.CTXT[i].TEX0.TBP0 != TEX0.TBP0 || tex_flushed) && m_env.CTXT[i].TEX1.MTBA)
MTBA_reload = true;
// Spec max is 10
//
// Yakuza (minimap)
@ -915,7 +920,8 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
ApplyTEX0<i>(TEX0);
if (m_env.CTXT[i].TEX1.MTBA)
// Textures must be of equal width/height and a minimum of 32x32
if (MTBA_reload && TEX0.TW == TEX0.TH && TEX0.TW >= 5)
{
// NOTE 1: TEX1.MXL must not be automatically set to 3 here.
// NOTE 2: Mipmap levels are tightly packed, if (tbw << 6) > (1 << tw) then the left-over space to the right is used. (common for PSM_PSMT4)
@ -925,36 +931,46 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
u32 bw = TEX0.TBW;
u32 w = 1u << TEX0.TW;
u32 h = 1u << TEX0.TH;
u32 minwidth = m_context->TEX1.MMIN >= 4 ? 8 : 1;
const u32 bpp = GSLocalMemory::m_psm[TEX0.PSM].bpp;
if (h < w)
h = w;
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
bp += ((w * h * bpp >> 3) + 255) >> 8;
bw = std::max<u32>(bw >> 1, 1);
w = std::max<u32>(w >> 1, 1);
h = std::max<u32>(h >> 1, 1);
if (w > minwidth)
{
bw = std::max<u32>(bw >> 1, 1);
w = std::max<u32>(w >> 1, 1);
h = std::max<u32>(h >> 1, 1);
}
m_env.CTXT[i].MIPTBP1.TBP1 = bp;
m_env.CTXT[i].MIPTBP1.TBW1 = bw;
bp += ((w * h * bpp >> 3) + 255) >> 8;
bw = std::max<u32>(bw >> 1, 1);
w = std::max<u32>(w >> 1, 1);
h = std::max<u32>(h >> 1, 1);
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
if (w > minwidth)
{
bw = std::max<u32>(bw >> 1, 1);
w = std::max<u32>(w >> 1, 1);
h = std::max<u32>(h >> 1, 1);
}
m_env.CTXT[i].MIPTBP1.TBP2 = bp;
m_env.CTXT[i].MIPTBP1.TBW2 = bw;
bp += ((w * h * bpp >> 3) + 255) >> 8;
bw = std::max<u32>(bw >> 1, 1);
w = std::max<u32>(w >> 1, 1);
h = std::max<u32>(h >> 1, 1);
bp += (int)((w * h * ((float)bpp / 8))) >> 8;
if (w > minwidth)
{
bw = std::max<u32>(bw >> 1, 1);
}
m_env.CTXT[i].MIPTBP1.TBP3 = bp;
m_env.CTXT[i].MIPTBP1.TBW3 = bw;
}
tex_flushed = false;
}
template <int i>
@ -1115,6 +1131,7 @@ void GSState::GIFRegHandlerFOGCOL(const GIFReg* RESTRICT r)
void GSState::GIFRegHandlerTEXFLUSH(const GIFReg* RESTRICT r)
{
GL_REG("TEXFLUSH = 0x%x_%x", r->U32[1], r->U32[0]);
tex_flushed = true;
}
template <int i>
@ -2891,7 +2908,7 @@ bool GSState::IsOpaque()
bool GSState::IsMipMapDraw()
{
return m_context->TEX1.MXL > 0 && m_context->TEX1.MMIN >= 2 && m_context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0;
return m_context->TEX1.MXL > 0 && m_context->TEX1.MMIN >= 2 && m_context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0 && (!m_context->TEX1.MTBA || m_context->TEX0.TH == m_context->TEX0.TW);
}
bool GSState::IsMipMapActive()

View File

@ -157,6 +157,7 @@ protected:
float m_q;
GSVector4i m_scissor;
GSVector4i m_ofxy;
bool tex_flushed;
struct
{