Hey Ilia, Marek,

Do you have an opinion about this?  I've got a R-b from Eric Anholt
and what sounds like an Ack from Roland, but I wanted to make sure
everyone was OK with this before landing it.

--Ken

On Wednesday, March 6, 2019 12:32:23 AM PST Kenneth Graunke wrote:
> The glMemoryBarrier() function makes shader memory stores ordered with
> respect to things specified by the given bits.  Until now, st/mesa has
> ignored GL_TEXTURE_UPDATE_BARRIER_BIT and GL_BUFFER_UPDATE_BARRIER_BIT,
> saying that drivers should implicitly perform the needed flushing.
> 
> This seems like a pretty big assumption to make.  Instead, this commit
> opts to translate them to new PIPE_BARRIER bits, and adjusts existing
> drivers to continue ignoring them (preserving the current behavior).
> 
> The i965 driver performs actions on these memory barriers.  Shader
> memory stores go through a "data cache" which is separate from the
> render cache and other read caches (like the texture cache).  All
> memory barriers need to flush the data cache (to ensure shader memory
> stores are visible), and possibly invalidate read caches (to ensure
> stale data is no longer visible).  The driver implicitly flushes for
> most caches, but not for data cache, since ARB_shader_image_load_store
> introduced MemoryBarrier() precisely to order these explicitly.
> 
> I would like to follow i965's approach in iris, flushing the data cache
> on any MemoryBarrier() call, so I need st/mesa to actually call the
> pipe->memory_barrier() callback.
> ---
>  .../drivers/freedreno/freedreno_context.c     |  3 ++
>  src/gallium/drivers/r600/r600_state_common.c  |  4 +++
>  src/gallium/drivers/radeonsi/si_state.c       |  3 ++
>  src/gallium/drivers/softpipe/sp_flush.c       |  3 ++
>  src/gallium/drivers/tegra/tegra_context.c     |  3 ++
>  src/gallium/drivers/v3d/v3d_context.c         |  3 ++
>  src/gallium/include/pipe/p_defines.h          |  7 +++-
>  src/mesa/state_tracker/st_cb_texturebarrier.c | 34 +++++++++++--------
>  8 files changed, 44 insertions(+), 16 deletions(-)
> 
> I am curious to hear people's thoughts on this.  It seems useful for the
> driver to receive a memory_barrier() call...and adding a few bits seemed
> to be the cleanest way to make that happen.  But I'm open to ideas.
> 
> There are no nouveau changes in this patch, but that's only because none
> appeared to be necessary.  Most drivers performed some kind of flush on
> any memory_barrier() call, regardless of the bits - but nouveau's hooks
> don't.  So the newly added case would already be a no-op.
> 
> diff --git a/src/gallium/drivers/freedreno/freedreno_context.c 
> b/src/gallium/drivers/freedreno/freedreno_context.c
> index 6c01c15bb32..4e86d099974 100644
> --- a/src/gallium/drivers/freedreno/freedreno_context.c
> +++ b/src/gallium/drivers/freedreno/freedreno_context.c
> @@ -99,6 +99,9 @@ fd_texture_barrier(struct pipe_context *pctx, unsigned 
> flags)
>  static void
>  fd_memory_barrier(struct pipe_context *pctx, unsigned flags)
>  {
> +     if (!(flags & ~PIPE_BARRIER_UPDATE))
> +             return;
> +
>       fd_context_flush(pctx, NULL, 0);
>       /* TODO do we need to check for persistently mapped buffers and 
> fd_bo_cpu_prep()?? */
>  }
> diff --git a/src/gallium/drivers/r600/r600_state_common.c 
> b/src/gallium/drivers/r600/r600_state_common.c
> index f886a27170d..c7c606f131b 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -94,6 +94,10 @@ void r600_emit_alphatest_state(struct r600_context *rctx, 
> struct r600_atom *atom
>  static void r600_memory_barrier(struct pipe_context *ctx, unsigned flags)
>  {
>       struct r600_context *rctx = (struct r600_context *)ctx;
> +
> +     if (!(flags & ~PIPE_BARRIER_UPDATE))
> +             return;
> +
>       if (flags & PIPE_BARRIER_CONSTANT_BUFFER)
>               rctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE;
>  
> diff --git a/src/gallium/drivers/radeonsi/si_state.c 
> b/src/gallium/drivers/radeonsi/si_state.c
> index 458b108a7e3..3c29b4c92ed 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -4710,6 +4710,9 @@ void si_memory_barrier(struct pipe_context *ctx, 
> unsigned flags)
>  {
>       struct si_context *sctx = (struct si_context *)ctx;
>  
> +     if (!(flags & ~PIPE_BARRIER_UPDATE))
> +             return;
> +
>       /* Subsequent commands must wait for all shader invocations to
>        * complete. */
>       sctx->flags |= SI_CONTEXT_PS_PARTIAL_FLUSH |
> diff --git a/src/gallium/drivers/softpipe/sp_flush.c 
> b/src/gallium/drivers/softpipe/sp_flush.c
> index 3bf8c499218..5eccbe34d46 100644
> --- a/src/gallium/drivers/softpipe/sp_flush.c
> +++ b/src/gallium/drivers/softpipe/sp_flush.c
> @@ -192,5 +192,8 @@ void softpipe_texture_barrier(struct pipe_context *pipe, 
> unsigned flags)
>  
>  void softpipe_memory_barrier(struct pipe_context *pipe, unsigned flags)
>  {
> +   if (!(flags & ~PIPE_BARRIER_UPDATE))
> +      return;
> +
>     softpipe_texture_barrier(pipe, 0);
>  }
> diff --git a/src/gallium/drivers/tegra/tegra_context.c 
> b/src/gallium/drivers/tegra/tegra_context.c
> index bbc03628336..e9e51656921 100644
> --- a/src/gallium/drivers/tegra/tegra_context.c
> +++ b/src/gallium/drivers/tegra/tegra_context.c
> @@ -974,6 +974,9 @@ tegra_memory_barrier(struct pipe_context *pcontext, 
> unsigned int flags)
>  {
>     struct tegra_context *context = to_tegra_context(pcontext);
>  
> +   if (!(flags & ~PIPE_BARRIER_UPDATE))
> +      return;
> +
>     context->gpu->memory_barrier(context->gpu, flags);
>  }
>  
> diff --git a/src/gallium/drivers/v3d/v3d_context.c 
> b/src/gallium/drivers/v3d/v3d_context.c
> index d07ad403590..fcd2d5ec69b 100644
> --- a/src/gallium/drivers/v3d/v3d_context.c
> +++ b/src/gallium/drivers/v3d/v3d_context.c
> @@ -71,6 +71,9 @@ v3d_memory_barrier(struct pipe_context *pctx, unsigned int 
> flags)
>  {
>          struct v3d_context *v3d = v3d_context(pctx);
>  
> +     if (!(flags & ~PIPE_BARRIER_UPDATE))
> +             return;
> +
>          /* We only need to flush jobs writing to SSBOs/images. */
>          perf_debug("Flushing all jobs for glMemoryBarrier(), could do 
> better");
>          v3d_flush(pctx);
> diff --git a/src/gallium/include/pipe/p_defines.h 
> b/src/gallium/include/pipe/p_defines.h
> index e2b0104ce43..2970c47c3c7 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -425,7 +425,12 @@ enum pipe_flush_flags
>  #define PIPE_BARRIER_FRAMEBUFFER       (1 << 9)
>  #define PIPE_BARRIER_STREAMOUT_BUFFER  (1 << 10)
>  #define PIPE_BARRIER_GLOBAL_BUFFER     (1 << 11)
> -#define PIPE_BARRIER_ALL               ((1 << 12) - 1)
> +#define PIPE_BARRIER_UPDATE_BUFFER     (1 << 12)
> +#define PIPE_BARRIER_UPDATE_TEXTURE    (1 << 13)
> +#define PIPE_BARRIER_ALL               ((1 << 14) - 1)
> +
> +#define PIPE_BARRIER_UPDATE \
> +   (PIPE_BARRIER_UPDATE_BUFFER | PIPE_BARRIER_UPDATE_TEXTURE)
>  
>  /**
>   * Flags for pipe_context::texture_barrier.
> diff --git a/src/mesa/state_tracker/st_cb_texturebarrier.c 
> b/src/mesa/state_tracker/st_cb_texturebarrier.c
> index 2bff03b484a..4a9c72f2c62 100644
> --- a/src/mesa/state_tracker/st_cb_texturebarrier.c
> +++ b/src/mesa/state_tracker/st_cb_texturebarrier.c
> @@ -95,21 +95,25 @@ st_MemoryBarrier(struct gl_context *ctx, GLbitfield 
> barriers)
>         */
>        flags |= PIPE_BARRIER_TEXTURE;
>     }
> -   /* GL_TEXTURE_UPDATE_BARRIER_BIT:
> -    * Texture updates translate to:
> -    *  (1) texture transfers to/from the CPU,
> -    *  (2) texture as blit destination, or
> -    *  (3) texture as framebuffer.
> -    * In all cases, we assume the driver does the required flushing
> -    * automatically.
> -    */
> -   /* GL_BUFFER_UPDATE_BARRIER_BIT:
> -    * Buffer updates translate to
> -    *  (1) buffer transfers to/from the CPU,
> -    *  (2) resource copies and clears.
> -    * In all cases, we assume the driver does the required flushing
> -    * automatically.
> -    */
> +   if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) {
> +      /* GL_TEXTURE_UPDATE_BARRIER_BIT:
> +       * Texture updates translate to:
> +       *  (1) texture transfers to/from the CPU,
> +       *  (2) texture as blit destination, or
> +       *  (3) texture as framebuffer.
> +       * Some drivers may handle these automatically, and can ignore the bit.
> +       */
> +      flags |= PIPE_BARRIER_UPDATE_TEXTURE;
> +   }
> +   if (barriers & GL_BUFFER_UPDATE_BARRIER_BIT) {
> +      /* GL_BUFFER_UPDATE_BARRIER_BIT:
> +       * Buffer updates translate to
> +       *  (1) buffer transfers to/from the CPU,
> +       *  (2) resource copies and clears.
> +       * Some drivers may handle these automatically, and can ignore the bit.
> +       */
> +      flags |= PIPE_BARRIER_UPDATE_BUFFER;
> +   }
>     if (barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT)
>        flags |= PIPE_BARRIER_MAPPED_BUFFER;
>     if (barriers & GL_QUERY_BUFFER_BARRIER_BIT)
> 

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to