summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2018-12-04 22:19:33 -0800
committerKenneth Graunke <[email protected]>2019-02-21 10:26:11 -0800
commit5307ff6a5fdb4f76e80da42795f1970f06e4e3b6 (patch)
tree400a0744dff699f73046803eccdbba9318794f89
parent2e103fff63404916de1b2c4039cbeccb196117df (diff)
iris: Implement DrawTransformFeedback()
We get the count by dividing the offset by the stride.
-rw-r--r--src/gallium/drivers/iris/iris_context.h6
-rw-r--r--src/gallium/drivers/iris/iris_defines.h2
-rw-r--r--src/gallium/drivers/iris/iris_program.c23
-rw-r--r--src/gallium/drivers/iris/iris_query.c2
-rw-r--r--src/gallium/drivers/iris/iris_state.c47
5 files changed, 60 insertions, 20 deletions
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index af9034cb12f..5753a0864c9 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -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;
diff --git a/src/gallium/drivers/iris/iris_defines.h b/src/gallium/drivers/iris/iris_defines.h
index a006e7a9ae1..d36b6452612 100644
--- a/src/gallium/drivers/iris/iris_defines.h
+++ b/src/gallium/drivers/iris/iris_defines.h
@@ -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
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index 0200b9bb1ec..8a3a77ddb05 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -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);
// ...
diff --git a/src/gallium/drivers/iris/iris_query.c b/src/gallium/drivers/iris/iris_query.c
index 8960f31bb65..adc0838291b 100644
--- a/src/gallium/drivers/iris/iris_query.c
+++ b/src/gallium/drivers/iris/iris_query.c
@@ -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
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 5012ffd996e..09e8b2fb5e5 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -101,6 +101,7 @@
#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 = ...;
+ }
}
}