diff --git a/src/intel/vulkan/anv_batch_chain.c b/src/intel/vulkan/anv_batch_chain.c index d4793d2be65..1880e63e72e 100644 --- a/src/intel/vulkan/anv_batch_chain.c +++ b/src/intel/vulkan/anv_batch_chain.c @@ -425,6 +425,22 @@ anv_cmd_buffer_current_generation_batch_bo(struct anv_cmd_buffer *cmd_buffer) struct anv_address anv_cmd_buffer_surface_base_address(struct anv_cmd_buffer *cmd_buffer) { + /* Compute only queues don't need binding tables. */ + if (!(cmd_buffer->queue_family->queueFlags & VK_QUEUE_GRAPHICS_BIT)) + return ANV_NULL_ADDRESS; + + /* If we've never allocated a binding table block, do it now. Otherwise we + * would trigger another STATE_BASE_ADDRESS emission which would require an + * additional bunch of flushes/stalls. + */ + if (u_vector_length(&cmd_buffer->bt_block_states) == 0) { + VkResult result = anv_cmd_buffer_new_binding_table_block(cmd_buffer); + if (result != VK_SUCCESS) { + anv_batch_set_error(&cmd_buffer->batch, result); + return ANV_NULL_ADDRESS; + } + } + struct anv_state_pool *pool = &cmd_buffer->device->binding_table_pool; struct anv_state *bt_block = u_vector_head(&cmd_buffer->bt_block_states); return (struct anv_address) { @@ -670,6 +686,9 @@ struct anv_state anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer, uint32_t entries, uint32_t *state_offset) { + if (u_vector_length(&cmd_buffer->bt_block_states) == 0) + return (struct anv_state) { 0 }; + struct anv_state *bt_block = u_vector_head(&cmd_buffer->bt_block_states); uint32_t bt_size = align(entries * 4, 32); @@ -841,10 +860,6 @@ anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer) if (result != VK_SUCCESS) goto fail_bt_blocks; - result = anv_cmd_buffer_new_binding_table_block(cmd_buffer); - if (result != VK_SUCCESS) - goto fail_bt_blocks; - return VK_SUCCESS; fail_bt_blocks: @@ -899,13 +914,11 @@ anv_cmd_buffer_reset_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer) &cmd_buffer->batch, GFX8_MI_BATCH_BUFFER_START_length * 4); - while (u_vector_length(&cmd_buffer->bt_block_states) > 1) { + while (u_vector_length(&cmd_buffer->bt_block_states) > 0) { struct anv_state *bt_block = u_vector_remove(&cmd_buffer->bt_block_states); anv_binding_table_pool_free(cmd_buffer->device, *bt_block); } - assert(u_vector_length(&cmd_buffer->bt_block_states) == 1); - cmd_buffer->bt_next = *(struct anv_state *)u_vector_head(&cmd_buffer->bt_block_states); - cmd_buffer->bt_next.offset = 0; + cmd_buffer->bt_next = ANV_STATE_NULL; anv_reloc_list_clear(&cmd_buffer->surface_relocs);