From 2c08e6d8bb7a753b3a455357541f4f6ed1cf18d5 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Thu, 23 Oct 2025 19:57:18 -0700 Subject: [PATCH] venus: allow fence feedback to suspend and resume Previously, we either have to filter out incompatible queue or disable fence feedback. Now we track whether the queue can do feedback, and will mark the fence feedback not pollable if the fence is submitted on an incompatible queue. Part-of: --- .gitlab-ci/android-skips.txt | 1 - src/virtio/vulkan/vn_device.c | 4 ++++ src/virtio/vulkan/vn_queue.c | 18 ++++++++++++++---- src/virtio/vulkan/vn_queue.h | 11 +++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci/android-skips.txt b/.gitlab-ci/android-skips.txt index 03f0f6fedd5..af000d24732 100644 --- a/.gitlab-ci/android-skips.txt +++ b/.gitlab-ci/android-skips.txt @@ -10,4 +10,3 @@ dEQP-VK.wsi.* # Skip for now. The test is creating video queues without enabling video # extensions. To be clarified at spec level. dEQP-VK.synchronization* -dEQP-VK.sparse_resources.queue_bind.multi_queue_wait_one_signal_one_other diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c index a5ffe2bc4bb..103f246b489 100644 --- a/src/virtio/vulkan/vn_device.c +++ b/src/virtio/vulkan/vn_device.c @@ -57,10 +57,14 @@ vn_queue_init(struct vn_device *dev, assert(queue_index > 0); queue->emulated = true; queue->base.id = shared_queue->base.id; + queue->can_feedback = shared_queue->can_feedback; queue->ring_idx = shared_queue->ring_idx; return VK_SUCCESS; } + queue->can_feedback = vn_queue_family_can_feedback( + dev->physical_device, queue_info->queueFamilyIndex); + const int ring_idx = vn_instance_acquire_ring_idx(dev->instance); if (ring_idx < 0) { vn_log(dev->instance, "failed binding VkQueue to renderer timeline"); diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c index b231fbfa457..ee3eb0c8ac4 100644 --- a/src/virtio/vulkan/vn_queue.c +++ b/src/virtio/vulkan/vn_queue.c @@ -498,8 +498,12 @@ vn_queue_submission_prepare(struct vn_queue_submission *submit) struct vn_fence *fence = vn_fence_from_handle(submit->fence_handle); assert(!fence || !fence->is_external || !fence->feedback.slot); - if (fence && fence->feedback.slot) - submit->feedback_types |= VN_FEEDBACK_TYPE_FENCE; + if (fence && fence->feedback.slot) { + if (queue->can_feedback) + submit->feedback_types |= VN_FEEDBACK_TYPE_FENCE; + else + fence->feedback.pollable = false; + } if (submit->batch_type != VK_STRUCTURE_TYPE_BIND_SPARSE_INFO) submit->has_zink_sync_batch = vn_has_zink_sync_batch(submit); @@ -743,6 +747,7 @@ vn_queue_submission_add_fence_feedback(struct vn_queue_submission *submit, for (uint32_t i = 0; i < dev->queue_family_count; i++) { if (dev->queue_families[i] == queue_vk->queue_family_index) { ffb_cmd_handle = fence->feedback.commands[i]; + break; } } assert(ffb_cmd_handle != VK_NULL_HANDLE); @@ -1560,6 +1565,7 @@ vn_fence_feedback_init(struct vn_device *dev, fence->feedback.slot = slot; fence->feedback.commands = cmd_handles; + fence->feedback.pollable = true; return VK_SUCCESS; } @@ -1674,8 +1680,10 @@ vn_ResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) assert(perm->type == VN_SYNC_TYPE_DEVICE_ONLY); fence->payload = perm; - if (fence->feedback.slot) + if (fence->feedback.slot) { vn_feedback_reset_status(fence->feedback.slot); + fence->feedback.pollable = true; + } } return VK_SUCCESS; @@ -1691,7 +1699,9 @@ vn_GetFenceStatus(VkDevice device, VkFence _fence) VkResult result; switch (payload->type) { case VN_SYNC_TYPE_DEVICE_ONLY: - if (fence->feedback.slot) { + if (fence->feedback.pollable) { + assert(fence->feedback.slot); + result = vn_feedback_get_status(fence->feedback.slot); if (result == VK_SUCCESS) { /* When fence feedback slot gets signaled, the real fence diff --git a/src/virtio/vulkan/vn_queue.h b/src/virtio/vulkan/vn_queue.h index 71f35e27528..7191306b441 100644 --- a/src/virtio/vulkan/vn_queue.h +++ b/src/virtio/vulkan/vn_queue.h @@ -19,6 +19,9 @@ struct vn_queue { /* emulated queue shares base queue id and ring_idx with another queue */ bool emulated; + /* whether this queue supports venus feedback */ + bool can_feedback; + /* only used if renderer supports multiple timelines */ uint32_t ring_idx; @@ -80,6 +83,14 @@ struct vn_fence { /* non-NULL if VN_PERF_NO_FENCE_FEEDBACK is disabled */ struct vn_feedback_slot *slot; VkCommandBuffer *commands; + + /* Indicate whether the fence status in the feedback slot is pollable. + * When pollable is false, the fence feedback has been suspended and the + * slot won't be signaled to VK_SUCCESS. + * - suspend: submit on queues not supporting feedback + * - resume: vn_ResetFences will reset pollable to true + */ + bool pollable; } feedback; bool is_external;