gen7: Add support for base vertex/instance
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 26 Jan 2016 20:09:33 +0000 (12:09 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 26 Jan 2016 22:56:37 +0000 (14:56 -0800)
src/vulkan/gen7_cmd_buffer.c

index b83bfdadbaeab701cfaa816569d3855a1edd1b7d..8fae13518489a2b5d6989b224b2101feb244807f 100644 (file)
@@ -519,6 +519,41 @@ 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)[0] = 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,
@@ -531,6 +566,10 @@ void genX(CmdDraw)(
 
    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,
@@ -554,6 +593,10 @@ void genX(CmdDrawIndexed)(
 
    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,
@@ -604,6 +647,10 @@ void genX(CmdDrawIndirect)(
 
    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);
+
    gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
    gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
    gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
@@ -631,6 +678,10 @@ void genX(CmdDrawIndexedIndirect)(
 
    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);
+
    gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
    gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
    gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);