Skip to content

Commit

Permalink
gsdx-ogl: DATE with texture barrier
Browse files Browse the repository at this point in the history
Much faster for small batch that write the alpha value. Code can
be enabled with accurate_date option.

Here a summary of all DATE possibilities:
1/ no overlap of primitive
    => texture barrier (pro no setup of stencil and single draw)

2/ alpha written
    => small batch => texture barrier (primitive by primitive). Done in N-primitive draw calls.
    (based on GL_ARB_texture_barrier)

    => bigger batch => compute the first good primitive, slow but only 2 draw calls.
    (based on GL_ARB_shader_image_load_store)

    => Otherwise there is the UserHacks_AlphaStencil but it is a hack!

3/ alpha written
    => full setup of stencil ( 2 draw calls)
  • Loading branch information
gregory38 committed May 9, 2015
1 parent b89f0cf commit 5565544
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 9 deletions.
7 changes: 0 additions & 7 deletions plugins/GSdx/GLLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,13 +504,6 @@ namespace GLLoader {
theApp.SetConfig("accurate_blend", 0);
}
}
if (!found_GL_ARB_shader_image_load_store) {
if (theApp.GetConfig("accurate_date", 0)) {
fprintf(stderr, "Error GL_ARB_shader_image_load_store is not supported by your driver so you can't enable accurate_date! Sorry.\n");
theApp.SetConfig("accurate_date", 0);
}
}


fprintf(stderr, "\n");

Expand Down
16 changes: 14 additions & 2 deletions plugins/GSdx/GSRendererOGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ void GSRendererOGL::SendDraw(bool require_barrier)
ASSERT(m_vt.m_primclass != GS_LINE_CLASS);
ASSERT(GLLoader::found_geometry_shader);

GL_INS("Special Draw");

// FIXME: Investigate: do a dynamic check to pack as many primitives as possibles
size_t nb_vertex = (m_vt.m_primclass == GS_TRIANGLE_CLASS) ? 3 : 2;

for (size_t p = 0; p < m_index.tail; p += nb_vertex) {
Expand Down Expand Up @@ -278,8 +281,17 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
if (GLLoader::found_GL_ARB_texture_barrier && !PrimitiveOverlap()) {
DATE_GL45 = true;
DATE = false;
} else if (om_csel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS)) {
DATE_GL42 = m_accurate_date && GLLoader::found_GL_ARB_shader_image_load_store && !UserHacks_AlphaStencil;
} else if (m_accurate_date && !UserHacks_AlphaStencil &&
om_csel.wa && (!context->TEST.ATE || context->TEST.ATST == ATST_ALWAYS)) {
// texture barrier will split the draw call into n draw call. It is very efficient for
// few primitive draws. Otherwise it sucks.
if (GLLoader::found_GL_ARB_texture_barrier && (m_index.tail < 100)) {
require_barrier = true;
DATE_GL45 = true;
DATE = false;
} else {
DATE_GL42 = GLLoader::found_GL_ARB_shader_image_load_store;
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions plugins/GSdx/res/glsl/tfx_fs.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -419,16 +419,24 @@ void ps_main()
// Pixel with alpha equal to 1 will failed
float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).a;
if ((127.5f / 255.0f) < rt_a) { // < 0x80 pass (== 0x80 should not pass)
#if PS_DATE >= 5
discard;
#else
imageStore(img_prim_min, ivec2(gl_FragCoord.xy), ivec4(-1));
return;
#endif
}
#elif (PS_DATE & 3) == 2 && !defined(DISABLE_GL42_image)
// DATM == 1
// Pixel with alpha equal to 0 will failed
float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).a;
if(rt_a < (127.5f / 255.0f)) { // >= 0x80 pass
#if PS_DATE >= 5
discard;
#else
imageStore(img_prim_min, ivec2(gl_FragCoord.xy), ivec4(-1));
return;
#endif
}
#endif

Expand Down
8 changes: 8 additions & 0 deletions plugins/GSdx/res/glsl_source.h
Original file line number Diff line number Diff line change
Expand Up @@ -1133,16 +1133,24 @@ static const char* tfx_fs_all_glsl =
" // Pixel with alpha equal to 1 will failed\n"
" float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).a;\n"
" if ((127.5f / 255.0f) < rt_a) { // < 0x80 pass (== 0x80 should not pass)\n"
"#if PS_DATE >= 5\n"
" discard;\n"
"#else\n"
" imageStore(img_prim_min, ivec2(gl_FragCoord.xy), ivec4(-1));\n"
" return;\n"
"#endif\n"
" }\n"
"#elif (PS_DATE & 3) == 2 && !defined(DISABLE_GL42_image)\n"
" // DATM == 1\n"
" // Pixel with alpha equal to 0 will failed\n"
" float rt_a = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0).a;\n"
" if(rt_a < (127.5f / 255.0f)) { // >= 0x80 pass\n"
"#if PS_DATE >= 5\n"
" discard;\n"
"#else\n"
" imageStore(img_prim_min, ivec2(gl_FragCoord.xy), ivec4(-1));\n"
" return;\n"
"#endif\n"
" }\n"
"#endif\n"
"\n"
Expand Down

0 comments on commit 5565544

Please sign in to comment.