[Mesa-dev] [PATCH 30/53] r600: create LDS info constants buffer and write LDS registers.

Marek Olšák maraeo at gmail.com
Mon Nov 30 04:30:07 PST 2015


On Mon, Nov 30, 2015 at 7:20 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This creates a constant buffer with the information about
> the layout of the LDS memory that is given to the vertex, tess
> control and tess evaluation shaders.
>
> This also programs the LDS size and the LS_HS_CONFIG registers,
> on evergreen only.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/gallium/drivers/r600/evergreen_state.c   | 128 +++++++++++++++++++++++++++
>  src/gallium/drivers/r600/r600_pipe.h         |  24 ++++-
>  src/gallium/drivers/r600/r600_state_common.c |  13 +++
>  3 files changed, 162 insertions(+), 3 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
> index c01e8e3..edc6f28 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -3763,3 +3763,131 @@ void evergreen_init_state_functions(struct r600_context *rctx)
>
>         evergreen_init_compute_state_functions(rctx);
>  }
> +
> +/**
> + * This calculates the LDS size for tessellation shaders (VS, TCS, TES).
> + *
> + * The information about LDS and other non-compile-time parameters is then
> + * written to the const buffer.
> +
> + * const buffer contains -
> + * uint32_t input_patch_size
> + * uint32_t input_vertex_size
> + * uint32_t num_tcs_input_cp
> + * uint32_t num_tcs_output_cp;
> + * uint32_t output_patch_size
> + * uint32_t output_vertex_size
> + * uint32_t output_patch0_offset
> + * uint32_t perpatch_output_offset
> + * and the same constbuf is bound to LS/HS/VS(ES).
> + */
> +void evergreen_setup_tess_constants(struct r600_context *rctx, const struct pipe_draw_info *info, unsigned *num_patches, uint32_t *lds_alloc)
> +{
> +       struct pipe_constant_buffer constbuf = {0};
> +       struct r600_pipe_shader_selector *tcs = rctx->tcs_shader ? rctx->tcs_shader : rctx->tes_shader;
> +       struct r600_pipe_shader_selector *ls = rctx->vs_shader;
> +       unsigned num_tcs_input_cp = info->vertices_per_patch;
> +       unsigned num_tcs_outputs;
> +       unsigned num_tcs_output_cp;
> +       unsigned num_tcs_patch_outputs;
> +       unsigned num_tcs_inputs;
> +       unsigned input_vertex_size, output_vertex_size;
> +       unsigned input_patch_size, pervertex_output_patch_size, output_patch_size;
> +       unsigned output_patch0_offset, perpatch_output_offset, lds_size;
> +       uint32_t values[16];
> +       uint32_t tmp;
> +
> +       if (!rctx->tes_shader)
> +               return;
> +
> +       *num_patches = 1;

num_patches should be set before returning.

> +
> +       num_tcs_inputs = util_last_bit64(ls->lds_outputs_written_mask);
> +
> +       if (rctx->tcs_shader) {
> +               num_tcs_outputs = util_last_bit64(tcs->lds_outputs_written_mask);
> +               num_tcs_output_cp = tcs->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT];
> +               num_tcs_patch_outputs = util_last_bit64(tcs->lds_patch_outputs_written_mask);
> +       } else {
> +               num_tcs_outputs = num_tcs_inputs;
> +               num_tcs_output_cp = num_tcs_input_cp;
> +               num_tcs_patch_outputs = 2; /* TESSINNER + TESSOUTER */
> +       }
> +
> +       /* size in bytes */
> +       input_vertex_size = num_tcs_inputs * 16;
> +       output_vertex_size = num_tcs_outputs * 16;
> +
> +       input_patch_size = num_tcs_input_cp * input_vertex_size;
> +
> +       pervertex_output_patch_size = num_tcs_output_cp * output_vertex_size;
> +       output_patch_size = pervertex_output_patch_size + num_tcs_patch_outputs * 16;
> +
> +       output_patch0_offset = rctx->tcs_shader ? input_patch_size * *num_patches : 0;
> +       perpatch_output_offset = output_patch0_offset + pervertex_output_patch_size;
> +
> +       lds_size = output_patch0_offset + output_patch_size * *num_patches;
> +
> +       values[0] = input_patch_size;
> +       values[1] = input_vertex_size;
> +       values[2] = num_tcs_input_cp;
> +       values[3] = num_tcs_output_cp;
> +
> +       values[4] = output_patch_size;
> +       values[5] = output_vertex_size;
> +       values[6] = output_patch0_offset;
> +       values[7] = perpatch_output_offset;
> +
> +       /* docs say HS_NUM_WAVES - CEIL((LS_HS_CONFIG.NUM_PATCHES *
> +          LS_HS_CONFIG.HS_NUM_OUTPUT_CP) / (NUM_GOOD_PIPES * 16)) */
> +       tmp = (lds_size | (1 << 14)); /* TODO */

If I understand this correctly, num_good_pipes can be between 1 and 4.
Assume the worst case, which is 1. This gives us:
ceil(NUM_PATCHES * NUM_OUTPUT_CP / 16)

That equals 2 if NUM_OUTPUT_CP > 16 and NUM_PATCHES = 1.

Marek


More information about the mesa-dev mailing list