From 2314c9ed2e39bcf4ac6b206344acb05fec876a41 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 17 Oct 2016 09:28:46 -0700 Subject: [PATCH] anv/cmd_buffer: Move Begin/End/Execute to genX_cmd_buffer.c vkBeginCommandBuffer and vkCmdExecuteCommands both call into the gen-specific emit_state_base_address function and vkEndCommandBuffer belongs with begin. Signed-off-by: Jason Ekstrand Reviewed-by: Anuj Phogat --- src/intel/vulkan/anv_cmd_buffer.c | 94 +---------------------------- src/intel/vulkan/anv_dump.c | 11 +++- src/intel/vulkan/anv_private.h | 2 + src/intel/vulkan/genX_cmd_buffer.c | 95 ++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 95 deletions(-) diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index b55a07057d2..3c2d032aa92 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -327,7 +327,7 @@ void anv_FreeCommandBuffers( } } -static VkResult +VkResult anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer) { cmd_buffer->usage_flags = 0; @@ -371,71 +371,6 @@ anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer) } } -VkResult anv_BeginCommandBuffer( - VkCommandBuffer commandBuffer, - const VkCommandBufferBeginInfo* pBeginInfo) -{ - ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - - /* If this is the first vkBeginCommandBuffer, we must *initialize* the - * command buffer's state. Otherwise, we must *reset* its state. In both - * cases we reset it. - * - * From the Vulkan 1.0 spec: - * - * If a command buffer is in the executable state and the command buffer - * was allocated from a command pool with the - * VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, then - * vkBeginCommandBuffer implicitly resets the command buffer, behaving - * as if vkResetCommandBuffer had been called with - * VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT not set. It then puts - * the command buffer in the recording state. - */ - anv_cmd_buffer_reset(cmd_buffer); - - cmd_buffer->usage_flags = pBeginInfo->flags; - - assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY || - !(cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)); - - anv_cmd_buffer_emit_state_base_address(cmd_buffer); - - if (cmd_buffer->usage_flags & - VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { - cmd_buffer->state.framebuffer = - anv_framebuffer_from_handle(pBeginInfo->pInheritanceInfo->framebuffer); - cmd_buffer->state.pass = - anv_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass); - cmd_buffer->state.subpass = - &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass]; - - cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS; - } - - return VK_SUCCESS; -} - -VkResult anv_EndCommandBuffer( - VkCommandBuffer commandBuffer) -{ - ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); - struct anv_device *device = cmd_buffer->device; - - anv_cmd_buffer_end_batch_buffer(cmd_buffer); - - if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) { - /* The algorithm used to compute the validate list is not threadsafe as - * it uses the bo->index field. We have to lock the device around it. - * Fortunately, the chances for contention here are probably very low. - */ - pthread_mutex_lock(&device->mutex); - anv_cmd_buffer_prepare_execbuf(cmd_buffer); - pthread_mutex_unlock(&device->mutex); - } - - return VK_SUCCESS; -} - void anv_CmdBindPipeline( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, @@ -1164,33 +1099,6 @@ void anv_CmdPushConstants( cmd_buffer->state.push_constants_dirty |= stageFlags; } -void anv_CmdExecuteCommands( - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCmdBuffers) -{ - ANV_FROM_HANDLE(anv_cmd_buffer, primary, commandBuffer); - - assert(primary->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY); - - for (uint32_t i = 0; i < commandBufferCount; i++) { - ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]); - - assert(secondary->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY); - - anv_cmd_buffer_add_secondary(primary, secondary); - } - - /* Each of the secondary command buffers will use its own state base - * address. We need to re-emit state base address for the primary after - * all of the secondaries are done. - * - * TODO: Maybe we want to make this a dirty bit to avoid extra state base - * address calls? - */ - anv_cmd_buffer_emit_state_base_address(primary); -} - VkResult anv_CreateCommandPool( VkDevice _device, const VkCommandPoolCreateInfo* pCreateInfo, diff --git a/src/intel/vulkan/anv_dump.c b/src/intel/vulkan/anv_dump.c index 0a359a0015f..0608904219e 100644 --- a/src/intel/vulkan/anv_dump.c +++ b/src/intel/vulkan/anv_dump.c @@ -251,6 +251,13 @@ anv_dump_image_to_ppm(struct anv_device *device, VkDevice vk_device = anv_device_to_handle(device); MAYBE_UNUSED VkResult result; + PFN_vkBeginCommandBuffer BeginCommandBuffer = + (void *)anv_GetDeviceProcAddr(anv_device_to_handle(device), + "vkBeginCommandBuffer"); + PFN_vkEndCommandBuffer EndCommandBuffer = + (void *)anv_GetDeviceProcAddr(anv_device_to_handle(device), + "vkEndCommandBuffer"); + const uint32_t width = anv_minify(image->extent.width, miplevel); const uint32_t height = anv_minify(image->extent.height, miplevel); @@ -276,7 +283,7 @@ anv_dump_image_to_ppm(struct anv_device *device, }, &cmd); assert(result == VK_SUCCESS); - result = anv_BeginCommandBuffer(cmd, + result = BeginCommandBuffer(cmd, &(VkCommandBufferBeginInfo) { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, @@ -286,7 +293,7 @@ anv_dump_image_to_ppm(struct anv_device *device, dump_image_do_blit(device, &dump, anv_cmd_buffer_from_handle(cmd), image, aspect, miplevel, array_layer); - result = anv_EndCommandBuffer(cmd); + result = EndCommandBuffer(cmd); assert(result == VK_SUCCESS); VkFence fence; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index c9d102d4e1a..9454e08bda7 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1284,6 +1284,8 @@ void anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary, struct anv_cmd_buffer *secondary); void anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer); +VkResult anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer); + VkResult anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, unsigned stage, struct anv_state *bt_state); VkResult anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer, diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 02f84056654..d61b9719e62 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -150,6 +150,101 @@ genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer) } } +VkResult +genX(BeginCommandBuffer)( + VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo* pBeginInfo) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + + /* If this is the first vkBeginCommandBuffer, we must *initialize* the + * command buffer's state. Otherwise, we must *reset* its state. In both + * cases we reset it. + * + * From the Vulkan 1.0 spec: + * + * If a command buffer is in the executable state and the command buffer + * was allocated from a command pool with the + * VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, then + * vkBeginCommandBuffer implicitly resets the command buffer, behaving + * as if vkResetCommandBuffer had been called with + * VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT not set. It then puts + * the command buffer in the recording state. + */ + anv_cmd_buffer_reset(cmd_buffer); + + cmd_buffer->usage_flags = pBeginInfo->flags; + + assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY || + !(cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)); + + genX(cmd_buffer_emit_state_base_address)(cmd_buffer); + + if (cmd_buffer->usage_flags & + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { + cmd_buffer->state.framebuffer = + anv_framebuffer_from_handle(pBeginInfo->pInheritanceInfo->framebuffer); + cmd_buffer->state.pass = + anv_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass); + cmd_buffer->state.subpass = + &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass]; + + cmd_buffer->state.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS; + } + + return VK_SUCCESS; +} + +VkResult +genX(EndCommandBuffer)( + VkCommandBuffer commandBuffer) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); + struct anv_device *device = cmd_buffer->device; + + anv_cmd_buffer_end_batch_buffer(cmd_buffer); + + if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) { + /* The algorithm used to compute the validate list is not threadsafe as + * it uses the bo->index field. We have to lock the device around it. + * Fortunately, the chances for contention here are probably very low. + */ + pthread_mutex_lock(&device->mutex); + anv_cmd_buffer_prepare_execbuf(cmd_buffer); + pthread_mutex_unlock(&device->mutex); + } + + return VK_SUCCESS; +} + +void +genX(CmdExecuteCommands)( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer* pCmdBuffers) +{ + ANV_FROM_HANDLE(anv_cmd_buffer, primary, commandBuffer); + + assert(primary->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY); + + for (uint32_t i = 0; i < commandBufferCount; i++) { + ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]); + + assert(secondary->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY); + + anv_cmd_buffer_add_secondary(primary, secondary); + } + + /* Each of the secondary command buffers will use its own state base + * address. We need to re-emit state base address for the primary after + * all of the secondaries are done. + * + * TODO: Maybe we want to make this a dirty bit to avoid extra state base + * address calls? + */ + genX(cmd_buffer_emit_state_base_address)(primary); +} + #define IVB_L3SQCREG1_SQGHPCI_DEFAULT 0x00730000 #define VLV_L3SQCREG1_SQGHPCI_DEFAULT 0x00d30000 #define HSW_L3SQCREG1_SQGHPCI_DEFAULT 0x00610000 -- 2.30.2