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}, {0xA61A4C6D, GodOfWar, Unknown},
{0xE23D532B, GodOfWar, Unknown}, {0xE23D532B, GodOfWar, Unknown},
{0xDF1AF973, GodOfWar, Unknown}, {0xDF1AF973, GodOfWar, Unknown},
{0xD6385328, GodOfWar, Unknown},
{0x2F123FD8, GodOfWar2, RU}, {0x2F123FD8, GodOfWar2, RU},
{0x2F123FD8, GodOfWar2, US}, {0x2F123FD8, GodOfWar2, US},
{0x44A8A22A, GodOfWar2, EU}, {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 sx = 2.0f * rt->m_scale.x / (rt->GetWidth() * 16);
float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16); float sy = 2.0f * rt->m_scale.y / (rt->GetHeight() * 16);
float ox = (float)(int)context->XYOFFSET.OFX; float ox = (float)((int)context->XYOFFSET.OFX - 8);
float oy = (float)(int)context->XYOFFSET.OFY; 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.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f);
vs_cb.VertexOffset = GSVector4(ox * sx + 1, -(oy * sy + 1), 0.0f, -1.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; 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) switch(context->CLAMP.WMS)
{ {
case 0: case 0:
@ -360,13 +367,15 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
ps_ssel.tau = 0; ps_ssel.tau = 0;
break; break;
case 2: case 2:
ps_cb.MINU = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW); ps_cb.MinMax.x = (int)context->CLAMP.MINU * w / (1 << context->TEX0.TW);
ps_cb.MAXU = ((float)(int)context->CLAMP.MAXU) / (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; ps_ssel.tau = 0;
break; break;
case 3: case 3:
ps_cb.UMSK = context->CLAMP.MINU; ps_cb.MskFix.x = context->CLAMP.MINU;
ps_cb.UFIX = context->CLAMP.MAXU; ps_cb.MskFix.z = context->CLAMP.MAXU;
ps_ssel.tau = 1; ps_ssel.tau = 1;
break; break;
default: default:
@ -382,24 +391,20 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
ps_ssel.tav = 0; ps_ssel.tav = 0;
break; break;
case 2: case 2:
ps_cb.MINV = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH); ps_cb.MinMax.y = (int)context->CLAMP.MINV * h / (1 << context->TEX0.TH);
ps_cb.MAXV = ((float)(int)context->CLAMP.MAXV) / (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; ps_ssel.tav = 0;
break; break;
case 3: case 3:
ps_cb.VMSK = context->CLAMP.MINV; ps_cb.MskFix.y = context->CLAMP.MINV;
ps_cb.VFIX = context->CLAMP.MAXV; ps_cb.MskFix.w = context->CLAMP.MAXV;
ps_ssel.tav = 1; ps_ssel.tav = 1;
break; break;
default: default:
__assume(0); __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 else
{ {

View File

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

View File

@ -1237,7 +1237,7 @@ template<int index> void GSState::Transfer(uint8* mem, uint32 size)
{ {
m_q = 1.0f; 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) 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.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); hash_map<uint32, CComPtr<ID3D10SamplerState> >::const_iterator i = m_ps_ss.find(ssel);
if(i != m_ps_ss.end()) if(i != m_ps_ss.end())

View File

@ -78,18 +78,12 @@ public:
__declspec(align(16)) struct PSConstantBuffer __declspec(align(16)) struct PSConstantBuffer
{ {
GSVector4 FogColorAREF; GSVector4 FogColorAREF;
GSVector4 HalfTexel; GSVector2i WH;
GSVector2 WH;
float TA0; float TA0;
float TA1; float TA1;
float MINU; GSVector4i MinMax;
float MINV; GSVector4 MinMaxF;
float MAXU; GSVector4i MskFix;
float MAXV;
uint32 UMSK;
uint32 VMSK;
uint32 UFIX;
uint32 VFIX;
struct PSConstantBuffer() {memset(this, 0, sizeof(*this));} 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(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); (*m_dev)->SetTexture(2, *(GSTexture9*)t);
} }
@ -160,7 +160,7 @@ bool GSTextureFX9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSampler
if(sel.wmt == 3) 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); (*m_dev)->SetTexture(3, *(GSTexture9*)t);
} }

View File

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

View File

@ -48,16 +48,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
VS_OUTPUT output; VS_OUTPUT output;
float4 p = float4(input.p, input.z, 0); output.p = float4(input.p, input.z, 0) * VertexScale - VertexOffset;
// 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;
if(VS_TME == 1) if(VS_TME == 1)
{ {
@ -164,14 +155,12 @@ cbuffer cb1
{ {
float3 FogColor; float3 FogColor;
float AREF; float AREF;
float4 HalfTexel; uint2 WH;
float2 WH;
float TA0; float TA0;
float TA1; float TA1;
float2 MINUV; uint4 MinMax;
float2 MAXUV; float4 MinMaxF;
uint2 UVMSK; uint4 MskFix;
uint2 UVFIX;
}; };
struct PS_INPUT struct PS_INPUT
@ -189,14 +178,14 @@ struct PS_OUTPUT
#ifndef FST #ifndef FST
#define FST 0 #define FST 0
#define WMS 1 #define WMS 3
#define WMT 1 #define WMT 3
#define BPP 0 #define BPP 0
#define AEM 0 #define AEM 0
#define TFX 0 #define TFX 0
#define TCC 1 #define TCC 1
#define ATE 1 #define ATE 1
#define ATST 2 #define ATST 4
#define FOG 1 #define FOG 1
#define CLR1 0 #define CLR1 0
#define FBA 0 #define FBA 0
@ -221,85 +210,56 @@ float4 Extract16(uint i)
return f; return f;
} }
int2 wrapu(float2 f, int2 i) int4 wrapuv(int4 uv)
{
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)
{ {
if(WMS == WMT) 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 else
{ {
iuv.xz = wrapu(uv.xz, iuv.xz); switch(WMS)
iuv.yw = wrapv(uv.yw, iuv.yw); {
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;
}
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 iuv; 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) float4 sample(float2 tc, float w)
@ -318,19 +278,13 @@ float4 sample(float2 tc, float w)
*/ */
if(BPP < 3 && WMS < 3 && WMT < 3) if(BPP < 3 && WMS < 3 && WMT < 3)
{ {
if(WMS == 2 && WMT == 2) tc = clamp(tc, MINUV.xy, MAXUV.xy); t = Texture.Sample(TextureSampler, clampuv(tc));
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);
} }
else else
{ {
float4 uv = tc.xyxy + HalfTexel; float4 tc2 = (tc * WH).xyxy + float4(-0.499, -0.499, 0.501, 0.501);
float4 uv2 = uv * WH.xyxy; float2 dd = frac(tc2.xy);
float2 dd = frac(uv2.xy); int4 uv = wrapuv((int4)tc2);
int4 iuv = wrap(uv, uv2);
float4 t00, t01, t10, t11; float4 t00, t01, t10, t11;
@ -338,10 +292,10 @@ float4 sample(float2 tc, float w)
{ {
float4 a; float4 a;
a.x = Texture.Load(int3(iuv.xy, 0)).a; a.x = Texture.Load(int3(uv.xy, 0)).a;
a.y = Texture.Load(int3(iuv.zy, 0)).a; a.y = Texture.Load(int3(uv.zy, 0)).a;
a.z = Texture.Load(int3(iuv.xw, 0)).a; a.z = Texture.Load(int3(uv.xw, 0)).a;
a.w = Texture.Load(int3(iuv.zw, 0)).a; a.w = Texture.Load(int3(uv.zw, 0)).a;
t00 = Palette.Load(a.x); t00 = Palette.Load(a.x);
t01 = Palette.Load(a.y); t01 = Palette.Load(a.y);
@ -356,10 +310,10 @@ float4 sample(float2 tc, float w)
{ {
float4 r; float4 r;
r.x = Texture.Load(int3(iuv.xy, 0)).r; r.x = Texture.Load(int3(uv.xy, 0)).r;
r.y = Texture.Load(int3(iuv.zy, 0)).r; r.y = Texture.Load(int3(uv.zy, 0)).r;
r.z = Texture.Load(int3(iuv.xw, 0)).r; r.z = Texture.Load(int3(uv.xw, 0)).r;
r.w = Texture.Load(int3(iuv.zw, 0)).r; r.w = Texture.Load(int3(uv.zw, 0)).r;
uint4 i = r * 65535; uint4 i = r * 65535;
@ -370,10 +324,10 @@ float4 sample(float2 tc, float w)
} }
else else
{ {
t00 = Texture.Load(int3(iuv.xy, 0)); t00 = Texture.Load(int3(uv.xy, 0));
t01 = Texture.Load(int3(iuv.zy, 0)); t01 = Texture.Load(int3(uv.zy, 0));
t10 = Texture.Load(int3(iuv.xw, 0)); t10 = Texture.Load(int3(uv.xw, 0));
t11 = Texture.Load(int3(iuv.zw, 0)); t11 = Texture.Load(int3(uv.zw, 0));
} }
if(LTF) if(LTF)

View File

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