winsys/svga/drm: Enable import/export fence FD
authorSinclair Yeh <syeh@vmware.com>
Tue, 16 May 2017 15:19:41 +0000 (08:19 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 17 Jul 2017 16:09:25 +0000 (10:09 -0600)
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>
src/gallium/winsys/svga/drm/vmw_context.c
src/gallium/winsys/svga/drm/vmw_screen.h
src/gallium/winsys/svga/drm/vmw_screen_ioctl.c

index c306d988e0ce6a336ec5020d46662afc23a7d927..c0ee833e334924c1148cee2b0284b0764e92e474 100644 (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;
index 0ef8e8415e14e91f816b95c6cd8af0042c36d116..f21cabb51f93acfb98cf27bdd4e5dc2cdb63637e 100644 (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);
index aad5ff98105b26f8bf931ad465b63710f7a0f596..79f9d950d910d37ae10e8902fd20c1e803c9569c 100644 (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__);