[Mesa-dev] [PATCH] st/dri: Add fence extension to SW path

Gurchetan Singh gurchetansingh at chromium.org
Mon May 15 23:00:25 UTC 2017


Ping.

On Mon, May 8, 2017 at 3:25 PM, Gurchetan Singh <gurchetansingh at chromium.org
> wrote:

> Use the same fence implementation for drisw.c as dri2.c by making
> dri2FenceExtension an external variable. Since the fence implementation
> is not dri2.c specific, put it in a separate file. This is desirable for
> synchronization in virtual machines.
>
> v2: Don't depend on dri2.c for extensions (Emil)
> ---
>  src/gallium/state_trackers/dri/Makefile.sources |   2 +
>  src/gallium/state_trackers/dri/dri2.c           | 203
> +--------------------
>  src/gallium/state_trackers/dri/dri_extensions.c | 229
> ++++++++++++++++++++++++
>  src/gallium/state_trackers/dri/dri_extensions.h |  30 ++++
>  src/gallium/state_trackers/dri/drisw.c          |   2 +
>  5 files changed, 264 insertions(+), 202 deletions(-)
>  create mode 100644 src/gallium/state_trackers/dri/dri_extensions.c
>  create mode 100644 src/gallium/state_trackers/dri/dri_extensions.h
>
> diff --git a/src/gallium/state_trackers/dri/Makefile.sources
> b/src/gallium/state_trackers/dri/Makefile.sources
> index 52d60ac928..46da886c00 100644
> --- a/src/gallium/state_trackers/dri/Makefile.sources
> +++ b/src/gallium/state_trackers/dri/Makefile.sources
> @@ -3,6 +3,8 @@ common_SOURCES := \
>         dri_context.h \
>         dri_drawable.c \
>         dri_drawable.h \
> +       dri_extensions.c \
> +       dri_extensions.h \
>         dri_query_renderer.c \
>         dri_query_renderer.h \
>         dri_screen.c \
> diff --git a/src/gallium/state_trackers/dri/dri2.c
> b/src/gallium/state_trackers/dri/dri2.c
> index ed6004f836..2d95e668f8 100644
> --- a/src/gallium/state_trackers/dri/dri2.c
> +++ b/src/gallium/state_trackers/dri/dri2.c
> @@ -49,6 +49,7 @@
>  #include "dri_screen.h"
>  #include "dri_context.h"
>  #include "dri_drawable.h"
> +#include "dri_extensions.h"
>  #include "dri_query_renderer.h"
>  #include "dri2_buffer.h"
>
> @@ -1415,208 +1416,6 @@ static __DRIimageExtension dri2ImageExtension = {
>      .unmapImage                   = dri2_unmap_image,
>  };
>
> -
> -static bool
> -dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
> -{
> -   return screen->opencl_dri_event_add_ref &&
> -          screen->opencl_dri_event_release &&
> -          screen->opencl_dri_event_wait &&
> -          screen->opencl_dri_event_get_fence;
> -}
> -
> -static bool
> -dri2_load_opencl_interop(struct dri_screen *screen)
> -{
> -#if defined(RTLD_DEFAULT)
> -   bool success;
> -
> -   mtx_lock(&screen->opencl_func_mutex);
> -
> -   if (dri2_is_opencl_interop_loaded_locked(screen)) {
> -      mtx_unlock(&screen->opencl_func_mutex);
> -      return true;
> -   }
> -
> -   screen->opencl_dri_event_add_ref =
> -      dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref");
> -   screen->opencl_dri_event_release =
> -      dlsym(RTLD_DEFAULT, "opencl_dri_event_release");
> -   screen->opencl_dri_event_wait =
> -      dlsym(RTLD_DEFAULT, "opencl_dri_event_wait");
> -   screen->opencl_dri_event_get_fence =
> -      dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence");
> -
> -   success = dri2_is_opencl_interop_loaded_locked(screen);
> -   mtx_unlock(&screen->opencl_func_mutex);
> -   return success;
> -#else
> -   return false;
> -#endif
> -}
> -
> -struct dri2_fence {
> -   struct dri_screen *driscreen;
> -   struct pipe_fence_handle *pipe_fence;
> -   void *cl_event;
> -};
> -
> -static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
> -{
> -   struct dri_screen *driscreen = dri_screen(_screen);
> -   struct pipe_screen *screen = driscreen->base.screen;
> -   unsigned caps = 0;
> -
> -   if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
> -      caps |= __DRI_FENCE_CAP_NATIVE_FD;
> -
> -   return caps;
> -}
> -
> -static void *
> -dri2_create_fence(__DRIcontext *_ctx)
> -{
> -   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> -   struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> -
> -   if (!fence)
> -      return NULL;
> -
> -   ctx->flush(ctx, &fence->pipe_fence, 0);
> -
> -   if (!fence->pipe_fence) {
> -      FREE(fence);
> -      return NULL;
> -   }
> -
> -   fence->driscreen = dri_screen(_ctx->driScreenPriv);
> -   return fence;
> -}
> -
> -static void *
> -dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
> -{
> -   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> -   struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> -
> -   if (fd == -1) {
> -      /* exporting driver created fence, flush: */
> -      ctx->flush(ctx, &fence->pipe_fence,
> -                 PIPE_FLUSH_DEFERRED | PIPE_FLUSH_FENCE_FD);
> -   } else {
> -      /* importing a foreign fence fd: */
> -      ctx->create_fence_fd(ctx, &fence->pipe_fence, fd);
> -   }
> -   if (!fence->pipe_fence) {
> -      FREE(fence);
> -      return NULL;
> -   }
> -
> -   fence->driscreen = dri_screen(_ctx->driScreenPriv);
> -   return fence;
> -}
> -
> -static int
> -dri2_get_fence_fd(__DRIscreen *_screen, void *_fence)
> -{
> -   struct dri_screen *driscreen = dri_screen(_screen);
> -   struct pipe_screen *screen = driscreen->base.screen;
> -   struct dri2_fence *fence = (struct dri2_fence*)_fence;
> -
> -   return screen->fence_get_fd(screen, fence->pipe_fence);
> -}
> -
> -static void *
> -dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
> -{
> -   struct dri_screen *driscreen = dri_screen(_screen);
> -   struct dri2_fence *fence;
> -
> -   if (!dri2_load_opencl_interop(driscreen))
> -      return NULL;
> -
> -   fence = CALLOC_STRUCT(dri2_fence);
> -   if (!fence)
> -      return NULL;
> -
> -   fence->cl_event = (void*)cl_event;
> -
> -   if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) {
> -      free(fence);
> -      return NULL;
> -   }
> -
> -   fence->driscreen = driscreen;
> -   return fence;
> -}
> -
> -static void
> -dri2_destroy_fence(__DRIscreen *_screen, void *_fence)
> -{
> -   struct dri_screen *driscreen = dri_screen(_screen);
> -   struct pipe_screen *screen = driscreen->base.screen;
> -   struct dri2_fence *fence = (struct dri2_fence*)_fence;
> -
> -   if (fence->pipe_fence)
> -      screen->fence_reference(screen, &fence->pipe_fence, NULL);
> -   else if (fence->cl_event)
> -      driscreen->opencl_dri_event_release(fence->cl_event);
> -   else
> -      assert(0);
> -
> -   FREE(fence);
> -}
> -
> -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, 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, NULL, pipe_fence, timeout);
> -      else
> -         return driscreen->opencl_dri_event_wait(fence->cl_event,
> timeout);
> -   }
> -   else {
> -      assert(0);
> -      return false;
> -   }
> -}
> -
> -static void
> -dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
> -{
> -   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> -   struct dri2_fence *fence = (struct dri2_fence*)_fence;
> -
> -   if (ctx->fence_server_sync)
> -      ctx->fence_server_sync(ctx, fence->pipe_fence);
> -}
> -
> -static __DRI2fenceExtension dri2FenceExtension = {
> -   .base = { __DRI2_FENCE, 2 },
> -
> -   .create_fence = dri2_create_fence,
> -   .get_fence_from_cl_event = dri2_get_fence_from_cl_event,
> -   .destroy_fence = dri2_destroy_fence,
> -   .client_wait_sync = dri2_client_wait_sync,
> -   .server_wait_sync = dri2_server_wait_sync,
> -   .get_capabilities = dri2_fence_get_caps,
> -   .create_fence_fd = dri2_create_fence_fd,
> -   .get_fence_fd = dri2_get_fence_fd,
> -};
> -
>  static const __DRIrobustnessExtension dri2Robustness = {
>     .base = { __DRI2_ROBUSTNESS, 1 }
>  };
> diff --git a/src/gallium/state_trackers/dri/dri_extensions.c
> b/src/gallium/state_trackers/dri/dri_extensions.c
> new file mode 100644
> index 0000000000..2fa7233aab
> --- /dev/null
> +++ b/src/gallium/state_trackers/dri/dri_extensions.c
> @@ -0,0 +1,229 @@
> +/*
> + * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> "Software"),
> + * to deal in the Software without restriction, including without
> limitation
> + * the rights to use, copy, modify, merge, publish, distribute,
> sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included
> + * in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
> SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include "dri_context.h"
> +#include "dri_screen.h"
> +#include "pipe/p_screen.h"
> +#include "util/u_memory.h"
> +
> +static bool
> +dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
> +{
> +   return screen->opencl_dri_event_add_ref &&
> +          screen->opencl_dri_event_release &&
> +          screen->opencl_dri_event_wait &&
> +          screen->opencl_dri_event_get_fence;
> +}
> +
> +static bool
> +dri2_load_opencl_interop(struct dri_screen *screen)
> +{
> +#if defined(RTLD_DEFAULT)
> +   bool success;
> +
> +   pipe_mutex_lock(screen->opencl_func_mutex);
> +
> +   if (dri2_is_opencl_interop_loaded_locked(screen)) {
> +      pipe_mutex_unlock(screen->opencl_func_mutex);
> +      return true;
> +   }
> +
> +   screen->opencl_dri_event_add_ref =
> +      dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref");
> +   screen->opencl_dri_event_release =
> +      dlsym(RTLD_DEFAULT, "opencl_dri_event_release");
> +   screen->opencl_dri_event_wait =
> +      dlsym(RTLD_DEFAULT, "opencl_dri_event_wait");
> +   screen->opencl_dri_event_get_fence =
> +      dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence");
> +
> +   success = dri2_is_opencl_interop_loaded_locked(screen);
> +   pipe_mutex_unlock(screen->opencl_func_mutex);
> +   return success;
> +#else
> +   return false;
> +#endif
> +}
> +
> +struct dri2_fence {
> +   struct dri_screen *driscreen;
> +   struct pipe_fence_handle *pipe_fence;
> +   void *cl_event;
> +};
> +
> +static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
> +{
> +   struct dri_screen *driscreen = dri_screen(_screen);
> +   struct pipe_screen *screen = driscreen->base.screen;
> +   unsigned caps = 0;
> +
> +   if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
> +      caps |= __DRI_FENCE_CAP_NATIVE_FD;
> +
> +   return caps;
> +}
> +
> +static void *
> +dri2_create_fence(__DRIcontext *_ctx)
> +{
> +   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> +   struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> +
> +   if (!fence)
> +      return NULL;
> +
> +   ctx->flush(ctx, &fence->pipe_fence, 0);
> +
> +   if (!fence->pipe_fence) {
> +      FREE(fence);
> +      return NULL;
> +   }
> +
> +   fence->driscreen = dri_screen(_ctx->driScreenPriv);
> +   return fence;
> +}
> +
> +static void *
> +dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
> +{
> +   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> +   struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
> +
> +   if (fd == -1) {
> +      /* exporting driver created fence, flush: */
> +      ctx->flush(ctx, &fence->pipe_fence,
> +                 PIPE_FLUSH_DEFERRED | PIPE_FLUSH_FENCE_FD);
> +   } else {
> +      /* importing a foreign fence fd: */
> +      ctx->create_fence_fd(ctx, &fence->pipe_fence, fd);
> +   }
> +   if (!fence->pipe_fence) {
> +      FREE(fence);
> +      return NULL;
> +   }
> +
> +   fence->driscreen = dri_screen(_ctx->driScreenPriv);
> +   return fence;
> +}
> +
> +static int
> +dri2_get_fence_fd(__DRIscreen *_screen, void *_fence)
> +{
> +   struct dri_screen *driscreen = dri_screen(_screen);
> +   struct pipe_screen *screen = driscreen->base.screen;
> +   struct dri2_fence *fence = (struct dri2_fence*)_fence;
> +
> +   return screen->fence_get_fd(screen, fence->pipe_fence);
> +}
> +
> +static void *
> +dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
> +{
> +   struct dri_screen *driscreen = dri_screen(_screen);
> +   struct dri2_fence *fence;
> +
> +   if (!dri2_load_opencl_interop(driscreen))
> +      return NULL;
> +
> +   fence = CALLOC_STRUCT(dri2_fence);
> +   if (!fence)
> +      return NULL;
> +
> +   fence->cl_event = (void*)cl_event;
> +
> +   if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) {
> +      free(fence);
> +      return NULL;
> +   }
> +
> +   fence->driscreen = driscreen;
> +   return fence;
> +}
> +
> +static void
> +dri2_destroy_fence(__DRIscreen *_screen, void *_fence)
> +{
> +   struct dri_screen *driscreen = dri_screen(_screen);
> +   struct pipe_screen *screen = driscreen->base.screen;
> +   struct dri2_fence *fence = (struct dri2_fence*)_fence;
> +
> +   if (fence->pipe_fence)
> +      screen->fence_reference(screen, &fence->pipe_fence, NULL);
> +   else if (fence->cl_event)
> +      driscreen->opencl_dri_event_release(fence->cl_event);
> +   else
> +      assert(0);
> +
> +   FREE(fence);
> +}
> +
> +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, 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, NULL, pipe_fence, timeout);
> +      else
> +         return driscreen->opencl_dri_event_wait(fence->cl_event,
> timeout);
> +   }
> +   else {
> +      assert(0);
> +      return false;
> +   }
> +}
> +
> +static void
> +dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
> +{
> +   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
> +   struct dri2_fence *fence = (struct dri2_fence*)_fence;
> +
> +   if (ctx->fence_server_sync)
> +      ctx->fence_server_sync(ctx, fence->pipe_fence);
> +}
> +
> +const __DRI2fenceExtension dri2FenceExtension = {
> +   .base = { __DRI2_FENCE, 2 },
> +
> +   .create_fence = dri2_create_fence,
> +   .get_fence_from_cl_event = dri2_get_fence_from_cl_event,
> +   .destroy_fence = dri2_destroy_fence,
> +   .client_wait_sync = dri2_client_wait_sync,
> +   .server_wait_sync = dri2_server_wait_sync,
> +   .get_capabilities = dri2_fence_get_caps,
> +   .create_fence_fd = dri2_create_fence_fd,
> +   .get_fence_fd = dri2_get_fence_fd,
> +};
> +
> +/* vim: set sw=3 ts=8 sts=3 expandtab: */
> diff --git a/src/gallium/state_trackers/dri/dri_extensions.h
> b/src/gallium/state_trackers/dri/dri_extensions.h
> new file mode 100644
> index 0000000000..89b01cd3ed
> --- /dev/null
> +++ b/src/gallium/state_trackers/dri/dri_extensions.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> "Software"),
> + * to deal in the Software without restriction, including without
> limitation
> + * the rights to use, copy, modify, merge, publish, distribute,
> sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included
> + * in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT
> SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifndef DRI_EXTENSIONS_H
> +#define DRI_EXTENSIONS_H
> +
> +extern const __DRI2fenceExtension dri2FenceExtension;
> +
> +#endif
> +
> +/* vim: set sw=3 ts=8 sts=3 expandtab: */
> diff --git a/src/gallium/state_trackers/dri/drisw.c
> b/src/gallium/state_trackers/dri/drisw.c
> index b85a73c57d..8fbfa9ecea 100644
> --- a/src/gallium/state_trackers/dri/drisw.c
> +++ b/src/gallium/state_trackers/dri/drisw.c
> @@ -46,6 +46,7 @@
>  #include "dri_screen.h"
>  #include "dri_context.h"
>  #include "dri_drawable.h"
> +#include "dri_extensions.h"
>  #include "dri_query_renderer.h"
>
>  DEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT",
> FALSE);
> @@ -369,6 +370,7 @@ static const __DRIextension *drisw_screen_extensions[]
> = {
>     &driTexBufferExtension.base,
>     &dri2RendererQueryExtension.base,
>     &dri2ConfigQueryExtension.base,
> +   &dri2FenceExtension.base,
>     NULL
>  };
>
> --
> 2.12.2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170515/179a1b32/attachment-0001.html>


More information about the mesa-dev mailing list