anv: refactor queue chain

Simplify the buffer chaining process with a single loop and
a helper function from Lionel Landwerlin's input.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Signed-off-by: Jianxun Zhang <jianxun.zhang@linux.intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14578>
This commit is contained in:
Jianxun Zhang 2022-01-13 12:29:33 -08:00 committed by Marge Bot
parent be11948a95
commit e1376b59ef

View file

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