summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c16
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h12
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c44
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 c306d988e0c..c0ee833e334 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 0ef8e8415e1..f21cabb51f9 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 aad5ff98105..79f9d950d91 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__);