anv: Add get_push_range_address() helper.
authorRafael Antognolli <rafael.antognolli@intel.com>
Tue, 26 Nov 2019 21:05:06 +0000 (13:05 -0800)
committerRafael Antognolli <rafael.antognolli@intel.com>
Wed, 4 Dec 2019 20:48:25 +0000 (20:48 +0000)
Add a helper function to get the push range address. Once we have a
separate function for emitting gen12 push constants, we can use this
helper and avoid duplicating code.

v3: Do not add range->start to the address in gen7 (Caio).
v4: Do not drop range->start from gen7 (Caio, Jason).

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
src/intel/vulkan/genX_cmd_buffer.c

index bceae33cfbcf4ef431ec2516e7cbcf5e94eede6e..98927f2971e4fc93798e833b898644c5b84ea7c1 100644 (file)
@@ -2509,6 +2509,70 @@ cmd_buffer_emit_descriptor_pointers(struct anv_cmd_buffer *cmd_buffer,
    }
 }
 
+static struct anv_address
+get_push_range_address(struct anv_cmd_buffer *cmd_buffer,
+                       gl_shader_stage stage,
+                       const struct anv_push_range *range)
+{
+#if GEN_GEN >= 8 || GEN_IS_HASWELL
+   const struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx;
+   switch (range->set) {
+   case ANV_DESCRIPTOR_SET_DESCRIPTORS: {
+      /* This is a descriptor set buffer so the set index is
+       * actually given by binding->binding.  (Yes, that's
+       * confusing.)
+       */
+      struct anv_descriptor_set *set =
+         gfx_state->base.descriptors[range->index];
+      return anv_descriptor_set_address(cmd_buffer, set);
+      break;
+   }
+
+   case ANV_DESCRIPTOR_SET_PUSH_CONSTANTS: {
+      struct anv_state state =
+         anv_cmd_buffer_push_constants(cmd_buffer, stage);
+      return (struct anv_address) {
+         .bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
+         .offset = state.offset,
+      };
+      break;
+   }
+
+   default: {
+      assert(range->set < MAX_SETS);
+      struct anv_descriptor_set *set =
+         gfx_state->base.descriptors[range->set];
+      const struct anv_descriptor *desc =
+         &set->descriptors[range->index];
+
+      if (desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
+         return desc->buffer_view->address;
+      } else {
+         assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
+         struct anv_push_constants *push =
+            &cmd_buffer->state.push_constants[stage];
+         uint32_t dynamic_offset =
+            push->dynamic_offsets[range->dynamic_offset_index];
+         return anv_address_add(desc->buffer->address,
+                                desc->offset + dynamic_offset);
+      }
+   }
+   }
+#else
+   /* For Ivy Bridge, push constants are relative to dynamic state
+    * base address and we only ever push actual push constants.
+    */
+   assert(range->length > 0);
+   assert(range->set == ANV_DESCRIPTOR_SET_PUSH_CONSTANTS);
+   struct anv_state state =
+      anv_cmd_buffer_push_constants(cmd_buffer, stage);
+   return (struct anv_address) {
+      .bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
+      .offset = state.offset,
+   };
+#endif
+}
+
 static void
 cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
                                 VkShaderStageFlags dirty_stages)
@@ -2538,7 +2602,6 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
             const struct anv_pipeline_bind_map *bind_map =
                &pipeline->shaders[stage]->bind_map;
 
-#if GEN_GEN >= 8 || GEN_IS_HASWELL
             unsigned buffer_count = 0;
             for (unsigned i = 0; i < 4; i++) {
                const struct anv_push_range *range = &bind_map->push_ranges[i];
@@ -2565,70 +2628,18 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
                /* At this point we only have non-empty ranges */
                assert(range->length > 0);
 
-               struct anv_address addr;
-               switch (range->set) {
-               case ANV_DESCRIPTOR_SET_DESCRIPTORS: {
-                  /* This is a descriptor set buffer so the set index is
-                   * actually given by binding->binding.  (Yes, that's
-                   * confusing.)
-                   */
-                  struct anv_descriptor_set *set =
-                     gfx_state->base.descriptors[range->index];
-                  addr = anv_descriptor_set_address(cmd_buffer, set);
-                  break;
-               }
-
-               case ANV_DESCRIPTOR_SET_PUSH_CONSTANTS: {
-                  struct anv_state state =
-                     anv_cmd_buffer_push_constants(cmd_buffer, stage);
-                  addr = (struct anv_address) {
-                     .bo = cmd_buffer->device->dynamic_state_pool.block_pool.bo,
-                     .offset = state.offset,
-                  };
-                  break;
-               }
+               /* For Ivy Bridge, make sure we only set the first range (actual
+                * push constants)
+                */
+               assert((GEN_GEN >= 8 || GEN_IS_HASWELL) || i == 0);
 
-               default: {
-                  assert(range->set < MAX_SETS);
-                  struct anv_descriptor_set *set =
-                     gfx_state->base.descriptors[range->set];
-                  const struct anv_descriptor *desc =
-                     &set->descriptors[range->index];
-
-                  if (desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
-                     addr = desc->buffer_view->address;
-                  } else {
-                     assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
-                     struct anv_push_constants *push =
-                        &cmd_buffer->state.push_constants[stage];
-                     uint32_t dynamic_offset =
-                        push->dynamic_offsets[range->dynamic_offset_index];
-                     addr = anv_address_add(desc->buffer->address,
-                                            desc->offset + dynamic_offset);
-                  }
-               }
-               }
+               const struct anv_address addr =
+                  get_push_range_address(cmd_buffer, stage, range);
 
                c.ConstantBody.ReadLength[i + shift] = range->length;
                c.ConstantBody.Buffer[i + shift] =
                   anv_address_add(addr, range->start * 32);
             }
-#else
-            /* For Ivy Bridge, push constants are relative to dynamic state
-             * base address and we only ever push actual push constants.
-             */
-            if (bind_map->push_ranges[0].length > 0) {
-               assert(bind_map->push_ranges[0].set ==
-                      ANV_DESCRIPTOR_SET_PUSH_CONSTANTS);
-               struct anv_state state =
-                  anv_cmd_buffer_push_constants(cmd_buffer, stage);
-               c.ConstantBody.ReadLength[0] = bind_map->push_ranges[0].length;
-               c.ConstantBody.Buffer[0].offset = state.offset;
-            }
-            assert(bind_map->push_ranges[1].length == 0);
-            assert(bind_map->push_ranges[2].length == 0);
-            assert(bind_map->push_ranges[3].length == 0);
-#endif
          }
       }