From 026a7223a6c9dcd7c59b95dbaf5e64b7258f8700 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 1 Apr 2016 16:10:42 -0400 Subject: [PATCH] gallium: support for native fence fd's This enables gallium support for EGL_ANDROID_native_fence_sync, for drivers which support PIPE_CAP_NATIVE_FENCE_FD. Signed-off-by: Rob Clark --- .../drivers/freedreno/freedreno_screen.c | 2 + src/gallium/drivers/i915/i915_screen.c | 1 + src/gallium/drivers/ilo/ilo_screen.c | 1 + src/gallium/drivers/llvmpipe/lp_screen.c | 1 + .../drivers/nouveau/nv30/nv30_screen.c | 1 + .../drivers/nouveau/nv50/nv50_screen.c | 1 + .../drivers/nouveau/nvc0/nvc0_screen.c | 1 + src/gallium/drivers/r300/r300_screen.c | 1 + src/gallium/drivers/r600/r600_pipe.c | 1 + src/gallium/drivers/radeonsi/si_pipe.c | 1 + src/gallium/drivers/softpipe/sp_screen.c | 1 + src/gallium/drivers/svga/svga_screen.c | 1 + src/gallium/drivers/vc4/vc4_screen.c | 1 + src/gallium/drivers/virgl/virgl_screen.c | 2 + src/gallium/include/pipe/p_context.h | 13 +++++ src/gallium/include/pipe/p_defines.h | 2 + src/gallium/include/pipe/p_screen.h | 10 ++++ src/gallium/state_trackers/dri/dri2.c | 52 ++++++++++++++++++- 18 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 48b796406d1..90060e219fe 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -379,6 +379,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 10; case PIPE_CAP_UMA: return 1; + case PIPE_CAP_NATIVE_FENCE_FD: + return 0; } debug_printf("unknown param %d\n", param); return 0; diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index fa19b8bb0e7..14f42717b1d 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -295,6 +295,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_SAMPLER_VIEW_TARGET: case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_MAX_VIEWPORTS: diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c index 3fce936cde2..c3fad7314ed 100644 --- a/src/gallium/drivers/ilo/ilo_screen.c +++ b/src/gallium/drivers/ilo/ilo_screen.c @@ -518,6 +518,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 2d75f2d403c..83045cd5e35 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -339,6 +339,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; } /* should only get here on unhandled cases */ diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index b4b7a200b64..beffeac7a1f 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -204,6 +204,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 60dfddc1552..5b388b5aa17 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -256,6 +256,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 67f1d6b7a03..2526a14c504 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -275,6 +275,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_PCI_FUNCTION: case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 0cb817befc9..d6e3aa4a7bf 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -226,6 +226,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; /* SWTCL-only features. */ diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 16c936f0905..b99da2212dd 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -375,6 +375,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_WINDOW_RECTANGLES: case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS: diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 4297a4fa57f..71fc5570d60 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -459,6 +459,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_PRIMITIVE_RESTART_FOR_PATCHES: case PIPE_CAP_TGSI_VOTE: case PIPE_CAP_MAX_WINDOW_RECTANGLES: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_QUERY_BUFFER_OBJECT: diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 4af1b00f83f..824e8678823 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -289,6 +289,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_POLYGON_OFFSET_UNITS_UNSCALED: case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: return 4; diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 4e0ebc376de..91484aaa717 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -369,6 +369,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_PCI_DEVICE: case PIPE_CAP_PCI_FUNCTION: case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: return 64; diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index 5334453a18c..2a640b1c87d 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -240,6 +240,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS: case PIPE_CAP_TGSI_ARRAY_COMPONENTS: case PIPE_CAP_TGSI_CAN_READ_OUTPUTS: + case PIPE_CAP_NATIVE_FENCE_FD: return 0; /* Stream output. */ diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c index 87c4ce26bf2..8c062ba10b7 100644 --- a/src/gallium/drivers/virgl/virgl_screen.c +++ b/src/gallium/drivers/virgl/virgl_screen.c @@ -261,6 +261,8 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_UMA: case PIPE_CAP_VIDEO_MEMORY: return 0; + case PIPE_CAP_NATIVE_FENCE_FD: + return 0; } /* should only get here on unhandled cases */ debug_printf("Unexpected PIPE_CAP %d query\n", param); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index ee8a5113caa..171dc570ba0 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -474,6 +474,19 @@ struct pipe_context { struct pipe_fence_handle **fence, unsigned flags); + /** + * Create a fence from a native sync fd. + * + * This is used for importing a foreign/external fence fd. + * + * \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); + /** * Insert commands to have GPU wait for fence to be signaled. */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 46e9039a9ec..f1dd7935a78 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -350,6 +350,7 @@ enum pipe_flush_flags { PIPE_FLUSH_END_OF_FRAME = (1 << 0), PIPE_FLUSH_DEFERRED = (1 << 1), + PIPE_FLUSH_FENCE_FD = (1 << 2), }; /** @@ -741,6 +742,7 @@ enum pipe_cap PIPE_CAP_TGSI_ARRAY_COMPONENTS, PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS, PIPE_CAP_TGSI_CAN_READ_OUTPUTS, + 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 255647ed273..f04c2ed83ab 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -264,6 +264,16 @@ struct pipe_screen { struct pipe_fence_handle *fence, uint64_t timeout); + /** + * For fences created with PIPE_FLUSH_FENCE_FD (exported fd) or + * by create_fence_fd() (imported fd), return the native fence fd + * associated with the fence. This may return -1 for fences + * created with PIPE_FLUSH_DEFERRED if the fence command has not + * been flushed yet. + */ + int (*fence_get_fd)(struct pipe_screen *screen, + struct pipe_fence_handle *fence); + /** * Returns a driver-specific query. * diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c index 1a44bcb771e..77523e98ffe 100644 --- a/src/gallium/state_trackers/dri/dri2.c +++ b/src/gallium/state_trackers/dri/dri2.c @@ -1457,6 +1457,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) { @@ -1477,6 +1489,39 @@ dri2_create_fence(__DRIcontext *_ctx) 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) { @@ -1556,13 +1601,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.30.2