gsdx ogl: re-normalize coordinate when TEX0 is invalid

Fix #258
Fix #695
This commit is contained in:
Gregory Hainaut 2019-02-15 15:01:18 +01:00 committed by lightningterror
parent 12dcb701c7
commit 29aef04fbf
4 changed files with 23 additions and 5 deletions

View File

@ -948,6 +948,7 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
+ format("#define PS_URBAN_CHAOS_HLE %d\n", sel.urban_chaos_hle)
+ format("#define PS_TALES_OF_ABYSS_HLE %d\n", sel.tales_of_abyss_hle)
+ format("#define PS_TEX_IS_FB %d\n", sel.tex_is_fb)
+ format("#define PS_INVALID_TEX0 %d\n", sel.invalid_tex0)
+ format("#define PS_AEM %d\n", sel.aem)
+ format("#define PS_TFX %d\n", sel.tfx)
+ format("#define PS_TCC %d\n", sel.tcc)

View File

@ -301,8 +301,9 @@ public:
uint32 automatic_lod:1;
uint32 manual_lod:1;
uint32 point_sampler:1;
uint32 invalid_tex0:1; // Lupin the 3rd
uint32 _free2:10;
uint32 _free2:9;
};
uint64 key;

View File

@ -839,6 +839,13 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
m_ps_sel.tcoffsethack = m_userhacks_tcoffset;
ps_cb.TC_OH_TS = GSVector4(1/16.0f, 1/16.0f, m_userhacks_tcoffset_x, m_userhacks_tcoffset_y) / 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);

View File

@ -122,6 +122,11 @@ vec4 sample_p(float idx)
vec4 clamp_wrap_uv(vec4 uv)
{
vec4 uv_out = uv;
#if PS_INVALID_TEX0 == 1
vec4 tex_size = WH.zwzw;
#else
vec4 tex_size = WH.xyxy;
#endif
#if PS_WMS == PS_WMT
@ -133,7 +138,7 @@ vec4 clamp_wrap_uv(vec4 uv)
// textures. Fixes Xenosaga's hair issue.
uv = fract(uv);
#endif
uv_out = vec4((uvec4(uv * WH.xyxy) & MskFix.xyxy) | MskFix.zwzw) / WH.xyxy;
uv_out = vec4((uvec4(uv * tex_size) & MskFix.xyxy) | MskFix.zwzw) / tex_size;
#endif
#else // PS_WMS != PS_WMT
@ -145,7 +150,7 @@ vec4 clamp_wrap_uv(vec4 uv)
#if PS_FST == 0
uv.xz = fract(uv.xz);
#endif
uv_out.xz = vec2((uvec2(uv.xz * WH.xx) & MskFix.xx) | MskFix.zz) / WH.xx;
uv_out.xz = vec2((uvec2(uv.xz * tex_size.xx) & MskFix.xx) | MskFix.zz) / tex_size.xx;
#endif
@ -156,7 +161,7 @@ vec4 clamp_wrap_uv(vec4 uv)
#if PS_FST == 0
uv.yw = fract(uv.yw);
#endif
uv_out.yw = vec2((uvec2(uv.yw * WH.yy) & MskFix.yy) | MskFix.ww) / WH.yy;
uv_out.yw = vec2((uvec2(uv.yw * tex_size.yy) & MskFix.yy) | MskFix.ww) / tex_size.yy;
#endif
#endif
@ -574,7 +579,11 @@ void fog(inout vec4 C, float f)
vec4 ps_color()
{
//FIXME: maybe we can set gl_Position.w = q in VS
#if (PS_FST == 0)
#if (PS_FST == 0) && (PS_INVALID_TEX0 == 1)
// Re-normalize coordinate from invalid GS to corrected texture size
vec2 st = (PSin.t_float.xy * WH.xy) / (vec2(PSin.t_float.w) * WH.zw);
// no st_int yet
#elif (PS_FST == 0)
vec2 st = PSin.t_float.xy / vec2(PSin.t_float.w);
vec2 st_int = PSin.t_int.zw / vec2(PSin.t_float.w);
#else