diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index 15677320c4d..a32eb3bd9ec 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -2264,6 +2264,12 @@ anv_queue_exec_locked(struct anv_queue *queue, return result; } +static inline bool +can_chain_query_pools(struct anv_query_pool *p1, struct anv_query_pool *p2) +{ + return (!p1 || !p2 || p1 == p2); +} + static VkResult anv_queue_submit_locked(struct anv_queue *queue, struct vk_queue_submit *submit) @@ -2280,55 +2286,49 @@ anv_queue_submit_locked(struct anv_queue *queue, if (result != VK_SUCCESS) return result; } else { - struct anv_query_pool *perf_query_pool = NULL; - uint32_t start = 0; - /* Everything's easier if we don't have to bother with container_of() */ STATIC_ASSERT(offsetof(struct anv_cmd_buffer, vk) == 0); struct vk_command_buffer **vk_cmd_buffers = submit->command_buffers; struct anv_cmd_buffer **cmd_buffers = (void *)vk_cmd_buffers; - - const uint32_t end = submit->command_buffer_count; - while (start < end) { - uint32_t i = start + 1; - - /* Save the first query pool or NULL */ - perf_query_pool = cmd_buffers[start]->perf_query_pool; - - for (; i < end; i++) { - /* Can we chain the last buffer into the next one? */ - if (!anv_cmd_buffer_is_chainable(cmd_buffers[i])) - break; - - if (cmd_buffers[i]->perf_query_pool != NULL) { - if (perf_query_pool != NULL) { - /* They have to have the same query pool */ - if (cmd_buffers[i]->perf_query_pool != perf_query_pool) - break; - } else { - perf_query_pool = cmd_buffers[i]->perf_query_pool; - } + uint32_t start = 0; + uint32_t end = submit->command_buffer_count; + struct anv_query_pool *perf_query_pool = + cmd_buffers[start]->perf_query_pool; + for (uint32_t n = 0; n < end; n++) { + bool can_chain = false; + uint32_t next = n + 1; + /* Can we chain the last buffer into the next one? */ + if (next < end && + anv_cmd_buffer_is_chainable(cmd_buffers[next]) && + can_chain_query_pools + (cmd_buffers[next]->perf_query_pool, perf_query_pool)) { + can_chain = true; + perf_query_pool = + perf_query_pool ? perf_query_pool : + cmd_buffers[next]->perf_query_pool; + } + if (!can_chain) { + /* The next buffer cannot be chained, or we have reached the + * last buffer, submit what have been chained so far. + */ + VkResult result = + anv_queue_exec_locked(queue, + start == 0 ? submit->wait_count : 0, + start == 0 ? submit->waits : NULL, + next - start, &cmd_buffers[start], + next == end ? submit->signal_count : 0, + next == end ? submit->signals : NULL, + perf_query_pool, + submit->perf_pass_index); + if (result != VK_SUCCESS) + return result; + if (next < end) { + start = next; + perf_query_pool = cmd_buffers[start]->perf_query_pool; } } - - VkResult result = - anv_queue_exec_locked(queue, - start == 0 ? submit->wait_count : 0, - start == 0 ? submit->waits : NULL, - i - start, &cmd_buffers[start], - i == end ? submit->signal_count : 0, - i == end ? submit->signals : NULL, - perf_query_pool, - submit->perf_pass_index); - if (result != VK_SUCCESS) - return result; - - perf_query_pool = NULL; - start = i; } - assert(start == end); } - for (uint32_t i = 0; i < submit->signal_count; i++) { if (!vk_sync_is_anv_bo_sync(submit->signals[i].sync)) continue;