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

Gurchetan Singh gurchetansingh at chromium.org
Mon May 8 22:25:15 UTC 2017


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



More information about the mesa-dev mailing list