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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38049>
This commit is contained in:
Yiwei Zhang 2025-10-23 19:57:18 -07:00 committed by Marge Bot
parent 30b41c2b57
commit 2c08e6d8bb
4 changed files with 29 additions and 5 deletions

View file

@ -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

View file

@ -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");

View file

@ -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

View file

@ -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;