diff --git a/plugins/GSdx/GSDeviceDX.h b/plugins/GSdx/GSDeviceDX.h index b42c54a52a..e13b53aba9 100644 --- a/plugins/GSdx/GSDeviceDX.h +++ b/plugins/GSdx/GSDeviceDX.h @@ -175,12 +175,13 @@ public: uint32 colclip:2; uint32 date:2; uint32 spritehack:1; + uint32 point_sampler:1; }; uint32 key; }; - operator uint32() {return key & 0x7ffffff;} + operator uint32() {return key & 0xfffffff;} PSSelector() : key(0) {} }; diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp index f7c13aef34..9fb0f4aaf0 100644 --- a/plugins/GSdx/GSRendererDX.cpp +++ b/plugins/GSdx/GSRendererDX.cpp @@ -292,6 +292,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc ps_sel.ltf = bilinear && !simple_sample; ps_sel.rt = tex->m_target; ps_sel.spritehack = tex->m_spritehack_t; + ps_sel.point_sampler = !(bilinear && simple_sample); int w = tex->m_texture->GetWidth(); int h = tex->m_texture->GetHeight(); diff --git a/plugins/GSdx/GSTextureFX11.cpp b/plugins/GSdx/GSTextureFX11.cpp index 84189a7d85..04cd318156 100644 --- a/plugins/GSdx/GSTextureFX11.cpp +++ b/plugins/GSdx/GSTextureFX11.cpp @@ -177,7 +177,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe if(i == m_ps.end()) { - string str[16]; + string str[17]; str[0] = format("%d", sel.fst); str[1] = format("%d", sel.wms); @@ -195,6 +195,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe str[13] = format("%d", sel.colclip); str[14] = format("%d", sel.date); str[15] = format("%d", sel.spritehack); + str[16] = format("%d", sel.point_sampler); D3D11_SHADER_MACRO macro[] = { @@ -214,6 +215,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe {"PS_COLCLIP", str[13].c_str()}, {"PS_DATE", str[14].c_str()}, {"PS_SPRITEHACK", str[15].c_str()}, + {"PS_POINT_SAMPLER", str[16].c_str()}, {NULL, NULL}, }; diff --git a/plugins/GSdx/GSTextureFX9.cpp b/plugins/GSdx/GSTextureFX9.cpp index a8e0d913b3..41b7dd96d5 100644 --- a/plugins/GSdx/GSTextureFX9.cpp +++ b/plugins/GSdx/GSTextureFX9.cpp @@ -135,7 +135,7 @@ void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSel if(i == m_ps.end()) { - string str[15]; + string str[16]; str[0] = format("%d", sel.fst); str[1] = format("%d", sel.wms); @@ -152,6 +152,7 @@ void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSel str[12] = format("%d", sel.colclip); str[13] = format("%d", sel.date); str[14] = format("%d", sel.spritehack); + str[15] = format("%d", sel.point_sampler); D3DXMACRO macro[] = { @@ -170,6 +171,7 @@ void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSel {"PS_COLCLIP", str[12].c_str()}, {"PS_DATE", str[13].c_str()}, {"PS_SPRITEHACK", str[14].c_str()}, + {"PS_POINT_SAMPLER", str[15].c_str()}, {NULL, NULL}, }; diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index 70028e01d3..013080a810 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -4,6 +4,9 @@ #define FMT_16 2 #define FMT_PAL 4 /* flag bit */ +// And I say this as an ATI user. +#define ATI_SUCKS 1 + #if SHADER_MODEL >= 0x400 #ifndef VS_BPPZ @@ -34,6 +37,7 @@ #define PS_COLCLIP 0 #define PS_DATE 0 #define PS_SPRITEHACK 0 +#define PS_POINT_SAMPLER 0 #endif struct VS_INPUT @@ -101,6 +105,15 @@ cbuffer cb1 float4 sample_c(float2 uv) { + if (ATI_SUCKS && PS_POINT_SAMPLER) + { + // Weird issue with ATI cards (happens on at least HD 4xxx and 5xxx), + // it looks like they add 127/128 of a texel to sampling coordinates + // occasionally causing point sampling to erroneously round up. + // I'm manually adjusting coordinates to the centre of texels here, + // though the centre is just paranoia, the top left corner works fine. + uv = (trunc(uv * WH.zw) + float2(0.5, 0.5)) / WH.zw; + } return Texture.Sample(TextureSampler, uv); } @@ -378,7 +391,7 @@ float4 sample(float2 st, float q) if(PS_LTF) { uv = st.xyxy + HalfTexel; - dd = frac(uv.xy * WH.zw); + dd = frac(uv.xy * WH.zw); } else {