[Mesa-dev] [PATCH] st/mesa: inform the driver of framebuffer changes before compute dispatches

Nicolai Hähnle nhaehnle at gmail.com
Wed Feb 22 18:59:06 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Even though compute shaders cannot access the framebuffer, there is a
synchronization issue when a compute dispatch accesses a texture that
was previously bound and drawn to as a framebuffer.

Section 9.3 (Feedback Loops Between Textures and the Framebuffer) of
the OpenGL 4.5 spec rather implicitly clarifies that undefined behavior
results if the texture is still attached to the currently bound
framebuffer. However, the feedback loop is broken when the application
changes the framebuffer binding before a compute dispatch, and the
state tracker needs to let the driver known about this.

Fixes GL45-CTS.compute_shader.pipeline-post-fs on SI family Radeons.

Cc: mesa-stable at lists.freedesktop.org
---
 src/mesa/state_tracker/st_atom.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 65ac517..9e1137e 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -181,21 +181,29 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline )
       struct gl_program *new_cp = ctx->ComputeProgram._Current;
 
       if (new_cp != &old_cp->Base) {
          if (old_cp)
             st->dirty |= old_cp->affected_states;
          assert(new_cp);
          st->dirty |= st_compute_program(new_cp)->affected_states;
       }
 
       st->compute_shader_may_be_dirty = false;
-      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK;
+
+      /*
+       * We add the ST_NEW_FB_STATE bit here as well, because glBindFramebuffer
+       * acts as a barrier that breaks feedback loops between the framebuffer
+       * and textures bound to the framebuffer, even when those textures are
+       * accessed by compute shaders; so we must inform the driver of new
+       * framebuffer state.
+       */
+      pipeline_mask = ST_PIPELINE_COMPUTE_STATE_MASK | ST_NEW_FB_STATE;
       break;
    }
 
    default:
       unreachable("Invalid pipeline specified");
    }
 
    dirty = st->dirty & pipeline_mask;
    if (!dirty)
       return;
-- 
2.9.3



More information about the mesa-dev mailing list