*/
#include <xf86drm.h>
+#include <dlfcn.h>
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.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 pipe_fence_handle *pipe_fence;
+ void *cl_event;
};
static void *
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
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);
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;
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
+ pipe_mutex_init(screen->opencl_func_mutex);
sPriv->driverPrivate = (void *)screen;
#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;
/* 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 */