From 27a37712279c6287615c24f3ea462a92d85b9bb8 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Wed, 3 Apr 2024 16:40:23 +0300 Subject: [PATCH] anv: pull surface state copies for secondary in one loop It'll be easier for the next commit. Signed-off-by: Lionel Landwerlin Tested-by: Mark Janes Part-of: --- src/intel/vulkan/genX_cmd_buffer.c | 70 ++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index c9bf73f0271..bdd1a144c0c 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -3196,6 +3196,57 @@ genX(CmdExecuteCommands)( UNUSED enum anv_cmd_descriptor_buffer_mode db_mode = container->state.current_db_mode; + + /* Do a first pass to copy the surface state content of the render targets + * if needed. + */ + bool need_surface_state_copy = false; + for (uint32_t i = 0; i < commandBufferCount; i++) { + ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]); + + if (secondary->usage_flags & + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { + need_surface_state_copy = true; + break; + } + } + + if (need_surface_state_copy) { + /* The memcpy will take care of the 3D preemption requirements. */ + struct anv_memcpy_state memcpy_state; + genX(emit_so_memcpy_init)(&memcpy_state, device, &container->batch); + + for (uint32_t i = 0; i < commandBufferCount; i++) { + ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]); + + assert(secondary->vk.level == VK_COMMAND_BUFFER_LEVEL_SECONDARY); + assert(!anv_batch_has_error(&secondary->batch)); + + if (secondary->usage_flags & + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { + /* If we're continuing a render pass from the container, we need + * to copy the surface states for the current subpass into the + * storage we allocated for them in BeginCommandBuffer. + */ + struct anv_state src_state = container->state.gfx.att_states; + struct anv_state dst_state = secondary->state.gfx.att_states; + assert(src_state.alloc_size == dst_state.alloc_size); + + genX(emit_so_memcpy)( + &memcpy_state, + anv_state_pool_state_address(&device->internal_surface_state_pool, + dst_state), + anv_state_pool_state_address(&device->internal_surface_state_pool, + src_state), + src_state.alloc_size); + } + } + genX(emit_so_memcpy_fini)(&memcpy_state); + } + + /* Ensure preemption is enabled (assumption for all secondary) */ + genX(cmd_buffer_set_preemption)(container, true); + for (uint32_t i = 0; i < commandBufferCount; i++) { ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]); @@ -3215,25 +3266,6 @@ genX(CmdExecuteCommands)( } } - if (secondary->usage_flags & - VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { - /* If we're continuing a render pass from the container, we need to - * copy the surface states for the current subpass into the storage - * we allocated for them in BeginCommandBuffer. - */ - struct anv_state src_state = container->state.gfx.att_states; - struct anv_state dst_state = secondary->state.gfx.att_states; - assert(src_state.alloc_size == dst_state.alloc_size); - - genX(cmd_buffer_so_memcpy)( - container, - anv_state_pool_state_address(&device->internal_surface_state_pool, - dst_state), - anv_state_pool_state_address(&device->internal_surface_state_pool, - src_state), - src_state.alloc_size); - } - anv_cmd_buffer_add_secondary(container, secondary); /* Add secondary buffer's RCS command buffer to container buffer's RCS