From 5307ff6a5fdb4f76e80da42795f1970f06e4e3b6 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 4 Dec 2018 22:19:33 -0800 Subject: [PATCH] iris: Implement DrawTransformFeedback() We get the count by dividing the offset by the stride. --- src/gallium/drivers/iris/iris_context.h | 6 +++++ src/gallium/drivers/iris/iris_defines.h | 2 ++ src/gallium/drivers/iris/iris_program.c | 23 +++++++++++----- src/gallium/drivers/iris/iris_query.c | 2 -- src/gallium/drivers/iris/iris_state.c | 47 ++++++++++++++++++++++++--------- 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 = ...; + } } } -- 2.11.0