mirror of https://github.com/PCSX2/pcsx2.git
gsdx: lupin 3 fix, texture addressing outside the limits, only for sw and opencl yet
This commit is contained in:
parent
d631030608
commit
42f51591df
|
@ -125,6 +125,88 @@ public:
|
|||
return ZBUF.ZMSK == 0 && TEST.ZTE != 0; // ZTE == 0 is bug on the real hardware, write is blocked then
|
||||
}
|
||||
|
||||
GIFRegTEX0 GetSizeFixedTEX0(const GSVector4i& uvmax, bool mipmap)
|
||||
{
|
||||
// find max value for TW/TH by analyzing vertex trace and clamp values, only for region clamp modes, no mipmaping allowed
|
||||
|
||||
if(mipmap) return TEX0;
|
||||
|
||||
int tw = TEX0.TW;
|
||||
int th = TEX0.TH;
|
||||
|
||||
int wms = (int)CLAMP.WMS;
|
||||
int wmt = (int)CLAMP.WMT;
|
||||
|
||||
int minu = (int)CLAMP.MINU;
|
||||
int minv = (int)CLAMP.MINV;
|
||||
int maxu = (int)CLAMP.MAXU;
|
||||
int maxv = (int)CLAMP.MAXV;
|
||||
|
||||
GSVector4i uv = uvmax;// GSVector4i(m_vt.m_max.t.ceil());
|
||||
|
||||
if(wms == CLAMP_REGION_CLAMP)
|
||||
{
|
||||
int x = uv.x;
|
||||
|
||||
if(x < minu) x = minu;
|
||||
if(x > maxu + 1) x = maxu + 1;
|
||||
|
||||
while(tw < 10 && (1 << tw) < x)
|
||||
{
|
||||
tw++;
|
||||
}
|
||||
}
|
||||
else if(wms == CLAMP_REGION_REPEAT)
|
||||
{
|
||||
int x = maxu + (minu + 1);
|
||||
|
||||
while(tw < 10 && (1 << tw) < x)
|
||||
{
|
||||
tw++;
|
||||
}
|
||||
}
|
||||
|
||||
if(wmt == CLAMP_REGION_CLAMP)
|
||||
{
|
||||
int y = uv.y;
|
||||
|
||||
if(y < minv) y = minv;
|
||||
if(y > maxv + 1) y = maxv + 1;
|
||||
|
||||
while(th < 10 && (1 << th) < y)
|
||||
{
|
||||
th++;
|
||||
}
|
||||
}
|
||||
else if(wmt == CLAMP_REGION_REPEAT)
|
||||
{
|
||||
int y = maxv + (minv + 1);
|
||||
|
||||
while(th < 10 && (1 << th) < y)
|
||||
{
|
||||
th++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if(TEX0.TW != tw || TEX0.TH != th)
|
||||
{
|
||||
printf("FixedTEX0 %05x %d %d tw %d=>%d th %d=>%d uvmax %d,%d wm %d,%d (%d,%d,%d,%d)\n",
|
||||
(int)TEX0.TBP0, (int)TEX0.TBW, (int)TEX0.PSM,
|
||||
(int)TEX0.TW, tw, (int)TEX0.TH, th,
|
||||
uv.x, uv.y,
|
||||
wms, wmt, minu, maxu, minv, maxv);
|
||||
}
|
||||
#endif
|
||||
|
||||
GIFRegTEX0 res = TEX0;
|
||||
|
||||
res.TW = tw;
|
||||
res.TH = th;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Dump(const std::string& filename)
|
||||
{
|
||||
// Append on purpose so env + context are merged into a single file
|
||||
|
|
|
@ -40,7 +40,6 @@ GSRenderer::GSRenderer()
|
|||
m_filter = theApp.GetConfig("filter", 1);
|
||||
m_vsync = !!theApp.GetConfig("vsync", 0);
|
||||
m_aa1 = !!theApp.GetConfig("aa1", 0);
|
||||
m_mipmap = !!theApp.GetConfig("mipmap", 1);
|
||||
m_fxaa = !!theApp.GetConfig("fxaa", 0);
|
||||
m_shaderfx = !!theApp.GetConfig("shaderfx", 0);
|
||||
m_shadeboost = !!theApp.GetConfig("ShadeBoost", 0);
|
||||
|
|
|
@ -45,7 +45,6 @@ protected:
|
|||
int m_filter;
|
||||
bool m_vsync;
|
||||
bool m_aa1;
|
||||
bool m_mipmap;
|
||||
bool m_framelimit;
|
||||
bool m_shaderfx;
|
||||
bool m_fxaa;
|
||||
|
|
|
@ -1440,9 +1440,15 @@ bool GSRendererCL::SetupParameter(TFXJob* job, TFXParameter* pb, GSVertexCL* ver
|
|||
sel.tfx = TFX_DECAL;
|
||||
}
|
||||
|
||||
GSVector4i uvmax = GSVector4i(m_vt.m_max.t.ceil());
|
||||
|
||||
bool mipmap = IsMipMapActive();
|
||||
|
||||
GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(uvmax, mipmap);
|
||||
|
||||
GSVector4i r;
|
||||
|
||||
GetTextureMinMax(r, context->TEX0, context->CLAMP, sel.ltf);
|
||||
GetTextureMinMax(r, TEX0, context->CLAMP, sel.ltf);
|
||||
|
||||
GSVector4i* src_pages = job->GetSrcPages();
|
||||
|
||||
|
@ -1455,7 +1461,7 @@ bool GSRendererCL::SetupParameter(TFXJob* job, TFXParameter* pb, GSVertexCL* ver
|
|||
src_pages[i] |= m_tmp_pages[i];
|
||||
}
|
||||
|
||||
if(m_mipmap && context->TEX1.MXL > 0 && context->TEX1.MMIN >= 2 && context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0)
|
||||
if(mipmap)
|
||||
{
|
||||
// TEX1.MMIN
|
||||
// 000 p
|
||||
|
@ -1521,7 +1527,7 @@ bool GSRendererCL::SetupParameter(TFXJob* job, TFXParameter* pb, GSVertexCL* ver
|
|||
pb->k = (float)k;
|
||||
}
|
||||
|
||||
GIFRegTEX0 MIP_TEX0 = context->TEX0;
|
||||
GIFRegTEX0 MIP_TEX0 = TEX0;
|
||||
GIFRegCLAMP MIP_CLAMP = context->CLAMP;
|
||||
|
||||
GSVector4 tmin = m_vt.m_min.t;
|
||||
|
@ -1638,8 +1644,8 @@ bool GSRendererCL::SetupParameter(TFXJob* job, TFXParameter* pb, GSVertexCL* ver
|
|||
}
|
||||
}
|
||||
|
||||
int tw = 1 << context->TEX0.TW;
|
||||
int th = 1 << context->TEX0.TH;
|
||||
int tw = 1 << TEX0.TW;
|
||||
int th = 1 << TEX0.TH;
|
||||
|
||||
switch(context->CLAMP.WMS)
|
||||
{
|
||||
|
|
|
@ -1121,19 +1121,25 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
|||
gd.sel.tfx = TFX_DECAL;
|
||||
}
|
||||
|
||||
GSTextureCacheSW::Texture* t = m_tc->Lookup(context->TEX0, env.TEXA);
|
||||
GSVector4i uvmax = GSVector4i(m_vt.m_max.t.ceil());
|
||||
|
||||
if(t == NULL) {ASSERT(0); return false;}
|
||||
bool mipmap = IsMipMapActive();
|
||||
|
||||
GIFRegTEX0 TEX0 = m_context->GetSizeFixedTEX0(uvmax, mipmap);
|
||||
|
||||
GSVector4i r;
|
||||
|
||||
GetTextureMinMax(r, context->TEX0, context->CLAMP, gd.sel.ltf);
|
||||
GetTextureMinMax(r, TEX0, context->CLAMP, gd.sel.ltf);
|
||||
|
||||
GSTextureCacheSW::Texture* t = m_tc->Lookup(TEX0, env.TEXA);
|
||||
|
||||
if(t == NULL) {ASSERT(0); return false;}
|
||||
|
||||
data->SetSource(t, r, 0);
|
||||
|
||||
gd.sel.tw = t->m_tw - 3;
|
||||
|
||||
if(m_mipmap && context->TEX1.MXL > 0 && context->TEX1.MMIN >= 2 && context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0)
|
||||
if(mipmap)
|
||||
{
|
||||
// TEX1.MMIN
|
||||
// 000 p
|
||||
|
@ -1200,7 +1206,7 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
|||
gd.k = GSVector4((float)k);
|
||||
}
|
||||
|
||||
GIFRegTEX0 MIP_TEX0 = context->TEX0;
|
||||
GIFRegTEX0 MIP_TEX0 = TEX0;
|
||||
GIFRegCLAMP MIP_CLAMP = context->CLAMP;
|
||||
|
||||
GSVector4 tmin = m_vt.m_min.t;
|
||||
|
@ -1329,8 +1335,8 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
|
|||
}
|
||||
}
|
||||
|
||||
uint16 tw = 1u << context->TEX0.TW;
|
||||
uint16 th = 1u << context->TEX0.TH;
|
||||
uint16 tw = 1u << TEX0.TW;
|
||||
uint16 th = 1u << TEX0.TH;
|
||||
|
||||
switch(context->CLAMP.WMS)
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ GSState::GSState()
|
|||
, m_crcinited(false)
|
||||
{
|
||||
m_nativeres = !!theApp.GetConfig("nativeres", 1);
|
||||
m_mipmap = !!theApp.GetConfig("mipmap", 1);
|
||||
|
||||
s_n = 0;
|
||||
s_dump = !!theApp.GetConfig("dump", 0);
|
||||
|
@ -2713,6 +2714,7 @@ void GSState::GetTextureMinMax(GSVector4i& r, const GIFRegTEX0& TEX0, const GIFR
|
|||
int mask = 0;
|
||||
|
||||
// See commented code below for the meaning of mask
|
||||
|
||||
if(wms == CLAMP_REPEAT || wmt == CLAMP_REPEAT)
|
||||
{
|
||||
u = uv & GSVector4i::xffffffff().srl32(32 - tw);
|
||||
|
@ -2985,6 +2987,11 @@ bool GSState::IsOpaque()
|
|||
return context->ALPHA.IsOpaque(amin, amax);
|
||||
}
|
||||
|
||||
bool GSState::IsMipMapActive()
|
||||
{
|
||||
return m_mipmap && m_context->TEX1.MXL > 0 && m_context->TEX1.MMIN >= 2 && m_context->TEX1.MMIN <= 5 && m_vt.m_lod.y > 0;
|
||||
}
|
||||
|
||||
// GSTransferBuffer
|
||||
|
||||
GSState::GSTransferBuffer::GSTransferBuffer()
|
||||
|
|
|
@ -184,6 +184,7 @@ protected:
|
|||
void GetAlphaMinMax();
|
||||
bool TryAlphaTest(uint32& fm, uint32& zm);
|
||||
bool IsOpaque();
|
||||
bool IsMipMapActive();
|
||||
|
||||
public:
|
||||
GIFPath m_path[4];
|
||||
|
@ -201,6 +202,7 @@ public:
|
|||
CRC::Game m_game;
|
||||
GSDump m_dump;
|
||||
bool m_nativeres;
|
||||
bool m_mipmap;
|
||||
|
||||
int s_n;
|
||||
bool s_dump;
|
||||
|
|
Loading…
Reference in New Issue