iris: Implement DrawTransformFeedback()
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 5 Dec 2018 06:19:33 +0000 (22:19 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:11 +0000 (10:26 -0800)
We get the count by dividing the offset by the stride.

src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_defines.h
src/gallium/drivers/iris/iris_program.c
src/gallium/drivers/iris/iris_query.c
src/gallium/drivers/iris/iris_state.c

index af9034cb12f1f49c8400a14b81caffddf0ecf766..5753a0864c9b94d8a7bceb61594df3be5d3f0d74 100644 (file)
@@ -314,6 +314,9 @@ struct iris_stream_output_target {
 
    /** Storage holding the offset where we're writing in the buffer */
    struct iris_state_ref offset;
+
+   /** Stride (dwords-per-vertex) during this transform feedback operation */
+   uint16_t stride;
 };
 
 /**
@@ -513,6 +516,9 @@ struct iris_context {
       /** 3DSTATE_STREAMOUT and 3DSTATE_SO_DECL_LIST packets */
       uint32_t *streamout;
 
+      /** Current strides for each streamout buffer */
+      uint16_t *streamout_strides;
+
       /** The SURFACE_STATE for a 1x1x1 null surface. */
       struct iris_state_ref unbound_tex;
 
index a006e7a9ae1b3441ac4f81cf22008882f7f9cd0a..d36b6452612c91c660a47ddf6a4367d3da1d81b7 100644 (file)
@@ -50,6 +50,8 @@
 #define MI_PREDICATE_RESULT_1                0x241C
 #define MI_PREDICATE_RESULT_2                0x2214
 
+#define CS_GPR(n) (0x2600 + (n) * 8)
+
 /* The number of bits in our TIMESTAMP queries. */
 #define TIMESTAMP_BITS 36
 
index 0200b9bb1ec62c3ee848c4c6b0c8d8af06c9d099..8a3a77ddb0519bbf1310e165402cf85a55d402a5 100644 (file)
@@ -1253,16 +1253,16 @@ iris_update_compiled_fs(struct iris_context *ice)
  *
  * This stage is the one which will feed stream output and the rasterizer.
  */
-static struct iris_compiled_shader *
-last_vue_shader(struct iris_context *ice)
+static gl_shader_stage
+last_vue_stage(struct iris_context *ice)
 {
    if (ice->shaders.prog[MESA_SHADER_GEOMETRY])
-      return ice->shaders.prog[MESA_SHADER_GEOMETRY];
+      return MESA_SHADER_GEOMETRY;
 
    if (ice->shaders.prog[MESA_SHADER_TESS_EVAL])
-      return ice->shaders.prog[MESA_SHADER_TESS_EVAL];
+      return MESA_SHADER_TESS_EVAL;
 
-   return ice->shaders.prog[MESA_SHADER_VERTEX];
+   return MESA_SHADER_VERTEX;
 }
 
 /**
@@ -1355,13 +1355,24 @@ iris_update_compiled_shaders(struct iris_context *ice)
    if (dirty & IRIS_DIRTY_UNCOMPILED_GS)
       iris_update_compiled_gs(ice);
 
-   struct iris_compiled_shader *shader = last_vue_shader(ice);
+   gl_shader_stage last_stage = last_vue_stage(ice);
+   struct iris_compiled_shader *shader = ice->shaders.prog[last_stage];
+   struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[last_stage];
    update_last_vue_map(ice, shader->prog_data);
    if (ice->state.streamout != shader->streamout) {
       ice->state.streamout = shader->streamout;
       ice->state.dirty |= IRIS_DIRTY_SO_DECL_LIST | IRIS_DIRTY_STREAMOUT;
    }
 
+   if (ice->state.streamout_active) {
+      for (int i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
+         struct iris_stream_output_target *so =
+            (void *) ice->state.so_target[i];
+         if (so)
+            so->stride = ish->stream_output.stride[i];
+      }
+   }
+
    if (dirty & IRIS_DIRTY_UNCOMPILED_FS)
       iris_update_compiled_fs(ice);
    // ...
index 8960f31bb65e98a5a737ba3e4075c8542fb47425..adc0838291be249d00d4073183b6f6b666537ac1 100644 (file)
@@ -58,8 +58,6 @@
 
 #define SO_NUM_PRIMS_WRITTEN(n)    (0x5200 + (n) * 8)
 
-#define CS_GPR(n) (0x2600 + (n) * 8)
-
 #define MI_MATH (0x1a << 23)
 
 #define MI_ALU_LOAD      0x080
index 5012ffd996ea8d53f4cc189da8dc97a820cd4800..09e8b2fb5e5f0845b4c81f7b33f3dcc28822081d 100644 (file)
 #include "intel/common/gen_sample_positions.h"
 #include "iris_batch.h"
 #include "iris_context.h"
+#include "iris_defines.h"
 #include "iris_pipe.h"
 #include "iris_resource.h"
 
@@ -4583,28 +4584,50 @@ iris_upload_render_state(struct iris_context *ice,
             lri.DataDWord = 0;
          }
       }
+   } else if (draw->count_from_stream_output) {
+      struct iris_stream_output_target *so =
+         (void *) draw->count_from_stream_output;
+
+      // XXX: avoid if possible
+      iris_emit_pipe_control_flush(batch, PIPE_CONTROL_CS_STALL);
+
+      iris_emit_cmd(batch, GENX(MI_LOAD_REGISTER_MEM), lrm) {
+         lrm.RegisterAddress = CS_GPR(0);
+         lrm.MemoryAddress =
+            ro_bo(iris_resource_bo(so->offset.res), so->offset.offset);
+      }
+      iris_math_div32_gpr0(ice, batch, so->stride);
+      _iris_emit_lrr(batch, _3DPRIM_VERTEX_COUNT, CS_GPR(0));
+
+      _iris_emit_lri(batch, _3DPRIM_START_VERTEX, 0);
+      _iris_emit_lri(batch, _3DPRIM_BASE_VERTEX, 0);
+      _iris_emit_lri(batch, _3DPRIM_START_INSTANCE, 0);
+      _iris_emit_lri(batch, _3DPRIM_INSTANCE_COUNT, draw->instance_count);
    }
 
    iris_emit_cmd(batch, GENX(3DPRIMITIVE), prim) {
-      prim.StartInstanceLocation = draw->start_instance;
-      prim.InstanceCount = draw->instance_count;
-      prim.VertexCountPerInstance = draw->count;
       prim.VertexAccessType = draw->index_size > 0 ? RANDOM : SEQUENTIAL;
       prim.PredicateEnable =
          ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT;
 
-      // XXX: this is probably bonkers.
-      prim.StartVertexLocation = draw->start;
+      if (draw->indirect || draw->count_from_stream_output) {
+         prim.IndirectParameterEnable = true;
+      } else {
+         prim.StartInstanceLocation = draw->start_instance;
+         prim.InstanceCount = draw->instance_count;
+         prim.VertexCountPerInstance = draw->count;
 
-      prim.IndirectParameterEnable = draw->indirect != NULL;
+         // XXX: this is probably bonkers.
+         prim.StartVertexLocation = draw->start;
 
-      if (draw->index_size) {
-         prim.BaseVertexLocation += draw->index_bias;
-      } else {
-         prim.StartVertexLocation += draw->index_bias;
-      }
+         if (draw->index_size) {
+            prim.BaseVertexLocation += draw->index_bias;
+         } else {
+            prim.StartVertexLocation += draw->index_bias;
+         }
 
-      //prim.BaseVertexLocation = ...;
+         //prim.BaseVertexLocation = ...;
+      }
    }
 }