GSdx: that damned different pixel center of dx10... this one should fix the screen edge and other strange artifacts that appeared in non-native resolution.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1357 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-06-11 09:27:59 +00:00
parent f8a94b15ff
commit 6841f7fd98
3 changed files with 39 additions and 38 deletions

View File

@ -287,13 +287,13 @@ 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 - 8); float ox = (float)(int)context->XYOFFSET.OFX;
float oy = (float)((int)context->XYOFFSET.OFY - 8); float oy = (float)(int)context->XYOFFSET.OFY;
float ox2 = 1.0f / rt->GetWidth();
// dx10 pixel center is different => offset - 8 (half pixel) float oy2 = 1.0f / rt->GetHeight();
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 - ox2 + 1, -(oy * sy - oy2 + 1), 0.0f, -1.0f);
vs_cb.TextureScale = GSVector2(1.0f, 1.0f); vs_cb.TextureScale = GSVector2(1.0f, 1.0f);
if(PRIM->TME && PRIM->FST) if(PRIM->TME && PRIM->FST)
@ -337,8 +337,7 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
GSTextureFX10::PSConstantBuffer ps_cb; GSTextureFX10::PSConstantBuffer ps_cb;
ps_cb.FogColorAREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255; ps_cb.FogColorAREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, (int)context->TEST.AREF) / 255;
ps_cb.TA0 = (float)(int)env.TEXA.TA0 / 255; ps_cb.TA = GSVector4((int)env.TEXA.TA0, (int)env.TEXA.TA1) / 255;
ps_cb.TA1 = (float)(int)env.TEXA.TA1 / 255;
if(context->TEST.ATST == 2 || context->TEST.ATST == 5) if(context->TEST.ATST == 2 || context->TEST.ATST == 5)
{ {
@ -356,14 +355,16 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
int w = tex->m_texture->GetWidth(); int w = tex->m_texture->GetWidth();
int h = tex->m_texture->GetHeight(); int h = tex->m_texture->GetHeight();
ps_cb.WH = GSVector2i(w, h);
switch(context->CLAMP.WMS) switch(context->CLAMP.WMS)
{ {
case 0: case 0:
ps_cb.MinMax.x = w - 1;
ps_cb.MinMax.z = 0;
ps_ssel.tau = 1; ps_ssel.tau = 1;
break; break;
case 1: case 1:
ps_cb.MinMax.x = 0;
ps_cb.MinMax.z = w - 1;
ps_ssel.tau = 0; ps_ssel.tau = 0;
break; break;
case 2: case 2:
@ -374,8 +375,8 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
ps_ssel.tau = 0; ps_ssel.tau = 0;
break; break;
case 3: case 3:
ps_cb.MskFix.x = context->CLAMP.MINU; ps_cb.MinMax.x = context->CLAMP.MINU;
ps_cb.MskFix.z = context->CLAMP.MAXU; ps_cb.MinMax.z = context->CLAMP.MAXU;
ps_ssel.tau = 1; ps_ssel.tau = 1;
break; break;
default: default:
@ -385,9 +386,13 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
switch(context->CLAMP.WMT) switch(context->CLAMP.WMT)
{ {
case 0: case 0:
ps_cb.MinMax.y = h - 1;
ps_cb.MinMax.w = 0;
ps_ssel.tav = 1; ps_ssel.tav = 1;
break; break;
case 1: case 1:
ps_cb.MinMax.y = 0;
ps_cb.MinMax.w = h - 1;
ps_ssel.tav = 0; ps_ssel.tav = 0;
break; break;
case 2: case 2:
@ -398,8 +403,8 @@ void GSRendererHW10::Draw(int prim, GSTexture* rt, GSTexture* ds, GSTextureCache
ps_ssel.tav = 0; ps_ssel.tav = 0;
break; break;
case 3: case 3:
ps_cb.MskFix.y = context->CLAMP.MINV; ps_cb.MinMax.y = context->CLAMP.MINV;
ps_cb.MskFix.w = context->CLAMP.MAXV; ps_cb.MinMax.w = context->CLAMP.MAXV;
ps_ssel.tav = 1; ps_ssel.tav = 1;
break; break;
default: default:

View File

@ -78,12 +78,9 @@ public:
__declspec(align(16)) struct PSConstantBuffer __declspec(align(16)) struct PSConstantBuffer
{ {
GSVector4 FogColorAREF; GSVector4 FogColorAREF;
GSVector2i WH; GSVector4 TA;
float TA0;
float TA1;
GSVector4i MinMax; GSVector4i MinMax;
GSVector4 MinMaxF; GSVector4 MinMaxF;
GSVector4i MskFix;
struct PSConstantBuffer() {memset(this, 0, sizeof(*this));} struct PSConstantBuffer() {memset(this, 0, sizeof(*this));}
@ -96,15 +93,13 @@ public:
GSVector4i b1 = b[1]; GSVector4i b1 = b[1];
GSVector4i b2 = b[2]; GSVector4i b2 = b[2];
GSVector4i b3 = b[3]; GSVector4i b3 = b[3];
GSVector4i b4 = b[4];
if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3) & (a[4] == b4)).alltrue()) if(!((a[0] == b0) & (a[1] == b1) & (a[2] == b2) & (a[3] == b3)).alltrue())
{ {
a[0] = b0; a[0] = b0;
a[1] = b1; a[1] = b1;
a[2] = b2; a[2] = b2;
a[3] = b3; a[3] = b3;
a[4] = b4;
return true; return true;
} }

View File

@ -155,12 +155,9 @@ cbuffer cb1
{ {
float3 FogColor; float3 FogColor;
float AREF; float AREF;
uint2 WH; float4 TA;
float TA0;
float TA1;
uint4 MinMax; uint4 MinMax;
float4 MinMaxF; float4 MinMaxF;
uint4 MskFix;
}; };
struct PS_INPUT struct PS_INPUT
@ -178,8 +175,8 @@ struct PS_OUTPUT
#ifndef FST #ifndef FST
#define FST 0 #define FST 0
#define WMS 3 #define WMS 1
#define WMT 3 #define WMT 1
#define BPP 0 #define BPP 0
#define AEM 0 #define AEM 0
#define TFX 0 #define TFX 0
@ -216,28 +213,28 @@ int4 wrapuv(int4 uv)
{ {
switch(WMS) switch(WMS)
{ {
case 0: uv &= WH.xyxy - 1; break; case 0: uv &= MinMax.xyxy; break;
case 1: uv = clamp(uv, 0, WH.xyxy); break; case 1: uv = clamp(uv, 0, MinMax.zwzw); break;
case 2: uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); break; case 2: uv = clamp(uv, MinMax.xyxy, MinMax.zwzw); break;
case 3: uv = (uv & MskFix.xyxy) | MskFix.zwzw; break; case 3: uv = (uv & MinMax.xyxy) | MinMax.zwzw; break;
} }
} }
else else
{ {
switch(WMS) switch(WMS)
{ {
case 0: uv.xz &= WH.xx - 1; break; case 0: uv.xz &= MinMax.xx; break;
case 1: uv.xz = clamp(uv.xz, 0, WH.xx); break; case 1: uv.xz = clamp(uv.xz, 0, MinMax.zz); break;
case 2: uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); break; case 2: uv.xz = clamp(uv.xz, MinMax.xx, MinMax.zz); break;
case 3: uv.xz = (uv.xz & MskFix.xx) | MskFix.zz; break; case 3: uv.xz = (uv.xz & MinMax.xx) | MinMax.zz; break;
} }
switch(WMT) switch(WMT)
{ {
case 0: uv.yw &= WH.yy - 1; break; case 0: uv.yw &= MinMax.yy; break;
case 1: uv.yw = clamp(uv.yw, 0, WH.yy); break; case 1: uv.yw = clamp(uv.yw, 0, MinMax.ww); break;
case 2: uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); break; case 2: uv.yw = clamp(uv.yw, MinMax.yy, MinMax.ww); break;
case 3: uv.yw = (uv.yw & MskFix.yy) | MskFix.ww; break; case 3: uv.yw = (uv.yw & MinMax.yy) | MinMax.ww; break;
} }
} }
@ -282,7 +279,11 @@ float4 sample(float2 tc, float w)
} }
else else
{ {
float4 tc2 = (tc * WH).xyxy + float4(-0.499, -0.499, 0.501, 0.501); float w, h;
Texture.GetDimensions(w, h);
float4 tc2 = (tc * float2(w, h)).xyxy + float4(-0.499, -0.499, 0.501, 0.501);
float2 dd = frac(tc2.xy); float2 dd = frac(tc2.xy);
int4 uv = wrapuv((int4)tc2); int4 uv = wrapuv((int4)tc2);
@ -342,7 +343,7 @@ float4 sample(float2 tc, float w)
if(BPP == 1) // 24 if(BPP == 1) // 24
{ {
t.a = AEM == 0 || any(t.rgb) ? TA0 : 0; t.a = AEM == 0 || any(t.rgb) ? TA.x : 0;
} }
else if(BPP == 2 || BPP == 5) // 16 || 16P else if(BPP == 2 || BPP == 5) // 16 || 16P
{ {
@ -353,7 +354,7 @@ float4 sample(float2 tc, float w)
// a bit incompatible with up-scaling because the 1 bit alpha is interpolated // a bit incompatible with up-scaling because the 1 bit alpha is interpolated
t.a = t.a >= 0.5 ? TA1 : AEM == 0 || any(t.rgb) ? TA0 : 0; t.a = t.a >= 0.5 ? TA.y : AEM == 0 || any(t.rgb) ? TA.x : 0;
} }
return t; return t;