[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