virgl: handle fence_server_sync in winsys
authorChia-I Wu <olvaffe@gmail.com>
Tue, 9 Apr 2019 17:55:40 +0000 (17:55 +0000)
committerGurchetan Singh <gurchetansingh@chromium.org>
Mon, 15 Apr 2019 23:25:47 +0000 (23:25 +0000)
It does not need help from the driver.  This also fixes one issue where
the fence is ignored when the transfer queue is full.

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_transfer_queue.c
src/gallium/drivers/virgl/virgl_winsys.h
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
src/gallium/winsys/virgl/drm/virgl_drm_winsys.h
src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c

index 6f54655..f9591e2 100644 (file)
@@ -759,7 +759,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->in_fence_fd,
+   rs->vws->submit_cmd(rs->vws, ctx->cbuf,
                        ctx->cbuf->needs_out_fence_fd ? &out_fence_fd : NULL);
 
    if (fence)
@@ -786,10 +786,6 @@ static void virgl_flush_from_st(struct pipe_context *ctx,
 
    virgl_flush_eq(vctx, vctx, fence);
 
-   if (vctx->cbuf->in_fence_fd != -1) {
-      close(vctx->cbuf->in_fence_fd);
-      vctx->cbuf->in_fence_fd = -1;
-   }
    vctx->cbuf->needs_out_fence_fd = false;
 }
 
index 25267d4..6551d6a 100644 (file)
@@ -206,7 +206,7 @@ static void add_internal(struct virgl_transfer_queue *queue,
          iter.data = queue->tbuf;
          perform_action(queue, &iter);
 
-         vws->submit_cmd(vws, queue->tbuf, -1, NULL);
+         vws->submit_cmd(vws, queue->tbuf, NULL);
          queue->num_dwords = 0;
       }
    }
index e7f1532..d374545 100644 (file)
@@ -41,7 +41,6 @@ struct virgl_drm_caps {
 struct virgl_cmd_buf {
    unsigned cdw;
    uint32_t *buf;
-   int in_fence_fd;
    bool needs_out_fence_fd;
 };
 
@@ -89,7 +88,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 in_fence_fd, int32_t *out_fence_fd);
+                     int32_t *out_fence_fd);
 
    boolean (*res_is_referenced)(struct virgl_winsys *vws,
                                 struct virgl_cmd_buf *buf,
index 2cf8b4b..1c5ec71 100644 (file)
@@ -692,8 +692,8 @@ static struct virgl_cmd_buf *virgl_drm_cmd_buf_create(struct virgl_winsys *qws,
       return NULL;
    }
 
+   cbuf->in_fence_fd = -1;
    cbuf->base.buf = cbuf->buf;
-   cbuf->base.in_fence_fd = -1;
    return &cbuf->base;
 }
 
@@ -711,7 +711,7 @@ static void virgl_drm_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf)
 
 static int virgl_drm_winsys_submit_cmd(struct virgl_winsys *qws,
                                        struct virgl_cmd_buf *_cbuf,
-                                       int in_fence_fd, int *out_fence_fd)
+                                       int *out_fence_fd)
 {
    struct virgl_drm_winsys *qdws = virgl_drm_winsys(qws);
    struct virgl_drm_cmd_buf *cbuf = virgl_drm_cmd_buf(_cbuf);
@@ -726,21 +726,33 @@ static int virgl_drm_winsys_submit_cmd(struct virgl_winsys *qws,
    eb.size = cbuf->base.cdw * 4;
    eb.num_bo_handles = cbuf->cres;
    eb.bo_handles = (unsigned long)(void *)cbuf->res_hlist;
+
    eb.fence_fd = -1;
+   if (qws->supports_fences) {
+      if (cbuf->in_fence_fd >= 0) {
+         eb.flags |= VIRTGPU_EXECBUF_FENCE_FD_IN;
+         eb.fence_fd = cbuf->in_fence_fd;
+      }
 
-   if (in_fence_fd != -1) {
-       eb.flags |= VIRTGPU_EXECBUF_FENCE_FD_IN;
-       eb.fence_fd = in_fence_fd;
+      if (out_fence_fd != NULL)
+         eb.flags |= VIRTGPU_EXECBUF_FENCE_FD_OUT;
+   } else {
+      assert(cbuf->in_fence_fd < 0);
+      assert(out_fence_fd == NULL);
    }
 
-   if (out_fence_fd != NULL)
-       eb.flags |= VIRTGPU_EXECBUF_FENCE_FD_OUT;
-
    ret = drmIoctl(qdws->fd, DRM_IOCTL_VIRTGPU_EXECBUFFER, &eb);
    if (ret == -1)
       fprintf(stderr,"got error from kernel - expect bad rendering %d\n", errno);
    cbuf->base.cdw = 0;
 
+   if (qws->supports_fences) {
+      if (cbuf->in_fence_fd >= 0) {
+         close(cbuf->in_fence_fd);
+         cbuf->in_fence_fd = -1;
+      }
+   }
+
    if (out_fence_fd != NULL)
       *out_fence_fd = eb.fence_fd;
 
@@ -849,9 +861,10 @@ static void virgl_fence_reference(struct virgl_winsys *vws,
 }
 
 static void virgl_fence_server_sync(struct virgl_winsys *vws,
-                                   struct virgl_cmd_buf *cbuf,
+                                   struct virgl_cmd_buf *_cbuf,
                                     struct pipe_fence_handle *fence)
 {
+   struct virgl_drm_cmd_buf *cbuf = virgl_drm_cmd_buf(_cbuf);
    struct virgl_hw_res *hw_res = virgl_hw_res(fence);
 
    /* if not an external fence, then nothing more to do without preemption: */
index 51fad9c..1fbbde2 100644 (file)
@@ -73,6 +73,8 @@ struct virgl_drm_cmd_buf {
 
    uint32_t *buf;
 
+   int in_fence_fd;
+
    unsigned nres;
    unsigned cres;
    struct virgl_hw_res **res_bo;
index 3ca15e6..2ea0187 100644 (file)
@@ -474,7 +474,6 @@ static struct virgl_cmd_buf *virgl_vtest_cmd_buf_create(struct virgl_winsys *vws
    }
    cbuf->ws = vws;
    cbuf->base.buf = cbuf->buf;
-   cbuf->base.in_fence_fd = -1;
    return &cbuf->base;
 }
 
@@ -489,7 +488,7 @@ static void virgl_vtest_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf)
 
 static int virgl_vtest_winsys_submit_cmd(struct virgl_winsys *vws,
                                          struct virgl_cmd_buf *_cbuf,
-                                         int in_fence_fd, int *out_fence_fd)
+                                         int *out_fence_fd)
 {
    struct virgl_vtest_winsys *vtws = virgl_vtest_winsys(vws);
    struct virgl_vtest_cmd_buf *cbuf = virgl_vtest_cmd_buf(_cbuf);
@@ -498,7 +497,6 @@ static int virgl_vtest_winsys_submit_cmd(struct virgl_winsys *vws,
    if (cbuf->base.cdw == 0)
       return 0;
 
-   assert(in_fence_fd == -1);
    assert(out_fence_fd == NULL);
 
    ret = virgl_vtest_submit_cmd(vtws, cbuf);