virgl: hide fence internals from the driver
authorChia-I Wu <olvaffe@gmail.com>
Tue, 9 Apr 2019 18:18:43 +0000 (18:18 +0000)
committerGurchetan Singh <gurchetansingh@chromium.org>
Mon, 15 Apr 2019 23:25:47 +0000 (23:25 +0000)
Fence fds are cheaper than resources.  We want to let winsys make the
decision and use fence fds whenever they are supported.  This commit
prepares the work.

For the moment, we create a resource _and_ a fence fd when
supports_fences is true.  This will be fixed such that we create a
resource _or_ a fence fd.  (And because of a version check bug that we
will fix later, supports_fences is actually never true).

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
src/gallium/drivers/virgl/virgl_context.c
src/gallium/drivers/virgl/virgl_winsys.h
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c

index f9591e214b5f935f9ea36580ef946d38b3860f15..5e608e47fd03d08cf0622918b1ca18772d58e0f3 100644 (file)
@@ -750,7 +750,6 @@ static void virgl_flush_eq(struct virgl_context *ctx, void *closure,
                           struct pipe_fence_handle **fence)
 {
    struct virgl_screen *rs = virgl_screen(ctx->base.screen);
-   int out_fence_fd = -1;
 
    if (ctx->num_draws)
       u_upload_unmap(ctx->uploader);
@@ -759,11 +758,7 @@ static void virgl_flush_eq(struct virgl_context *ctx, void *closure,
    ctx->num_transfers = ctx->num_draws = ctx->num_compute = 0;
 
    virgl_transfer_queue_clear(&ctx->queue, ctx->cbuf);
-   rs->vws->submit_cmd(rs->vws, ctx->cbuf,
-                       ctx->cbuf->needs_out_fence_fd ? &out_fence_fd : NULL);
-
-   if (fence)
-      *fence = rs->vws->cs_create_fence(rs->vws, out_fence_fd);
+   rs->vws->submit_cmd(rs->vws, ctx->cbuf, fence);
 
    /* Reserve some space for transfers. */
    if (ctx->encoded_transfers)
@@ -781,12 +776,7 @@ static void virgl_flush_from_st(struct pipe_context *ctx,
 {
    struct virgl_context *vctx = virgl_context(ctx);
 
-   if (flags & PIPE_FLUSH_FENCE_FD)
-       vctx->cbuf->needs_out_fence_fd = true;
-
    virgl_flush_eq(vctx, vctx, fence);
-
-   vctx->cbuf->needs_out_fence_fd = false;
 }
 
 static struct pipe_sampler_view *virgl_create_sampler_view(struct pipe_context *ctx,
index d37454513cd9d5630afcc2765ea8de9659a3b1cf..9256bf97b03053a5153fe2cd038c8b0e6d66d00f 100644 (file)
@@ -41,7 +41,6 @@ struct virgl_drm_caps {
 struct virgl_cmd_buf {
    unsigned cdw;
    uint32_t *buf;
-   bool needs_out_fence_fd;
 };
 
 struct virgl_winsys {
@@ -88,7 +87,7 @@ struct virgl_winsys {
 
    void (*emit_res)(struct virgl_winsys *vws, struct virgl_cmd_buf *buf, struct virgl_hw_res *res, boolean write_buffer);
    int (*submit_cmd)(struct virgl_winsys *vws, struct virgl_cmd_buf *buf,
-                     int32_t *out_fence_fd);
+                     struct pipe_fence_handle **fence);
 
    boolean (*res_is_referenced)(struct virgl_winsys *vws,
                                 struct virgl_cmd_buf *buf,
index 1c5ec714e255e4eae5bb15744f28bd4929bf5358..2cd4bf70429ed87943d029f134505435781f960b 100644 (file)
@@ -709,9 +709,24 @@ static void virgl_drm_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf)
 
 }
 
+static struct pipe_fence_handle *
+virgl_drm_fence_create(struct virgl_winsys *vws, int fd)
+{
+   struct virgl_hw_res *res;
+
+   res = virgl_drm_winsys_resource_cache_create(vws,
+                                                PIPE_BUFFER,
+                                                PIPE_FORMAT_R8_UNORM,
+                                                VIRGL_BIND_CUSTOM,
+                                                8, 1, 1, 0, 0, 0, 8);
+
+   res->fence_fd = fd;
+   return (struct pipe_fence_handle *)res;
+}
+
 static int virgl_drm_winsys_submit_cmd(struct virgl_winsys *qws,
                                        struct virgl_cmd_buf *_cbuf,
-                                       int *out_fence_fd)
+                                       struct pipe_fence_handle **fence)
 {
    struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
    struct virgl_drm_cmd_buf *cbuf = virgl_drm_cmd_buf(_cbuf);
@@ -734,11 +749,10 @@ static int virgl_drm_winsys_submit_cmd(struct virgl_winsys *qws,
          eb.fence_fd = cbuf->in_fence_fd;
       }
 
-      if (out_fence_fd != NULL)
+      if (fence != NULL)
          eb.flags |= VIRTGPU_EXECBUF_FENCE_FD_OUT;
    } else {
       assert(cbuf->in_fence_fd < 0);
-      assert(out_fence_fd == NULL);
    }
 
    ret = drmIoctl(qdws->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &eb);
@@ -751,10 +765,13 @@ static int virgl_drm_winsys_submit_cmd(struct virgl_winsys *qws,
          close(cbuf->in_fence_fd);
          cbuf->in_fence_fd = -1;
       }
-   }
 
-   if (out_fence_fd != NULL)
-      *out_fence_fd = eb.fence_fd;
+      if (fence != NULL && ret == 0)
+         *fence = virgl_drm_fence_create(qws, eb.fence_fd);
+   } else {
+      if (fence != NULL && ret == 0)
+         *fence = virgl_drm_fence_create(qws, -1);
+   }
 
    virgl_drm_release_all_res(qdws, cbuf);
 
@@ -809,16 +826,7 @@ static int handle_compare(void *key1, void *key2)
 static struct pipe_fence_handle *
 virgl_cs_create_fence(struct virgl_winsys *vws, int fd)
 {
-   struct virgl_hw_res *res;
-
-   res = virgl_drm_winsys_resource_cache_create(vws,
-                                                PIPE_BUFFER,
-                                                PIPE_FORMAT_R8_UNORM,
-                                                VIRGL_BIND_CUSTOM,
-                                                8, 1, 1, 0, 0, 0, 8);
-
-   res->fence_fd = fd;
-   return (struct pipe_fence_handle *)res;
+   return virgl_drm_fence_create(vws, fd);
 }
 
 static bool virgl_fence_wait(struct virgl_winsys *vws,
index 2ea0187fec9b94de12af9ea0c14919c5630cea30..e3a38e00ec5c5a46278ce70815e51c40da30b6f7 100644 (file)
@@ -486,9 +486,23 @@ static void virgl_vtest_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf)
    FREE(cbuf);
 }
 
+static struct pipe_fence_handle *
+virgl_vtest_fence_create(struct virgl_winsys *vws)
+{
+   struct virgl_hw_res *res;
+
+   res = virgl_vtest_winsys_resource_cache_create(vws,
+                                                PIPE_BUFFER,
+                                                PIPE_FORMAT_R8_UNORM,
+                                                VIRGL_BIND_CUSTOM,
+                                                8, 1, 1, 0, 0, 0, 8);
+
+   return (struct pipe_fence_handle *)res;
+}
+
 static int virgl_vtest_winsys_submit_cmd(struct virgl_winsys *vws,
                                          struct virgl_cmd_buf *_cbuf,
-                                         int *out_fence_fd)
+                                         struct pipe_fence_handle **fence)
 {
    struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws);
    struct virgl_vtest_cmd_buf *cbuf = virgl_vtest_cmd_buf(_cbuf);
@@ -497,9 +511,9 @@ static int virgl_vtest_winsys_submit_cmd(struct virgl_winsys *vws,
    if (cbuf->base.cdw == 0)
       return 0;
 
-   assert(out_fence_fd == NULL);
-
    ret = virgl_vtest_submit_cmd(vtws, cbuf);
+   if (fence && ret == 0)
+      *fence = virgl_vtest_fence_create(vws);
 
    virgl_vtest_release_all_res(vtws, cbuf);
    memset(cbuf->is_handle_added, 0, sizeof(cbuf->is_handle_added));
@@ -543,15 +557,7 @@ static int virgl_vtest_get_caps(struct virgl_winsys *vws,
 static struct pipe_fence_handle *
 virgl_cs_create_fence(struct virgl_winsys *vws, int fd)
 {
-   struct virgl_hw_res *res;
-
-   res = virgl_vtest_winsys_resource_cache_create(vws,
-                                                PIPE_BUFFER,
-                                                PIPE_FORMAT_R8_UNORM,
-                                                VIRGL_BIND_CUSTOM,
-                                                8, 1, 1, 0, 0, 0, 8);
-
-   return (struct pipe_fence_handle *)res;
+   return virgl_vtest_fence_create(vws);
 }
 
 static bool virgl_fence_wait(struct virgl_winsys *vws,