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);
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;
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,
__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;
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,
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,
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);
+}