From ed45e8db3c5001baac690b3129e31328805267cd Mon Sep 17 00:00:00 2001 From: Sinclair Yeh Date: Tue, 16 May 2017 08:19:41 -0700 Subject: [PATCH] winsys/svga/drm: Enable import/export fence FD Enable the capability if the DRM supports it. Hook up mechanism to send and receive fence FD from the DRM. Reviewed-by: Brian Paul Reviewed-by: Charmaine Lee --- src/gallium/winsys/svga/drm/vmw_context.c | 16 ++++++++-- src/gallium/winsys/svga/drm/vmw_screen.h | 12 ++++--- src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 44 +++++++++++++++++++------- 3 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c index c306d98..c0ee833 100644 --- a/src/gallium/winsys/svga/drm/vmw_context.c +++ b/src/gallium/winsys/svga/drm/vmw_context.c @@ -236,11 +236,13 @@ vmw_swc_flush(struct svga_winsys_context *swc, if (vswc->command.used || pfence != NULL) vmw_ioctl_command(vws, - vswc->base.cid, - 0, + vswc->base.cid, + 0, vswc->command.buffer, vswc->command.used, - &fence); + &fence, + vswc->base.imported_fence_fd, + vswc->base.hints); pb_validate_fence(vswc->validate, fence); mtx_lock(&vws->cs_mutex); @@ -280,11 +282,17 @@ vmw_swc_flush(struct svga_winsys_context *swc, debug_flush_flush(vswc->fctx); #endif swc->hints &= ~SVGA_HINT_FLAG_CAN_PRE_FLUSH; + swc->hints &= ~SVGA_HINT_FLAG_EXPORT_FENCE_FD; vswc->preemptive_flush = FALSE; vswc->seen_surfaces = 0; vswc->seen_regions = 0; vswc->seen_mobs = 0; + if (vswc->base.imported_fence_fd != -1) { + close(vswc->base.imported_fence_fd); + vswc->base.imported_fence_fd = -1; + } + if(pfence) vmw_fence_reference(vswc->vws, pfence, fence); @@ -823,6 +831,8 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws) if (vswc->base.cid == -1) goto out_no_context; + vswc->base.imported_fence_fd = -1; + vswc->base.have_gb_objects = sws->have_gb_objects; vswc->vws = vws; diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h index 0ef8e84..f21cabb 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen.h +++ b/src/gallium/winsys/svga/drm/vmw_screen.h @@ -162,11 +162,13 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, void vmw_ioctl_command(struct vmw_winsys_screen *vws, - int32_t cid, - uint32_t throttle_us, - void *commands, - uint32_t size, - struct pipe_fence_handle **fence); + int32_t cid, + uint32_t throttle_us, + void *commands, + uint32_t size, + struct pipe_fence_handle **fence, + int32_t imported_fence_fd, + uint32_t flags); struct vmw_region * vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size); diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c index aad5ff9..79f9d95 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c @@ -408,8 +408,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid) void vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid, - uint32_t throttle_us, void *commands, uint32_t size, - struct pipe_fence_handle **pfence) + uint32_t throttle_us, void *commands, uint32_t size, + struct pipe_fence_handle **pfence, int32_t imported_fence_fd, + uint32_t flags) { struct drm_vmw_execbuf_arg arg; struct drm_vmw_fence_rep rep; @@ -439,6 +440,14 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid, memset(&arg, 0, sizeof(arg)); memset(&rep, 0, sizeof(rep)); + if (flags & SVGA_HINT_FLAG_EXPORT_FENCE_FD) { + arg.flags |= DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD; + } + + if (imported_fence_fd != -1) { + arg.flags |= DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD; + } + rep.error = -EFAULT; if (pfence) arg.fence_rep = (unsigned long)&rep; @@ -448,6 +457,10 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid, arg.version = vws->ioctl.drm_execbuf_version; arg.context_handle = (vws->base.have_vgpu10 ? cid : SVGA3D_INVALID_ID); + /* Older DRM module requires this to be zero */ + if (vws->base.have_fence_fd) + arg.imported_fence_fd = imported_fence_fd; + /* In DRM_VMW_EXECBUF_VERSION 1, the drm_vmw_execbuf_arg structure ends with * the flags field. The structure size sent to drmCommandWrite must match * the drm_execbuf_version. Otherwise, an invalid value will be returned. @@ -474,15 +487,20 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid, vmw_fences_signal(vws->fence_ops, rep.passed_seqno, rep.seqno, TRUE); - *pfence = vmw_fence_create(vws->fence_ops, rep.handle, - rep.seqno, rep.mask, -1); - if (*pfence == NULL) { - /* - * Fence creation failed. Need to sync. - */ - (void) vmw_ioctl_fence_finish(vws, rep.handle, rep.mask); - vmw_ioctl_fence_unref(vws, rep.handle); - } + /* Older DRM module will set this to zero, but -1 is the proper FD + * to use for no Fence FD support */ + if (!vws->base.have_fence_fd) + rep.fd = -1; + + *pfence = vmw_fence_create(vws->fence_ops, rep.handle, + rep.seqno, rep.mask, rep.fd); + if (*pfence == NULL) { + /* + * Fence creation failed. Need to sync. + */ + (void) vmw_ioctl_fence_finish(vws, rep.handle, rep.mask); + vmw_ioctl_fence_unref(vws, rep.handle); + } } } } @@ -1033,6 +1051,10 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws) vws->base.have_set_predication_cmd = TRUE; } + if (version->version_major == 2 && version->version_minor >= 14) { + vws->base.have_fence_fd = TRUE; + } + free(cap_buffer); drmFreeVersion(version); vmw_printf("%s OK\n", __FUNCTION__); -- 2.7.4