turnip: implement secondary command buffers
authorJonathan Marek <jonathan@marek.ca>
Thu, 12 Dec 2019 22:06:14 +0000 (17:06 -0500)
committerMarge Bot <eric+marge@anholt.net>
Thu, 19 Dec 2019 20:42:08 +0000 (20:42 +0000)
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 <jonathan@marek.ca>
Reviewed-by: Eric Anholt <eric@anholt.net>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3075>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3075>

src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_cs.c
src/freedreno/vulkan/tu_cs.h

index 34c3ea8a436bf673e99d0a2891b363321b5ac9a2..73045783891ea3ebb17ed710f83ebe49590f3ccf 100644 (file)
@@ -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");
    }
 }
 
index 22c0527db880fcca0eea906c64aa99729f2d573f..18c942ec3ab2ce5006960443381ecaf5e4b3beee 100644 (file)
@@ -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;
index 19fe984b4312783e4db49edae5b6aac334a197a3..e5c47d005bead3e102e8cc61bc1528aedd273ece 100644 (file)
@@ -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.