diff --git a/plugins/GSdx/Renderers/DX11/GSDevice11.h b/plugins/GSdx/Renderers/DX11/GSDevice11.h index 317731d95d..aec90d2cac 100644 --- a/plugins/GSdx/Renderers/DX11/GSDevice11.h +++ b/plugins/GSdx/Renderers/DX11/GSDevice11.h @@ -216,8 +216,9 @@ public: uint32 urban_chaos_hle:1; uint32 tales_of_abyss_hle:1; uint32 point_sampler:1; + uint32 invalid_tex0:1; // Lupin the 3rd - uint32 _free:28; + uint32 _free:27; }; uint64 key; diff --git a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp index bf00d074cd..49a6693614 100644 --- a/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSRendererDX11.cpp @@ -678,6 +678,15 @@ void GSRendererDX11::EmulateTextureSampler(const GSTextureCache::Source* tex) m_ps_sel.tcoffsethack = m_userhacks_tcoffset; ps_cb.TC_OffsetHack = GSVector4(m_userhacks_tcoffset_x, m_userhacks_tcoffset_y).xyxy() / WH.xyxy(); + // Must be done after all coordinates math + if (m_context->HasFixedTEX0() && !PRIM->FST) + { + m_ps_sel.invalid_tex0 = 1; + // Use invalid size to denormalize ST coordinate + ps_cb.WH.x = (float)(1 << m_context->stack.TEX0.TW); + ps_cb.WH.y = (float)(1 << m_context->stack.TEX0.TH); + } + // Only enable clamping in CLAMP mode. REGION_CLAMP will be done manually in the shader m_ps_ssel.tau = (wms != CLAMP_CLAMP); m_ps_ssel.tav = (wmt != CLAMP_CLAMP); diff --git a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp index bc8af7d2b7..6db9ab1f55 100644 --- a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp @@ -207,7 +207,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe if(i == m_ps.end()) { - std::string str[25]; + std::string str[26]; str[0] = format("%d", sel.fst); str[1] = format("%d", sel.wms); @@ -233,7 +233,8 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe str[21] = format("%d", sel.dfmt); str[22] = format("%d", sel.depth_fmt); str[23] = format("%d", sel.fmt >> 2); - str[24] = format("%d", m_upscale_multiplier ? m_upscale_multiplier : 1); + str[24] = format("%d", sel.invalid_tex0); + str[25] = format("%d", m_upscale_multiplier ? m_upscale_multiplier : 1); D3D_SHADER_MACRO macro[] = { @@ -261,7 +262,8 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe {"PS_DFMT", str[21].c_str() }, {"PS_DEPTH_FMT", str[22].c_str() }, {"PS_PAL_FMT", str[23].c_str() }, - {"PS_SCALE_FACTOR", str[24].c_str() }, + {"PS_INVALID_TEX0", str[24].c_str() }, + {"PS_SCALE_FACTOR", str[25].c_str() }, {NULL, NULL}, }; diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index 81ac1aaad0..08b867ff83 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -42,6 +42,7 @@ #define PS_CHANNEL_FETCH 0 #define PS_TALES_OF_ABYSS_HLE 0 #define PS_URBAN_CHAOS_HLE 0 +#define PS_INVALID_TEX0 0 #define PS_SCALE_FACTOR 1 #endif @@ -331,6 +332,13 @@ float4 sample_depth(float2 st, float2 pos) float4 clamp_wrap_uv(float4 uv) { + float4 tex_size; + + if (PS_INVALID_TEX0 == 1) + tex_size = WH.zwzw; + else + tex_size = WH.xyxy; + if(PS_WMS == PS_WMT) { if(PS_WMS == 2) @@ -344,7 +352,7 @@ float4 clamp_wrap_uv(float4 uv) // textures. Fixes Xenosaga's hair issue. uv = frac(uv); #endif - uv = (float4)(((uint4)(uv * WH.xyxy) & MskFix.xyxy) | MskFix.zwzw) / WH.xyxy; + uv = (float4)(((uint4)(uv * tex_size) & MskFix.xyxy) | MskFix.zwzw) / tex_size; } } else @@ -358,7 +366,7 @@ float4 clamp_wrap_uv(float4 uv) #if PS_FST == 0 uv.xz = frac(uv.xz); #endif - uv.xz = (float2)(((uint2)(uv.xz * WH.xx) & MskFix.xx) | MskFix.zz) / WH.xx; + uv.xz = (float2)(((uint2)(uv.xz * tex_size.xx) & MskFix.xx) | MskFix.zz) / tex_size.xx; } if(PS_WMT == 2) { @@ -369,7 +377,7 @@ float4 clamp_wrap_uv(float4 uv) #if PS_FST == 0 uv.yw = frac(uv.yw); #endif - uv.yw = (float2)(((uint2)(uv.yw * WH.yy) & MskFix.yy) | MskFix.ww) / WH.yy; + uv.yw = (float2)(((uint2)(uv.yw * tex_size.yy) & MskFix.yy) | MskFix.ww) / tex_size.yy; } } @@ -602,9 +610,13 @@ float4 fog(float4 c, float f) float4 ps_color(PS_INPUT input) { -#if PS_FST == 0 - float2 st = input.t.xy / input.t.w; - float2 st_int = input.ti.zw / input.t.w; +#if PS_FST == 0 && PS_INVALID_TEX0 == 1 + // Re-normalize coordinate from invalid GS to corrected texture size + float2 st = (input.t.xy * WH.xy) / (input.t.w * WH.zw); + // no st_int yet +#elif PS_FST == 0 + float2 st = input.t.xy / (input.t.w); + float2 st_int = input.ti.zw / (input.t.w); #else float2 st = input.ti.xy; float2 st_int = input.ti.zw;