turnip: Move vertex buffer bindings to SET_DRAW_STATE.
authorEric Anholt <eric@anholt.net>
Thu, 4 Jun 2020 17:10:01 +0000 (10:10 -0700)
committerMarge Bot <eric+marge@anholt.net>
Thu, 4 Jun 2020 19:42:54 +0000 (19:42 +0000)
This means that the HW can skip over the vertex buffer state when it's not
used in a bin.  The blob also has this behavior.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5321>

src/freedreno/vulkan/tu_cmd_buffer.c

index b7eae22962e18699157d8219e34cc8c6dd3d857b..7c76a08b4ba5a92cddb9d004b13cad89477a9c08 100644 (file)
@@ -1743,6 +1743,10 @@ tu_BeginCommandBuffer(VkCommandBuffer commandBuffer,
    return VK_SUCCESS;
 }
 
+/* Sets vertex buffers to HW binding points.  We emit VBs in SDS (so that bin
+ * rendering can skip over unused state), so we need to collect all the
+ * bindings together into a single state emit at draw time.
+ */
 void
 tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
                         uint32_t firstBinding,
@@ -1755,12 +1759,14 @@ tu_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,
    assert(firstBinding + bindingCount <= MAX_VBS);
 
    for (uint32_t i = 0; i < bindingCount; i++) {
-      cmd->state.vb.buffers[firstBinding + i] =
-         tu_buffer_from_handle(pBuffers[i]);
+      struct tu_buffer *buf = tu_buffer_from_handle(pBuffers[i]);
+
+      cmd->state.vb.buffers[firstBinding + i] = buf;
       cmd->state.vb.offsets[firstBinding + i] = pOffsets[i];
+
+      tu_bo_list_add(&cmd->bo_list, buf->bo, MSM_SUBMIT_BO_READ);
    }
 
-   /* VB states depend on VkPipelineVertexInputStateCreateInfo */
    cmd->state.dirty |= TU_CMD_DIRTY_VERTEX_BUFFERS;
 }
 
@@ -2469,6 +2475,7 @@ enum tu_draw_state_group_id
 {
    TU_DRAW_STATE_PROGRAM,
    TU_DRAW_STATE_PROGRAM_BINNING,
+   TU_DRAW_STATE_VB,
    TU_DRAW_STATE_VI,
    TU_DRAW_STATE_VI_BINNING,
    TU_DRAW_STATE_VP,
@@ -2656,6 +2663,30 @@ tu6_emit_vs_params(struct tu_cmd_buffer *cmd,
    return VK_SUCCESS;
 }
 
+static struct tu_cs_entry
+tu6_emit_vertex_buffers(struct tu_cmd_buffer *cmd,
+                        const struct tu_pipeline *pipeline)
+{
+   struct tu_cs cs;
+   tu_cs_begin_sub_stream(&cmd->sub_cs, 4 * MAX_VBS, &cs);
+
+   for (uint32_t i = 0; i < pipeline->vi.count; i++) {
+      const uint32_t binding = pipeline->vi.bindings[i];
+      const struct tu_buffer *buf = cmd->state.vb.buffers[binding];
+      const VkDeviceSize offset = buf->bo_offset +
+         cmd->state.vb.offsets[binding];
+      const VkDeviceSize size =
+         offset < buf->size ? buf->size - offset : 0;
+
+      tu_cs_emit_regs(&cs,
+                      A6XX_VFD_FETCH_BASE(i, .bo = buf->bo, .bo_offset = offset),
+                      A6XX_VFD_FETCH_SIZE(i, size));
+
+   }
+
+   return tu_cs_end_sub_stream(&cmd->sub_cs, &cs);
+}
+
 static VkResult
 tu6_emit_descriptor_sets(struct tu_cmd_buffer *cmd,
                          const struct tu_pipeline *pipeline,
@@ -2909,22 +2940,6 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
       tu6_emit_scissor(cs, &cmd->state.dynamic.scissor.scissors[0]);
    }
 
-   if (cmd->state.dirty &
-       (TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_VERTEX_BUFFERS)) {
-      for (uint32_t i = 0; i < pipeline->vi.count; i++) {
-         const uint32_t binding = pipeline->vi.bindings[i];
-         const struct tu_buffer *buf = cmd->state.vb.buffers[binding];
-         const VkDeviceSize offset = buf->bo_offset +
-                                     cmd->state.vb.offsets[binding];
-         const VkDeviceSize size =
-            offset < buf->size ? buf->size - offset : 0;
-
-         tu_cs_emit_regs(cs,
-                         A6XX_VFD_FETCH_BASE(i, .bo = buf->bo, .bo_offset = offset),
-                         A6XX_VFD_FETCH_SIZE(i, size));
-      }
-   }
-
    if (cmd->state.dirty & TU_CMD_DIRTY_PIPELINE) {
       draw_state_groups[draw_state_group_count++] =
          (struct tu_draw_state_group) {
@@ -2998,6 +3013,16 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
          };
    }
 
+   if (cmd->state.dirty &
+       (TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_VERTEX_BUFFERS)) {
+      draw_state_groups[draw_state_group_count++] =
+         (struct tu_draw_state_group) {
+            .id = TU_DRAW_STATE_VB,
+            .enable_mask = ENABLE_ALL,
+            .ib = tu6_emit_vertex_buffers(cmd, pipeline)
+         };
+   }
+
    if (cmd->state.dirty & TU_CMD_DIRTY_STREAMOUT_BUFFERS)
       tu6_emit_streamout(cmd, cs);
 
@@ -3122,13 +3147,6 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
    tu_cs_sanity_check(cs);
 
    /* track BOs */
-   if (cmd->state.dirty & TU_CMD_DIRTY_VERTEX_BUFFERS) {
-      for (uint32_t i = 0; i < MAX_VBS; i++) {
-         const struct tu_buffer *buf = cmd->state.vb.buffers[i];
-         if (buf)
-            tu_bo_list_add(&cmd->bo_list, buf->bo, MSM_SUBMIT_BO_READ);
-      }
-   }
    if (cmd->state.dirty & TU_CMD_DIRTY_DESCRIPTOR_SETS) {
       unsigned i;
       for_each_bit(i, descriptors_state->valid) {