From: Samuel Pitoiset Date: Thu, 30 Sep 2021 09:10:08 +0000 (+0200) Subject: radv: determine the VS output parameters in the shader info pass X-Git-Tag: upstream/22.3.5~17152 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2aa705ec87ca4bf1e8d86cb836a685b2959f08fc;p=platform%2Fupstream%2Fmesa.git radv: determine the VS output parameters in the shader info pass This can be determined earlier instead of duplicating code in both compiler backends. Signed-off-by: Samuel Pitoiset Reviewed-by: Timur Kristóf Part-of: --- diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp index a2166e5..e8bae91 100644 --- a/src/amd/compiler/aco_instruction_selection_setup.cpp +++ b/src/amd/compiler/aco_instruction_selection_setup.cpp @@ -278,53 +278,12 @@ void setup_vs_output_info(isel_context* ctx, nir_shader* nir, bool export_prim_id, bool export_clip_dists, radv_vs_output_info* outinfo) { - memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED, - sizeof(outinfo->vs_output_param_offset)); - - outinfo->param_exports = 0; - int pos_written = 0x1; - bool writes_primitive_shading_rate = - outinfo->writes_primitive_shading_rate || ctx->options->force_vrs_rates; - if (outinfo->writes_pointsize || outinfo->writes_viewport_index || outinfo->writes_layer || - writes_primitive_shading_rate) - pos_written |= 1 << 1; - - uint64_t mask = nir->info.outputs_written; - while (mask) { - int idx = u_bit_scan64(&mask); - if (idx >= VARYING_SLOT_VAR0 || idx == VARYING_SLOT_LAYER || - idx == VARYING_SLOT_PRIMITIVE_ID || idx == VARYING_SLOT_VIEWPORT || - ((idx == VARYING_SLOT_CLIP_DIST0 || idx == VARYING_SLOT_CLIP_DIST1) && - export_clip_dists)) { - if (outinfo->vs_output_param_offset[idx] == AC_EXP_PARAM_UNDEFINED) - outinfo->vs_output_param_offset[idx] = outinfo->param_exports++; - } - } - if (outinfo->writes_layer && - outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] == AC_EXP_PARAM_UNDEFINED) { - /* when ctx->options->key.has_multiview_view_index = true, the layer - * variable isn't declared in NIR and it's isel's job to get the layer */ - outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = outinfo->param_exports++; - } - - if (export_prim_id) { - assert(outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] == AC_EXP_PARAM_UNDEFINED); - outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = outinfo->param_exports++; - } - ctx->export_clip_dists = export_clip_dists; ctx->num_clip_distances = util_bitcount(outinfo->clip_dist_mask); ctx->num_cull_distances = util_bitcount(outinfo->cull_dist_mask); assert(ctx->num_clip_distances + ctx->num_cull_distances <= 8); - if (ctx->num_clip_distances + ctx->num_cull_distances > 0) - pos_written |= 1 << 2; - if (ctx->num_clip_distances + ctx->num_cull_distances > 4) - pos_written |= 1 << 3; - - outinfo->pos_exports = util_bitcount(pos_written); - /* GFX10+ early rasterization: * When there are no param exports in an NGG (or legacy VS) shader, * RADV sets NO_PC_EXPORT=1, which means the HW will start clipping and rasterization diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c index 2f38ddf..2bc408c 100644 --- a/src/amd/vulkan/radv_nir_to_llvm.c +++ b/src/amd/vulkan/radv_nir_to_llvm.c @@ -1197,12 +1197,7 @@ radv_build_param_exports(struct radv_shader_context *ctx, struct radv_shader_out continue; radv_export_param(ctx, param_count, outputs[i].values, usage_mask); - - assert(i < ARRAY_SIZE(outinfo->vs_output_param_offset)); - outinfo->vs_output_param_offset[slot_name] = param_count++; } - - outinfo->param_exports = param_count; } /* Generate export instructions for hardware VS shader stage or NGG GS stage @@ -1325,11 +1320,6 @@ radv_llvm_export_vs(struct radv_shader_context *ctx, struct radv_shader_output_v } } - for (i = 0; i < 4; i++) { - if (pos_args[i].out[0]) - outinfo->pos_exports++; - } - /* GFX10 skip POS0 exports if EXEC=0 and DONE=0, causing a hang. * Setting valid_mask=1 prevents it and has no other effect. */ @@ -1375,10 +1365,6 @@ handle_vs_outputs_post(struct radv_shader_context *ctx, bool export_prim_id, boo ctx->output_mask |= 1ull << VARYING_SLOT_LAYER; } - memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED, - sizeof(outinfo->vs_output_param_offset)); - outinfo->pos_exports = 0; - if (ctx->args->shader_info->so.num_outputs && !ctx->args->is_gs_copy_shader) { /* The GS copy shader emission already emits streamout. */ radv_emit_streamout(ctx, 0); @@ -1695,9 +1681,6 @@ handle_ngg_outputs_post_2(struct radv_shader_context *ctx) values[j] = ctx->ac.f32_0; radv_export_param(ctx, param_count, values, 0x1); - - outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++; - outinfo->param_exports = param_count; } } ac_build_endif(&ctx->ac, 6002); @@ -1957,10 +1940,6 @@ gfx10_ngg_gs_emit_epilogue_2(struct radv_shader_context *ctx) unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_view_index; outputs = calloc(num_outputs, sizeof(outputs[0])); - memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED, - sizeof(outinfo->vs_output_param_offset)); - outinfo->pos_exports = 0; - tmp = ngg_gs_vertex_ptr(ctx, tid); tmp = LLVMBuildLoad(builder, ngg_gs_get_emit_primflag_ptr(ctx, tmp, 1), ""); tmp = LLVMBuildZExt(builder, tmp, ctx->ac.i32, ""); diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c index ec3822c..dd80b74 100644 --- a/src/amd/vulkan/radv_shader_info.c +++ b/src/amd/vulkan/radv_shader_info.c @@ -25,6 +25,8 @@ #include "radv_private.h" #include "radv_shader.h" +#include "ac_exp_param.h" + static void mark_sampler_desc(const nir_variable *var, struct radv_shader_info *info) { @@ -459,30 +461,47 @@ gather_info_output_decl_gs(const nir_shader *nir, const nir_variable *var, info->gs.output_streams[idx] = stream; } +static struct radv_vs_output_info * +get_vs_output_info(const nir_shader *nir, struct radv_shader_info *info) +{ + + switch (nir->info.stage) { + case MESA_SHADER_VERTEX: + if (!info->vs.as_ls && !info->vs.as_es) + return &info->vs.outinfo; + break; + case MESA_SHADER_GEOMETRY: + return &info->vs.outinfo; + break; + case MESA_SHADER_TESS_EVAL: + if (!info->tes.as_es) + return &info->tes.outinfo; + break; + default: + break; + } + + return NULL; +} + static void gather_info_output_decl(const nir_shader *nir, const nir_variable *var, struct radv_shader_info *info) { - struct radv_vs_output_info *vs_info = NULL; + struct radv_vs_output_info *vs_info = get_vs_output_info(nir, info); switch (nir->info.stage) { case MESA_SHADER_FRAGMENT: gather_info_output_decl_ps(nir, var, info); break; case MESA_SHADER_VERTEX: - if (!info->vs.as_ls && !info->vs.as_es) - vs_info = &info->vs.outinfo; - if (!info->vs.as_ls && info->is_ngg) gather_info_output_decl_gs(nir, var, info); break; case MESA_SHADER_GEOMETRY: - vs_info = &info->vs.outinfo; gather_info_output_decl_gs(nir, var, info); break; case MESA_SHADER_TESS_EVAL: - if (!info->tes.as_es) - vs_info = &info->tes.outinfo; break; default: break; @@ -603,6 +622,54 @@ radv_nir_shader_info_pass(struct radv_device *device, const struct nir_shader *n } } + struct radv_vs_output_info *outinfo = get_vs_output_info(nir, info); + if (outinfo) { + bool writes_primitive_shading_rate = + outinfo->writes_primitive_shading_rate || device->force_vrs != RADV_FORCE_VRS_NONE; + int pos_written = 0x1; + + if (outinfo->writes_pointsize || outinfo->writes_viewport_index || outinfo->writes_layer || + writes_primitive_shading_rate) + pos_written |= 1 << 1; + + unsigned num_clip_distances = util_bitcount(outinfo->clip_dist_mask); + unsigned num_cull_distances = util_bitcount(outinfo->cull_dist_mask); + + if (num_clip_distances + num_cull_distances > 0) + pos_written |= 1 << 2; + if (num_clip_distances + num_cull_distances > 4) + pos_written |= 1 << 3; + + outinfo->pos_exports = util_bitcount(pos_written); + + memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED, + sizeof(outinfo->vs_output_param_offset)); + outinfo->param_exports = 0; + + uint64_t mask = nir->info.outputs_written; + while (mask) { + int idx = u_bit_scan64(&mask); + if (idx >= VARYING_SLOT_VAR0 || idx == VARYING_SLOT_LAYER || + idx == VARYING_SLOT_PRIMITIVE_ID || idx == VARYING_SLOT_VIEWPORT || + ((idx == VARYING_SLOT_CLIP_DIST0 || idx == VARYING_SLOT_CLIP_DIST1) && + outinfo->export_clip_dists)) { + if (outinfo->vs_output_param_offset[idx] == AC_EXP_PARAM_UNDEFINED) + outinfo->vs_output_param_offset[idx] = outinfo->param_exports++; + } + } + if (outinfo->writes_layer && + outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] == AC_EXP_PARAM_UNDEFINED) { + /* when ctx->options->key.has_multiview_view_index = true, the layer + * variable isn't declared in NIR and it's isel's job to get the layer */ + outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = outinfo->param_exports++; + } + + if (outinfo->export_prim_id) { + assert(outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] == AC_EXP_PARAM_UNDEFINED); + outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = outinfo->param_exports++; + } + } + if (nir->info.stage == MESA_SHADER_FRAGMENT) info->ps.num_interp = nir->num_inputs;