From ea4cbf601d3e854fbe4bfa9d90544c4b2d002bbd Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 9 Nov 2018 14:46:28 -0500 Subject: [PATCH] freedreno/ir3: remove pipe_stream_output_info dependency A bit annoying to have to copy into our own struct. But this is something the compiler really needs to know, at least on earlier generations where streamout is implemented in shader. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/a5xx/fd5_emit.c | 2 +- .../drivers/freedreno/a5xx/fd5_program.c | 8 ++--- src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 2 +- .../drivers/freedreno/a6xx/fd6_program.c | 8 ++--- .../drivers/freedreno/ir3/ir3_cmdline.c | 2 +- .../drivers/freedreno/ir3/ir3_compiler_nir.c | 3 +- .../drivers/freedreno/ir3/ir3_shader.c | 28 ++++++++++++++-- .../drivers/freedreno/ir3/ir3_shader.h | 32 ++++++++++++++++++- 8 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index 6becc563cf3..ad942fd7f5a 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -704,7 +704,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, if (!emit->binning_pass) ir3_emit_fs_consts(fp, ring, ctx); - struct pipe_stream_output_info *info = &vp->shader->stream_output; + struct ir3_stream_output_info *info = &vp->shader->stream_output; if (info->num_outputs) { struct fd_streamout_stateobj *so = &ctx->streamout; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_program.c b/src/gallium/drivers/freedreno/a5xx/fd5_program.c index 16729bc2fef..97a84b01c0a 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_program.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_program.c @@ -125,14 +125,14 @@ fd5_emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so) static void link_stream_out(struct ir3_shader_linkage *l, const struct ir3_shader_variant *v) { - const struct pipe_stream_output_info *strmout = &v->shader->stream_output; + const struct ir3_stream_output_info *strmout = &v->shader->stream_output; /* * First, any stream-out varyings not already in linkage map (ie. also * consumed by frag shader) need to be added: */ for (unsigned i = 0; i < strmout->num_outputs; i++) { - const struct pipe_stream_output *out = &strmout->output[i]; + const struct ir3_stream_output *out = &strmout->output[i]; unsigned k = out->register_index; unsigned compmask = (1 << (out->num_components + out->start_component)) - 1; @@ -173,14 +173,14 @@ static void emit_stream_out(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v, struct ir3_shader_linkage *l) { - const struct pipe_stream_output_info *strmout = &v->shader->stream_output; + const struct ir3_stream_output_info *strmout = &v->shader->stream_output; unsigned ncomp[PIPE_MAX_SO_BUFFERS] = {0}; unsigned prog[align(l->max_loc, 2) / 2]; memset(prog, 0, sizeof(prog)); for (unsigned i = 0; i < strmout->num_outputs; i++) { - const struct pipe_stream_output *out = &strmout->output[i]; + const struct ir3_stream_output *out = &strmout->output[i]; unsigned k = out->register_index; unsigned idx; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 8419b2c9a0b..4697b2f6b9a 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -775,7 +775,7 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit) fd_ringbuffer_del(fsconstobj); } - struct pipe_stream_output_info *info = &vp->shader->stream_output; + struct ir3_stream_output_info *info = &vp->shader->stream_output; if (info->num_outputs) { struct fd_streamout_stateobj *so = &ctx->streamout; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.c b/src/gallium/drivers/freedreno/a6xx/fd6_program.c index 69cdece3e8c..71dadef97e2 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.c @@ -140,14 +140,14 @@ fd6_emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so) static void link_stream_out(struct ir3_shader_linkage *l, const struct ir3_shader_variant *v) { - const struct pipe_stream_output_info *strmout = &v->shader->stream_output; + const struct ir3_stream_output_info *strmout = &v->shader->stream_output; /* * First, any stream-out varyings not already in linkage map (ie. also * consumed by frag shader) need to be added: */ for (unsigned i = 0; i < strmout->num_outputs; i++) { - const struct pipe_stream_output *out = &strmout->output[i]; + const struct ir3_stream_output *out = &strmout->output[i]; unsigned k = out->register_index; unsigned compmask = (1 << (out->num_components + out->start_component)) - 1; @@ -185,7 +185,7 @@ static void setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_variant *v, struct ir3_shader_linkage *l) { - const struct pipe_stream_output_info *strmout = &v->shader->stream_output; + const struct ir3_stream_output_info *strmout = &v->shader->stream_output; struct fd6_streamout_state *tf = &state->tf; memset(tf, 0, sizeof(*tf)); @@ -195,7 +195,7 @@ setup_stream_out(struct fd6_program_state *state, const struct ir3_shader_varian debug_assert(tf->prog_count < ARRAY_SIZE(tf->prog)); for (unsigned i = 0; i < strmout->num_outputs; i++) { - const struct pipe_stream_output *out = &strmout->output[i]; + const struct ir3_stream_output *out = &strmout->output[i]; unsigned k = out->register_index; unsigned idx; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index 77fba9f4445..a06eb89b9c6 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -350,7 +350,7 @@ int main(int argc, char **argv) } if (!strcmp(argv[n], "--stream-out")) { - struct pipe_stream_output_info *so = &s.stream_output; + struct ir3_stream_output_info *so = &s.stream_output; debug_printf(" %s", argv[n]); /* TODO more dynamic config based on number of outputs, etc * rather than just hard-code for first output: diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c index 75c00a02224..5d647a6d8a2 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c @@ -26,7 +26,6 @@ #include -#include "pipe/p_state.h" #include "util/u_string.h" #include "util/u_memory.h" #include "util/u_inlines.h" @@ -3106,7 +3105,7 @@ emit_stream_out(struct ir3_context *ctx) { struct ir3_shader_variant *v = ctx->so; struct ir3 *ir = ctx->ir; - struct pipe_stream_output_info *strmout = + struct ir3_stream_output_info *strmout = &ctx->so->shader->stream_output; struct ir3_block *orig_end_block, *stream_out_block, *new_end_block; struct ir3_instruction *vtxcnt, *maxvtxcnt, *cond; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index 14605902458..3becd757833 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -311,6 +311,27 @@ ir3_shader_destroy(struct ir3_shader *shader) free(shader); } +static void +copy_stream_out(struct ir3_stream_output_info *i, + const struct pipe_stream_output_info *p) +{ + STATIC_ASSERT(ARRAY_SIZE(i->stride) == ARRAY_SIZE(p->stride)); + STATIC_ASSERT(ARRAY_SIZE(i->output) == ARRAY_SIZE(p->output)); + + i->num_outputs = p->num_outputs; + for (int n = 0; n < ARRAY_SIZE(i->stride); n++) + i->stride[n] = p->stride[n]; + + for (int n = 0; n < ARRAY_SIZE(i->output); n++) { + i->output[n].register_index = p->output[n].register_index; + i->output[n].start_component = p->output[n].start_component; + i->output[n].num_components = p->output[n].num_components; + i->output[n].output_buffer = p->output[n].output_buffer; + i->output[n].dst_offset = p->output[n].dst_offset; + i->output[n].stream = p->output[n].stream; + } +} + struct ir3_shader * ir3_shader_create(struct ir3_compiler *compiler, const struct pipe_shader_state *cso, gl_shader_stage type, @@ -342,7 +363,8 @@ ir3_shader_create(struct ir3_compiler *compiler, nir_print_shader(shader->nir, stdout); } - shader->stream_output = cso->stream_output; + copy_stream_out(&shader->stream_output, &cso->stream_output); + if (fd_mesa_debug & FD_DBG_SHADERDB) { /* if shader-db run, create a standard variant immediately * (as otherwise nothing will trigger the shader to be @@ -758,7 +780,7 @@ emit_tfbos(struct fd_context *ctx, const struct ir3_shader_variant *v, uint32_t offset = v->constbase.tfbo; if (v->constlen > offset) { struct fd_streamout_stateobj *so = &ctx->streamout; - struct pipe_stream_output_info *info = &v->shader->stream_output; + struct ir3_stream_output_info *info = &v->shader->stream_output; uint32_t params = 4; uint32_t offsets[params]; struct pipe_resource *prscs[params]; @@ -785,7 +807,7 @@ static uint32_t max_tf_vtx(struct fd_context *ctx, const struct ir3_shader_variant *v) { struct fd_streamout_stateobj *so = &ctx->streamout; - struct pipe_stream_output_info *info = &v->shader->stream_output; + struct ir3_stream_output_info *info = &v->shader->stream_output; uint32_t maxvtxcnt = 0x7fffffff; if (ctx->screen->gpu_id >= 500) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h index d32ef10a160..f6ad49a50ae 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h @@ -63,6 +63,9 @@ enum ir3_driver_param { IR3_DP_VS_COUNT = 36 /* must be aligned to vec4 */ }; +#define IR3_MAX_SO_BUFFERS 4 +#define IR3_MAX_SO_OUTPUTS 64 + /** * For consts needed to pass internal values to shader which may or may not * be required, rather than allocating worst-case const space, we scan the @@ -97,6 +100,33 @@ struct ir3_driver_const_layout { } image_dims; }; +/** + * A single output for vertex transform feedback. + */ +struct ir3_stream_output { + unsigned register_index:6; /**< 0 to 63 (OUT index) */ + unsigned start_component:2; /** 0 to 3 */ + unsigned num_components:3; /** 1 to 4 */ + unsigned output_buffer:3; /**< 0 to PIPE_MAX_SO_BUFFERS */ + unsigned dst_offset:16; /**< offset into the buffer in dwords */ + unsigned stream:2; /**< 0 to 3 */ +}; + +/** + * Stream output for vertex transform feedback. + */ +struct ir3_stream_output_info { + unsigned num_outputs; + /** stride for an entire vertex for each buffer in dwords */ + uint16_t stride[IR3_MAX_SO_BUFFERS]; + + /** + * Array of stream outputs, in the order they are to be written in. + * Selected components are tightly packed into the output buffer. + */ + struct ir3_stream_output output[IR3_MAX_SO_OUTPUTS]; +}; + /* Configuration key used to identify a shader variant.. different * shader variants can be used to implement features not supported * in hw (two sided color), binning-pass vertex shader, etc. @@ -363,7 +393,7 @@ struct ir3_shader { struct ir3_compiler *compiler; struct nir_shader *nir; - struct pipe_stream_output_info stream_output; + struct ir3_stream_output_info stream_output; struct ir3_shader_variant *variants; }; -- 2.30.2