From a23c091988f30fd432b5e1a68aedc95c307efa34 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 9 Apr 2019 17:55:40 +0000 Subject: [PATCH] virgl: handle fence_server_sync in winsys 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 Reviewed-by: Emil Velikov --- src/gallium/drivers/virgl/virgl_context.c | 6 +---- src/gallium/drivers/virgl/virgl_transfer_queue.c | 2 +- src/gallium/drivers/virgl/virgl_winsys.h | 3 +-- src/gallium/winsys/virgl/drm/virgl_drm_winsys.c | 31 +++++++++++++++------- src/gallium/winsys/virgl/drm/virgl_drm_winsys.h | 2 ++ .../winsys/virgl/vtest/virgl_vtest_winsys.c | 4 +-- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 6f54655..f9591e2 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -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; } diff --git a/src/gallium/drivers/virgl/virgl_transfer_queue.c b/src/gallium/drivers/virgl/virgl_transfer_queue.c index 25267d4..6551d6a 100644 --- a/src/gallium/drivers/virgl/virgl_transfer_queue.c +++ b/src/gallium/drivers/virgl/virgl_transfer_queue.c @@ -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; } } diff --git a/src/gallium/drivers/virgl/virgl_winsys.h b/src/gallium/drivers/virgl/virgl_winsys.h index e7f1532..d374545 100644 --- a/src/gallium/drivers/virgl/virgl_winsys.h +++ b/src/gallium/drivers/virgl/virgl_winsys.h @@ -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, diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c index 2cf8b4b..1c5ec71 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c @@ -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: */ diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h index 51fad9c..1fbbde2 100644 --- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h +++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.h @@ -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; diff --git a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c index 3ca15e6..2ea0187 100644 --- a/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c +++ b/src/gallium/winsys/virgl/vtest/virgl_vtest_winsys.c @@ -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); -- 2.7.4