[Mesa-dev] [PATCH 4/4] radv: handle primitive id input into fragment shader with no geom shader

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Sat Jun 24 19:11:31 UTC 2017


Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

for the series.

On Tue, Jun 20, 2017 at 6:38 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> Fixes:
> dEQP-VK.pipeline.framebuffer_attachment.no_attachments
> dEQP-VK.pipeline.framebuffer_attachment.no_attachments_ms
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/amd/common/ac_nir_to_llvm.c  | 26 +++++++++++++++++++++---
>  src/amd/common/ac_nir_to_llvm.h  |  3 +++
>  src/amd/vulkan/radv_cmd_buffer.c |  2 +-
>  src/amd/vulkan/radv_pipeline.c   | 43 +++++++++++++++++++++++++++++++---------
>  src/amd/vulkan/radv_private.h    |  1 +
>  src/amd/vulkan/si_cmd_buffer.c   |  4 +++-
>  6 files changed, 65 insertions(+), 14 deletions(-)
>
> diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
> index afef3fd..f0ae708 100644
> --- a/src/amd/common/ac_nir_to_llvm.c
> +++ b/src/amd/common/ac_nir_to_llvm.c
> @@ -5124,6 +5124,7 @@ si_llvm_init_export_args(struct nir_to_llvm_context *ctx,
>
>  static void
>  handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
> +                      bool export_prim_id,
>                        struct ac_vs_output_info *outinfo)
>  {
>         uint32_t param_count = 0;
> @@ -5265,6 +5266,23 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
>                 ac_build_export(&ctx->ac, &pos_args[i]);
>         }
>
> +
> +       if (export_prim_id) {
> +               LLVMValueRef values[4];
> +               target = V_008DFC_SQ_EXP_PARAM + param_count;
> +               outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count;
> +               param_count++;
> +
> +               values[0] = ctx->vs_prim_id;
> +               ctx->shader_info->vs.vgpr_comp_cnt = MAX2(2,
> +                                                         ctx->shader_info->vs.vgpr_comp_cnt);
> +               for (unsigned j = 1; j < 4; j++)
> +                       values[j] = ctx->f32zero;
> +               si_llvm_init_export_args(ctx, values, target, &args);
> +               ac_build_export(&ctx->ac, &args);
> +               outinfo->export_prim_id = true;
> +       }
> +
>         outinfo->pos_exports = num_pos_exports;
>         outinfo->param_exports = param_count;
>  }
> @@ -5700,7 +5718,8 @@ handle_shader_outputs_post(struct nir_to_llvm_context *ctx)
>                 else if (ctx->options->key.vs.as_es)
>                         handle_es_outputs_post(ctx, &ctx->shader_info->vs.es_info);
>                 else
> -                       handle_vs_outputs_post(ctx, &ctx->shader_info->vs.outinfo);
> +                       handle_vs_outputs_post(ctx, ctx->options->key.vs.export_prim_id,
> +                                              &ctx->shader_info->vs.outinfo);
>                 break;
>         case MESA_SHADER_FRAGMENT:
>                 handle_fs_outputs_post(ctx);
> @@ -5715,7 +5734,8 @@ handle_shader_outputs_post(struct nir_to_llvm_context *ctx)
>                 if (ctx->options->key.tes.as_es)
>                         handle_es_outputs_post(ctx, &ctx->shader_info->tes.es_info);
>                 else
> -                       handle_vs_outputs_post(ctx, &ctx->shader_info->tes.outinfo);
> +                       handle_vs_outputs_post(ctx, ctx->options->key.tes.export_prim_id,
> +                                              &ctx->shader_info->tes.outinfo);
>                 break;
>         default:
>                 break;
> @@ -6191,7 +6211,7 @@ ac_gs_copy_shader_emit(struct nir_to_llvm_context *ctx)
>                 }
>                 idx += slot_inc;
>         }
> -       handle_vs_outputs_post(ctx, &ctx->shader_info->vs.outinfo);
> +       handle_vs_outputs_post(ctx, false, &ctx->shader_info->vs.outinfo);
>  }
>
>  void ac_create_gs_copy_shader(LLVMTargetMachineRef tm,
> diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h
> index 724d5e6..54d5489 100644
> --- a/src/amd/common/ac_nir_to_llvm.h
> +++ b/src/amd/common/ac_nir_to_llvm.h
> @@ -41,10 +41,12 @@ struct ac_vs_variant_key {
>         uint32_t instance_rate_inputs;
>         uint32_t as_es:1;
>         uint32_t as_ls:1;
> +       uint32_t export_prim_id:1;
>  };
>
>  struct ac_tes_variant_key {
>         uint32_t as_es:1;
> +       uint32_t export_prim_id:1;
>  };
>
>  struct ac_tcs_variant_key {
> @@ -128,6 +130,7 @@ struct ac_vs_output_info {
>         bool writes_pointsize;
>         bool writes_layer;
>         bool writes_viewport_index;
> +       bool export_prim_id;
>         uint32_t export_mask;
>         unsigned pos_exports;
>  };
> diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
> index 9f36d98..105384d 100644
> --- a/src/amd/vulkan/radv_cmd_buffer.c
> +++ b/src/amd/vulkan/radv_cmd_buffer.c
> @@ -669,7 +669,7 @@ radv_emit_vertex_shader(struct radv_cmd_buffer *cmd_buffer,
>         else
>                 radv_emit_hw_vs(cmd_buffer, pipeline, vs, &vs->info.vs.outinfo);
>
> -       radeon_set_context_reg(cmd_buffer->cs, R_028A84_VGT_PRIMITIVEID_EN, 0);
> +       radeon_set_context_reg(cmd_buffer->cs, R_028A84_VGT_PRIMITIVEID_EN, pipeline->graphics.vgt_primitiveid_en);
>  }
>
>
> diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
> index e58ada6..0c26279 100644
> --- a/src/amd/vulkan/radv_pipeline.c
> +++ b/src/amd/vulkan/radv_pipeline.c
> @@ -605,11 +605,14 @@ radv_pipeline_compile(struct radv_pipeline *pipeline,
>  }
>
>  static union ac_shader_variant_key
> -radv_compute_tes_key(bool as_es)
> +radv_compute_tes_key(bool as_es, bool export_prim_id)
>  {
>         union ac_shader_variant_key key;
>         memset(&key, 0, sizeof(key));
>         key.tes.as_es = as_es;
> +       /* export prim id only happens when no geom shader */
> +       if (!as_es)
> +               key.tes.export_prim_id = export_prim_id;
>         return key;
>  }
>
> @@ -640,10 +643,12 @@ radv_tess_pipeline_compile(struct radv_pipeline *pipeline,
>         nir_shader *tes_nir, *tcs_nir;
>         void *tes_code = NULL, *tcs_code = NULL;
>         unsigned tes_code_size = 0, tcs_code_size = 0;
> -       union ac_shader_variant_key tes_key = radv_compute_tes_key(radv_pipeline_has_gs(pipeline));
> +       union ac_shader_variant_key tes_key;
>         union ac_shader_variant_key tcs_key;
>         bool dump = (pipeline->device->debug_flags & RADV_DEBUG_DUMP_SHADERS);
>
> +       tes_key = radv_compute_tes_key(radv_pipeline_has_gs(pipeline),
> +                                      pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input);
>         if (tes_module->nir)
>                 _mesa_sha1_compute(tes_module->nir->info.name,
>                                    strlen(tes_module->nir->info.name),
> @@ -1606,7 +1611,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
>  }
>
>  static union ac_shader_variant_key
> -radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es, bool as_ls)
> +radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es, bool as_ls, bool export_prim_id)
>  {
>         union ac_shader_variant_key key;
>         const VkPipelineVertexInputStateCreateInfo *input_state =
> @@ -1616,6 +1621,7 @@ radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es,
>         key.vs.instance_rate_inputs = 0;
>         key.vs.as_es = as_es;
>         key.vs.as_ls = as_ls;
> +       key.vs.export_prim_id = export_prim_id;
>
>         for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) {
>                 unsigned binding;
> @@ -1857,6 +1863,24 @@ static uint32_t si_vgt_gs_mode(struct radv_shader_variant *gs)
>                S_028A40_GS_WRITE_OPTIMIZE(1);
>  }
>
> +static void calculate_vgt_gs_mode(struct radv_pipeline *pipeline)
> +{
> +       struct radv_shader_variant *vs;
> +       vs = radv_pipeline_has_gs(pipeline) ? pipeline->gs_copy_shader : (radv_pipeline_has_tess(pipeline) ? pipeline->shaders[MESA_SHADER_TESS_EVAL] :  pipeline->shaders[MESA_SHADER_VERTEX]);
> +
> +       struct ac_vs_output_info *outinfo = &vs->info.vs.outinfo;
> +
> +       pipeline->graphics.vgt_primitiveid_en = false;
> +       pipeline->graphics.vgt_gs_mode = 0;
> +
> +       if (radv_pipeline_has_gs(pipeline)) {
> +               pipeline->graphics.vgt_gs_mode = si_vgt_gs_mode(pipeline->shaders[MESA_SHADER_GEOMETRY]);
> +       } else if (outinfo->export_prim_id) {
> +               pipeline->graphics.vgt_gs_mode = S_028A40_MODE(V_028A40_GS_SCENARIO_A);
> +               pipeline->graphics.vgt_primitiveid_en = true;
> +       }
> +}
> +
>  static void calculate_pa_cl_vs_out_cntl(struct radv_pipeline *pipeline)
>  {
>         struct radv_shader_variant *vs;
> @@ -2018,11 +2042,14 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
>         if (modules[MESA_SHADER_VERTEX]) {
>                 bool as_es = false;
>                 bool as_ls = false;
> +               bool export_prim_id = false;
>                 if (modules[MESA_SHADER_TESS_CTRL])
>                         as_ls = true;
>                 else if (modules[MESA_SHADER_GEOMETRY])
>                         as_es = true;
> -               union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, as_es, as_ls);
> +               else if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input)
> +                       export_prim_id = true;
> +               union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, as_es, as_ls, export_prim_id);
>
>                 pipeline->shaders[MESA_SHADER_VERTEX] =
>                          radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_VERTEX],
> @@ -2035,7 +2062,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
>         }
>
>         if (modules[MESA_SHADER_GEOMETRY]) {
> -               union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, false, false);
> +               union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, false, false, false);
>
>                 pipeline->shaders[MESA_SHADER_GEOMETRY] =
>                          radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_GEOMETRY],
> @@ -2045,10 +2072,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
>                                                pipeline->layout, &key);
>
>                 pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_GEOMETRY);
> -
> -               pipeline->graphics.vgt_gs_mode = si_vgt_gs_mode(pipeline->shaders[MESA_SHADER_GEOMETRY]);
> -       } else
> -               pipeline->graphics.vgt_gs_mode = 0;
> +       }
>
>         if (modules[MESA_SHADER_TESS_EVAL]) {
>                 assert(modules[MESA_SHADER_TESS_CTRL]);
> @@ -2130,6 +2154,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
>                 ps->info.fs.writes_z ? V_028710_SPI_SHADER_32_R :
>                 V_028710_SPI_SHADER_ZERO;
>
> +       calculate_vgt_gs_mode(pipeline);
>         calculate_pa_cl_vs_out_cntl(pipeline);
>         calculate_ps_inputs(pipeline);
>
> diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
> index 87cb0a6..630448d 100644
> --- a/src/amd/vulkan/radv_private.h
> +++ b/src/amd/vulkan/radv_private.h
> @@ -1071,6 +1071,7 @@ struct radv_pipeline {
>                         unsigned prim;
>                         unsigned gs_out;
>                         uint32_t vgt_gs_mode;
> +                       bool vgt_primitiveid_en;
>                         bool prim_restart_enable;
>                         unsigned esgs_ring_size;
>                         unsigned gsvs_ring_size;
> diff --git a/src/amd/vulkan/si_cmd_buffer.c b/src/amd/vulkan/si_cmd_buffer.c
> index 1525d44..bf08214 100644
> --- a/src/amd/vulkan/si_cmd_buffer.c
> +++ b/src/amd/vulkan/si_cmd_buffer.c
> @@ -700,13 +700,15 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer,
>
>         multi_instances_smaller_than_primgroup = indirect_draw || (instanced_draw &&
>                                                                    num_prims < primgroup_size);
> +       if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input)
> +               ia_switch_on_eoi = true;
> +
>         if (radv_pipeline_has_tess(cmd_buffer->state.pipeline)) {
>                 /* SWITCH_ON_EOI must be set if PrimID is used. */
>                 if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.uses_prim_id ||
>                     cmd_buffer->state.pipeline->shaders[MESA_SHADER_TESS_EVAL]->info.tes.uses_prim_id)
>                         ia_switch_on_eoi = true;
>
> -
>                 /* Bug with tessellation and GS on Bonaire and older 2 SE chips. */
>                 if ((family == CHIP_TAHITI ||
>                      family == CHIP_PITCAIRN ||
> --
> 2.9.4
>
> _______________________________________________
> 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