From: Rob Clark <robcl...@freedesktop.org> This enables gallium support for EGL_ANDROID_native_fence_sync, for drivers which support PIPE_CAP_NATIVE_FENCE_FD.
TODO: add PIPE_CAP_NATIVE_FENCE_FD to every's switch statement returning false.. but I'll leave that until this patchset is ready to push since that sort of thing makes a lot of rebase noise. Signed-off-by: Rob Clark <robcl...@freedesktop.org> --- src/gallium/include/pipe/p_context.h | 17 +++++++++++++ src/gallium/include/pipe/p_defines.h | 1 + src/gallium/include/pipe/p_screen.h | 8 +++++++ src/gallium/state_trackers/dri/dri2.c | 45 +++++++++++++++++++++++++++++++++-- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index d617ec4..152fb91 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -473,6 +473,23 @@ struct pipe_context { struct pipe_fence_handle **fence); /** + * Create a fence from a native sync fd. + * + * If the fence fd is -1, the driver should insert fence commands + * in command-stream, and (after flush) be prepared to return a + * valid fd from screen->get_fence_fd(). Otherwise, the driver + * should wrap an existing native fence fd (and be prepared for + * ctx->fence_server_sync()) + * + * \param fence if not NULL, an old fence to unref and transfer a + * new fence reference to + * \param fd native fence fd + */ + void (*create_fence_fd)(struct pipe_context *pipe, + struct pipe_fence_handle **fence, + int fd); + + /** * Wait for the fence to finish. * \param timeout in nanoseconds (may be PIPE_TIMEOUT_INFINITE). */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 8257b4a..654a576 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -689,6 +689,7 @@ enum pipe_cap PIPE_CAP_PCI_BUS, PIPE_CAP_PCI_DEVICE, PIPE_CAP_PCI_FUNCTION, + PIPE_CAP_NATIVE_FENCE_FD, }; #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0) diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 4f30e75..9e8e942 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -246,6 +246,14 @@ struct pipe_screen { uint64_t timeout ); /** + * For fences created via ctx->create_fence_fd(), return the native + * fence fd associated with the fence, or -1 if the fence commands + * have not been flushed yet. + */ + int (*fence_get_fd)(struct pipe_screen *screen, + struct pipe_fence_handle *fence); + + /** * Returns a driver-specific query. * * If \p info is NULL, the number of available queries is returned. diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 6c8bb37..1a970c5 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -1311,6 +1311,18 @@ struct dri2_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) { @@ -1337,6 +1349,32 @@ dri2_create_fence(__DRIcontext *_ctx) } 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); + + 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); @@ -1421,13 +1459,16 @@ dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags) } static __DRI2fenceExtension dri2FenceExtension = { - .base = { __DRI2_FENCE, 1 }, + .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 + .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 = { -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev