turnip: Simplify vertex buffer bindings.
authorEric Anholt <eric@anholt.net>
Thu, 4 Jun 2020 00:07:06 +0000 (17:07 -0700)
committerMarge Bot <eric+marge@anholt.net>
Thu, 4 Jun 2020 19:42:54 +0000 (19:42 +0000)
We were remapping the bindings so the HW binding points were consecutive,
which there's no need for.  Now that we don't shuffle, we can mostly drop
the dependency on the pipeline for this SDS.

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

src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_pipeline.c
src/freedreno/vulkan/tu_private.h

index a67a5838264d7db877607a0d4b46cef309fc9d77..a1f690288d7127e3750b4c2e26dda62b62046ae6 100644 (file)
@@ -2009,6 +2009,13 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
       break;
    }
 
+   /* If the new pipeline requires more VBs than we had previously set up, we
+    * need to re-emit them in SDS.  If it requires the same set or fewer, we
+    * can just re-use the old SDS.
+    */
+   if (pipeline->vi.bindings_used & ~cmd->vertex_bindings_set)
+      cmd->state.dirty |= TU_CMD_DIRTY_VERTEX_BUFFERS;
+
    tu_bo_list_add(&cmd->bo_list, &pipeline->program.binary_bo,
                   MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_DUMP);
    for (uint32_t i = 0; i < pipeline->cs.bo_count; i++) {
@@ -2670,18 +2677,20 @@ tu6_emit_vertex_buffers(struct tu_cmd_buffer *cmd,
    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];
+   int binding;
+   for_each_bit(binding, pipeline->vi.bindings_used) {
       const struct tu_buffer *buf = cmd->state.vb.buffers[binding];
       const VkDeviceSize offset = buf->bo_offset +
          cmd->state.vb.offsets[binding];
 
       tu_cs_emit_regs(&cs,
-                      A6XX_VFD_FETCH_BASE(i, .bo = buf->bo, .bo_offset = offset),
-                      A6XX_VFD_FETCH_SIZE(i, buf->size - offset));
+                      A6XX_VFD_FETCH_BASE(binding, .bo = buf->bo, .bo_offset = offset),
+                      A6XX_VFD_FETCH_SIZE(binding, buf->size - offset));
 
    }
 
+   cmd->vertex_bindings_set = pipeline->vi.bindings_used;
+
    return tu_cs_end_sub_stream(&cmd->sub_cs, &cs);
 }
 
@@ -3011,8 +3020,7 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
          };
    }
 
-   if (cmd->state.dirty &
-       (TU_CMD_DIRTY_PIPELINE | TU_CMD_DIRTY_VERTEX_BUFFERS)) {
+   if (cmd->state.dirty & TU_CMD_DIRTY_VERTEX_BUFFERS) {
       draw_state_groups[draw_state_group_count++] =
          (struct tu_draw_state_group) {
             .id = TU_DRAW_STATE_VB,
index 5002f9f6f2a2685c420a3a6a16d5c5263a5da733..4b04a98dd2505b703ab970d033a3b83db271b2f5 100644 (file)
@@ -1621,10 +1621,8 @@ static void
 tu6_emit_vertex_input(struct tu_cs *cs,
                       const struct ir3_shader_variant *vs,
                       const VkPipelineVertexInputStateCreateInfo *info,
-                      uint8_t bindings[MAX_VERTEX_ATTRIBS],
-                      uint32_t *count)
+                      uint32_t *bindings_used)
 {
-   uint32_t vfd_fetch_idx = 0;
    uint32_t vfd_decode_idx = 0;
    uint32_t binding_instanced = 0; /* bitmask of instanced bindings */
 
@@ -1633,13 +1631,12 @@ tu6_emit_vertex_input(struct tu_cs *cs,
          &info->pVertexBindingDescriptions[i];
 
       tu_cs_emit_regs(cs,
-                      A6XX_VFD_FETCH_STRIDE(vfd_fetch_idx, binding->stride));
+                      A6XX_VFD_FETCH_STRIDE(binding->binding, binding->stride));
 
       if (binding->inputRate == VK_VERTEX_INPUT_RATE_INSTANCE)
          binding_instanced |= 1 << binding->binding;
 
-      bindings[vfd_fetch_idx] = binding->binding;
-      vfd_fetch_idx++;
+      *bindings_used |= 1 << binding->binding;
    }
 
    /* TODO: emit all VFD_DECODE/VFD_DEST_CNTL in same (two) pkt4 */
@@ -1647,13 +1644,7 @@ tu6_emit_vertex_input(struct tu_cs *cs,
    for (uint32_t i = 0; i < info->vertexAttributeDescriptionCount; i++) {
       const VkVertexInputAttributeDescription *attr =
          &info->pVertexAttributeDescriptions[i];
-      uint32_t binding_idx, input_idx;
-
-      for (binding_idx = 0; binding_idx < vfd_fetch_idx; binding_idx++) {
-         if (bindings[binding_idx] == attr->binding)
-            break;
-      }
-      assert(binding_idx < vfd_fetch_idx);
+      uint32_t input_idx;
 
       for (input_idx = 0; input_idx < vs->inputs_count; input_idx++) {
          if ((vs->inputs[input_idx].slot - VERT_ATTRIB_GENERIC0) == attr->location)
@@ -1667,7 +1658,7 @@ tu6_emit_vertex_input(struct tu_cs *cs,
       const struct tu_native_format format = tu6_format_vtx(attr->format);
       tu_cs_emit_regs(cs,
                       A6XX_VFD_DECODE_INSTR(vfd_decode_idx,
-                        .idx = binding_idx,
+                        .idx = attr->binding,
                         .offset = attr->offset,
                         .instanced = binding_instanced & (1 << attr->binding),
                         .format = format.fmt,
@@ -1686,10 +1677,8 @@ tu6_emit_vertex_input(struct tu_cs *cs,
 
    tu_cs_emit_regs(cs,
                    A6XX_VFD_CONTROL_0(
-                     .fetch_cnt = vfd_fetch_idx,
+                     .fetch_cnt = info->vertexBindingDescriptionCount,
                      .decode_cnt = vfd_decode_idx));
-
-   *count = vfd_fetch_idx;
 }
 
 static uint32_t
@@ -2317,15 +2306,14 @@ tu_pipeline_builder_parse_vertex_input(struct tu_pipeline_builder *builder,
    tu_cs_begin_sub_stream(&pipeline->cs,
                           MAX_VERTEX_ATTRIBS * 7 + 2, &vi_cs);
    tu6_emit_vertex_input(&vi_cs, &vs->variants[0], vi_info,
-                         pipeline->vi.bindings, &pipeline->vi.count);
+                         &pipeline->vi.bindings_used);
    pipeline->vi.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &vi_cs);
 
    if (vs->has_binning_pass) {
       tu_cs_begin_sub_stream(&pipeline->cs,
                              MAX_VERTEX_ATTRIBS * 7 + 2, &vi_cs);
       tu6_emit_vertex_input(
-         &vi_cs, &vs->variants[1], vi_info, pipeline->vi.binning_bindings,
-         &pipeline->vi.binning_count);
+         &vi_cs, &vs->variants[1], vi_info, &pipeline->vi.bindings_used);
       pipeline->vi.binning_state_ib =
          tu_cs_end_sub_stream(&pipeline->cs, &vi_cs);
    }
index eabc4a335bdb737f3a41aca09224b1d7797a9f08..4d70bdc9e36707245b4f32ff6ba307a5c1f5a135 100644 (file)
@@ -878,6 +878,7 @@ enum tu_cmd_dirty_bits
    TU_CMD_DIRTY_PIPELINE = 1 << 0,
    TU_CMD_DIRTY_COMPUTE_PIPELINE = 1 << 1,
    TU_CMD_DIRTY_VERTEX_BUFFERS = 1 << 2,
+
    TU_CMD_DIRTY_DESCRIPTOR_SETS = 1 << 3,
    TU_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS = 1 << 4,
    TU_CMD_DIRTY_PUSH_CONSTANTS = 1 << 5,
@@ -1027,6 +1028,7 @@ struct tu_cmd_buffer
 
    struct tu_cmd_state state;
    struct tu_vertex_binding vertex_bindings[MAX_VBS];
+   uint32_t vertex_bindings_set;
    uint32_t queue_family_index;
 
    uint32_t push_constants[MAX_PUSH_CONSTANTS_SIZE / 4];
@@ -1242,14 +1244,9 @@ struct tu_pipeline
 
    struct
    {
-      uint8_t bindings[MAX_VERTEX_ATTRIBS];
-      uint32_t count;
-
-      uint8_t binning_bindings[MAX_VERTEX_ATTRIBS];
-      uint32_t binning_count;
-
       struct tu_cs_entry state_ib;
       struct tu_cs_entry binning_state_ib;
+      uint32_t bindings_used;
    } vi;
 
    struct