[Mesa-dev] [PATCH 4/6] gallium: add way for drivers to create fences without flushing
Rob Clark
robdclark at gmail.com
Mon Apr 4 13:46:51 UTC 2016
well,
https://groups.google.com/a/chromium.org/forum/#!topic/chromium-os-reviews/IFiv8rZfAq0
does imply that it could be called without a ctx bound.. hmm..
BR,
-R
On Mon, Apr 4, 2016 at 8:43 AM, Rob Clark <robdclark at gmail.com> wrote:
> Hmm, what are the requirements of eglClientWaitSyncKHR() about having
> current context bound? Not being thread-safe (ie. being associated w/
> current ctx) is pretty important to allow apps that create fences at
> in-opportune times to not force a mid-frame flush for tilers.. :-(
>
> BR,
> -R
>
>
> On Mon, Apr 4, 2016 at 8:10 AM, Marek Olšák <maraeo at 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 <robdclark at gmail.com> wrote:
>>> From: Rob Clark <robclark at 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 <robclark at 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 at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list