Skip to content

Commit fb9bad3

Browse files
zzyiweiMichael Tokarev
authored andcommitted
virtio-gpu: support context init multiple timeline
Venus and later native contexts have their own fence context along with multiple timelines within. Fences wtih VIRTIO_GPU_FLAG_INFO_RING_IDX in the flags must be dispatched to be created on the target context. Fence signaling also has to be handled on the specific timeline within that target context. Before this change, venus fencing is completely broken if the host driver doesn't support implicit fencing with external memory objects. Frames can go backwards along with random artifacts on screen if the host driver doesn't attach an implicit fence to the render target. The symptom could be hidden by certain guest wsi backend that waits on a venus native VkFence object for the actual payload with limited present modes or under special configs. e.g. x11 mailbox or xwayland. After this change, everything related to venus fencing starts making sense. Confirmed this via guest and host side perfetto tracing. Cc: [email protected] Fixes: 94d0ea1 ("virtio-gpu: Support Venus context") Signed-off-by: Yiwei Zhang <[email protected]> Reviewed-by: Dmitry Osipenko <[email protected]> Message-Id: <[email protected]> [AJB: remove version history from commit message] Tested-by: Dmitry Osipenko <[email protected]> Signed-off-by: Alex Bennée <[email protected]> Reviewed-by: Akihiko Odaki <[email protected]> Message-ID: <[email protected]> (cherry picked from commit 1fa2ffdbec55d84326e22f046bc3e26322836f5a) Signed-off-by: Michael Tokarev <[email protected]>
1 parent 5df7910 commit fb9bad3

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

hw/display/virtio-gpu-virgl.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,15 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
970970
}
971971

972972
trace_virtio_gpu_fence_ctrl(cmd->cmd_hdr.fence_id, cmd->cmd_hdr.type);
973+
#if VIRGL_VERSION_MAJOR >= 1
974+
if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX) {
975+
virgl_renderer_context_create_fence(cmd->cmd_hdr.ctx_id,
976+
VIRGL_RENDERER_FENCE_FLAG_MERGEABLE,
977+
cmd->cmd_hdr.ring_idx,
978+
cmd->cmd_hdr.fence_id);
979+
return;
980+
}
981+
#endif
973982
virgl_renderer_create_fence(cmd->cmd_hdr.fence_id, cmd->cmd_hdr.type);
974983
}
975984

@@ -983,6 +992,11 @@ static void virgl_write_fence(void *opaque, uint32_t fence)
983992
* the guest can end up emitting fences out of order
984993
* so we should check all fenced cmds not just the first one.
985994
*/
995+
#if VIRGL_VERSION_MAJOR >= 1
996+
if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX) {
997+
continue;
998+
}
999+
#endif
9861000
if (cmd->cmd_hdr.fence_id > fence) {
9871001
continue;
9881002
}
@@ -997,6 +1011,29 @@ static void virgl_write_fence(void *opaque, uint32_t fence)
9971011
}
9981012
}
9991013

1014+
#if VIRGL_VERSION_MAJOR >= 1
1015+
static void virgl_write_context_fence(void *opaque, uint32_t ctx_id,
1016+
uint32_t ring_idx, uint64_t fence_id) {
1017+
VirtIOGPU *g = opaque;
1018+
struct virtio_gpu_ctrl_command *cmd, *tmp;
1019+
1020+
QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) {
1021+
if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_INFO_RING_IDX &&
1022+
cmd->cmd_hdr.ctx_id == ctx_id && cmd->cmd_hdr.ring_idx == ring_idx &&
1023+
cmd->cmd_hdr.fence_id <= fence_id) {
1024+
trace_virtio_gpu_fence_resp(cmd->cmd_hdr.fence_id);
1025+
virtio_gpu_ctrl_response_nodata(g, cmd, VIRTIO_GPU_RESP_OK_NODATA);
1026+
QTAILQ_REMOVE(&g->fenceq, cmd, next);
1027+
g_free(cmd);
1028+
g->inflight--;
1029+
if (virtio_gpu_stats_enabled(g->parent_obj.conf)) {
1030+
trace_virtio_gpu_dec_inflight_fences(g->inflight);
1031+
}
1032+
}
1033+
}
1034+
}
1035+
#endif
1036+
10001037
static virgl_renderer_gl_context
10011038
virgl_create_context(void *opaque, int scanout_idx,
10021039
struct virgl_renderer_gl_ctx_param *params)
@@ -1031,11 +1068,18 @@ static int virgl_make_context_current(void *opaque, int scanout_idx,
10311068
}
10321069

10331070
static struct virgl_renderer_callbacks virtio_gpu_3d_cbs = {
1071+
#if VIRGL_VERSION_MAJOR >= 1
1072+
.version = 3,
1073+
#else
10341074
.version = 1,
1075+
#endif
10351076
.write_fence = virgl_write_fence,
10361077
.create_gl_context = virgl_create_context,
10371078
.destroy_gl_context = virgl_destroy_context,
10381079
.make_current = virgl_make_context_current,
1080+
#if VIRGL_VERSION_MAJOR >= 1
1081+
.write_context_fence = virgl_write_context_fence,
1082+
#endif
10391083
};
10401084

10411085
static void virtio_gpu_print_stats(void *opaque)

0 commit comments

Comments
 (0)