venus: skip feedback cmd record on incompatible queue families

Feedback requires transfer capability, so we must skip feedback cmd
pool initialization on incompatible queue families. Meanwhile, use
pool_handle for all validity check needed.
- fence and semaphore feedback: skip feedback cmd alloc and record when
  pool_handle is VK_NULL_HANDLE
- event feedback: not affected as we patch in-place upon recording
- query feedback: assert the feedback cmd alloc is on supported queue

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38016>
This commit is contained in:
Yiwei Zhang
2025-10-22 13:26:43 -07:00
committed by Marge Bot
parent 457d8926e1
commit 2e32dd7472
2 changed files with 34 additions and 1 deletions

View File

@@ -7,5 +7,7 @@ dEQP-VK.api.external.memory.android_hardware_buffer.*
dEQP-VK.image.swapchain_mutable.* dEQP-VK.image.swapchain_mutable.*
dEQP-VK.wsi.* dEQP-VK.wsi.*
# These tests cause hangs and need to be skipped for now. # Skip for now. The test is creating video queues without enabling video
# extensions. To be clarified at spec level.
dEQP-VK.synchronization* dEQP-VK.synchronization*
dEQP-VK.sparse_resources.queue_bind.multi_queue_wait_one_signal_one_other

View File

@@ -690,6 +690,8 @@ vn_query_feedback_cmd_alloc(VkDevice dev_handle,
struct vn_query_feedback_cmd *qfb_cmd; struct vn_query_feedback_cmd *qfb_cmd;
VkResult result; VkResult result;
assert(fb_cmd_pool->pool_handle != VK_NULL_HANDLE);
simple_mtx_lock(&fb_cmd_pool->mutex); simple_mtx_lock(&fb_cmd_pool->mutex);
if (list_is_empty(&fb_cmd_pool->free_qfb_cmds)) { if (list_is_empty(&fb_cmd_pool->free_qfb_cmds)) {
@@ -754,6 +756,11 @@ vn_feedback_cmd_alloc(VkDevice dev_handle,
struct vn_feedback_slot *src_slot, struct vn_feedback_slot *src_slot,
VkCommandBuffer *out_cmd_handle) VkCommandBuffer *out_cmd_handle)
{ {
if (fb_cmd_pool->pool_handle == VK_NULL_HANDLE) {
*out_cmd_handle = VK_NULL_HANDLE;
return VK_SUCCESS;
}
VkCommandPool cmd_pool_handle = fb_cmd_pool->pool_handle; VkCommandPool cmd_pool_handle = fb_cmd_pool->pool_handle;
const VkCommandBufferAllocateInfo info = { const VkCommandBufferAllocateInfo info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
@@ -789,6 +796,9 @@ vn_feedback_cmd_free(VkDevice dev_handle,
struct vn_feedback_cmd_pool *fb_cmd_pool, struct vn_feedback_cmd_pool *fb_cmd_pool,
VkCommandBuffer cmd_handle) VkCommandBuffer cmd_handle)
{ {
if (fb_cmd_pool->pool_handle == VK_NULL_HANDLE)
return;
simple_mtx_lock(&fb_cmd_pool->mutex); simple_mtx_lock(&fb_cmd_pool->mutex);
vn_FreeCommandBuffers(dev_handle, fb_cmd_pool->pool_handle, 1, vn_FreeCommandBuffers(dev_handle, fb_cmd_pool->pool_handle, 1,
&cmd_handle); &cmd_handle);
@@ -800,6 +810,7 @@ vn_feedback_cmd_pools_init(struct vn_device *dev)
{ {
const VkAllocationCallbacks *alloc = &dev->base.vk.alloc; const VkAllocationCallbacks *alloc = &dev->base.vk.alloc;
VkDevice dev_handle = vn_device_to_handle(dev); VkDevice dev_handle = vn_device_to_handle(dev);
struct vn_physical_device *physical_dev = dev->physical_device;
struct vn_feedback_cmd_pool *fb_cmd_pools; struct vn_feedback_cmd_pool *fb_cmd_pools;
VkCommandPoolCreateInfo info = { VkCommandPoolCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
@@ -822,11 +833,28 @@ vn_feedback_cmd_pools_init(struct vn_device *dev)
for (uint32_t i = 0; i < dev->queue_family_count; i++) { for (uint32_t i = 0; i < dev->queue_family_count; i++) {
VkResult result; VkResult result;
/* Feedback requires transfer capability, so we must skip feedback cmd
* pool initialization on incompatible queue families. Meanwhile, use
* pool_handle for all validity check needed.
*/
assert(dev->queue_families[i] < physical_dev->queue_family_count);
const struct VkQueueFamilyProperties2 *props =
&physical_dev->queue_family_properties[dev->queue_families[i]];
const VkQueueFlags fb_req_flags =
VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
if (!(props->queueFamilyProperties.queueFlags & fb_req_flags)) {
fb_cmd_pools[i].pool_handle = VK_NULL_HANDLE;
continue;
}
info.queueFamilyIndex = dev->queue_families[i]; info.queueFamilyIndex = dev->queue_families[i];
result = vn_CreateCommandPool(dev_handle, &info, alloc, result = vn_CreateCommandPool(dev_handle, &info, alloc,
&fb_cmd_pools[i].pool_handle); &fb_cmd_pools[i].pool_handle);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
for (uint32_t j = 0; j < i; j++) { for (uint32_t j = 0; j < i; j++) {
if (fb_cmd_pools[j].pool_handle == VK_NULL_HANDLE)
continue;
vn_DestroyCommandPool(dev_handle, fb_cmd_pools[j].pool_handle, vn_DestroyCommandPool(dev_handle, fb_cmd_pools[j].pool_handle,
alloc); alloc);
simple_mtx_destroy(&fb_cmd_pools[j].mutex); simple_mtx_destroy(&fb_cmd_pools[j].mutex);
@@ -855,6 +883,9 @@ vn_feedback_cmd_pools_fini(struct vn_device *dev)
return; return;
for (uint32_t i = 0; i < dev->queue_family_count; i++) { for (uint32_t i = 0; i < dev->queue_family_count; i++) {
if (dev->fb_cmd_pools[i].pool_handle == VK_NULL_HANDLE)
continue;
list_for_each_entry_safe(struct vn_query_feedback_cmd, feedback_cmd, list_for_each_entry_safe(struct vn_query_feedback_cmd, feedback_cmd,
&dev->fb_cmd_pools[i].free_qfb_cmds, head) &dev->fb_cmd_pools[i].free_qfb_cmds, head)
vk_free(alloc, feedback_cmd); vk_free(alloc, feedback_cmd);