mirror of https://github.com/PCSX2/pcsx2.git
GS: Modify clamp behaviour on large specified texture sizes
Add temp logging
This commit is contained in:
parent
f70da4b33e
commit
96071e157a
|
@ -20,10 +20,17 @@
|
||||||
|
|
||||||
static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
|
static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
|
||||||
{
|
{
|
||||||
// return max possible texcoord
|
// return max possible texcoord.
|
||||||
|
|
||||||
int uv = br;
|
int uv = br;
|
||||||
|
|
||||||
|
// Confirmed on hardware if the size exceeds 1024, it basically gets masked so you end up with a 1x1 pixel (Except Region Clamp).
|
||||||
|
if (limit > 1024)
|
||||||
|
{
|
||||||
|
if (wm != CLAMP_REGION_CLAMP) // TEMPLOG
|
||||||
|
Console.Warning("Masking TEX0 to 1x1 was %d", limit + 1);
|
||||||
|
limit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (wm == CLAMP_CLAMP)
|
if (wm == CLAMP_CLAMP)
|
||||||
{
|
{
|
||||||
if (uv > limit)
|
if (uv > limit)
|
||||||
|
@ -45,10 +52,14 @@ static int findmax(int tl, int br, int limit, int wm, int minuv, int maxuv)
|
||||||
}
|
}
|
||||||
else if (wm == CLAMP_REGION_REPEAT)
|
else if (wm == CLAMP_REGION_REPEAT)
|
||||||
{
|
{
|
||||||
|
// REGION_REPEAT adhears to the original texture size, even if offset outside the texture (with MAXUV).
|
||||||
|
if (limit < minuv) // TEMPLOG
|
||||||
|
Console.Warning("Limiting minuv, limit %x minuv from %x to %x", limit, minuv, minuv & limit);
|
||||||
|
minuv &= limit;
|
||||||
if (tl < 0)
|
if (tl < 0)
|
||||||
uv = minuv | maxuv; // wrap around, just use (any & mask) | fix
|
uv = minuv | maxuv; // wrap around, just use (any & mask) | fix.
|
||||||
else
|
else
|
||||||
uv = std::min(uv, minuv) | maxuv; // (any & mask) cannot be larger than mask, select br if that is smaller (not br & mask because there might be a larger value between tl and br when &'ed with the mask)
|
uv = std::min(uv, minuv) | maxuv; // (any & mask) cannot be larger than mask, select br if that is smaller (not br & mask because there might be a larger value between tl and br when &'ed with the mask).
|
||||||
}
|
}
|
||||||
|
|
||||||
return uv;
|
return uv;
|
||||||
|
@ -122,8 +133,13 @@ GIFRegTEX0 GSDrawingContext::GetSizeFixedTEX0(const GSVector4& st, bool linear,
|
||||||
|
|
||||||
GIFRegTEX0 res = TEX0;
|
GIFRegTEX0 res = TEX0;
|
||||||
|
|
||||||
res.TW = std::clamp(tw, 0, 10);
|
if (tw > 10) // TEMPLOG
|
||||||
res.TH = std::clamp(th, 0, 10);
|
Console.Warning("Limiting Width to 1");
|
||||||
|
if (th > 10) // TEMPLOG
|
||||||
|
Console.Warning("Limiting Height to 1");
|
||||||
|
|
||||||
|
res.TW = tw > 10 ? 0 : tw;
|
||||||
|
res.TH = th > 10 ? 0 : th;
|
||||||
|
|
||||||
if (GSConfig.Renderer == GSRendererType::SW && (TEX0.TW != res.TW || TEX0.TH != res.TH))
|
if (GSConfig.Renderer == GSRendererType::SW && (TEX0.TW != res.TW || TEX0.TH != res.TH))
|
||||||
{
|
{
|
||||||
|
@ -153,6 +169,12 @@ void GSDrawingContext::ComputeFixedTEX0(const GSVector4& st)
|
||||||
int maxu = (int)CLAMP.MAXU;
|
int maxu = (int)CLAMP.MAXU;
|
||||||
int maxv = (int)CLAMP.MAXV;
|
int maxv = (int)CLAMP.MAXV;
|
||||||
|
|
||||||
|
if (wms != CLAMP_REGION_CLAMP)
|
||||||
|
tw = tw > 10 ? 0 : tw;
|
||||||
|
|
||||||
|
if (wmt != CLAMP_REGION_CLAMP)
|
||||||
|
th = th > 10 ? 0 : th;
|
||||||
|
|
||||||
GSVector4i uv = GSVector4i(st.floor().xyzw(st.ceil()));
|
GSVector4i uv = GSVector4i(st.floor().xyzw(st.ceil()));
|
||||||
|
|
||||||
uv.x = findmax(uv.x, uv.z, (1 << tw) - 1, wms, minu, maxu);
|
uv.x = findmax(uv.x, uv.z, (1 << tw) - 1, wms, minu, maxu);
|
||||||
|
|
|
@ -4074,59 +4074,69 @@ bool GSRendererHW::SwPrimRender()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const u16 tw = 1u << TEX0.TW;
|
u16 tw = 1u << TEX0.TW;
|
||||||
const u16 th = 1u << TEX0.TH;
|
u16 th = 1u << TEX0.TH;
|
||||||
|
|
||||||
|
if (tw > 1024)
|
||||||
|
tw = 1;
|
||||||
|
|
||||||
|
if (th > 1024)
|
||||||
|
th = 1;
|
||||||
|
|
||||||
switch (context->CLAMP.WMS)
|
switch (context->CLAMP.WMS)
|
||||||
{
|
{
|
||||||
case CLAMP_REPEAT:
|
case CLAMP_REPEAT:
|
||||||
gd.t.min.U16[0] = gd.t.minmax.U16[0] = tw - 1;
|
gd.t.min.U16[0] = gd.t.minmax.U16[0] = tw - 1;
|
||||||
gd.t.max.U16[0] = gd.t.minmax.U16[2] = 0;
|
gd.t.max.U16[0] = gd.t.minmax.U16[2] = 0;
|
||||||
gd.t.mask.U32[0] = 0xffffffff;
|
gd.t.mask.U32[0] = 0xffffffff;
|
||||||
break;
|
break;
|
||||||
case CLAMP_CLAMP:
|
case CLAMP_CLAMP:
|
||||||
gd.t.min.U16[0] = gd.t.minmax.U16[0] = 0;
|
gd.t.min.U16[0] = gd.t.minmax.U16[0] = 0;
|
||||||
gd.t.max.U16[0] = gd.t.minmax.U16[2] = tw - 1;
|
gd.t.max.U16[0] = gd.t.minmax.U16[2] = tw - 1;
|
||||||
gd.t.mask.U32[0] = 0;
|
gd.t.mask.U32[0] = 0;
|
||||||
break;
|
break;
|
||||||
case CLAMP_REGION_CLAMP:
|
case CLAMP_REGION_CLAMP:
|
||||||
gd.t.min.U16[0] = gd.t.minmax.U16[0] = std::min<u16>(context->CLAMP.MINU, tw - 1);
|
// REGION_CLAMP ignores the actual texture size
|
||||||
gd.t.max.U16[0] = gd.t.minmax.U16[2] = std::min<u16>(context->CLAMP.MAXU, tw - 1);
|
gd.t.min.U16[0] = gd.t.minmax.U16[0] = context->CLAMP.MINU;
|
||||||
gd.t.mask.U32[0] = 0;
|
gd.t.max.U16[0] = gd.t.minmax.U16[2] = context->CLAMP.MAXU;
|
||||||
break;
|
gd.t.mask.U32[0] = 0;
|
||||||
case CLAMP_REGION_REPEAT:
|
break;
|
||||||
gd.t.min.U16[0] = gd.t.minmax.U16[0] = context->CLAMP.MINU & (tw - 1);
|
case CLAMP_REGION_REPEAT:
|
||||||
gd.t.max.U16[0] = gd.t.minmax.U16[2] = context->CLAMP.MAXU & (tw - 1);
|
// MINU is restricted to MINU or texture size, whichever is smaller, MAXU is an offset in the texture.
|
||||||
gd.t.mask.U32[0] = 0xffffffff;
|
gd.t.min.U16[0] = gd.t.minmax.U16[0] = context->CLAMP.MINU & (tw - 1);
|
||||||
break;
|
gd.t.max.U16[0] = gd.t.minmax.U16[2] = context->CLAMP.MAXU;
|
||||||
default:
|
gd.t.mask.U32[0] = 0xffffffff;
|
||||||
__assume(0);
|
break;
|
||||||
|
default:
|
||||||
|
__assume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (context->CLAMP.WMT)
|
switch (context->CLAMP.WMT)
|
||||||
{
|
{
|
||||||
case CLAMP_REPEAT:
|
case CLAMP_REPEAT:
|
||||||
gd.t.min.U16[4] = gd.t.minmax.U16[1] = th - 1;
|
gd.t.min.U16[4] = gd.t.minmax.U16[1] = th - 1;
|
||||||
gd.t.max.U16[4] = gd.t.minmax.U16[3] = 0;
|
gd.t.max.U16[4] = gd.t.minmax.U16[3] = 0;
|
||||||
gd.t.mask.U32[2] = 0xffffffff;
|
gd.t.mask.U32[2] = 0xffffffff;
|
||||||
break;
|
break;
|
||||||
case CLAMP_CLAMP:
|
case CLAMP_CLAMP:
|
||||||
gd.t.min.U16[4] = gd.t.minmax.U16[1] = 0;
|
gd.t.min.U16[4] = gd.t.minmax.U16[1] = 0;
|
||||||
gd.t.max.U16[4] = gd.t.minmax.U16[3] = th - 1;
|
gd.t.max.U16[4] = gd.t.minmax.U16[3] = th - 1;
|
||||||
gd.t.mask.U32[2] = 0;
|
gd.t.mask.U32[2] = 0;
|
||||||
break;
|
break;
|
||||||
case CLAMP_REGION_CLAMP:
|
case CLAMP_REGION_CLAMP:
|
||||||
gd.t.min.U16[4] = gd.t.minmax.U16[1] = std::min<u16>(context->CLAMP.MINV, th - 1);
|
// REGION_CLAMP ignores the actual texture size
|
||||||
gd.t.max.U16[4] = gd.t.minmax.U16[3] = std::min<u16>(context->CLAMP.MAXV, th - 1); // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256)
|
gd.t.min.U16[4] = gd.t.minmax.U16[1] = context->CLAMP.MINV;
|
||||||
gd.t.mask.U32[2] = 0;
|
gd.t.max.U16[4] = gd.t.minmax.U16[3] = context->CLAMP.MAXV; // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256)
|
||||||
break;
|
gd.t.mask.U32[2] = 0;
|
||||||
case CLAMP_REGION_REPEAT:
|
break;
|
||||||
gd.t.min.U16[4] = gd.t.minmax.U16[1] = context->CLAMP.MINV & (th - 1); // skygunner main menu water texture 64x64, MINV = 127
|
case CLAMP_REGION_REPEAT:
|
||||||
gd.t.max.U16[4] = gd.t.minmax.U16[3] = context->CLAMP.MAXV & (th - 1);
|
// MINV is restricted to MINV or texture size, whichever is smaller, MAXV is an offset in the texture.
|
||||||
gd.t.mask.U32[2] = 0xffffffff;
|
gd.t.min.U16[4] = gd.t.minmax.U16[1] = context->CLAMP.MINV & (th - 1); // skygunner main menu water texture 64x64, MINV = 127
|
||||||
break;
|
gd.t.max.U16[4] = gd.t.minmax.U16[3] = context->CLAMP.MAXV;
|
||||||
default:
|
gd.t.mask.U32[2] = 0xffffffff;
|
||||||
__assume(0);
|
break;
|
||||||
|
default:
|
||||||
|
__assume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gd.t.min = gd.t.min.xxxxlh();
|
gd.t.min = gd.t.min.xxxxlh();
|
||||||
|
|
|
@ -1211,6 +1211,11 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
||||||
u16 tw = 1u << TEX0.TW;
|
u16 tw = 1u << TEX0.TW;
|
||||||
u16 th = 1u << TEX0.TH;
|
u16 th = 1u << TEX0.TH;
|
||||||
|
|
||||||
|
if (tw > 1024)
|
||||||
|
tw = 1;
|
||||||
|
if (th > 1024)
|
||||||
|
th = 1;
|
||||||
|
|
||||||
switch (context->CLAMP.WMS)
|
switch (context->CLAMP.WMS)
|
||||||
{
|
{
|
||||||
case CLAMP_REPEAT:
|
case CLAMP_REPEAT:
|
||||||
|
@ -1224,13 +1229,15 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
||||||
gd.t.mask.U32[0] = 0;
|
gd.t.mask.U32[0] = 0;
|
||||||
break;
|
break;
|
||||||
case CLAMP_REGION_CLAMP:
|
case CLAMP_REGION_CLAMP:
|
||||||
gd.t.min.U16[0] = gd.t.minmax.U16[0] = std::min<u16>(context->CLAMP.MINU, tw - 1);
|
// REGION_CLAMP ignores the actual texture size
|
||||||
gd.t.max.U16[0] = gd.t.minmax.U16[2] = std::min<u16>(context->CLAMP.MAXU, tw - 1);
|
gd.t.min.U16[0] = gd.t.minmax.U16[0] = context->CLAMP.MINU;
|
||||||
|
gd.t.max.U16[0] = gd.t.minmax.U16[2] = context->CLAMP.MAXU;
|
||||||
gd.t.mask.U32[0] = 0;
|
gd.t.mask.U32[0] = 0;
|
||||||
break;
|
break;
|
||||||
case CLAMP_REGION_REPEAT:
|
case CLAMP_REGION_REPEAT:
|
||||||
|
// MINU is restricted to MINU or texture size, whichever is smaller, MAXU is an offset in the texture (Can be bigger than the texture).
|
||||||
gd.t.min.U16[0] = gd.t.minmax.U16[0] = context->CLAMP.MINU & (tw - 1);
|
gd.t.min.U16[0] = gd.t.minmax.U16[0] = context->CLAMP.MINU & (tw - 1);
|
||||||
gd.t.max.U16[0] = gd.t.minmax.U16[2] = context->CLAMP.MAXU & (tw - 1);
|
gd.t.max.U16[0] = gd.t.minmax.U16[2] = context->CLAMP.MAXU;
|
||||||
gd.t.mask.U32[0] = 0xffffffff;
|
gd.t.mask.U32[0] = 0xffffffff;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1250,13 +1257,15 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
||||||
gd.t.mask.U32[2] = 0;
|
gd.t.mask.U32[2] = 0;
|
||||||
break;
|
break;
|
||||||
case CLAMP_REGION_CLAMP:
|
case CLAMP_REGION_CLAMP:
|
||||||
gd.t.min.U16[4] = gd.t.minmax.U16[1] = std::min<u16>(context->CLAMP.MINV, th - 1);
|
// REGION_CLAMP ignores the actual texture size
|
||||||
gd.t.max.U16[4] = gd.t.minmax.U16[3] = std::min<u16>(context->CLAMP.MAXV, th - 1); // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256)
|
gd.t.min.U16[4] = gd.t.minmax.U16[1] = context->CLAMP.MINV;
|
||||||
|
gd.t.max.U16[4] = gd.t.minmax.U16[3] = context->CLAMP.MAXV; // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256)
|
||||||
gd.t.mask.U32[2] = 0;
|
gd.t.mask.U32[2] = 0;
|
||||||
break;
|
break;
|
||||||
case CLAMP_REGION_REPEAT:
|
case CLAMP_REGION_REPEAT:
|
||||||
|
// MINV is restricted to MINV or texture size, whichever is smaller, MAXV is an offset in the texture (Can be bigger than the texture).
|
||||||
gd.t.min.U16[4] = gd.t.minmax.U16[1] = context->CLAMP.MINV & (th - 1); // skygunner main menu water texture 64x64, MINV = 127
|
gd.t.min.U16[4] = gd.t.minmax.U16[1] = context->CLAMP.MINV & (th - 1); // skygunner main menu water texture 64x64, MINV = 127
|
||||||
gd.t.max.U16[4] = gd.t.minmax.U16[3] = context->CLAMP.MAXV & (th - 1);
|
gd.t.max.U16[4] = gd.t.minmax.U16[3] = context->CLAMP.MAXV;
|
||||||
gd.t.mask.U32[2] = 0xffffffff;
|
gd.t.mask.U32[2] = 0xffffffff;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue