GSdx: dx10 hw mode sharper again

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1354 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-06-10 17:03:23 +00:00
parent a7f2130595
commit 4e20305fe2
10 changed files with 182 additions and 252 deletions

View File

@ -115,6 +115,7 @@ CRC::Game CRC::m_games[] =
{0xA61A4C6D, GodOfWar, Unknown},
{0xE23D532B, GodOfWar, Unknown},
{0xDF1AF973, GodOfWar, Unknown},
{0xD6385328, GodOfWar, Unknown},
{0x2F123FD8, GodOfWar2, RU},
{0x2F123FD8, GodOfWar2, US},
{0x44A8A22A, GodOfWar2, EU},

View File

@ -287,8 +287,10 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
float sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16);
float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16);
float ox = (float)(int)context->XYOFFSET.OFX;
float oy = (float)(int)context->XYOFFSET.OFY;
float ox = (float)((int)context->XYOFFSET.OFX - 8);
float oy = (float)((int)context->XYOFFSET.OFY - 8);
// dx10 pixel center is different => offset - 8 (half pixel)
vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f);
vs_cb.VertexOffset = GSVector4(ox * sx + 1, -(oy * sy + 1), 0.0f, -1.0f);
@ -351,6 +353,11 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
{
ps_sel.bpp = tex->m_bpp2;
int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight();
ps_cb.WH = GSVector2i(w, h);
switch(context->CLAMP.WMS)
{
case 0:
@ -360,13 +367,15 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
ps_ssel.tau = 0;
break;
case 2:
ps_cb.MINU = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW);
ps_cb.MAXU = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_cb.MinMax.x = (int)context->CLAMP.MINU * w / (1 << context->TEX0.TW);
ps_cb.MinMax.z = (int)context->CLAMP.MAXU * w / (1 << context->TEX0.TW);
ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW);
ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_ssel.tau = 0;
break;
case 3:
ps_cb.UMSK = context->CLAMP.MINU;
ps_cb.UFIX = context->CLAMP.MAXU;
ps_cb.MskFix.x = context->CLAMP.MINU;
ps_cb.MskFix.z = context->CLAMP.MAXU;
ps_ssel.tau = 1;
break;
default:
@ -382,24 +391,20 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
ps_ssel.tav = 0;
break;
case 2:
ps_cb.MINV = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH);
ps_cb.MAXV = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_cb.MinMax.y = (int)context->CLAMP.MINV * h / (1 << context->TEX0.TH);
ps_cb.MinMax.w = (int)context->CLAMP.MAXV * h / (1 << context->TEX0.TH);
ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH);
ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_ssel.tav = 0;
break;
case 3:
ps_cb.VMSK = context->CLAMP.MINV;
ps_cb.VFIX = context->CLAMP.MAXV;
ps_cb.MskFix.y = context->CLAMP.MINV;
ps_cb.MskFix.w = context->CLAMP.MAXV;
ps_ssel.tav = 1;
break;
default:
__assume(0);
}
float w = (float)tex->m_texture->GetWidth();
float h = (float)tex->m_texture->GetHeight();
ps_cb.WH = GSVector2(w, h);
ps_cb.HalfTexel = GSVector4(-0.5f / w, -0.5f / h, +0.5f / w, +0.5f / h);
}
else
{

View File

@ -325,6 +325,12 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
{
ps_sel.bpp = tex->m_bpp2;
int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight();
ps_cb.WH = GSVector2(w, h);
ps_cb.HalfTexel = GSVector4(-0.5f / w, -0.5f / h, +0.5f / w, +0.5f / h);
switch(context->CLAMP.WMS)
{
case 0:
@ -334,13 +340,15 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
ps_ssel.tau = 0;
break;
case 2:
ps_cb.MINU = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW);
ps_cb.MAXU = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_cb.MinMax.x = (float)(int)context->CLAMP.MINU / (1 << context->TEX0.TW);
ps_cb.MinMax.z = (float)(int)context->CLAMP.MAXU / (1 << context->TEX0.TW);
ps_cb.MinMaxF.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW);
ps_cb.MinMaxF.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
ps_ssel.tau = 0;
break;
case 3:
ps_cb.UMSK = context->CLAMP.MINU;
ps_cb.UFIX = context->CLAMP.MAXU;
ps_cb.MskFix.x = context->CLAMP.MINU;
ps_cb.MskFix.z = context->CLAMP.MAXU;
ps_ssel.tau = 1;
break;
default:
@ -356,24 +364,20 @@ void GSRendererHW9::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache:
ps_ssel.tav = 0;
break;
case 2:
ps_cb.MINV = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH);
ps_cb.MAXV = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_cb.MinMax.y = (float)(int)context->CLAMP.MINV / (1 << context->TEX0.TH);
ps_cb.MinMax.w = (float)(int)context->CLAMP.MAXV / (1 << context->TEX0.TH);
ps_cb.MinMaxF.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH);
ps_cb.MinMaxF.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
ps_ssel.tav = 0;
break;
case 3:
ps_cb.VMSK = context->CLAMP.MINV;
ps_cb.VFIX = context->CLAMP.MAXV;
ps_cb.MskFix.y = context->CLAMP.MINV;
ps_cb.MskFix.w = context->CLAMP.MAXV;
ps_ssel.tav = 1;
break;
default:
__assume(0);
}
float w = (float)tex->m_texture->GetWidth();
float h = (float)tex->m_texture->GetHeight();
ps_cb.WH = GSVector2(w, h);
ps_cb.HalfTexel = GSVector4(-0.5f / w, -0.5f / h, +0.5f / w, +0.5f / h);
}
else
{

View File

@ -1237,7 +1237,7 @@ template<int index> void GSState::Transfer(uint8* mem, uint32 size)
{
m_q = 1.0f;
ASSERT(!(path.tag.PRE && path.tag.FLG == GIF_FLG_REGLIST));
// ASSERT(!(path.tag.PRE && path.tag.FLG == GIF_FLG_REGLIST)); // kingdom hearts
if(path.tag.PRE && path.tag.FLG == GIF_FLG_PACKED)
{

View File

@ -270,6 +270,11 @@ void GSTextureFX10::UpdatePS(PSSelector sel, const PSConstantBuffer* cb, PSSampl
if(sel.tfx != 4)
{
if(!(sel.bpp < 3 && sel.wms < 3 && sel.wmt < 3))
{
ssel.ltf = 0;
}
hash_map<uint32, CComPtr<ID3D10SamplerState> >::const_iterator i = m_ps_ss.find(ssel);
if(i != m_ps_ss.end())

View File

@ -78,18 +78,12 @@ public:
__declspec(align(16)) struct PSConstantBuffer
{
GSVector4 FogColorAREF;
GSVector4 HalfTexel;
GSVector2 WH;
GSVector2i WH;
float TA0;
float TA1;
float MINU;
float MINV;
float MAXU;
float MAXV;
uint32 UMSK;
uint32 VMSK;
uint32 UFIX;
uint32 VFIX;
GSVector4i MinMax;
GSVector4 MinMaxF;
GSVector4i MskFix;
struct PSConstantBuffer() {memset(this, 0, sizeof(*this));}

View File

@ -152,7 +152,7 @@ bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSampler
{
if(sel.wms == 3)
{
if(GSTexture* t = CreateMskFix(tex->GetWidth(), cb->UMSK, cb->UFIX))
if(GSTexture* t = CreateMskFix(tex->GetWidth(), cb->MskFix.x, cb->MskFix.z))
{
(*m_dev)->SetTexture(2, *(GSTexture9*)t);
}
@ -160,7 +160,7 @@ bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSampler
if(sel.wmt == 3)
{
if(GSTexture* t = CreateMskFix(tex->GetHeight(), cb->VMSK, cb->VFIX))
if(GSTexture* t = CreateMskFix(tex->GetHeight(), cb->MskFix.y, cb->MskFix.w))
{
(*m_dev)->SetTexture(3, *(GSTexture9*)t);
}

View File

@ -58,14 +58,9 @@ public:
GSVector2 WH;
float TA0;
float TA1;
float MINU;
float MINV;
float MAXU;
float MAXV;
uint32 UMSK;
uint32 VMSK;
uint32 UFIX;
uint32 VFIX;
GSVector4 MinMax;
GSVector4 MinMaxF;
GSVector4i MskFix;
};
union PSSelector

View File

@ -48,16 +48,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
VS_OUTPUT output;
float4 p = float4(input.p, input.z, 0);
// FIXME:
// A litte accuracy problem in many games where the screen is copied in columns and the sides have a half pixel gap for some reason
// (probably to avoid page breaks with linear filtering). That half pixel coordinate gets multiplied by 2 (VertexScale) and occasionally
// ends on .9999999, which the rasterizer floors to 1 less pixel we need, leaving a visible gap after drawing.
p += float4(0.5f, 0.5f, 0, 0); // add 1/32 pixel
output.p = p * VertexScale - VertexOffset;
output.p = float4(input.p, input.z, 0) * VertexScale - VertexOffset;
if(VS_TME == 1)
{
@ -164,14 +155,12 @@ cbuffer cb1
{
float3 FogColor;
float AREF;
float4 HalfTexel;
float2 WH;
uint2 WH;
float TA0;
float TA1;
float2 MINUV;
float2 MAXUV;
uint2 UVMSK;
uint2 UVFIX;
uint4 MinMax;
float4 MinMaxF;
uint4 MskFix;
};
struct PS_INPUT
@ -189,14 +178,14 @@ struct PS_OUTPUT
#ifndef FST
#define FST 0
#define WMS 1
#define WMT 1
#define WMS 3
#define WMT 3
#define BPP 0
#define AEM 0
#define TFX 0
#define TCC 1
#define ATE 1
#define ATST 2
#define ATST 4
#define FOG 1
#define CLR1 0
#define FBA 0
@ -221,85 +210,56 @@ float4 Extract16(uint i)
return f;
}
int2 wrapu(float2 f, int2 i)
{
if(WMS == 0)
{
i = frac(f) * WH.xx;
}
else if(WMS == 1)
{
i = saturate(f) * WH.xx;
}
else if(WMS == 2)
{
i = clamp(f, MINUV.xx, MAXUV.xx) * WH.xx;
}
else if(WMS == 3)
{
i = (i & UVMSK.xx) | UVFIX.xx;
}
return i;
}
int2 wrapv(float2 f, int2 i)
{
if(WMT == 0)
{
i = frac(f) * WH.yy;
}
else if(WMT == 1)
{
i = saturate(f) * WH.yy;
}
else if(WMT == 2)
{
i = clamp(f, MINUV.yy, MAXUV.yy) * WH.yy;
}
else if(WMT == 3)
{
i = (i & UVMSK.yy) | UVFIX.yy;
}
return i;
}
int4 wrapuv(float4 f, int4 i)
{
if(WMT == 0)
{
i = frac(f) * WH.xyxy;
}
else if(WMT == 1)
{
i = saturate(f) * WH.xyxy;
}
else if(WMT == 2)
{
i = clamp(f, MINUV.xyxy, MAXUV.xyxy) * WH.xyxy;
}
else if(WMT == 3)
{
i = (i & UVMSK.xyxy) | UVFIX.xyxy;
}
return i;
}
int4 wrap(float4 uv, int4 iuv)
int4 wrapuv(int4 uv)
{
if(WMS == WMT)
{
iuv = wrapuv(uv, iuv);
switch(WMS)
{
case 0: uv &= WH.xyxy - 1; break;
case 1: uv = clamp(uv, 0, WH.xyxy); break;
case 2: uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); break;
case 3: uv = (uv & MskFix.xyxy) | MskFix.zwzw; break;
}
}
else
{
iuv.xz = wrapu(uv.xz, iuv.xz);
iuv.yw = wrapv(uv.yw, iuv.yw);
switch(WMS)
{
case 0: uv.xz &= WH.xx - 1; break;
case 1: uv.xz = clamp(uv.xz, 0, WH.xx); break;
case 2: uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); break;
case 3: uv.xz = (uv.xz & MskFix.xx) | MskFix.zz; break;
}
return iuv;
switch(WMT)
{
case 0: uv.yw &= WH.yy - 1; break;
case 1: uv.yw = clamp(uv.yw, 0, WH.yy); break;
case 2: uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); break;
case 3: uv.yw = (uv.yw & MskFix.yy) | MskFix.ww; break;
}
}
return uv;
}
float2 clampuv(float2 tc)
{
if(WMS == 2 && WMT == 2)
{
tc = clamp(tc, MinMaxF.xy, MinMaxF.zw);
}
else if(WMS == 2)
{
tc.x = clamp(tc.x, MinMaxF.x, MinMaxF.z);
}
else if(WMT == 2)
{
tc.y = clamp(tc.y, MinMaxF.y, MinMaxF.w);
}
return tc;
}
float4 sample(float2 tc, float w)
@ -318,19 +278,13 @@ float4 sample(float2 tc, float w)
*/
if(BPP < 3 && WMS < 3 && WMT < 3)
{
if(WMS == 2 && WMT == 2) tc = clamp(tc, MINUV.xy, MAXUV.xy);
else if(WMS == 2) tc.x = clamp(tc.x, MINUV.x, MAXUV.x);
else if(WMT == 2) tc.y = clamp(tc.y, MINUV.y, MAXUV.y);
t = Texture.Sample(TextureSampler, tc);
t = Texture.Sample(TextureSampler, clampuv(tc));
}
else
{
float4 uv = tc.xyxy + HalfTexel;
float4 uv2 = uv * WH.xyxy;
float2 dd = frac(uv2.xy);
int4 iuv = wrap(uv, uv2);
float4 tc2 = (tc * WH).xyxy + float4(-0.499, -0.499, 0.501, 0.501);
float2 dd = frac(tc2.xy);
int4 uv = wrapuv((int4)tc2);
float4 t00, t01, t10, t11;
@ -338,10 +292,10 @@ float4 sample(float2 tc, float w)
{
float4 a;
a.x = Texture.Load(int3(iuv.xy, 0)).a;
a.y = Texture.Load(int3(iuv.zy, 0)).a;
a.z = Texture.Load(int3(iuv.xw, 0)).a;
a.w = Texture.Load(int3(iuv.zw, 0)).a;
a.x = Texture.Load(int3(uv.xy, 0)).a;
a.y = Texture.Load(int3(uv.zy, 0)).a;
a.z = Texture.Load(int3(uv.xw, 0)).a;
a.w = Texture.Load(int3(uv.zw, 0)).a;
t00 = Palette.Load(a.x);
t01 = Palette.Load(a.y);
@ -356,10 +310,10 @@ float4 sample(float2 tc, float w)
{
float4 r;
r.x = Texture.Load(int3(iuv.xy, 0)).r;
r.y = Texture.Load(int3(iuv.zy, 0)).r;
r.z = Texture.Load(int3(iuv.xw, 0)).r;
r.w = Texture.Load(int3(iuv.zw, 0)).r;
r.x = Texture.Load(int3(uv.xy, 0)).r;
r.y = Texture.Load(int3(uv.zy, 0)).r;
r.z = Texture.Load(int3(uv.xw, 0)).r;
r.w = Texture.Load(int3(uv.zw, 0)).r;
uint4 i = r * 65535;
@ -370,10 +324,10 @@ float4 sample(float2 tc, float w)
}
else
{
t00 = Texture.Load(int3(iuv.xy, 0));
t01 = Texture.Load(int3(iuv.zy, 0));
t10 = Texture.Load(int3(iuv.xw, 0));
t11 = Texture.Load(int3(iuv.zw, 0));
t00 = Texture.Load(int3(uv.xy, 0));
t01 = Texture.Load(int3(uv.zy, 0));
t10 = Texture.Load(int3(uv.xw, 0));
t11 = Texture.Load(int3(uv.zw, 0));
}
if(LTF)

View File

@ -71,7 +71,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
return output;
}
float4 ps_params[4];
float4 ps_params[5];
#define FogColor ps_params[0].bgr
#define AREF ps_params[0].a
@ -79,8 +79,8 @@ float4 ps_params[4];
#define WH ps_params[2].xy
#define TA0 ps_params[2].z
#define TA1 ps_params[2].w
#define MINUV ps_params[3].xy
#define MAXUV ps_params[3].zw
#define MinMax ps_params[3]
#define MinMaxF ps_params[4]
struct PS_INPUT
{
@ -90,8 +90,8 @@ struct PS_INPUT
#ifndef FST
#define FST 0
#define WMS 1
#define WMT 1
#define WMS 3
#define WMT 3
#define BPP 0
#define AEM 0
#define TFX 0
@ -109,92 +109,69 @@ sampler1D Palette : register(s1);
sampler1D UMSKFIX : register(s2);
sampler1D VMSKFIX : register(s3);
float2 wrapu(float2 f)
{
if(WMS == 0)
{
f = frac(f);
}
else if(WMS == 1)
{
f = saturate(f);
}
else if(WMS == 2)
{
f = clamp(f, MINUV.xx, MAXUV.xx);
}
else if(WMS == 3)
{
f.x = tex1D(UMSKFIX, f.x);
f.y = tex1D(UMSKFIX, f.y);
}
return f;
}
float2 wrapv(float2 f)
{
if(WMS == 0)
{
f = frac(f);
}
else if(WMS == 1)
{
f = saturate(f);
}
else if(WMS == 2)
{
f = clamp(f, MINUV.yy, MAXUV.yy);
}
else if(WMS == 3)
{
f.x = tex1D(VMSKFIX, f.x);
f.y = tex1D(VMSKFIX, f.y);
}
return f;
}
float4 wrapuv(float4 f)
{
if(WMS == 0)
{
f = frac(f);
}
else if(WMS == 1)
{
f = saturate(f);
}
else if(WMS == 2)
{
f = clamp(f, MINUV.xyxy, MAXUV.xyxy);
}
else if(WMS == 3)
{
f.x = tex1D(UMSKFIX, f.x);
f.y = tex1D(VMSKFIX, f.y);
f.z = tex1D(UMSKFIX, f.z);
f.w = tex1D(VMSKFIX, f.w);
}
return f;
}
float4 wrap(float4 uv)
float4 wrapuv(float4 uv)
{
if(WMS == WMT)
{
uv = wrapuv(uv);
switch(WMS)
{
case 0: uv = frac(uv); break;
case 1: uv = saturate(uv); break;
case 2: uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); break;
case 3:
uv.x = tex1D(UMSKFIX, uv.x);
uv.y = tex1D(VMSKFIX, uv.y);
uv.z = tex1D(UMSKFIX, uv.z);
uv.w = tex1D(VMSKFIX, uv.w);
break;
}
}
else
{
uv.xz = wrapu(uv.xz);
uv.yw = wrapv(uv.yw);
switch(WMS)
{
case 0: uv.xz = frac(uv.xz); break;
case 1: uv.xz = saturate(uv.xz); break;
case 2: uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); break;
case 3:
uv.x = tex1D(UMSKFIX, uv.x);
uv.z = tex1D(UMSKFIX, uv.z);
break;
}
switch(WMT)
{
case 0: uv.yw = frac(uv.yw); break;
case 1: uv.yw = saturate(uv.yw); break;
case 2: uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); break;
case 3:
uv.y = tex1D(VMSKFIX, uv.y);
uv.w = tex1D(VMSKFIX, uv.w);
break;
}
}
return uv;
}
float2 clampuv(float2 tc)
{
if(WMS == 2 && WMT == 2)
{
tc = clamp(tc, MinMaxF.xy, MinMaxF.zw);
}
else if(WMS == 2)
{
tc.x = clamp(tc.x, MinMaxF.x, MinMaxF.z);
}
else if(WMT == 2)
{
tc.y = clamp(tc.y, MinMaxF.y, MinMaxF.w);
}
return tc;
}
float4 sample(float2 tc, float w)
{
if(FST == 0)
@ -211,18 +188,13 @@ float4 sample(float2 tc, float w)
*/
if(BPP < 3 && WMS < 3 && WMT < 3)
{
if(WMS == 2 && WMT == 2) tc = clamp(tc, MINUV.xy, MAXUV.xy);
else if(WMS == 2) tc.x = clamp(tc.x, MINUV.x, MAXUV.x);
else if(WMT == 2) tc.y = clamp(tc.y, MINUV.y, MAXUV.y);
t = tex2D(Texture, tc);
t = tex2D(Texture, clampuv(tc));
}
else
{
float4 uv = tc.xyxy + HalfTexel;
float2 dd = frac(uv.xy * WH);
uv = wrap(uv);
float4 tc2 = tc.xyxy + HalfTexel;
float2 dd = frac(tc2.xy * WH);
float4 uv = wrapuv(tc2);
float4 t00, t01, t10, t11;