[Mesa-dev] [PATCH 4/6] radeon: add support for streams to the common streamout code.
Marek Olšák
maraeo at gmail.com
Tue Jul 28 11:19:53 PDT 2015
On Mon, Jul 27, 2015 at 3:50 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This adds to the common radeon streamout code, support
> for multiple streams.
>
> It updates radeonsi/r600 to set the enabled mask up.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/gallium/drivers/r600/r600_shader.c | 7 +++++++
> src/gallium/drivers/r600/r600_shader.h | 1 +
> src/gallium/drivers/r600/r600_state_common.c | 2 ++
> src/gallium/drivers/radeon/r600_pipe_common.h | 1 +
> src/gallium/drivers/radeon/r600_streamout.c | 25 ++++++++++++++++++-------
> src/gallium/drivers/radeonsi/si_state_shaders.c | 17 ++++++++++++++---
> 6 files changed, 43 insertions(+), 10 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
> index 1a72bf6..dda38f6 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -310,6 +310,7 @@ struct r600_shader_ctx {
> int gs_next_vertex;
> struct r600_shader *gs_for_vs;
> int gs_export_gpr_treg;
> + unsigned enabled_stream_buffers_mask;
> };
>
> struct r600_shader_tgsi_instruction {
> @@ -1402,6 +1403,9 @@ static int emit_streamout(struct r600_shader_ctx *ctx, struct pipe_stream_output
> * with MEM_STREAM instructions */
> output.array_size = 0xFFF;
> output.comp_mask = ((1 << so->output[i].num_components) - 1) << so->output[i].start_component;
> +
> + ctx->enabled_stream_buffers_mask |= (1 << so->output[i].output_buffer);
> +
> if (ctx->bc->chip_class >= EVERGREEN) {
> switch (so->output[i].output_buffer) {
> case 0:
> @@ -1718,6 +1722,8 @@ static int generate_gs_copy_shader(struct r600_context *rctx,
> gs->gs_copy_shader = cshader;
>
> ctx.bc->nstack = 1;
> +
> + cshader->enabled_stream_buffers_mask = ctx.enabled_stream_buffers_mask;
> cshader->shader.ring_item_size = ocnt * 16;
>
> return r600_bytecode_build(ctx.bc);
> @@ -2261,6 +2267,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
> so.num_outputs && !use_llvm)
> emit_streamout(&ctx, &so);
>
> + pipeshader->enabled_stream_buffers_mask = ctx.enabled_stream_buffers_mask;
> convert_edgeflag_to_int(&ctx);
>
> if (ring_outputs) {
> diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
> index dd359d7..5d05c81 100644
> --- a/src/gallium/drivers/r600/r600_shader.h
> +++ b/src/gallium/drivers/r600/r600_shader.h
> @@ -125,6 +125,7 @@ struct r600_pipe_shader {
> struct r600_shader_key key;
> unsigned db_shader_control;
> unsigned ps_depth_export;
> + unsigned enabled_stream_buffers_mask;
> };
>
> /* return the table index 0-5 for TGSI_INTERPOLATE_LINEAR/PERSPECTIVE and
> diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
> index 0c78b50..455e59a 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -1208,6 +1208,7 @@ static bool r600_update_derived_state(struct r600_context *rctx)
> rctx->clip_misc_state.clip_disable = rctx->gs_shader->current->shader.vs_position_window_space;
> rctx->clip_misc_state.atom.dirty = true;
> }
> + rctx->b.streamout.enabled_stream_buffers_mask = rctx->gs_shader->current->gs_copy_shader->enabled_stream_buffers_mask;
> }
>
> r600_shader_select(ctx, rctx->vs_shader, &vs_dirty);
> @@ -1242,6 +1243,7 @@ static bool r600_update_derived_state(struct r600_context *rctx)
> rctx->clip_misc_state.clip_disable = rctx->vs_shader->current->shader.vs_position_window_space;
> rctx->clip_misc_state.atom.dirty = true;
> }
> + rctx->b.streamout.enabled_stream_buffers_mask = rctx->vs_shader->current->enabled_stream_buffers_mask;
> }
> }
>
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index d225f25..16613af 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -328,6 +328,7 @@ struct r600_streamout {
> /* External state which comes from the vertex shader,
> * it must be set explicitly when binding a shader. */
> unsigned *stride_in_dw;
> + unsigned enabled_stream_buffers_mask; /* stream0 buffers0-3 in 4 LSB */
>
> /* The state of VGT_STRMOUT_(CONFIG|EN). */
> struct r600_atom enable_atom;
> diff --git a/src/gallium/drivers/radeon/r600_streamout.c b/src/gallium/drivers/radeon/r600_streamout.c
> index 0688397..520c71e 100644
> --- a/src/gallium/drivers/radeon/r600_streamout.c
> +++ b/src/gallium/drivers/radeon/r600_streamout.c
> @@ -321,16 +321,27 @@ static bool r600_get_strmout_en(struct r600_common_context *rctx)
> static void r600_emit_streamout_enable(struct r600_common_context *rctx,
> struct r600_atom *atom)
> {
> + unsigned reg = R_028AB0_VGT_STRMOUT_EN;
> + unsigned val = S_028B94_STREAMOUT_0_EN(r600_get_strmout_en(rctx));
> +
> r600_write_context_reg(rctx->rings.gfx.cs, rctx->chip_class >= EVERGREEN ?
> R_028B98_VGT_STRMOUT_BUFFER_CONFIG :
> R_028B20_VGT_STRMOUT_BUFFER_EN,
> - rctx->streamout.enabled_mask);
> -
> - r600_write_context_reg(rctx->rings.gfx.cs,
> - rctx->chip_class >= EVERGREEN ?
> - R_028B94_VGT_STRMOUT_CONFIG :
> - R_028AB0_VGT_STRMOUT_EN,
> - S_028B94_STREAMOUT_0_EN(r600_get_strmout_en(rctx)));
> + (rctx->streamout.enabled_mask |
> + (rctx->streamout.enabled_mask << 4) |
> + (rctx->streamout.enabled_mask << 8) |
> + (rctx->streamout.enabled_mask << 12)) &
> + rctx->streamout.enabled_stream_buffers_mask);
> +
> + if (rctx->chip_class >= EVERGREEN) {
> + reg = R_028B94_VGT_STRMOUT_CONFIG;
> + val |=
> + S_028B94_RAST_STREAM(0) |
> + S_028B94_STREAMOUT_1_EN(r600_get_strmout_en(rctx)) |
> + S_028B94_STREAMOUT_2_EN(r600_get_strmout_en(rctx)) |
> + S_028B94_STREAMOUT_3_EN(r600_get_strmout_en(rctx));
> + }
> + r600_write_context_reg(rctx->rings.gfx.cs, reg, val);
> }
>
> static void r600_set_streamout_enable(struct r600_common_context *rctx, bool enable)
> diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
> index 24afed0..1e0228d 100644
> --- a/src/gallium/drivers/radeonsi/si_state_shaders.c
> +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
> @@ -1245,6 +1245,17 @@ static void si_update_vgt_shader_config(struct si_context *sctx)
> si_pm4_bind_state(sctx, vgt_shader_config, *pm4);
> }
>
> +static void si_update_so(struct si_context *sctx, struct si_shader_selector *shader)
> +{
> + struct pipe_stream_output_info *so = &shader->so;
> + uint32_t enabled_stream_buffers_mask = 0;
> + int i;
> + for (i = 0; i < so->num_outputs; i++)
> + enabled_stream_buffers_mask |= (1 << so->output[i].output_buffer);
> + sctx->b.streamout.enabled_stream_buffers_mask = enabled_stream_buffers_mask;
> + sctx->b.streamout.stride_in_dw = shader->so.stride;
> +}
An empty line is missing after the declarations.
Other than that, this is:
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
The streamout_enable atom doesn't have to be marked as dirty here,
because OpenGL doesn't allow changing the shader while transform
feedback is active.
Marek
More information about the mesa-dev
mailing list