gsdx ogl: handle float integral coordinate for depth sampling

Fix depth effect regression on Nemo (issue #1979)
This commit is contained in:
Gregory Hainaut 2017-07-02 18:54:43 +02:00
parent bab9826fb1
commit 38010432ee
5 changed files with 22 additions and 7 deletions

View File

@ -593,7 +593,8 @@ void GSDeviceOGL::CreateTextureFX()
m_gs[2] = CompileGS(GSSelector(2)); m_gs[2] = CompileGS(GSSelector(2));
m_gs[4] = CompileGS(GSSelector(4)); m_gs[4] = CompileGS(GSSelector(4));
m_vs[0] = CompileVS(VSSelector(0)); for (uint32 key = 0; key < countof(m_vs); key++)
m_vs[key] = CompileVS(VSSelector(key));
// Enable all bits for stencil operations. Technically 1 bit is // Enable all bits for stencil operations. Technically 1 bit is
// enough but buffer is polluted with noise. Clear will be limited // enough but buffer is polluted with noise. Clear will be limited
@ -917,10 +918,12 @@ void GSDeviceOGL::Barrier(GLbitfield b)
GLuint GSDeviceOGL::CompileVS(VSSelector sel) GLuint GSDeviceOGL::CompileVS(VSSelector sel)
{ {
std::string macro = format("#define VS_INT_FST %d\n", sel.int_fst);
if (GLLoader::buggy_sso_dual_src) if (GLLoader::buggy_sso_dual_src)
return m_shader->CompileShader("tfx_vgs.glsl", "vs_main", GL_VERTEX_SHADER, m_shader_tfx_vgs.data(), ""); return m_shader->CompileShader("tfx_vgs.glsl", "vs_main", GL_VERTEX_SHADER, m_shader_tfx_vgs.data(), macro);
else else
return m_shader->Compile("tfx_vgs.glsl", "vs_main", GL_VERTEX_SHADER, m_shader_tfx_vgs.data(), ""); return m_shader->Compile("tfx_vgs.glsl", "vs_main", GL_VERTEX_SHADER, m_shader_tfx_vgs.data(), macro);
} }
GLuint GSDeviceOGL::CompileGS(GSSelector sel) GLuint GSDeviceOGL::CompileGS(GSSelector sel)

View File

@ -158,7 +158,8 @@ public:
{ {
struct struct
{ {
uint32 _free:32; uint32 int_fst:1;
uint32 _free:31;
}; };
uint32 key; uint32 key;
@ -473,7 +474,7 @@ public:
GLuint timer() { return timer_query[last_query]; } GLuint timer() { return timer_query[last_query]; }
} m_profiler; } m_profiler;
GLuint m_vs[1]; GLuint m_vs[1<<1];
GLuint m_gs[1<<3]; GLuint m_gs[1<<3];
GLuint m_ps_ss[1<<7]; GLuint m_ps_ss[1<<7];
GSDepthStencilOGL* m_om_dss[1<<5]; GSDepthStencilOGL* m_om_dss[1<<5];

View File

@ -733,6 +733,7 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
// Require a float conversion if the texure is a depth otherwise uses Integral scaling // Require a float conversion if the texure is a depth otherwise uses Integral scaling
if (psm.depth) { if (psm.depth) {
m_ps_sel.depth_fmt = (tex->m_texture->GetType() != GSTexture::DepthStencil) ? 3 : 1; m_ps_sel.depth_fmt = (tex->m_texture->GetType() != GSTexture::DepthStencil) ? 3 : 1;
m_vs_sel.int_fst = !PRIM->FST; // select float/int coordinate
} }
// Shuffle is a 16 bits format, so aem is always required // Shuffle is a 16 bits format, so aem is always required
@ -784,12 +785,14 @@ void GSRendererOGL::EmulateTextureSampler(const GSTextureCache::Source* tex)
if (tex->m_texture->GetType() == GSTexture::DepthStencil) { if (tex->m_texture->GetType() == GSTexture::DepthStencil) {
// Require a float conversion if the texure is a depth format // Require a float conversion if the texure is a depth format
m_ps_sel.depth_fmt = (psm.bpp == 16) ? 2 : 1; m_ps_sel.depth_fmt = (psm.bpp == 16) ? 2 : 1;
m_vs_sel.int_fst = !PRIM->FST; // select float/int coordinate
// Don't force interpolation on depth format // Don't force interpolation on depth format
bilinear &= m_vt.IsLinear(); bilinear &= m_vt.IsLinear();
} else if (psm.depth) { } else if (psm.depth) {
// Use Integral scaling // Use Integral scaling
m_ps_sel.depth_fmt = 3; m_ps_sel.depth_fmt = 3;
m_vs_sel.int_fst = !PRIM->FST; // select float/int coordinate
// Don't force interpolation on depth format // Don't force interpolation on depth format
bilinear &= m_vt.IsLinear(); bilinear &= m_vt.IsLinear();

View File

@ -557,9 +557,11 @@ vec4 ps_color()
//FIXME: maybe we can set gl_Position.w = q in VS //FIXME: maybe we can set gl_Position.w = q in VS
#if (PS_FST == 0) #if (PS_FST == 0)
vec2 st = PSin.t_float.xy / vec2(PSin.t_float.w); vec2 st = PSin.t_float.xy / vec2(PSin.t_float.w);
vec2 st_int = PSin.t_int.zw / vec2(PSin.t_float.w);
#else #else
// Note xy are normalized coordinate // Note xy are normalized coordinate
vec2 st = PSin.t_int.xy; vec2 st = PSin.t_int.xy;
vec2 st_int = PSin.t_int.zw;
#endif #endif
#if PS_CHANNEL_FETCH == 1 #if PS_CHANNEL_FETCH == 1
@ -576,7 +578,7 @@ vec4 ps_color()
vec4 T = fetch_rgb(); vec4 T = fetch_rgb();
#elif PS_DEPTH_FMT > 0 #elif PS_DEPTH_FMT > 0
// Integral coordinate // Integral coordinate
vec4 T = sample_depth(PSin.t_int.zw); vec4 T = sample_depth(st_int);
#else #else
vec4 T = sample_color(st); vec4 T = sample_color(st);
#endif #endif

View File

@ -25,15 +25,21 @@ const float exp_min32 = exp2(-32.0f);
void texture_coord() void texture_coord()
{ {
vec2 uv = vec2(i_uv) - TextureOffset.xy; vec2 uv = vec2(i_uv) - TextureOffset.xy;
vec2 st = i_st - TextureOffset.xy;
// Float coordinate // Float coordinate
VSout.t_float.xy = i_st - TextureOffset.xy; VSout.t_float.xy = st;
VSout.t_float.w = i_q; VSout.t_float.w = i_q;
// Integer coordinate => normalized // Integer coordinate => normalized
VSout.t_int.xy = uv * TextureScale; VSout.t_int.xy = uv * TextureScale;
#if VS_INT_FST == 1
// Some games uses float coordinate for post-processing effect
VSout.t_int.zw = st / TextureScale;
#else
// Integer coordinate => integral // Integer coordinate => integral
VSout.t_int.zw = uv; VSout.t_int.zw = uv;
#endif
} }
void vs_main() void vs_main()