[Mesa-dev] [PATCH 2/9] radv: start conditionalising vertex inputs.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Tue Apr 18 05:07:44 UTC 2017


On Tue, Apr 18, 2017 at 5:57 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> In practice this will probably just drop draw id in a few places.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/amd/common/ac_nir_to_llvm.c  | 42 +++++++++++++++++++++++++++-----------
>  src/amd/common/ac_shader_info.c  | 26 ++++++++++++++++++++++++
>  src/amd/common/ac_shader_info.h  |  5 +++++
>  src/amd/vulkan/radv_cmd_buffer.c | 44 +++++++++++++++++++++++++++++++---------
>  4 files changed, 95 insertions(+), 22 deletions(-)
>
> diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
> index dbb3b67..7161caf 100644
> --- a/src/amd/common/ac_nir_to_llvm.c
> +++ b/src/amd/common/ac_nir_to_llvm.c
> @@ -614,10 +614,15 @@ static void create_function(struct nir_to_llvm_context *ctx)
>                 break;
>         case MESA_SHADER_VERTEX:
>                 if (!ctx->is_gs_copy_shader) {
> -                       arg_types[arg_idx++] = const_array(ctx->v16i8, 16); /* vertex buffers */
> -                       arg_types[arg_idx++] = ctx->i32; // base vertex
> -                       arg_types[arg_idx++] = ctx->i32; // start instance
> -                       arg_types[arg_idx++] = ctx->i32; // draw index
> +                       if (ctx->shader_info->info.vs.has_vertex_buffers)
> +                               arg_types[arg_idx++] = const_array(ctx->v16i8, 16); /* vertex buffers */
> +                       if (ctx->shader_info->info.vs.needs_base_vertex_start_instance ||
> +                           ctx->shader_info->info.vs.needs_draw_id) {
> +                               arg_types[arg_idx++] = ctx->i32; // base vertex
> +                               arg_types[arg_idx++] = ctx->i32; // start instance

I'm not sure we can avoid having the CP write these two to some user
SGPRs for indirect draws? If so, we cannot skip them.


> +                               if (ctx->shader_info->info.vs.needs_draw_id)
> +                                       arg_types[arg_idx++] = ctx->i32; // draw index
> +                       }
>                 }
>                 user_sgpr_count = arg_idx;
>                 if (ctx->options->key.vs.as_es)
> @@ -773,14 +778,27 @@ static void create_function(struct nir_to_llvm_context *ctx)
>                 break;
>         case MESA_SHADER_VERTEX:
>                 if (!ctx->is_gs_copy_shader) {
> -                       set_userdata_location_shader(ctx, AC_UD_VS_VERTEX_BUFFERS, user_sgpr_idx, 2);
> -                       user_sgpr_idx += 2;
> -                       ctx->vertex_buffers = LLVMGetParam(ctx->main_function, arg_idx++);
> -                       set_userdata_location_shader(ctx, AC_UD_VS_BASE_VERTEX_START_INSTANCE, user_sgpr_idx, 3);
> -                       user_sgpr_idx += 3;
> -                       ctx->base_vertex = LLVMGetParam(ctx->main_function, arg_idx++);
> -                       ctx->start_instance = LLVMGetParam(ctx->main_function, arg_idx++);
> -                       ctx->draw_index = LLVMGetParam(ctx->main_function, arg_idx++);
> +                       if (ctx->shader_info->info.vs.has_vertex_buffers) {
> +                               set_userdata_location_shader(ctx, AC_UD_VS_VERTEX_BUFFERS, user_sgpr_idx, 2);
> +                               user_sgpr_idx += 2;
> +                               ctx->vertex_buffers = LLVMGetParam(ctx->main_function, arg_idx++);
> +                       }
> +                       unsigned vs_num = 0;
> +                       if (ctx->shader_info->info.vs.needs_draw_id)
> +                               vs_num = 3;
> +                       else if (ctx->shader_info->info.vs.needs_base_vertex_start_instance)
> +                               vs_num = 2;
> +
> +                       if (vs_num) {
> +                               set_userdata_location_shader(ctx, AC_UD_VS_BASE_VERTEX_START_INSTANCE, user_sgpr_idx, vs_num);
> +                               user_sgpr_idx += vs_num;
> +                       }
> +                       if (ctx->shader_info->info.vs.needs_base_vertex_start_instance) {
> +                               ctx->base_vertex = LLVMGetParam(ctx->main_function, arg_idx++);
> +                               ctx->start_instance = LLVMGetParam(ctx->main_function, arg_idx++);
> +                       }
> +                       if (ctx->shader_info->info.vs.needs_draw_id)
> +                               ctx->draw_index = LLVMGetParam(ctx->main_function, arg_idx++);
>                 }
>                 if (ctx->options->key.vs.as_es)
>                         ctx->es2gs_offset = LLVMGetParam(ctx->main_function, arg_idx++);
> diff --git a/src/amd/common/ac_shader_info.c b/src/amd/common/ac_shader_info.c
> index 85252fe..5061860 100644
> --- a/src/amd/common/ac_shader_info.c
> +++ b/src/amd/common/ac_shader_info.c
> @@ -30,6 +30,13 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, struct ac_shader_info *info)
>         case nir_intrinsic_interp_var_at_sample:
>                 info->ps.needs_sample_positions = true;
>                 break;
> +       case nir_intrinsic_load_base_vertex:
> +       case nir_intrinsic_load_base_instance:
> +               info->vs.needs_base_vertex_start_instance = true;
> +               break;
> +       case nir_intrinsic_load_draw_id:
> +               info->vs.needs_draw_id = true;
> +               break;
>         default:
>                 break;
>         }
> @@ -49,12 +56,31 @@ gather_info_block(nir_block *block, struct ac_shader_info *info)
>         }
>  }
>
> +static void
> +gather_info_input_decl(nir_shader *nir,
> +                      const struct ac_nir_compiler_options *options,
> +                      nir_variable *var,
> +                      struct ac_shader_info *info)
> +{
> +       switch (nir->stage) {
> +       case MESA_SHADER_VERTEX:
> +               info->vs.has_vertex_buffers = true;
> +               info->vs.needs_base_vertex_start_instance = true;
> +               break;
> +       default:
> +               break;
> +       }
> +}
> +
>  void
>  ac_nir_shader_info_pass(struct nir_shader *nir,
>                         const struct ac_nir_compiler_options *options,
>                         struct ac_shader_info *info)
>  {
>         struct nir_function *func = (struct nir_function *)exec_list_get_head(&nir->functions);
> +       nir_foreach_variable(variable, &nir->inputs)
> +               gather_info_input_decl(nir, options, variable, info);
> +
>         nir_foreach_block(block, func->impl) {
>                 gather_info_block(block, info);
>         }
> diff --git a/src/amd/common/ac_shader_info.h b/src/amd/common/ac_shader_info.h
> index 5576c3b..9d43637 100644
> --- a/src/amd/common/ac_shader_info.h
> +++ b/src/amd/common/ac_shader_info.h
> @@ -29,6 +29,11 @@ struct ac_nir_compiler_options;
>
>  struct ac_shader_info {
>         struct {
> +               bool has_vertex_buffers; /* needs vertex buffers and base/start */
> +               bool needs_base_vertex_start_instance;
> +               bool needs_draw_id;
> +       } vs;
> +       struct {
>                 bool needs_sample_positions;
>         } ps;
>  };
> diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
> index f3e5f82..22ae0c4 100644
> --- a/src/amd/vulkan/radv_cmd_buffer.c
> +++ b/src/amd/vulkan/radv_cmd_buffer.c
> @@ -1427,7 +1427,8 @@ radv_cmd_buffer_flush_state(struct radv_cmd_buffer *cmd_buffer,
>                                                            cmd_buffer->cs, 4096);
>
>         if ((cmd_buffer->state.vertex_descriptors_dirty || cmd_buffer->state.vb_dirty) &&
> -           cmd_buffer->state.pipeline->num_vertex_attribs) {
> +           cmd_buffer->state.pipeline->num_vertex_attribs &&
> +           cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.has_vertex_buffers) {
>                 unsigned vb_offset;
>                 void *vb_ptr;
>                 uint32_t i = 0;
> @@ -2512,10 +2513,21 @@ void radv_CmdDraw(
>         if (loc->sgpr_idx != -1) {
>                 uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline),
>                                                                 radv_pipeline_has_tess(cmd_buffer->state.pipeline));
> -               radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 3);
> -               radeon_emit(cmd_buffer->cs, firstVertex);
> -               radeon_emit(cmd_buffer->cs, firstInstance);
> -               radeon_emit(cmd_buffer->cs, 0);
> +               int vs_num = 0;
> +
> +               if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id)
> +                       vs_num = 3;
> +               else if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_base_vertex_start_instance)
> +                       vs_num = 2;
> +
> +               assert (loc->num_sgprs == vs_num);
> +               radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, vs_num);
> +               if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_base_vertex_start_instance) {
> +                       radeon_emit(cmd_buffer->cs, firstVertex);
> +                       radeon_emit(cmd_buffer->cs, firstInstance);
> +               }
> +               if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id)
> +                       radeon_emit(cmd_buffer->cs, 0);
>         }
>         radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
>         radeon_emit(cmd_buffer->cs, instanceCount);
> @@ -2555,10 +2567,21 @@ void radv_CmdDrawIndexed(
>         if (loc->sgpr_idx != -1) {
>                 uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline),
>                                                                 radv_pipeline_has_tess(cmd_buffer->state.pipeline));
> -               radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 3);
> -               radeon_emit(cmd_buffer->cs, vertexOffset);
> -               radeon_emit(cmd_buffer->cs, firstInstance);
> -               radeon_emit(cmd_buffer->cs, 0);
> +               int vs_num = 0;
> +
> +               if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id)
> +                       vs_num = 3;
> +               else if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_base_vertex_start_instance)
> +                       vs_num = 2;
> +
> +               assert (loc->num_sgprs == vs_num);
> +               radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, vs_num);
> +               if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_base_vertex_start_instance) {
> +                       radeon_emit(cmd_buffer->cs, vertexOffset);
> +                       radeon_emit(cmd_buffer->cs, firstInstance);
> +               }
> +               if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id)
> +                       radeon_emit(cmd_buffer->cs, 0);
>         }
>         radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
>         radeon_emit(cmd_buffer->cs, instanceCount);
> @@ -2609,6 +2632,7 @@ radv_emit_indirect_draw(struct radv_cmd_buffer *cmd_buffer,
>                                                              AC_UD_VS_BASE_VERTEX_START_INSTANCE);
>         uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline),
>                                                         radv_pipeline_has_tess(cmd_buffer->state.pipeline));
> +       bool draw_id_enable = cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id;
>         assert(loc->sgpr_idx != -1);
>         radeon_emit(cs, PKT3(PKT3_SET_BASE, 2, 0));
>         radeon_emit(cs, 1);
> @@ -2622,7 +2646,7 @@ radv_emit_indirect_draw(struct radv_cmd_buffer *cmd_buffer,
>         radeon_emit(cs, ((base_reg + loc->sgpr_idx * 4) - SI_SH_REG_OFFSET) >> 2);
>         radeon_emit(cs, ((base_reg + (loc->sgpr_idx + 1) * 4) - SI_SH_REG_OFFSET) >> 2);
>         radeon_emit(cs, (((base_reg + (loc->sgpr_idx + 2) * 4) - SI_SH_REG_OFFSET) >> 2) |
> -                       S_2C3_DRAW_INDEX_ENABLE(1) |
> +                       S_2C3_DRAW_INDEX_ENABLE(draw_id_enable) |
>                         S_2C3_COUNT_INDIRECT_ENABLE(!!count_va));
>         radeon_emit(cs, draw_count); /* count */
>         radeon_emit(cs, count_va); /* count_addr */
> --
> 2.9.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list