There is one problem with this: It doesn't allow calling pipe_context::fence_finish from another thread in a thread-safe manner, and it implies that fence_finish is generally NOT thread-safe. This thread safety is something I'd like to preserve.
I would say that a flush flag telling the driver not to flush would be better, so that drivers which have per-screen fences and cheap flushes can ignore it. Marek On Fri, Apr 1, 2016 at 10:29 PM, Rob Clark <robdcl...@gmail.com> wrote: > From: Rob Clark <robcl...@freedesktop.org> > > Since current thing is kinda horrible for tilers. And that issue will > be even worse with EGL_ANDROID_native_fence_sync. > > Not wired up yet for gl syncobj, which can come later. For now we just > need this with EGL. > > Signed-off-by: Rob Clark <robcl...@freedesktop.org> > --- > src/gallium/include/pipe/p_context.h | 24 ++++++++++++++++++++++++ > src/gallium/state_trackers/dri/dri2.c | 29 ++++++++++++++++++++--------- > 2 files changed, 44 insertions(+), 9 deletions(-) > > diff --git a/src/gallium/include/pipe/p_context.h > b/src/gallium/include/pipe/p_context.h > index 1c97e82..02a946b 100644 > --- a/src/gallium/include/pipe/p_context.h > +++ b/src/gallium/include/pipe/p_context.h > @@ -457,6 +457,30 @@ struct pipe_context { > unsigned flags); > > /** > + * Create a fence without necessarily flushing rendering. Note > + * that if the driver implements this, it must also implement > + * ctx->fence_finish() which will be used instead of > + * screen->fence_finish() to give the driver an opportunity to > + * flush. > + * > + * This allows drivers, in particular tilers, to defer flush > + * until someone actually wants to wait on a fence. > + * > + * \param fence if not NULL, an old fence to unref and transfer a > + * new fence reference to > + */ > + void (*create_fence)(struct pipe_context *pipe, > + struct pipe_fence_handle **fence); > + > + /** > + * Wait for the fence to finish. > + * \param timeout in nanoseconds (may be PIPE_TIMEOUT_INFINITE). > + */ > + boolean (*fence_finish)(struct pipe_context *pipe, > + struct pipe_fence_handle *fence, > + uint64_t timeout); > + > + /** > * Create a view on a texture to be used by a shader stage. > */ > struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context > *ctx, > diff --git a/src/gallium/state_trackers/dri/dri2.c > b/src/gallium/state_trackers/dri/dri2.c > index fb0a180..b66d885 100644 > --- a/src/gallium/state_trackers/dri/dri2.c > +++ b/src/gallium/state_trackers/dri/dri2.c > @@ -1320,7 +1320,12 @@ dri2_create_fence(__DRIcontext *_ctx) > if (!fence) > return NULL; > > - ctx->flush(ctx, &fence->pipe_fence, 0); > + if (ctx->create_fence) { > + debug_assert(ctx->fence_finish); > + ctx->create_fence(ctx, &fence->pipe_fence); > + } else { > + ctx->flush(ctx, &fence->pipe_fence, 0); > + } > > if (!fence->pipe_fence) { > FREE(fence); > @@ -1376,27 +1381,33 @@ static GLboolean > dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags, > uint64_t timeout) > { > + struct pipe_context *ctx = dri_context(_ctx)->st->pipe; > struct dri2_fence *fence = (struct dri2_fence*)_fence; > struct dri_screen *driscreen = fence->driscreen; > struct pipe_screen *screen = driscreen->base.screen; > + struct pipe_fence_handle *pipe_fence = NULL; > > - /* No need to flush. The context was flushed when the fence was created. > */ > + /* No need to flush. The context was flushed when the fence was created, > + * or the ctx implements ctx->fence_finish() which will take care of > + * flushing if required > + */ > > if (fence->pipe_fence) > - return screen->fence_finish(screen, fence->pipe_fence, timeout); > + pipe_fence = fence->pipe_fence; > 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); > - else > + pipe_fence = driscreen->opencl_dri_event_get_fence(fence->cl_event); > + if (!pipe_fence) > return driscreen->opencl_dri_event_wait(fence->cl_event, timeout); > } > else { > assert(0); > return false; > } > + > + if (ctx->fence_finish) > + return ctx->fence_finish(ctx, pipe_fence, timeout); > + > + return screen->fence_finish(screen, pipe_fence, timeout); > } > > static void > -- > 2.5.5 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev