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;