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 <brianp@vmware.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
This commit is contained in:
Sinclair Yeh 2017-05-16 08:19:41 -07:00 committed by Brian Paul
parent d554f72c41
commit ed45e8db3c
3 changed files with 53 additions and 19 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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__);