Skip to content

Commit

Permalink
GS: Handle higher TH/TW for STQ calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Oct 8, 2022
1 parent 9750cfe commit cadc49d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
20 changes: 11 additions & 9 deletions pcsx2/GS/GSDrawingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4& st, bool linear,
th = extend(uv.y, th);
}

if (GSConfig.Renderer == GSRendererType::SW && ((int)TEX0.TW != tw || (int)TEX0.TH != th))
GIFRegTEX0 res = TEX0;

res.TW = std::clamp(tw, 0, 10);
res.TH = std::clamp(th, 0, 10);

if (GSConfig.Renderer == GSRendererType::SW && (TEX0.TW != res.TW || TEX0.TH != res.TH))
{
GL_DBG("FixedTEX0 %05x %d %d tw %d=>%d th %d=>%d st (%.0f,%.0f,%.0f,%.0f) uvmax %d,%d wm %d,%d (%d,%d,%d,%d)",
(int)TEX0.TBP0, (int)TEX0.TBW, (int)TEX0.PSM,
Expand All @@ -130,19 +135,13 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4& st, bool linear,
wms, wmt, minu, maxu, minv, maxv);
}

GIFRegTEX0 res = TEX0;

res.TW = tw;
res.TH = th;

return res;
}

void GSDrawingContext::ComputeFixedTEX0(const GSVector4& st)
{
// It is quite complex to handle rescaling so this function is less stricter than GetSizeFixedTEX0,
// therefore we remove the reduce optimization and we don't handle bilinear filtering which might create wrong interpolation at the border.

int tw = TEX0.TW;
int th = TEX0.TH;

Expand All @@ -156,15 +155,18 @@ void GSDrawingContext::ComputeFixedTEX0(const GSVector4& st)

GSVector4i uv = GSVector4i(st.floor().xyzw(st.ceil()));

uv.x = findmax(uv.x, uv.z, (1 << TEX0.TW) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << TEX0.TH) - 1, wmt, minv, maxv);
uv.x = findmax(uv.x, uv.z, (1 << tw) - 1, wms, minu, maxu);
uv.y = findmax(uv.y, uv.w, (1 << th) - 1, wmt, minv, maxv);

if (wms == CLAMP_REGION_CLAMP || wms == CLAMP_REGION_REPEAT)
tw = extend(uv.x, tw);

if (wmt == CLAMP_REGION_CLAMP || wmt == CLAMP_REGION_REPEAT)
th = extend(uv.y, th);

tw = std::clamp<int>(tw, 0, 10);
th = std::clamp<int>(th, 0, 10);

if ((tw != (int)TEX0.TW) || (th != (int)TEX0.TH))
{
m_fixed_tex0 = true;
Expand Down
8 changes: 5 additions & 3 deletions pcsx2/GS/GSState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1099,7 +1099,9 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
// Max allowed MTBA size for 32bit swizzled textures (including 8H 4HL etc) is 512, 16bit and normal 8/4bit formats can be 1024
const u32 maxTex = (GSLocalMemory::m_psm[TEX0.PSM].bpp < 32) ? 10 : 9;

// Spec max is 10
// Spec max is 10, but bitfield allows for up to 15
// However STQ calculations expect the written size to be used for denormalization (Simple 2000 Series Vol 105 The Maid)
// This is clamped to 10 in the FixedTEX0 functions so texture sizes don't exceed 1024x1024, but STQ can calculate properly (with invalid_tex0)
//
// Yakuza (minimap)
// Sets TW/TH to 0
Expand All @@ -1110,8 +1112,8 @@ void GSState::GIFRegHandlerTEX0(const GIFReg* RESTRICT r)
// Sets TW/TH to 0
// there used to be a case to force this to 10
// but GetSizeFixedTEX0 sorts this now
TEX0.TW = std::clamp<u32>(TEX0.TW, 0, 10);
TEX0.TH = std::clamp<u32>(TEX0.TH, 0, 10);
TEX0.TW = std::clamp<u32>(TEX0.TW, 0, 15);
TEX0.TH = std::clamp<u32>(TEX0.TH, 0, 15);

// MTBA loads are triggered by writes to TEX0 (but not TEX2!)
// Textures MUST be a minimum width of 32 pixels
Expand Down

0 comments on commit cadc49d

Please sign in to comment.