Hmm, so we could actually use EGL_SYNC_FLUSH_COMMANDS_BIT_KHR (which is ignored when there is not a ctx bound).. from looking closer at KHR_fence_sync this appears to be how things are expected to work.
ofc that means that you end up needing to keep both ctx->fence_finish() and screen->fence_finish(), or maybe extend screen->fence_finish() to take an optional ctx ptr.. neither of which is the prettiest thing. BR, -R On Mon, Apr 4, 2016 at 8:10 AM, Marek Olšák <mar...@gmail.com> wrote: > 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