From: Jonathan Marek Date: Thu, 12 Dec 2019 22:06:14 +0000 (-0500) Subject: turnip: implement secondary command buffers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e9a32af3bfb359d6ba484d01d6875ed4dfbc94ee;p=mesa.git turnip: implement secondary command buffers Uses a new "tu_cs_add_entries" function because tu_cs_emit_call doesn't work inside draw_cs (which is already called by tu_cs_emit_call). Signed-off-by: Jonathan Marek Reviewed-by: Eric Anholt Tested-by: Marge Bot Part-of: --- diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 34c3ea8a436..73045783891 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -1876,6 +1876,11 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer, default: break; } + } else if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY && + (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) { + assert(pBeginInfo->pInheritanceInfo); + cmd_buffer->state.pass = tu_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass); + cmd_buffer->state.subpass = &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass]; } cmd_buffer->status = TU_CMD_BUFFER_STATUS_RECORDING; @@ -2203,6 +2208,27 @@ tu_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCmdBuffers) { + TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); + VkResult result; + + assert(commandBufferCount > 0); + + for (uint32_t i = 0; i < commandBufferCount; i++) { + TU_FROM_HANDLE(tu_cmd_buffer, secondary, pCmdBuffers[i]); + + result = tu_bo_list_merge(&cmd->bo_list, &secondary->bo_list); + if (result != VK_SUCCESS) { + cmd->record_result = result; + break; + } + + result = tu_cs_add_entries(&cmd->draw_cs, &secondary->draw_cs); + if (result != VK_SUCCESS) { + cmd->record_result = result; + break; + } + } + cmd->state.dirty = ~0u; /* TODO: set dirty only what needs to be */ } VkResult @@ -2565,6 +2591,9 @@ write_tex_const(struct tu_cmd_buffer *cmd, dst[5] = A6XX_TEX_CONST_5_DEPTH(1); for (unsigned i = 6; i < A6XX_TEX_CONST_DWORDS; i++) dst[i] = 0; + + if (cmd->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) + tu_finishme("patch input attachment pitch for secondary cmd buffer"); } } diff --git a/src/freedreno/vulkan/tu_cs.c b/src/freedreno/vulkan/tu_cs.c index 22c0527db88..18c942ec3ab 100644 --- a/src/freedreno/vulkan/tu_cs.c +++ b/src/freedreno/vulkan/tu_cs.c @@ -159,7 +159,7 @@ tu_cs_add_bo(struct tu_device *dev, struct tu_cs *cs, uint32_t size) * Reserve an IB entry. */ static VkResult -tu_cs_reserve_entry(struct tu_device *dev, struct tu_cs *cs) +tu_cs_reserve_entry(struct tu_cs *cs) { /* entries are only for TU_CS_MODE_GROW */ assert(cs->mode == TU_CS_MODE_GROW); @@ -209,6 +209,34 @@ tu_cs_add_entry(struct tu_cs *cs) cs->start = cs->cur; } +/** + * same behavior as tu_cs_emit_call but without the indirect + */ +VkResult +tu_cs_add_entries(struct tu_cs *cs, struct tu_cs *target) +{ + VkResult result; + + assert(cs->mode == TU_CS_MODE_GROW); + assert(target->mode == TU_CS_MODE_GROW); + + if (!tu_cs_is_empty(cs)) { + tu_cs_add_entry(cs); + result = tu_cs_reserve_entry(cs); + if (result != VK_SUCCESS) + return result; + } + + for (unsigned i = 0; i < target->entry_count; i++) { + cs->entries[cs->entry_count++] = target->entries[i]; + result = tu_cs_reserve_entry(cs); + if (result != VK_SUCCESS) + return result; + } + + return VK_SUCCESS; +} + /** * Begin (or continue) command packet emission. This does nothing but sanity * checks currently. \a cs must not be in TU_CS_MODE_SUB_STREAM mode. @@ -367,7 +395,7 @@ tu_cs_reserve_space(struct tu_device *dev, if (cs->mode == TU_CS_MODE_GROW) { /* reserve an entry for the next call to this function or tu_cs_end */ - return tu_cs_reserve_entry(dev, cs); + return tu_cs_reserve_entry(cs); } return VK_SUCCESS; diff --git a/src/freedreno/vulkan/tu_cs.h b/src/freedreno/vulkan/tu_cs.h index 19fe984b431..e5c47d005be 100644 --- a/src/freedreno/vulkan/tu_cs.h +++ b/src/freedreno/vulkan/tu_cs.h @@ -66,6 +66,9 @@ tu_cs_reserve_space(struct tu_device *dev, void tu_cs_reset(struct tu_device *dev, struct tu_cs *cs); +VkResult +tu_cs_add_entries(struct tu_cs *cs, struct tu_cs *target); + /** * Discard all entries. This allows \a cs to be reused while keeping the * existing BOs and command packets intact.