From 17796a3a9db4d7e463c228229f349991f140b4f7 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 30 Sep 2020 10:53:15 -0700 Subject: [PATCH] virgl: add fencing interface to virgl_context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Being an interface of virgl_context, this provides per-context fencing. This is motivated by Vulkan, where each context (i.e., VkInstance) is independent from one another. Fences submitted to difference contexts do not signal in the order they are submitted. It is in theory and in practice also true for OpenGL when SW/HW scheduling or context priority is considered. Besides being per-context, fences in Vulkan are also per-VkDevice and per-VkQueue within a context. This interface uses an opaque uint64_t to identify the queue a fence is submitted to, similar to how an opaque uint64_t is used to identify a blob. Signed-off-by: Chia-I Wu Acked-by: Gert Wollny Reviewed-by: Louis-Francis Ratté-Boulianne --- src/virgl_context.h | 31 +++++++++++++++++++++++++++++++ src/virglrenderer.c | 1 + src/vrend_decode.c | 4 ++++ 3 files changed, 36 insertions(+) diff --git a/src/virgl_context.h b/src/virgl_context.h index f009504..ea86b31 100644 --- a/src/virgl_context.h +++ b/src/virgl_context.h @@ -48,6 +48,12 @@ struct virgl_context_blob { void *renderer_data; }; +struct virgl_context; + +typedef void (*virgl_context_fence_retire)(struct virgl_context *ctx, + uint64_t queue_id, + void *fence_cookie); + /** * Base class for renderer contexts. For example, vrend_decode_ctx is a * subclass of virgl_context. @@ -57,6 +63,16 @@ struct virgl_context { enum virgl_renderer_capset capset_id; + /* + * Each fence goes through submitted, signaled, and retired. This callback + * is called from virgl_context::retire_fences to retire signaled fences of + * each queue. When a queue has multiple signaled fences by the time + * virgl_context::retire_fences is called, this callback might not be called + * on all fences but only on the latest one, depending on the flags of the + * fences. + */ + virgl_context_fence_retire fence_retire; + void (*destroy)(struct virgl_context *ctx); void (*attach_resource)(struct virgl_context *ctx, @@ -89,6 +105,21 @@ struct virgl_context { int (*submit_cmd)(struct virgl_context *ctx, const void *buffer, size_t size); + + /* + * Return an fd that is readable whenever there is any signaled fence in + * any queue, or -1 if not supported. + */ + int (*get_fencing_fd)(struct virgl_context *ctx); + + /* retire signaled fences of all queues */ + void (*retire_fences)(struct virgl_context *ctx); + + /* submit a fence to the queue identified by queue_id */ + int (*submit_fence)(struct virgl_context *ctx, + uint32_t flags, + uint64_t queue_id, + void *fence_cookie); }; struct virgl_context_foreach_args { diff --git a/src/virglrenderer.c b/src/virglrenderer.c index e496bef..4462918 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -204,6 +204,7 @@ int virgl_renderer_context_create_with_flags(uint32_t ctx_id, ctx->ctx_id = ctx_id; ctx->capset_id = capset_id; + ctx->fence_retire = NULL; ret = virgl_context_add(ctx); if (ret) { diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 61cb01a..557ad02 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -1683,4 +1683,8 @@ static void vrend_decode_ctx_init_base(struct vrend_decode_ctx *dctx, ctx->get_blob = vrend_decode_ctx_get_blob; ctx->get_blob_done = NULL; ctx->submit_cmd = vrend_decode_ctx_submit_cmd; + + ctx->get_fencing_fd = NULL; + ctx->retire_fences = NULL; + ctx->submit_fence = NULL; }