From 4e20305fe2adea218d0c8d50b38d3dad5db26f07 Mon Sep 17 00:00:00 2001 From: gabest11 Date: Wed, 10 Jun 2009 17:03:23 +0000 Subject: [PATCH] GSdx: dx10 hw mode sharper again git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1354 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSCrc.cpp | 1 + plugins/GSdx/GSRendererHW10.cpp | 37 ++++--- plugins/GSdx/GSRendererHW9.cpp | 32 +++--- plugins/GSdx/GSState.cpp | 2 +- plugins/GSdx/GSTextureFX10.cpp | 5 + plugins/GSdx/GSTextureFX10.h | 14 +-- plugins/GSdx/GSTextureFX9.cpp | 4 +- plugins/GSdx/GSTextureFX9.h | 11 +- plugins/GSdx/res/tfx10.fx | 178 ++++++++++++-------------------- plugins/GSdx/res/tfx9.fx | 150 +++++++++++---------------- 10 files changed, 182 insertions(+), 252 deletions(-) diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index c0075a01d7..c8d5a44f42 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -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}, diff --git a/plugins/GSdx/GSRendererHW10.cpp b/plugins/GSdx/GSRendererHW10.cpp index 4423d582e5..f300ac44dd 100644 --- a/plugins/GSdx/GSRendererHW10.cpp +++ b/plugins/GSdx/GSRendererHW10.cpp @@ -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 { diff --git a/plugins/GSdx/GSRendererHW9.cpp b/plugins/GSdx/GSRendererHW9.cpp index b4b0877352..f88143c334 100644 --- a/plugins/GSdx/GSRendererHW9.cpp +++ b/plugins/GSdx/GSRendererHW9.cpp @@ -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 { diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 9a2d347065..1458fd7290 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -1237,7 +1237,7 @@ template 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) { diff --git a/plugins/GSdx/GSTextureFX10.cpp b/plugins/GSdx/GSTextureFX10.cpp index 60d79f75dc..b00de4e1d0 100644 --- a/plugins/GSdx/GSTextureFX10.cpp +++ b/plugins/GSdx/GSTextureFX10.cpp @@ -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 >::const_iterator i = m_ps_ss.find(ssel); if(i != m_ps_ss.end()) diff --git a/plugins/GSdx/GSTextureFX10.h b/plugins/GSdx/GSTextureFX10.h index 3377acd1fd..14e36c03e7 100644 --- a/plugins/GSdx/GSTextureFX10.h +++ b/plugins/GSdx/GSTextureFX10.h @@ -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));} diff --git a/plugins/GSdx/GSTextureFX9.cpp b/plugins/GSdx/GSTextureFX9.cpp index 31f27b0983..f0ed275778 100644 --- a/plugins/GSdx/GSTextureFX9.cpp +++ b/plugins/GSdx/GSTextureFX9.cpp @@ -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); } diff --git a/plugins/GSdx/GSTextureFX9.h b/plugins/GSdx/GSTextureFX9.h index e3e1b5823e..c657a2b06d 100644 --- a/plugins/GSdx/GSTextureFX9.h +++ b/plugins/GSdx/GSTextureFX9.h @@ -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 diff --git a/plugins/GSdx/res/tfx10.fx b/plugins/GSdx/res/tfx10.fx index 72f9688732..a16b2a8286 100644 --- a/plugins/GSdx/res/tfx10.fx +++ b/plugins/GSdx/res/tfx10.fx @@ -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; + } + + 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) @@ -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) diff --git a/plugins/GSdx/res/tfx9.fx b/plugins/GSdx/res/tfx9.fx index 0c2956423a..9c1011f735 100644 --- a/plugins/GSdx/res/tfx9.fx +++ b/plugins/GSdx/res/tfx9.fx @@ -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;