summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/dri/dri2.c72
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c1
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h9
3 files changed, 81 insertions, 1 deletions
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 9b5631326d4..8b6fe67dc91 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -29,6 +29,7 @@
*/
#include <xf86drm.h>
+#include <dlfcn.h>
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
@@ -1252,8 +1253,48 @@ static __DRIimageExtension dri2ImageExtension = {
};
+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 pipe_fence_handle *pipe_fence;
+ void *cl_event;
};
static void *
@@ -1278,7 +1319,24 @@ dri2_create_fence(__DRIcontext *_ctx)
static void *
dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
{
- return NULL;
+ 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;
+ }
+
+ return fence;
}
static void
@@ -1290,6 +1348,8 @@ dri2_destroy_fence(__DRIscreen *_screen, void *_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);
@@ -1308,6 +1368,15 @@ dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags,
if (fence->pipe_fence)
return screen->fence_finish(screen, 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, pipe_fence, timeout);
+ else
+ return driscreen->opencl_dri_event_wait(fence->cl_event, timeout);
+ }
else {
assert(0);
return false;
@@ -1365,6 +1434,7 @@ dri2_init_screen(__DRIscreen * sPriv)
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
+ pipe_mutex_init(screen->opencl_func_mutex);
sPriv->driverPrivate = (void *)screen;
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 1b14ab162f1..85393d867e4 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -365,6 +365,7 @@ dri_destroy_screen_helper(struct dri_screen * screen)
screen->base.screen->destroy(screen->base.screen);
dri_destroy_option_cache(screen);
+ pipe_mutex_destroy(screen->opencl_func_mutex);
}
void
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index e4a1a39aa21..bdab74f2802 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -39,6 +39,8 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "state_tracker/st_api.h"
+#include "state_tracker/opencl_interop.h"
+#include "os/os_thread.h"
#include "postprocess/filters.h"
struct dri_context;
@@ -84,6 +86,13 @@ struct dri_screen
/* hooks filled in by dri2 & drisw */
__DRIimage * (*lookup_egl_image)(struct dri_screen *ctx, void *handle);
+
+ /* OpenCL interop */
+ pipe_mutex opencl_func_mutex;
+ opencl_dri_event_add_ref_t opencl_dri_event_add_ref;
+ opencl_dri_event_release_t opencl_dri_event_release;
+ opencl_dri_event_wait_t opencl_dri_event_wait;
+ opencl_dri_event_get_fence_t opencl_dri_event_get_fence;
};
/** cast wrapper */