anv: Deduplicate anv_CmdDraw calls
authorKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Sat, 6 Feb 2016 00:41:56 +0000 (16:41 -0800)
committerKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Sat, 6 Feb 2016 00:41:56 +0000 (16:41 -0800)
These were all duplicated between gen7_cmd_buffer.c and
gen8_cmd_buffer.c. This commit consolidates both copies in
genX_cmd_buffer.c.

src/vulkan/anv_private.h
src/vulkan/gen7_cmd_buffer.c
src/vulkan/gen8_cmd_buffer.c
src/vulkan/genX_cmd_buffer.c

index 188bd77ab252f3ef58b616099fa2ce7e74ef6c0a..022aae12007a85567b898503af1e484a21d23d30 100644 (file)
@@ -1274,6 +1274,11 @@ void gen9_cmd_buffer_set_subpass(struct anv_cmd_buffer *cmd_buffer,
 void anv_cmd_buffer_set_subpass(struct anv_cmd_buffer *cmd_buffer,
                                   struct anv_subpass *subpass);
 
+void gen7_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer);
+void gen75_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer);
+void gen8_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer);
+void gen9_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer);
+
 struct anv_state
 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
                               gl_shader_stage stage);
index 7108d74ba658013812d536c85065d4cedca761b5..8c563c9b5f13517e9baad7750b54e8e8fd48bfe0 100644 (file)
@@ -371,8 +371,8 @@ cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->state.compute_dirty = 0;
 }
 
-static void
-cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
+void
+genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
    uint32_t *p;
@@ -568,164 +568,6 @@ cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->state.dirty = 0;
 }
 
-static void
-emit_base_vertex_instance_bo(struct anv_cmd_buffer *cmd_buffer,
-                             struct anv_bo *bo, uint32_t offset)
-{
-   uint32_t *p = anv_batch_emitn(&cmd_buffer->batch, 5,
-                                 GENX(3DSTATE_VERTEX_BUFFERS));
-
-   GENX(VERTEX_BUFFER_STATE_pack)(&cmd_buffer->batch, p + 1,
-      &(struct GENX(VERTEX_BUFFER_STATE)) {
-         .VertexBufferIndex = 32, /* Reserved for this */
-         .VertexBufferMemoryObjectControlState = GENX(MOCS),
-         .AddressModifyEnable = true,
-         .BufferPitch = 0,
-         .BufferStartingAddress = { bo, offset },
-         .EndAddress = { bo, offset + 8 },
-      });
-}
-
-static void
-emit_base_vertex_instance(struct anv_cmd_buffer *cmd_buffer,
-                          uint32_t base_vertex, uint32_t base_instance)
-{
-   struct anv_state id_state =
-      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 8, 4);
-
-   ((uint32_t *)id_state.map)[0] = base_vertex;
-   ((uint32_t *)id_state.map)[1] = base_instance;
-
-   if (!cmd_buffer->device->info.has_llc)
-      anv_state_clflush(id_state);
-
-   emit_base_vertex_instance_bo(cmd_buffer,
-      &cmd_buffer->device->dynamic_state_block_pool.bo, id_state.offset);
-}
-
-void genX(CmdDraw)(
-    VkCommandBuffer                             commandBuffer,
-    uint32_t                                    vertexCount,
-    uint32_t                                    instanceCount,
-    uint32_t                                    firstVertex,
-    uint32_t                                    firstInstance)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance(cmd_buffer, firstVertex, firstInstance);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
-                  .VertexAccessType = SEQUENTIAL,
-                  .PrimitiveTopologyType = pipeline->topology,
-                  .VertexCountPerInstance = vertexCount,
-                  .StartVertexLocation = firstVertex,
-                  .InstanceCount = instanceCount,
-                  .StartInstanceLocation = firstInstance,
-                  .BaseVertexLocation = 0);
-}
-
-void genX(CmdDrawIndexed)(
-    VkCommandBuffer                             commandBuffer,
-    uint32_t                                    indexCount,
-    uint32_t                                    instanceCount,
-    uint32_t                                    firstIndex,
-    int32_t                                     vertexOffset,
-    uint32_t                                    firstInstance)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance(cmd_buffer, vertexOffset, firstInstance);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
-                  .VertexAccessType = RANDOM,
-                  .PrimitiveTopologyType = pipeline->topology,
-                  .VertexCountPerInstance = indexCount,
-                  .StartVertexLocation = firstIndex,
-                  .InstanceCount = instanceCount,
-                  .StartInstanceLocation = firstInstance,
-                  .BaseVertexLocation = vertexOffset);
-}
-
-/* Auto-Draw / Indirect Registers */
-#define GEN7_3DPRIM_END_OFFSET          0x2420
-#define GEN7_3DPRIM_START_VERTEX        0x2430
-#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
-#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
-#define GEN7_3DPRIM_START_INSTANCE      0x243C
-#define GEN7_3DPRIM_BASE_VERTEX         0x2440
-
-void genX(CmdDrawIndirect)(
-    VkCommandBuffer                             commandBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    uint32_t                                    drawCount,
-    uint32_t                                    stride)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 8);
-
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
-   emit_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
-                  .IndirectParameterEnable = true,
-                  .VertexAccessType = SEQUENTIAL,
-                  .PrimitiveTopologyType = pipeline->topology);
-}
-
-void genX(CmdDrawIndexedIndirect)(
-    VkCommandBuffer                             commandBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    uint32_t                                    drawCount,
-    uint32_t                                    stride)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 12);
-
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
-                  .IndirectParameterEnable = true,
-                  .VertexAccessType = RANDOM,
-                  .PrimitiveTopologyType = pipeline->topology);
-}
-
 void genX(CmdDispatch)(
     VkCommandBuffer                             commandBuffer,
     uint32_t                                    x,
index 56d80e26eeb9b43d5112211e6138ee4f044fe1cb..b997a2ecf0552ace8a8ecf7eda81bf323a0ba063 100644 (file)
@@ -260,8 +260,8 @@ __emit_sf_state(struct anv_cmd_buffer *cmd_buffer)
       __emit_genx_sf_state(cmd_buffer);
 }
 
-static void
-cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
+void
+genX(cmd_buffer_flush_state)(struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
    uint32_t *p;
@@ -479,127 +479,6 @@ cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->state.dirty = 0;
 }
 
-static void
-emit_base_vertex_instance_bo(struct anv_cmd_buffer *cmd_buffer,
-                             struct anv_bo *bo, uint32_t offset)
-{
-   uint32_t *p = anv_batch_emitn(&cmd_buffer->batch, 5,
-                                 GENX(3DSTATE_VERTEX_BUFFERS));
-
-   GENX(VERTEX_BUFFER_STATE_pack)(&cmd_buffer->batch, p + 1,
-      &(struct GENX(VERTEX_BUFFER_STATE)) {
-         .VertexBufferIndex = 32, /* Reserved for this */
-         .MemoryObjectControlState = GENX(MOCS),
-         .AddressModifyEnable = true,
-         .BufferPitch = 0,
-         .BufferStartingAddress = { bo, offset },
-         .BufferSize = 8
-      });
-}
-
-static void
-emit_base_vertex_instance(struct anv_cmd_buffer *cmd_buffer,
-                          uint32_t base_vertex, uint32_t base_instance)
-{
-   struct anv_state id_state =
-      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 8, 4);
-
-   ((uint32_t *)id_state.map)[0] = base_vertex;
-   ((uint32_t *)id_state.map)[1] = base_instance;
-
-   if (!cmd_buffer->device->info.has_llc)
-      anv_state_clflush(id_state);
-
-   emit_base_vertex_instance_bo(cmd_buffer,
-      &cmd_buffer->device->dynamic_state_block_pool.bo, id_state.offset);
-}
-
-void genX(CmdDraw)(
-    VkCommandBuffer                             commandBuffer,
-    uint32_t                                    vertexCount,
-    uint32_t                                    instanceCount,
-    uint32_t                                    firstVertex,
-    uint32_t                                    firstInstance)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance(cmd_buffer, firstVertex, firstInstance);
-
-   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
-                  .VertexAccessType = SEQUENTIAL,
-                  .VertexCountPerInstance = vertexCount,
-                  .StartVertexLocation = firstVertex,
-                  .InstanceCount = instanceCount,
-                  .StartInstanceLocation = firstInstance,
-                  .BaseVertexLocation = 0);
-}
-
-void genX(CmdDrawIndexed)(
-    VkCommandBuffer                             commandBuffer,
-    uint32_t                                    indexCount,
-    uint32_t                                    instanceCount,
-    uint32_t                                    firstIndex,
-    int32_t                                     vertexOffset,
-    uint32_t                                    firstInstance)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance(cmd_buffer, vertexOffset, firstInstance);
-
-   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
-                  .VertexAccessType = RANDOM,
-                  .VertexCountPerInstance = indexCount,
-                  .StartVertexLocation = firstIndex,
-                  .InstanceCount = instanceCount,
-                  .StartInstanceLocation = firstInstance,
-                  .BaseVertexLocation = vertexOffset);
-}
-
-/* Auto-Draw / Indirect Registers */
-#define GEN7_3DPRIM_END_OFFSET          0x2420
-#define GEN7_3DPRIM_START_VERTEX        0x2430
-#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
-#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
-#define GEN7_3DPRIM_START_INSTANCE      0x243C
-#define GEN7_3DPRIM_BASE_VERTEX         0x2440
-
-void genX(CmdDrawIndirect)(
-    VkCommandBuffer                             commandBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    uint32_t                                    drawCount,
-    uint32_t                                    stride)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 8);
-
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
-   emit_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
-
-   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
-                  .IndirectParameterEnable = true,
-                  .VertexAccessType = SEQUENTIAL);
-}
-
 void genX(CmdBindIndexBuffer)(
     VkCommandBuffer                             commandBuffer,
     VkBuffer                                    _buffer,
@@ -745,36 +624,6 @@ cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->state.compute_dirty = 0;
 }
 
-void genX(CmdDrawIndexedIndirect)(
-    VkCommandBuffer                             commandBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    uint32_t                                    drawCount,
-    uint32_t                                    stride)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   cmd_buffer_flush_state(cmd_buffer);
-
-   /* TODO: We need to stomp base vertex to 0 somehow */
-   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
-       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
-      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 12);
-
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
-   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
-
-   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
-                  .IndirectParameterEnable = true,
-                  .VertexAccessType = RANDOM);
-}
-
 void genX(CmdDispatch)(
     VkCommandBuffer                             commandBuffer,
     uint32_t                                    x,
index 1ab1747093237066411673e94b777839b0233f87..e3fa043c66bb9d0781baba009b06d0a6eb7c420f 100644 (file)
@@ -273,3 +273,185 @@ void genX(CmdPipelineBarrier)(
    dw = anv_batch_emit_dwords(&cmd_buffer->batch, GENX(PIPE_CONTROL_length));
    GENX(PIPE_CONTROL_pack)(&cmd_buffer->batch, dw, &cmd);
 }
+
+static void
+emit_base_vertex_instance_bo(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_bo *bo, uint32_t offset)
+{
+   uint32_t *p = anv_batch_emitn(&cmd_buffer->batch, 5,
+                                 GENX(3DSTATE_VERTEX_BUFFERS));
+
+   GENX(VERTEX_BUFFER_STATE_pack)(&cmd_buffer->batch, p + 1,
+      &(struct GENX(VERTEX_BUFFER_STATE)) {
+         .VertexBufferIndex = 32, /* Reserved for this */
+         .AddressModifyEnable = true,
+         .BufferPitch = 0,
+#if (ANV_GEN >= 8)
+         .MemoryObjectControlState = GENX(MOCS),
+         .BufferStartingAddress = { bo, offset },
+         .BufferSize = 8
+#else
+         .VertexBufferMemoryObjectControlState = GENX(MOCS),
+         .BufferStartingAddress = { bo, offset },
+         .EndAddress = { bo, offset + 8 },
+#endif
+      });
+}
+
+static void
+emit_base_vertex_instance(struct anv_cmd_buffer *cmd_buffer,
+                          uint32_t base_vertex, uint32_t base_instance)
+{
+   struct anv_state id_state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 8, 4);
+
+   ((uint32_t *)id_state.map)[0] = base_vertex;
+   ((uint32_t *)id_state.map)[1] = base_instance;
+
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(id_state);
+
+   emit_base_vertex_instance_bo(cmd_buffer,
+      &cmd_buffer->device->dynamic_state_block_pool.bo, id_state.offset);
+}
+
+void genX(CmdDraw)(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    vertexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstVertex,
+    uint32_t                                    firstInstance)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
+       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
+      emit_base_vertex_instance(cmd_buffer, firstVertex, firstInstance);
+
+   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
+      .VertexAccessType                         = SEQUENTIAL,
+      .PrimitiveTopologyType                    = pipeline->topology,
+      .VertexCountPerInstance                   = vertexCount,
+      .StartVertexLocation                      = firstVertex,
+      .InstanceCount                            = instanceCount,
+      .StartInstanceLocation                    = firstInstance,
+      .BaseVertexLocation                       = 0);
+}
+
+void genX(CmdDrawIndexed)(
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    indexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstIndex,
+    int32_t                                     vertexOffset,
+    uint32_t                                    firstInstance)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
+       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
+      emit_base_vertex_instance(cmd_buffer, vertexOffset, firstInstance);
+
+   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
+      .VertexAccessType                         = RANDOM,
+      .PrimitiveTopologyType                    = pipeline->topology,
+      .VertexCountPerInstance                   = indexCount,
+      .StartVertexLocation                      = firstIndex,
+      .InstanceCount                            = instanceCount,
+      .StartInstanceLocation                    = firstInstance,
+      .BaseVertexLocation                       = vertexOffset);
+}
+
+/* Auto-Draw / Indirect Registers */
+#define GEN7_3DPRIM_END_OFFSET          0x2420
+#define GEN7_3DPRIM_START_VERTEX        0x2430
+#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
+#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
+#define GEN7_3DPRIM_START_INSTANCE      0x243C
+#define GEN7_3DPRIM_BASE_VERTEX         0x2440
+
+static void
+emit_lrm(struct anv_batch *batch,
+         uint32_t reg, struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_MEM),
+                  .RegisterAddress = reg,
+                  .MemoryAddress = { bo, offset });
+}
+
+static void
+emit_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
+{
+   anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_IMM),
+                  .RegisterOffset = reg,
+                  .DataDWord = imm);
+}
+
+void genX(CmdDrawIndirect)(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    drawCount,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
+       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
+      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 8);
+
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
+   emit_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
+
+   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
+      .IndirectParameterEnable                  = true,
+      .VertexAccessType                         = SEQUENTIAL,
+      .PrimitiveTopologyType                    = pipeline->topology);
+}
+
+void genX(CmdDrawIndexedIndirect)(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    drawCount,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   /* TODO: We need to stomp base vertex to 0 somehow */
+   if (cmd_buffer->state.pipeline->vs_prog_data.uses_basevertex ||
+       cmd_buffer->state.pipeline->vs_prog_data.uses_baseinstance)
+      emit_base_vertex_instance_bo(cmd_buffer, bo, bo_offset + 12);
+
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
+
+   anv_batch_emit(&cmd_buffer->batch, GENX(3DPRIMITIVE),
+      .IndirectParameterEnable                  = true,
+      .VertexAccessType                         = RANDOM,
+      .PrimitiveTopologyType                    = pipeline->topology);
+}