[Mesa-dev] [PATCH 1/3] gallium: add a pipe_context parameter to fence_finish

Rob Clark robdclark at gmail.com
Sat Aug 6 19:07:45 UTC 2016


On Sat, Aug 6, 2016 at 11:32 AM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> required by glClientWaitSync (GL 4.5 Core spec) that can optionally flush
> the context

Thanks, I've been meaning to add the same thing but haven't had time
to work on the native fd fence stuff in a bit..

mind squashing in http://hastebin.com/raw/cijubeduqe to avoid spurious
indentation change?

with that, r-b

BR,
-R

> ---
>  src/gallium/docs/source/context.rst              | 10 ++++------
>  src/gallium/drivers/ddebug/dd_draw.c             |  2 +-
>  src/gallium/drivers/ddebug/dd_screen.c           |  4 +++-
>  src/gallium/drivers/freedreno/freedreno_fence.c  |  5 +++--
>  src/gallium/drivers/freedreno/freedreno_fence.h  |  5 +++--
>  src/gallium/drivers/i915/i915_screen.c           |  1 +
>  src/gallium/drivers/ilo/ilo_screen.c             |  1 +
>  src/gallium/drivers/llvmpipe/lp_flush.c          |  3 ++-
>  src/gallium/drivers/llvmpipe/lp_screen.c         |  1 +
>  src/gallium/drivers/nouveau/nouveau_screen.c     |  1 +
>  src/gallium/drivers/r300/r300_screen.c           |  1 +
>  src/gallium/drivers/radeon/r600_pipe_common.c    |  1 +
>  src/gallium/drivers/radeon/r600_query.c          |  2 +-
>  src/gallium/drivers/rbug/rbug_screen.c           |  6 +++---
>  src/gallium/drivers/softpipe/sp_fence.c          |  1 +
>  src/gallium/drivers/softpipe/sp_flush.c          |  2 +-
>  src/gallium/drivers/svga/svga_context.c          |  4 ++--
>  src/gallium/drivers/svga/svga_screen.c           |  1 +
>  src/gallium/drivers/swr/swr_context.cpp          |  4 ++--
>  src/gallium/drivers/swr/swr_draw.cpp             |  2 +-
>  src/gallium/drivers/swr/swr_fence.cpp            |  1 +
>  src/gallium/drivers/swr/swr_fence.h              |  1 +
>  src/gallium/drivers/swr/swr_query.cpp            |  4 ++--
>  src/gallium/drivers/swr/swr_screen.cpp           |  6 +++---
>  src/gallium/drivers/swr/swr_state.cpp            |  2 +-
>  src/gallium/drivers/trace/tr_screen.c            |  5 ++++-
>  src/gallium/drivers/vc4/vc4_fence.c              |  1 +
>  src/gallium/drivers/virgl/virgl_screen.c         |  1 +
>  src/gallium/include/pipe/p_screen.h              | 15 ++++++++++++---
>  src/gallium/state_trackers/clover/core/event.cpp |  4 ++--
>  src/gallium/state_trackers/dri/dri2.c            |  6 +++---
>  src/gallium/state_trackers/dri/dri_drawable.c    |  2 +-
>  src/gallium/state_trackers/glx/xlib/xm_api.c     |  2 +-
>  src/gallium/state_trackers/nine/swapchain9.c     |  6 +++---
>  src/gallium/state_trackers/vdpau/presentation.c  |  4 ++--
>  src/gallium/state_trackers/xa/xa_context.c       |  2 +-
>  src/gallium/state_trackers/xvmc/surface.c        |  2 +-
>  src/mesa/state_tracker/st_cb_flush.c             |  2 +-
>  src/mesa/state_tracker/st_cb_syncobj.c           |  4 ++--
>  39 files changed, 77 insertions(+), 50 deletions(-)
>
> diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
> index e646ea0..af3d266 100644
> --- a/src/gallium/docs/source/context.rst
> +++ b/src/gallium/docs/source/context.rst
> @@ -459,26 +459,24 @@ processed even where they're known to be obscured.
>
>
>  Flushing
>  ^^^^^^^^
>
>  ``flush``
>
>  PIPE_FLUSH_END_OF_FRAME: Whether the flush marks the end of frame.
>
>  PIPE_FLUSH_DEFERRED: It is not required to flush right away, but it is required
> -to return a valid fence. The behavior of fence_finish or any other call isn't
> -changed. The only side effect can be that fence_finish will wait a little
> -longer. No guidance is given as to how drivers should implement fence_finish
> -with deferred flushes. If some drivers can't do deferred flushes safely, they
> -should just ignore the flag.
> -
> +to return a valid fence. If fence_finish is called with the returned fence
> +and the context is still unflushed, and the ctx parameter of fence_finish is
> +equal to the context where the fence was created, fence_finish will flush
> +the context.
>
>
>  ``flush_resource``
>
>  Flush the resource cache, so that the resource can be used
>  by an external client. Possible usage:
>  - flushing a resource before presenting it on the screen
>  - flushing a resource if some other process or device wants to use it
>  This shouldn't be used to flush caches if the resource is only managed
>  by a single pipe_screen and is not shared with another process.
> diff --git a/src/gallium/drivers/ddebug/dd_draw.c b/src/gallium/drivers/ddebug/dd_draw.c
> index c1bfdaf..97325e4 100644
> --- a/src/gallium/drivers/ddebug/dd_draw.c
> +++ b/src/gallium/drivers/ddebug/dd_draw.c
> @@ -541,21 +541,21 @@ dd_flush_and_check_hang(struct dd_context *dctx,
>     bool idle;
>
>     assert(timeout_ms > 0);
>
>     pipe->flush(pipe, &fence, flush_flags);
>     if (flush_fence)
>        screen->fence_reference(screen, flush_fence, fence);
>     if (!fence)
>        return false;
>
> -   idle = screen->fence_finish(screen, fence, timeout_ms * 1000000);
> +   idle = screen->fence_finish(screen, NULL, fence, timeout_ms * 1000000);
>     screen->fence_reference(screen, &fence, NULL);
>     if (!idle)
>        fprintf(stderr, "dd: GPU hang detected!\n");
>     return !idle;
>  }
>
>  static void
>  dd_flush_and_handle_hang(struct dd_context *dctx,
>                           struct pipe_fence_handle **fence, unsigned flags,
>                           const char *cause)
> diff --git a/src/gallium/drivers/ddebug/dd_screen.c b/src/gallium/drivers/ddebug/dd_screen.c
> index 412ea36..3deba0a 100644
> --- a/src/gallium/drivers/ddebug/dd_screen.c
> +++ b/src/gallium/drivers/ddebug/dd_screen.c
> @@ -256,26 +256,28 @@ dd_screen_fence_reference(struct pipe_screen *_screen,
>                            struct pipe_fence_handle **pdst,
>                            struct pipe_fence_handle *src)
>  {
>     struct pipe_screen *screen = dd_screen(_screen)->screen;
>
>     screen->fence_reference(screen, pdst, src);
>  }
>
>  static boolean
>  dd_screen_fence_finish(struct pipe_screen *_screen,
> +                       struct pipe_context *_ctx,
>                         struct pipe_fence_handle *fence,
>                         uint64_t timeout)
>  {
>     struct pipe_screen *screen = dd_screen(_screen)->screen;
> +   struct pipe_context *ctx = _ctx ? dd_context(_ctx)->pipe : NULL;
>
> -   return screen->fence_finish(screen, fence, timeout);
> +   return screen->fence_finish(screen, ctx, fence, timeout);
>  }
>
>
>  /********************************************************************
>   * screen
>   */
>
>  static void
>  dd_screen_destroy(struct pipe_screen *_screen)
>  {
> diff --git a/src/gallium/drivers/freedreno/freedreno_fence.c b/src/gallium/drivers/freedreno/freedreno_fence.c
> index 5125f09..a60da1c 100644
> --- a/src/gallium/drivers/freedreno/freedreno_fence.c
> +++ b/src/gallium/drivers/freedreno/freedreno_fence.c
> @@ -44,22 +44,23 @@ fd_screen_fence_ref(struct pipe_screen *pscreen,
>                 struct pipe_fence_handle **ptr,
>                 struct pipe_fence_handle *pfence)
>  {
>         if (pipe_reference(&(*ptr)->reference, &pfence->reference))
>                 FREE(*ptr);
>
>         *ptr = pfence;
>  }
>
>  boolean fd_screen_fence_finish(struct pipe_screen *screen,
> -               struct pipe_fence_handle *fence,
> -               uint64_t timeout)
> +                              struct pipe_context *ctx,
> +                              struct pipe_fence_handle *fence,
> +                              uint64_t timeout)
>  {
>         if (fd_pipe_wait_timeout(fence->screen->pipe, fence->timestamp, timeout))
>                 return false;
>
>         return true;
>  }
>
>  struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx,
>                 uint32_t timestamp)
>  {
> diff --git a/src/gallium/drivers/freedreno/freedreno_fence.h b/src/gallium/drivers/freedreno/freedreno_fence.h
> index 06c314a..e0a5899 100644
> --- a/src/gallium/drivers/freedreno/freedreno_fence.h
> +++ b/src/gallium/drivers/freedreno/freedreno_fence.h
> @@ -28,16 +28,17 @@
>
>  #ifndef FREEDRENO_FENCE_H_
>  #define FREEDRENO_FENCE_H_
>
>  #include "pipe/p_context.h"
>
>  void fd_screen_fence_ref(struct pipe_screen *pscreen,
>                 struct pipe_fence_handle **ptr,
>                 struct pipe_fence_handle *pfence);
>  boolean fd_screen_fence_finish(struct pipe_screen *screen,
> -               struct pipe_fence_handle *pfence,
> -               uint64_t timeout);
> +                              struct pipe_context *ctx,
> +                              struct pipe_fence_handle *pfence,
> +                              uint64_t timeout);
>  struct pipe_fence_handle * fd_fence_create(struct pipe_context *pctx,
>                 uint32_t timestamp);
>
>  #endif /* FREEDRENO_FENCE_H_ */
> diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
> index 6b5218b..ab3d4a6 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -493,20 +493,21 @@ i915_fence_reference(struct pipe_screen *screen,
>                       struct pipe_fence_handle **ptr,
>                       struct pipe_fence_handle *fence)
>  {
>     struct i915_screen *is = i915_screen(screen);
>
>     is->iws->fence_reference(is->iws, ptr, fence);
>  }
>
>  static boolean
>  i915_fence_finish(struct pipe_screen *screen,
> +                  struct pipe_context *ctx,
>                    struct pipe_fence_handle *fence,
>                    uint64_t timeout)
>  {
>     struct i915_screen *is = i915_screen(screen);
>
>     if (!timeout)
>        return is->iws->fence_signalled(is->iws, fence) == 1;
>
>     return is->iws->fence_finish(is->iws, fence) == 1;
>  }
> diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c
> index 448f512..e98b6f2 100644
> --- a/src/gallium/drivers/ilo/ilo_screen.c
> +++ b/src/gallium/drivers/ilo/ilo_screen.c
> @@ -689,20 +689,21 @@ ilo_screen_fence_reference(struct pipe_screen *screen,
>
>     STATIC_ASSERT(&((struct pipe_fence_handle *) NULL)->reference == NULL);
>     if (pipe_reference(&old->reference, &fence->reference)) {
>        intel_bo_unref(old->seqno_bo);
>        FREE(old);
>     }
>  }
>
>  static boolean
>  ilo_screen_fence_finish(struct pipe_screen *screen,
> +                        struct pipe_context *ctx,
>                          struct pipe_fence_handle *fence,
>                          uint64_t timeout)
>  {
>     const int64_t wait_timeout = (timeout > INT64_MAX) ? -1 : timeout;
>     bool signaled;
>
>     signaled = (!fence->seqno_bo ||
>           intel_bo_wait(fence->seqno_bo, wait_timeout) == 0);
>
>     /* XXX not thread safe */
> diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
> index 241c2cc..452753f 100644
> --- a/src/gallium/drivers/llvmpipe/lp_flush.c
> +++ b/src/gallium/drivers/llvmpipe/lp_flush.c
> @@ -75,21 +75,22 @@ llvmpipe_flush( struct pipe_context *pipe,
>     }
>  }
>
>  void
>  llvmpipe_finish( struct pipe_context *pipe,
>                   const char *reason )
>  {
>     struct pipe_fence_handle *fence = NULL;
>     llvmpipe_flush(pipe, &fence, reason);
>     if (fence) {
> -      pipe->screen->fence_finish(pipe->screen, fence, PIPE_TIMEOUT_INFINITE);
> +      pipe->screen->fence_finish(pipe->screen, NULL, fence,
> +                                 PIPE_TIMEOUT_INFINITE);
>        pipe->screen->fence_reference(pipe->screen, &fence, NULL);
>     }
>  }
>
>  /**
>   * Flush context if necessary.
>   *
>   * Returns FALSE if it would have block, but do_not_block was set, TRUE
>   * otherwise.
>   *
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
> index 61c3fb7..1c00aa9 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -565,20 +565,21 @@ llvmpipe_fence_reference(struct pipe_screen *screen,
>
>     lp_fence_reference(old, f);
>  }
>
>
>  /**
>   * Wait for the fence to finish.
>   */
>  static boolean
>  llvmpipe_fence_finish(struct pipe_screen *screen,
> +                      struct pipe_context *ctx,
>                        struct pipe_fence_handle *fence_handle,
>                        uint64_t timeout)
>  {
>     struct lp_fence *f = (struct lp_fence *) fence_handle;
>
>     if (!timeout)
>        return lp_fence_signalled(f);
>
>     lp_fence_wait(f);
>     return TRUE;
> diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
> index 2c421cc..f59e101 100644
> --- a/src/gallium/drivers/nouveau/nouveau_screen.c
> +++ b/src/gallium/drivers/nouveau/nouveau_screen.c
> @@ -63,20 +63,21 @@ nouveau_screen_get_timestamp(struct pipe_screen *pscreen)
>  static void
>  nouveau_screen_fence_ref(struct pipe_screen *pscreen,
>                           struct pipe_fence_handle **ptr,
>                           struct pipe_fence_handle *pfence)
>  {
>     nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr);
>  }
>
>  static boolean
>  nouveau_screen_fence_finish(struct pipe_screen *screen,
> +                            struct pipe_context *ctx,
>                              struct pipe_fence_handle *pfence,
>                              uint64_t timeout)
>  {
>     if (!timeout)
>        return nouveau_fence_signalled(nouveau_fence(pfence));
>
>     return nouveau_fence_wait(nouveau_fence(pfence), NULL);
>  }
>
>
> diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
> index 7d2ea4a..b69e524 100644
> --- a/src/gallium/drivers/r300/r300_screen.c
> +++ b/src/gallium/drivers/r300/r300_screen.c
> @@ -691,20 +691,21 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
>  static void r300_fence_reference(struct pipe_screen *screen,
>                                   struct pipe_fence_handle **ptr,
>                                   struct pipe_fence_handle *fence)
>  {
>      struct radeon_winsys *rws = r300_screen(screen)->rws;
>
>      rws->fence_reference(ptr, fence);
>  }
>
>  static boolean r300_fence_finish(struct pipe_screen *screen,
> +                                 struct pipe_context *ctx,
>                                   struct pipe_fence_handle *fence,
>                                   uint64_t timeout)
>  {
>      struct radeon_winsys *rws = r300_screen(screen)->rws;
>
>      return rws->fence_wait(rws, fence, timeout);
>  }
>
>  struct pipe_screen* r300_screen_create(struct radeon_winsys *rws)
>  {
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
> index 7fd3fe0..119fdf5 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.c
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.c
> @@ -947,20 +947,21 @@ static void r600_fence_reference(struct pipe_screen *screen,
>
>         if (pipe_reference(&(*rdst)->reference, &rsrc->reference)) {
>                 ws->fence_reference(&(*rdst)->gfx, NULL);
>                 ws->fence_reference(&(*rdst)->sdma, NULL);
>                 FREE(*rdst);
>         }
>          *rdst = rsrc;
>  }
>
>  static boolean r600_fence_finish(struct pipe_screen *screen,
> +                                struct pipe_context *ctx,
>                                  struct pipe_fence_handle *fence,
>                                  uint64_t timeout)
>  {
>         struct radeon_winsys *rws = ((struct r600_common_screen*)screen)->ws;
>         struct r600_multi_fence *rfence = (struct r600_multi_fence *)fence;
>         int64_t abs_timeout = os_time_get_absolute_timeout(timeout);
>
>         if (rfence->sdma) {
>                 if (!rws->fence_wait(rws, rfence->sdma, timeout))
>                         return false;
> diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c
> index f6a65a6..c203439 100644
> --- a/src/gallium/drivers/radeon/r600_query.c
> +++ b/src/gallium/drivers/radeon/r600_query.c
> @@ -202,21 +202,21 @@ static bool r600_query_sw_get_result(struct r600_common_context *rctx,
>
>         switch (query->b.type) {
>         case PIPE_QUERY_TIMESTAMP_DISJOINT:
>                 /* Convert from cycles per millisecond to cycles per second (Hz). */
>                 result->timestamp_disjoint.frequency =
>                         (uint64_t)rctx->screen->info.clock_crystal_freq * 1000;
>                 result->timestamp_disjoint.disjoint = false;
>                 return true;
>         case PIPE_QUERY_GPU_FINISHED: {
>                 struct pipe_screen *screen = rctx->b.screen;
> -               result->b = screen->fence_finish(screen, query->fence,
> +               result->b = screen->fence_finish(screen, NULL, query->fence,
>                                                  wait ? PIPE_TIMEOUT_INFINITE : 0);
>                 return result->b;
>         }
>
>         case R600_QUERY_GPIN_ASIC_ID:
>                 result->u32 = 0;
>                 return true;
>         case R600_QUERY_GPIN_NUM_SIMD:
>                 result->u32 = rctx->screen->info.num_good_compute_units;
>                 return true;
> diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c
> index c2950e4..8d21669 100644
> --- a/src/gallium/drivers/rbug/rbug_screen.c
> +++ b/src/gallium/drivers/rbug/rbug_screen.c
> @@ -222,29 +222,29 @@ rbug_screen_fence_reference(struct pipe_screen *_screen,
>     struct rbug_screen *rb_screen = rbug_screen(_screen);
>     struct pipe_screen *screen = rb_screen->screen;
>
>     screen->fence_reference(screen,
>                             ptr,
>                             fence);
>  }
>
>  static boolean
>  rbug_screen_fence_finish(struct pipe_screen *_screen,
> +                         struct pipe_context *_ctx,
>                           struct pipe_fence_handle *fence,
>                           uint64_t timeout)
>  {
>     struct rbug_screen *rb_screen = rbug_screen(_screen);
>     struct pipe_screen *screen = rb_screen->screen;
> +   struct pipe_context *ctx = _ctx ? rbug_context(_ctx)->pipe : NULL;
>
> -   return screen->fence_finish(screen,
> -                               fence,
> -                               timeout);
> +   return screen->fence_finish(screen, ctx, fence, timeout);
>  }
>
>  boolean
>  rbug_enabled()
>  {
>     return debug_get_option_rbug();
>  }
>
>  struct pipe_screen *
>  rbug_screen_create(struct pipe_screen *screen)
> diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c
> index 6168236..1861b0d 100644
> --- a/src/gallium/drivers/softpipe/sp_fence.c
> +++ b/src/gallium/drivers/softpipe/sp_fence.c
> @@ -35,20 +35,21 @@ static void
>  softpipe_fence_reference(struct pipe_screen *screen,
>                           struct pipe_fence_handle **ptr,
>                           struct pipe_fence_handle *fence)
>  {
>     *ptr = fence;
>  }
>
>
>  static boolean
>  softpipe_fence_finish(struct pipe_screen *screen,
> +                      struct pipe_context *ctx,
>                        struct pipe_fence_handle *fence,
>                        uint64_t timeout)
>  {
>     assert(fence);
>     return TRUE;
>  }
>
>
>  void
>  softpipe_init_screen_fence_funcs(struct pipe_screen *screen)
> diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
> index 29fcf7f..656d8a3 100644
> --- a/src/gallium/drivers/softpipe/sp_flush.c
> +++ b/src/gallium/drivers/softpipe/sp_flush.c
> @@ -146,21 +146,21 @@ softpipe_flush_resource(struct pipe_context *pipe,
>           if (do_not_block)
>              return FALSE;
>
>           softpipe_flush(pipe, flush_flags, &fence);
>
>           if (fence) {
>              /*
>               * This is for illustrative purposes only, as softpipe does not
>               * have fences.
>               */
> -            pipe->screen->fence_finish(pipe->screen, fence,
> +            pipe->screen->fence_finish(pipe->screen, NULL, fence,
>                                         PIPE_TIMEOUT_INFINITE);
>              pipe->screen->fence_reference(pipe->screen, &fence, NULL);
>           }
>        } else {
>           /*
>            * Just flush.
>            */
>
>           softpipe_flush(pipe, flush_flags, NULL);
>        }
> diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
> index c7f4aae..f623caf 100644
> --- a/src/gallium/drivers/svga/svga_context.c
> +++ b/src/gallium/drivers/svga/svga_context.c
> @@ -341,42 +341,42 @@ void svga_context_flush( struct svga_context *svga,
>        svga->rebind.flags.fs = TRUE;
>        svga->rebind.flags.gs = TRUE;
>
>        if (svga_need_to_rebind_resources(svga)) {
>           svga->rebind.flags.query = TRUE;
>        }
>     }
>
>     if (SVGA_DEBUG & DEBUG_SYNC) {
>        if (fence)
> -         svga->pipe.screen->fence_finish( svga->pipe.screen, fence,
> +         svga->pipe.screen->fence_finish( svga->pipe.screen, NULL, fence,
>                                            PIPE_TIMEOUT_INFINITE);
>     }
>
>     if (pfence)
>        svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
>
>     svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
>  }
>
>
>  /**
>   * Flush pending commands and wait for completion with a fence.
>   */
>  void
>  svga_context_finish(struct svga_context *svga)
>  {
>     struct pipe_screen *screen = svga->pipe.screen;
>     struct pipe_fence_handle *fence = NULL;
>
>     svga_context_flush(svga, &fence);
> -   screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
> +   screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
>     screen->fence_reference(screen, &fence, NULL);
>  }
>
>
>  /**
>   * Emit pending drawing commands to the command buffer.
>   * If the command buffer overflows, we flush it and retry.
>   * \sa svga_hwtnl_flush()
>   */
>  void svga_hwtnl_flush_retry( struct svga_context *svga )
> diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
> index 13253ac..7c4e305 100644
> --- a/src/gallium/drivers/svga/svga_screen.c
> +++ b/src/gallium/drivers/svga/svga_screen.c
> @@ -797,20 +797,21 @@ svga_fence_reference(struct pipe_screen *screen,
>                       struct pipe_fence_handle **ptr,
>                       struct pipe_fence_handle *fence)
>  {
>     struct svga_winsys_screen *sws = svga_screen(screen)->sws;
>     sws->fence_reference(sws, ptr, fence);
>  }
>
>
>  static boolean
>  svga_fence_finish(struct pipe_screen *screen,
> +                  struct pipe_context *ctx,
>                    struct pipe_fence_handle *fence,
>                    uint64_t timeout)
>  {
>     struct svga_winsys_screen *sws = svga_screen(screen)->sws;
>
>     if (!timeout)
>        return sws->fence_signalled(sws, fence, 0) == 0;
>
>     SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
>              __FUNCTION__, fence);
> diff --git a/src/gallium/drivers/swr/swr_context.cpp b/src/gallium/drivers/swr/swr_context.cpp
> index 1083c9d..835c353 100644
> --- a/src/gallium/drivers/swr/swr_context.cpp
> +++ b/src/gallium/drivers/swr/swr_context.cpp
> @@ -121,21 +121,21 @@ swr_transfer_map(struct pipe_context *pipe,
>        if (usage & PIPE_TRANSFER_DONTBLOCK) {
>           if (swr_is_fence_pending(screen->flush_fence))
>              return NULL;
>        } else {
>           if (spr->status) {
>              /* But, if there's no fence pending, submit one.
>               * XXX: Remove once draw timestamps are finished. */
>              if (!swr_is_fence_pending(screen->flush_fence))
>                 swr_fence_submit(swr_context(pipe), screen->flush_fence);
>
> -            swr_fence_finish(pipe->screen, screen->flush_fence, 0);
> +            swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
>              swr_resource_unused(resource);
>           }
>        }
>     }
>
>     pt = CALLOC_STRUCT(pipe_transfer);
>     if (!pt)
>        return NULL;
>     pipe_resource_reference(&pt->resource, resource);
>     pt->level = level;
> @@ -198,21 +198,21 @@ swr_resource_copy(struct pipe_context *pipe,
>                    struct pipe_resource *src,
>                    unsigned src_level,
>                    const struct pipe_box *src_box)
>  {
>     struct swr_screen *screen = swr_screen(pipe->screen);
>
>     /* If either the src or dst is a renderTarget, store tiles before copy */
>     swr_store_dirty_resource(pipe, src, SWR_TILE_RESOLVED);
>     swr_store_dirty_resource(pipe, dst, SWR_TILE_RESOLVED);
>
> -   swr_fence_finish(pipe->screen, screen->flush_fence, 0);
> +   swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
>     swr_resource_unused(src);
>     swr_resource_unused(dst);
>
>     if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER)
>         || (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER)) {
>        util_resource_copy_region(
>           pipe, dst, dst_level, dstx, dsty, dstz, src, src_level, src_box);
>        return;
>     }
>
> diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp
> index ab8d275..0f6a8c6 100644
> --- a/src/gallium/drivers/swr/swr_draw.cpp
> +++ b/src/gallium/drivers/swr/swr_draw.cpp
> @@ -232,21 +232,21 @@ swr_flush(struct pipe_context *pipe,
>     if (fence)
>        swr_fence_reference(pipe->screen, fence, screen->flush_fence);
>  }
>
>  void
>  swr_finish(struct pipe_context *pipe)
>  {
>     struct pipe_fence_handle *fence = nullptr;
>
>     swr_flush(pipe, &fence, 0);
> -   swr_fence_finish(pipe->screen, fence, 0);
> +   swr_fence_finish(pipe->screen, NULL, fence, 0);
>     swr_fence_reference(pipe->screen, &fence, NULL);
>  }
>
>
>  /*
>   * Store SWR HotTiles back to renderTarget surface.
>   */
>  void
>  swr_store_render_target(struct pipe_context *pipe,
>                          uint32_t attachment,
> diff --git a/src/gallium/drivers/swr/swr_fence.cpp b/src/gallium/drivers/swr/swr_fence.cpp
> index 8a8e864..7fe2470 100644
> --- a/src/gallium/drivers/swr/swr_fence.cpp
> +++ b/src/gallium/drivers/swr/swr_fence.cpp
> @@ -104,20 +104,21 @@ swr_fence_reference(struct pipe_screen *screen,
>     if (pipe_reference(&old->reference, &fence->reference))
>        swr_fence_destroy(old);
>  }
>
>
>  /*
>   * Wait for the fence to finish.
>   */
>  boolean
>  swr_fence_finish(struct pipe_screen *screen,
> +                 struct pipe_context *ctx,
>                   struct pipe_fence_handle *fence_handle,
>                   uint64_t timeout)
>  {
>     while (!swr_is_fence_done(fence_handle))
>        sched_yield();
>
>     swr_fence(fence_handle)->pending = FALSE;
>
>     return TRUE;
>  }
> diff --git a/src/gallium/drivers/swr/swr_fence.h b/src/gallium/drivers/swr/swr_fence.h
> index 47f4d2e..80a4345 100644
> --- a/src/gallium/drivers/swr/swr_fence.h
> +++ b/src/gallium/drivers/swr/swr_fence.h
> @@ -62,19 +62,20 @@ swr_is_fence_pending(struct pipe_fence_handle *fence_handle)
>
>  void swr_fence_init(struct pipe_screen *screen);
>
>  struct pipe_fence_handle *swr_fence_create();
>
>  void swr_fence_reference(struct pipe_screen *screen,
>                           struct pipe_fence_handle **ptr,
>                           struct pipe_fence_handle *f);
>
>  boolean swr_fence_finish(struct pipe_screen *screen,
> +                         struct pipe_context *ctx,
>                           struct pipe_fence_handle *fence_handle,
>                           uint64_t timeout);
>
>  void
>  swr_fence_submit(struct swr_context *ctx, struct pipe_fence_handle *fence);
>
>  uint64_t swr_get_timestamp(struct pipe_screen *screen);
>
>  #endif
> diff --git a/src/gallium/drivers/swr/swr_query.cpp b/src/gallium/drivers/swr/swr_query.cpp
> index 7867db3..5b8f059 100644
> --- a/src/gallium/drivers/swr/swr_query.cpp
> +++ b/src/gallium/drivers/swr/swr_query.cpp
> @@ -56,21 +56,21 @@ swr_create_query(struct pipe_context *pipe, unsigned type, unsigned index)
>  }
>
>
>  static void
>  swr_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
>  {
>     struct swr_query *pq = swr_query(q);
>
>     if (pq->fence) {
>        if (swr_is_fence_pending(pq->fence))
> -         swr_fence_finish(pipe->screen, pq->fence, 0);
> +         swr_fence_finish(pipe->screen, NULL, pq->fence, 0);
>        swr_fence_reference(pipe->screen, &pq->fence, NULL);
>     }
>
>     FREE(pq);
>  }
>
>
>  static void
>  swr_gather_stats(struct pipe_context *pipe, struct swr_query *pq)
>  {
> @@ -121,21 +121,21 @@ swr_get_query_result(struct pipe_context *pipe,
>  {
>     struct swr_query *pq = swr_query(q);
>     struct swr_query_result *start = &pq->start;
>     struct swr_query_result *end = &pq->end;
>     unsigned index = pq->index;
>
>     if (pq->fence) {
>        if (!wait && !swr_is_fence_done(pq->fence))
>           return FALSE;
>
> -      swr_fence_finish(pipe->screen, pq->fence, 0);
> +      swr_fence_finish(pipe->screen, NULL, pq->fence, 0);
>        swr_fence_reference(pipe->screen, &pq->fence, NULL);
>     }
>
>     /* XXX: Need to handle counter rollover */
>
>     switch (pq->type) {
>     /* Booleans */
>     case PIPE_QUERY_OCCLUSION_PREDICATE:
>        result->b = end->core.DepthPassCount != start->core.DepthPassCount;
>        break;
> diff --git a/src/gallium/drivers/swr/swr_screen.cpp b/src/gallium/drivers/swr/swr_screen.cpp
> index e0e59fa..df44967 100644
> --- a/src/gallium/drivers/swr/swr_screen.cpp
> +++ b/src/gallium/drivers/swr/swr_screen.cpp
> @@ -650,21 +650,21 @@ swr_resource_destroy(struct pipe_screen *p_screen, struct pipe_resource *pt)
>     struct swr_resource *spr = swr_resource(pt);
>     struct pipe_context *pipe = screen->pipe;
>
>     /* Only wait on fence if the resource is being used */
>     if (pipe && spr->status) {
>        /* But, if there's no fence pending, submit one.
>         * XXX: Remove once draw timestamps are implmented. */
>        if (!swr_is_fence_pending(screen->flush_fence))
>           swr_fence_submit(swr_context(pipe), screen->flush_fence);
>
> -      swr_fence_finish(p_screen, screen->flush_fence, 0);
> +      swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);
>        swr_resource_unused(pt);
>     }
>
>     /*
>      * Free resource primary surface.  If resource is display target, winsys
>      * manages the buffer and will free it on displaytarget_destroy.
>      */
>     if (spr->display_target) {
>        /* display target */
>        struct sw_winsys *winsys = screen->winsys;
> @@ -685,41 +685,41 @@ swr_flush_frontbuffer(struct pipe_screen *p_screen,
>                        unsigned layer,
>                        void *context_private,
>                        struct pipe_box *sub_box)
>  {
>     struct swr_screen *screen = swr_screen(p_screen);
>     struct sw_winsys *winsys = screen->winsys;
>     struct swr_resource *spr = swr_resource(resource);
>     struct pipe_context *pipe = screen->pipe;
>
>     if (pipe) {
> -      swr_fence_finish(p_screen, screen->flush_fence, 0);
> +      swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);
>        swr_resource_unused(resource);
>        SwrEndFrame(swr_context(pipe)->swrContext);
>     }
>
>     debug_assert(spr->display_target);
>     if (spr->display_target)
>        winsys->displaytarget_display(
>           winsys, spr->display_target, context_private, sub_box);
>  }
>
>
>  static void
>  swr_destroy_screen(struct pipe_screen *p_screen)
>  {
>     struct swr_screen *screen = swr_screen(p_screen);
>     struct sw_winsys *winsys = screen->winsys;
>
>     fprintf(stderr, "SWR destroy screen!\n");
>
> -   swr_fence_finish(p_screen, screen->flush_fence, 0);
> +   swr_fence_finish(p_screen, NULL, screen->flush_fence, 0);
>     swr_fence_reference(p_screen, &screen->flush_fence, NULL);
>
>     JitDestroyContext(screen->hJitMgr);
>
>     if (winsys->destroy)
>        winsys->destroy(winsys);
>
>     FREE(screen);
>  }
>
> diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp
> index dac95ce..2df7985 100644
> --- a/src/gallium/drivers/swr/swr_state.cpp
> +++ b/src/gallium/drivers/swr/swr_state.cpp
> @@ -1383,21 +1383,21 @@ swr_update_derived(struct pipe_context *pipe,
>     backendState.constantInterpolationMask =
>        ctx->rasterizer->flatshade ?
>        ctx->fs->flatConstantMask :
>        ctx->fs->constantMask;
>     backendState.pointSpriteTexCoordMask = ctx->fs->pointSpriteMask;
>
>     SwrSetBackendState(ctx->swrContext, &backendState);
>
>     /* Ensure that any in-progress attachment change StoreTiles finish */
>     if (swr_is_fence_pending(screen->flush_fence))
> -      swr_fence_finish(pipe->screen, screen->flush_fence, 0);
> +      swr_fence_finish(pipe->screen, NULL, screen->flush_fence, 0);
>
>     /* Finally, update the in-use status of all resources involved in draw */
>     swr_update_resource_status(pipe, p_draw_info);
>
>     ctx->dirty = post_update_dirty_flags;
>  }
>
>
>  static struct pipe_stream_output_target *
>  swr_create_so_target(struct pipe_context *pipe,
> diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
> index 260f1df..67241ca 100644
> --- a/src/gallium/drivers/trace/tr_screen.c
> +++ b/src/gallium/drivers/trace/tr_screen.c
> @@ -395,34 +395,37 @@ trace_screen_fence_reference(struct pipe_screen *_screen,
>     trace_dump_arg(ptr, src);
>
>     screen->fence_reference(screen, pdst, src);
>
>     trace_dump_call_end();
>  }
>
>
>  static boolean
>  trace_screen_fence_finish(struct pipe_screen *_screen,
> +                          struct pipe_context *_ctx,
>                            struct pipe_fence_handle *fence,
>                            uint64_t timeout)
>  {
>     struct trace_screen *tr_scr = trace_screen(_screen);
>     struct pipe_screen *screen = tr_scr->screen;
> +   struct pipe_context *ctx = _ctx ? trace_context(_ctx)->pipe : NULL;
>     int result;
>
>     trace_dump_call_begin("pipe_screen", "fence_finish");
>
>     trace_dump_arg(ptr, screen);
> +   trace_dump_arg(ptr, ctx);
>     trace_dump_arg(ptr, fence);
>     trace_dump_arg(uint, timeout);
>
> -   result = screen->fence_finish(screen, fence, timeout);
> +   result = screen->fence_finish(screen, ctx, fence, timeout);
>
>     trace_dump_ret(bool, result);
>
>     trace_dump_call_end();
>
>     return result;
>  }
>
>
>  /********************************************************************
> diff --git a/src/gallium/drivers/vc4/vc4_fence.c b/src/gallium/drivers/vc4/vc4_fence.c
> index b6fb2a8..f61e7c6 100644
> --- a/src/gallium/drivers/vc4/vc4_fence.c
> +++ b/src/gallium/drivers/vc4/vc4_fence.c
> @@ -54,20 +54,21 @@ vc4_fence_reference(struct pipe_screen *pscreen,
>          struct vc4_fence *old = *p;
>
>          if (pipe_reference(&(*p)->reference, &f->reference)) {
>                  free(old);
>          }
>          *p = f;
>  }
>
>  static boolean
>  vc4_fence_finish(struct pipe_screen *pscreen,
> +                struct pipe_context *ctx,
>                   struct pipe_fence_handle *pf,
>                   uint64_t timeout_ns)
>  {
>          struct vc4_screen *screen = vc4_screen(pscreen);
>          struct vc4_fence *f = (struct vc4_fence *)pf;
>
>          return vc4_wait_seqno(screen, f->seqno, timeout_ns, "fence wait");
>  }
>
>  struct vc4_fence *
> diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
> index fd3d35d..e01b5b4 100644
> --- a/src/gallium/drivers/virgl/virgl_screen.c
> +++ b/src/gallium/drivers/virgl/virgl_screen.c
> @@ -517,20 +517,21 @@ static void virgl_fence_reference(struct pipe_screen *screen,
>                                    struct pipe_fence_handle **ptr,
>                                    struct pipe_fence_handle *fence)
>  {
>     struct virgl_screen *vscreen = virgl_screen(screen);
>     struct virgl_winsys *vws = vscreen->vws;
>
>     vws->fence_reference(vws, ptr, fence);
>  }
>
>  static boolean virgl_fence_finish(struct pipe_screen *screen,
> +                                  struct pipe_context *ctx,
>                                    struct pipe_fence_handle *fence,
>                                    uint64_t timeout)
>  {
>     struct virgl_screen *vscreen = virgl_screen(screen);
>     struct virgl_winsys *vws = vscreen->vws;
>
>     return vws->fence_wait(vws, fence, timeout);
>  }
>
>  static uint64_t
> diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
> index 755291a..dd40e07 100644
> --- a/src/gallium/include/pipe/p_screen.h
> +++ b/src/gallium/include/pipe/p_screen.h
> @@ -235,25 +235,34 @@ struct pipe_screen {
>                                void *winsys_drawable_handle,
>                                struct pipe_box *subbox );
>
>     /** Set ptr = fence, with reference counting */
>     void (*fence_reference)( struct pipe_screen *screen,
>                              struct pipe_fence_handle **ptr,
>                              struct pipe_fence_handle *fence );
>
>     /**
>      * Wait for the fence to finish.
> +    *
> +    * If the fence was created with PIPE_FLUSH_DEFERRED, and the context is
> +    * still unflushed, and the ctx parameter of fence_finish is equal to
> +    * the context where the fence was created, fence_finish will flush
> +    * the context prior to waiting for the fence.
> +    *
> +    * In all other cases, the ctx parameter has no effect.
> +    *
>      * \param timeout  in nanoseconds (may be PIPE_TIMEOUT_INFINITE).
>      */
> -   boolean (*fence_finish)( struct pipe_screen *screen,
> -                            struct pipe_fence_handle *fence,
> -                            uint64_t timeout );
> +   boolean (*fence_finish)(struct pipe_screen *screen,
> +                           struct pipe_context *ctx,
> +                           struct pipe_fence_handle *fence,
> +                           uint64_t timeout);
>
>     /**
>      * Returns a driver-specific query.
>      *
>      * If \p info is NULL, the number of available queries is returned.
>      * Otherwise, the driver query at the specified \p index is returned
>      * in \p info. The function returns non-zero on success.
>      */
>     int (*get_driver_query_info)(struct pipe_screen *screen,
>                                  unsigned index,
> diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp
> index d75b839..8275e16 100644
> --- a/src/gallium/state_trackers/clover/core/event.cpp
> +++ b/src/gallium/state_trackers/clover/core/event.cpp
> @@ -134,21 +134,21 @@ hard_event::~hard_event() {
>  cl_int
>  hard_event::status() const {
>     pipe_screen *screen = queue()->device().pipe;
>
>     if (event::status() < 0)
>        return event::status();
>
>     else if (!_fence)
>        return CL_QUEUED;
>
> -   else if (!screen->fence_finish(screen, _fence, 0))
> +   else if (!screen->fence_finish(screen, NULL, _fence, 0))
>        return CL_SUBMITTED;
>
>     else
>        return CL_COMPLETE;
>  }
>
>  command_queue *
>  hard_event::queue() const {
>     return &_queue();
>  }
> @@ -161,21 +161,21 @@ hard_event::command() const {
>  void
>  hard_event::wait() const {
>     pipe_screen *screen = queue()->device().pipe;
>
>     event::wait();
>
>     if (status() == CL_QUEUED)
>        queue()->flush();
>
>     if (!_fence ||
> -       !screen->fence_finish(screen, _fence, PIPE_TIMEOUT_INFINITE))
> +       !screen->fence_finish(screen, NULL, _fence, PIPE_TIMEOUT_INFINITE))
>        throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
>  }
>
>  const lazy<cl_ulong> &
>  hard_event::time_queued() const {
>     return _time_queued;
>  }
>
>  const lazy<cl_ulong> &
>  hard_event::time_submit() const {
> diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
> index c22a8cd..9803b0e 100644
> --- a/src/gallium/state_trackers/dri/dri2.c
> +++ b/src/gallium/state_trackers/dri/dri2.c
> @@ -1245,21 +1245,21 @@ dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
>
>     pipe->blit(pipe, &blit);
>
>     if (flush_flag == __BLIT_FLAG_FLUSH) {
>        pipe->flush_resource(pipe, dst->texture);
>        ctx->st->flush(ctx->st, 0, NULL);
>     } else if (flush_flag == __BLIT_FLAG_FINISH) {
>        screen = dri_screen(ctx->sPriv)->base.screen;
>        pipe->flush_resource(pipe, dst->texture);
>        ctx->st->flush(ctx->st, 0, &fence);
> -      (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
> +      (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
>        screen->fence_reference(screen, &fence, NULL);
>     }
>  }
>
>  static void *
>  dri2_map_image(__DRIcontext *context, __DRIimage *image,
>                  int x0, int y0, int width, int height,
>                  unsigned int flags, int *stride, void **data)
>  {
>     struct dri_context *ctx = dri_context(context);
> @@ -1444,27 +1444,27 @@ static GLboolean
>  dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags,
>                        uint64_t timeout)
>  {
>     struct dri2_fence *fence = (struct dri2_fence*)_fence;
>     struct dri_screen *driscreen = fence->driscreen;
>     struct pipe_screen *screen = driscreen->base.screen;
>
>     /* No need to flush. The context was flushed when the fence was created. */
>
>     if (fence->pipe_fence)
> -      return screen->fence_finish(screen, fence->pipe_fence, timeout);
> +      return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
>     else if (fence->cl_event) {
>        struct pipe_fence_handle *pipe_fence =
>           driscreen->opencl_dri_event_get_fence(fence->cl_event);
>
>        if (pipe_fence)
> -         return screen->fence_finish(screen, pipe_fence, timeout);
> +         return screen->fence_finish(screen, NULL, pipe_fence, timeout);
>        else
>           return driscreen->opencl_dri_event_wait(fence->cl_event, timeout);
>     }
>     else {
>        assert(0);
>        return false;
>     }
>  }
>
>  static void
> diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
> index adc5128..edcd0e6 100644
> --- a/src/gallium/state_trackers/dri/dri_drawable.c
> +++ b/src/gallium/state_trackers/dri/dri_drawable.c
> @@ -518,21 +518,21 @@ dri_flush(__DRIcontext *cPriv,
>         *
>         * Then flushes to insert a fence at the current rendering position, and
>         * pushes that fence on the queue. This requires that the st_context_iface
>         * flush method returns a fence even if there are no commands to flush.
>         */
>        struct pipe_screen *screen = drawable->screen->base.screen;
>        struct pipe_fence_handle *fence;
>
>        fence = swap_fences_pop_front(drawable);
>        if (fence) {
> -         (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
> +         (void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
>           screen->fence_reference(screen, &fence, NULL);
>        }
>
>        ctx->st->flush(ctx->st, flush_flags, &fence);
>
>        if (fence) {
>           swap_fences_push_back(drawable, fence);
>           screen->fence_reference(screen, &fence, NULL);
>        }
>     }
> diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
> index 5799cce..8d1b360 100644
> --- a/src/gallium/state_trackers/glx/xlib/xm_api.c
> +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
> @@ -1369,21 +1369,21 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
>
>
>  void XMesaFlush( XMesaContext c )
>  {
>     if (c && c->xm_visual->display) {
>        XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
>        struct pipe_fence_handle *fence = NULL;
>
>        c->st->flush(c->st, ST_FLUSH_FRONT, &fence);
>        if (fence) {
> -         xmdpy->screen->fence_finish(xmdpy->screen, fence,
> +         xmdpy->screen->fence_finish(xmdpy->screen, NULL, fence,
>                                       PIPE_TIMEOUT_INFINITE);
>           xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
>        }
>        XFlush( c->xm_visual->display );
>     }
>  }
>
>
>
>
> diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c
> index bc01c2d..08ee482 100644
> --- a/src/gallium/state_trackers/nine/swapchain9.c
> +++ b/src/gallium/state_trackers/nine/swapchain9.c
> @@ -614,21 +614,21 @@ struct end_present_struct {
>      struct pipe_fence_handle *fence_to_wait;
>      ID3DPresent *present;
>      D3DWindowBuffer *present_handle;
>      HWND hDestWindowOverride;
>  };
>
>  static void work_present(void *data)
>  {
>      struct end_present_struct *work = data;
>      if (work->fence_to_wait) {
> -        (void) work->screen->fence_finish(work->screen, work->fence_to_wait, PIPE_TIMEOUT_INFINITE);
> +        (void) work->screen->fence_finish(work->screen, NULL, work->fence_to_wait, PIPE_TIMEOUT_INFINITE);
>          work->screen->fence_reference(work->screen, &(work->fence_to_wait), NULL);
>      }
>      ID3DPresent_PresentBuffer(work->present, work->present_handle, work->hDestWindowOverride, NULL, NULL, NULL, 0);
>      free(work);
>  }
>
>  static void pend_present(struct NineSwapChain9 *This,
>                           HWND hDestWindowOverride)
>  {
>      struct end_present_struct *work = calloc(1, sizeof(struct end_present_struct));
> @@ -736,32 +736,32 @@ present( struct NineSwapChain9 *This,
>      }
>
>      This->rendering_done = TRUE;
>  bypass_rendering:
>
>      if (dwFlags & D3DPRESENT_DONOTWAIT) {
>          UNTESTED(2);
>          BOOL still_draw = FALSE;
>          fence = swap_fences_see_front(This);
>          if (fence) {
> -            still_draw = !This->screen->fence_finish(This->screen, fence, 0);
> +            still_draw = !This->screen->fence_finish(This->screen, NULL, fence, 0);
>              This->screen->fence_reference(This->screen, &fence, NULL);
>          }
>          if (still_draw)
>              return D3DERR_WASSTILLDRAWING;
>      }
>
>      if (!This->enable_threadpool) {
>          This->tasks[0]=NULL;
>          fence = swap_fences_pop_front(This);
>          if (fence) {
> -            (void) This->screen->fence_finish(This->screen, fence, PIPE_TIMEOUT_INFINITE);
> +            (void) This->screen->fence_finish(This->screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
>              This->screen->fence_reference(This->screen, &fence, NULL);
>          }
>
>          hr = ID3DPresent_PresentBuffer(This->present, This->present_handles[0], hDestWindowOverride, pSourceRect, pDestRect, pDirtyRegion, dwFlags);
>
>          if (FAILED(hr)) { UNTESTED(3);return hr; }
>      } else {
>          pend_present(This, hDestWindowOverride);
>      }
>      This->rendering_done = FALSE;
> diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
> index e7f387e..2862eaf 100644
> --- a/src/gallium/state_trackers/vdpau/presentation.c
> +++ b/src/gallium/state_trackers/vdpau/presentation.c
> @@ -320,21 +320,21 @@ vlVdpPresentationQueueBlockUntilSurfaceIdle(VdpPresentationQueue presentation_qu
>     if (!pq)
>        return VDP_STATUS_INVALID_HANDLE;
>
>     surf = vlGetDataHTAB(surface);
>     if (!surf)
>        return VDP_STATUS_INVALID_HANDLE;
>
>     pipe_mutex_lock(pq->device->mutex);
>     if (surf->fence) {
>        screen = pq->device->vscreen->pscreen;
> -      screen->fence_finish(screen, surf->fence, PIPE_TIMEOUT_INFINITE);
> +      screen->fence_finish(screen, NULL, surf->fence, PIPE_TIMEOUT_INFINITE);
>        screen->fence_reference(screen, &surf->fence, NULL);
>     }
>     pipe_mutex_unlock(pq->device->mutex);
>
>     return vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
>  }
>
>  /**
>   * Poll the current queue status of a surface.
>   */
> @@ -362,21 +362,21 @@ vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue
>     *first_presentation_time = 0;
>
>     if (!surf->fence) {
>        if (pq->last_surf == surf)
>           *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
>        else
>           *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
>     } else {
>        pipe_mutex_lock(pq->device->mutex);
>        screen = pq->device->vscreen->pscreen;
> -      if (screen->fence_finish(screen, surf->fence, 0)) {
> +      if (screen->fence_finish(screen, NULL, surf->fence, 0)) {
>           screen->fence_reference(screen, &surf->fence, NULL);
>           *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
>           pipe_mutex_unlock(pq->device->mutex);
>
>           // We actually need to query the timestamp of the last VSYNC event from the hardware
>           vlVdpPresentationQueueGetTime(presentation_queue, first_presentation_time);
>           *first_presentation_time += 1;
>        } else {
>           *status = VDP_PRESENTATION_QUEUE_STATUS_QUEUED;
>           pipe_mutex_unlock(pq->device->mutex);
> diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c
> index 5553beb..715b48d 100644
> --- a/src/gallium/state_trackers/xa/xa_context.c
> +++ b/src/gallium/state_trackers/xa/xa_context.c
> @@ -376,21 +376,21 @@ xa_fence_get(struct xa_context *ctx)
>  XA_EXPORT int
>  xa_fence_wait(struct xa_fence *fence, uint64_t timeout)
>  {
>      if (!fence)
>         return XA_ERR_NONE;
>
>      if (fence->pipe_fence) {
>         struct pipe_screen *screen = fence->xa->screen;
>         boolean timed_out;
>
> -       timed_out = !screen->fence_finish(screen, fence->pipe_fence, timeout);
> +       timed_out = !screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
>         if (timed_out)
>             return -XA_ERR_BUSY;
>
>         screen->fence_reference(screen, &fence->pipe_fence, NULL);
>      }
>      return XA_ERR_NONE;
>  }
>
>  XA_EXPORT void
>  xa_fence_destroy(struct xa_fence *fence)
> diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c
> index 199712b..a4cd2aa 100644
> --- a/src/gallium/state_trackers/xvmc/surface.c
> +++ b/src/gallium/state_trackers/xvmc/surface.c
> @@ -481,21 +481,21 @@ Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
>
>     assert(status);
>
>     surface_priv = surface->privData;
>     context_priv = surface_priv->context->privData;
>     pipe = context_priv->pipe;
>
>     *status = 0;
>
>     if (surface_priv->fence)
> -      if (!pipe->screen->fence_finish(pipe->screen, surface_priv->fence, 0))
> +      if (!pipe->screen->fence_finish(pipe->screen, NULL, surface_priv->fence, 0))
>           *status |= XVMC_RENDERING;
>
>     return Success;
>  }
>
>  PUBLIC
>  Status XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
>  {
>     XvMCSurfacePrivate *surface_priv;
>     XvMCContextPrivate *context_priv;
> diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
> index 82affd2..5cab5a7 100644
> --- a/src/mesa/state_tracker/st_cb_flush.c
> +++ b/src/mesa/state_tracker/st_cb_flush.c
> @@ -91,21 +91,21 @@ void st_flush(struct st_context *st,
>  /**
>   * Flush, and wait for completion.
>   */
>  void st_finish( struct st_context *st )
>  {
>     struct pipe_fence_handle *fence = NULL;
>
>     st_flush(st, &fence, 0);
>
>     if(fence) {
> -      st->pipe->screen->fence_finish(st->pipe->screen, fence,
> +      st->pipe->screen->fence_finish(st->pipe->screen, NULL, fence,
>                                       PIPE_TIMEOUT_INFINITE);
>        st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL);
>     }
>  }
>
>
>
>  /**
>   * Called via ctx->Driver.Flush()
>   */
> diff --git a/src/mesa/state_tracker/st_cb_syncobj.c b/src/mesa/state_tracker/st_cb_syncobj.c
> index 69f2a28..1fa1403 100644
> --- a/src/mesa/state_tracker/st_cb_syncobj.c
> +++ b/src/mesa/state_tracker/st_cb_syncobj.c
> @@ -80,21 +80,21 @@ static void st_check_sync(struct gl_context *ctx, struct gl_sync_object *obj)
>  {
>     struct pipe_screen *screen = st_context(ctx)->pipe->screen;
>     struct st_sync_object *so = (struct st_sync_object*)obj;
>
>     /* If the fence doesn't exist, assume it's signalled. */
>     if (!so->fence) {
>        so->b.StatusFlag = GL_TRUE;
>        return;
>     }
>
> -   if (screen->fence_finish(screen, so->fence, 0)) {
> +   if (screen->fence_finish(screen, NULL, so->fence, 0)) {
>        screen->fence_reference(screen, &so->fence, NULL);
>        so->b.StatusFlag = GL_TRUE;
>     }
>  }
>
>  static void st_client_wait_sync(struct gl_context *ctx,
>                                  struct gl_sync_object *obj,
>                                  GLbitfield flags, GLuint64 timeout)
>  {
>     struct pipe_screen *screen = st_context(ctx)->pipe->screen;
> @@ -103,21 +103,21 @@ static void st_client_wait_sync(struct gl_context *ctx,
>     /* If the fence doesn't exist, assume it's signalled. */
>     if (!so->fence) {
>        so->b.StatusFlag = GL_TRUE;
>        return;
>     }
>
>     /* We don't care about GL_SYNC_FLUSH_COMMANDS_BIT, because flush is
>      * already called when creating a fence. */
>
>     if (so->fence &&
> -       screen->fence_finish(screen, so->fence, timeout)) {
> +       screen->fence_finish(screen, NULL, so->fence, timeout)) {
>        screen->fence_reference(screen, &so->fence, NULL);
>        so->b.StatusFlag = GL_TRUE;
>     }
>  }
>
>  static void st_server_wait_sync(struct gl_context *ctx,
>                                  struct gl_sync_object *obj,
>                                  GLbitfield flags, GLuint64 timeout)
>  {
>     /* NO-OP.
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list