From d554f72c41e367d8f9b5f441c45853efd35a162b Mon Sep 17 00:00:00 2001 From: Sinclair Yeh Date: Mon, 15 May 2017 17:10:38 -0700 Subject: [PATCH] winsys/svga/drm: Connect winsys-side fence_* functions Connect fence_get_fd, fence_create_fd, and fence_server_sync. Implement the required functions in vmw_fence module. Reviewed-by: Brian Paul Reviewed-by: Charmaine Lee --- src/gallium/winsys/svga/drm/vmw_fence.c | 78 +++++++++++++++++-- src/gallium/winsys/svga/drm/vmw_fence.h | 6 +- .../winsys/svga/drm/vmw_screen_ioctl.c | 2 +- src/gallium/winsys/svga/drm/vmw_screen_svga.c | 33 ++++++++ 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/src/gallium/winsys/svga/drm/vmw_fence.c b/src/gallium/winsys/svga/drm/vmw_fence.c index 5b1ba69930b..061f588c864 100644 --- a/src/gallium/winsys/svga/drm/vmw_fence.c +++ b/src/gallium/winsys/svga/drm/vmw_fence.c @@ -22,6 +22,8 @@ * SOFTWARE. * **********************************************************/ +#include + #include "util/u_memory.h" #include "util/u_atomic.h" #include "util/list.h" @@ -32,7 +34,7 @@ #include "vmw_screen.h" #include "vmw_fence.h" -struct vmw_fence_ops +struct vmw_fence_ops { /* * Immutable members. @@ -58,6 +60,8 @@ struct vmw_fence uint32_t mask; int32_t signalled; uint32_t seqno; + int32_t fence_fd; + boolean imported; /* TRUE if imported from another process */ }; /** @@ -175,15 +179,16 @@ vmw_fence(struct pipe_fence_handle *fence) * @fence_ops: The fence_ops manager to register with. * @handle: Handle identifying the kernel fence object. * @mask: Mask of flags that this fence object may signal. + * @fd: File descriptor to associate with the fence * * Returns NULL on failure. */ struct pipe_fence_handle * vmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle, - uint32_t seqno, uint32_t mask) + uint32_t seqno, uint32_t mask, int32_t fd) { struct vmw_fence *fence = CALLOC_STRUCT(vmw_fence); - struct vmw_fence_ops *ops = vmw_fence_ops(fence_ops); + struct vmw_fence_ops *ops = NULL; if (!fence) return NULL; @@ -192,7 +197,20 @@ vmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle, fence->handle = handle; fence->mask = mask; fence->seqno = seqno; + fence->fence_fd = fd; p_atomic_set(&fence->signalled, 0); + + /* + * If the fence was not created by our device, then we won't + * manage it with our ops + */ + if (!fence_ops) { + fence->imported = true; + return (struct pipe_fence_handle *) fence; + } + + ops = vmw_fence_ops(fence_ops); + mtx_lock(&ops->mutex); if (vmw_fence_seq_is_signaled(seqno, ops->last_signaled, seqno)) { @@ -209,6 +227,21 @@ vmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle, } +/** + * vmw_fence_destroy - Frees a vmw fence object. + * + * Also closes the file handle associated with the object, if any + */ +static +void vmw_fence_destroy(struct vmw_fence *vfence) +{ + if (vfence->fence_fd != -1) + close(vfence->fence_fd); + + FREE(vfence); +} + + /** * vmw_fence_reference - Reference / unreference a vmw fence object. * @@ -227,13 +260,15 @@ vmw_fence_reference(struct vmw_winsys_screen *vws, if (p_atomic_dec_zero(&vfence->refcount)) { struct vmw_fence_ops *ops = vmw_fence_ops(vws->fence_ops); - vmw_ioctl_fence_unref(vws, vfence->handle); + if (!vfence->imported) { + vmw_ioctl_fence_unref(vws, vfence->handle); - mtx_lock(&ops->mutex); - LIST_DELINIT(&vfence->ops_list); - mtx_unlock(&ops->mutex); + mtx_lock(&ops->mutex); + LIST_DELINIT(&vfence->ops_list); + mtx_unlock(&ops->mutex); + } - FREE(vfence); + vmw_fence_destroy(vfence); } } @@ -321,6 +356,16 @@ vmw_fence_finish(struct vmw_winsys_screen *vws, return 0; vfence = vmw_fence(fence); + + if (vfence->imported) { + ret = sync_wait(vfence->fence_fd, timeout / 1000000); + + if (!ret) + p_atomic_set(&vfence->signalled, 1); + + return !!ret; + } + old = p_atomic_read(&vfence->signalled); vflags &= ~vfence->mask; @@ -341,6 +386,23 @@ vmw_fence_finish(struct vmw_winsys_screen *vws, return ret; } +/** + * vmw_fence_get_fd + * + * Returns the file descriptor associated with the fence + */ +int +vmw_fence_get_fd(struct pipe_fence_handle *fence) +{ + struct vmw_fence *vfence; + + if (!fence) + return -1; + + vfence = vmw_fence(fence); + return vfence->fence_fd; +} + /** * vmw_fence_ops_fence_reference - wrapper for the pb_fence_ops api. diff --git a/src/gallium/winsys/svga/drm/vmw_fence.h b/src/gallium/winsys/svga/drm/vmw_fence.h index 31e1350c316..aab558f6b3d 100644 --- a/src/gallium/winsys/svga/drm/vmw_fence.h +++ b/src/gallium/winsys/svga/drm/vmw_fence.h @@ -38,13 +38,17 @@ struct vmw_winsys_screen; struct pipe_fence_handle * vmw_fence_create(struct pb_fence_ops *fence_ops, - uint32_t handle, uint32_t seqno, uint32_t mask); + uint32_t handle, uint32_t seqno, uint32_t mask, int32_t fd); int vmw_fence_finish(struct vmw_winsys_screen *vws, struct pipe_fence_handle *fence, uint64_t timeout, unsigned flag); + +int +vmw_fence_get_fd(struct pipe_fence_handle *fence); + int vmw_fence_signalled(struct vmw_winsys_screen *vws, struct pipe_fence_handle *fence, diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c index 1740d1ab062..aad5ff98105 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c @@ -475,7 +475,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid, TRUE); *pfence = vmw_fence_create(vws->fence_ops, rep.handle, - rep.seqno, rep.mask); + rep.seqno, rep.mask, -1); if (*pfence == NULL) { /* * Fence creation failed. Need to sync. diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c index 46335378e0a..7c80642b377 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c @@ -32,6 +32,7 @@ * @author Jose Fonseca */ +#include #include "svga_cmd.h" #include "svga3d_caps.h" @@ -132,6 +133,35 @@ vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws, } +static int +vmw_svga_winsys_fence_get_fd(struct svga_winsys_screen *sws, + struct pipe_fence_handle *fence, + boolean duplicate) +{ + if (duplicate) + return dup(vmw_fence_get_fd(fence)); + else + return vmw_fence_get_fd(fence); +} + + +static void +vmw_svga_winsys_fence_create_fd(struct svga_winsys_screen *sws, + struct pipe_fence_handle **fence, + int32_t fd) +{ + *fence = vmw_fence_create(NULL, 0, 0, 0, dup(fd)); +} + +static int +vmw_svga_winsys_fence_server_sync(struct svga_winsys_screen *sws, + int32_t *context_fd, + struct pipe_fence_handle *fence) +{ + return sync_accumulate("vmwgfx", context_fd, + sws->fence_get_fd(sws, fence, FALSE)); +} + static struct svga_winsys_surface * vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws, @@ -435,6 +465,9 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws) vws->base.shader_create = vmw_svga_winsys_shader_create; vws->base.shader_destroy = vmw_svga_winsys_shader_destroy; vws->base.fence_finish = vmw_svga_winsys_fence_finish; + vws->base.fence_get_fd = vmw_svga_winsys_fence_get_fd; + vws->base.fence_create_fd = vmw_svga_winsys_fence_create_fd; + vws->base.fence_server_sync = vmw_svga_winsys_fence_server_sync; vws->base.query_create = vmw_svga_winsys_query_create; vws->base.query_init = vmw_svga_winsys_query_init; -- 2.30.2