From 6988967a1f520e5928f93ae787d3734b92673206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 19 Nov 2024 09:35:49 -0500 Subject: [PATCH] radeonsi: rewrite/replace gfx10_ngg_get_vertices_per_prim Reuse si_get_input_prim (which is similar) and split it into 2 functions: - si_get_output_prim_simplified - si_get_num_vertices_per_output_prim Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- .../drivers/radeonsi/gfx10_shader_ngg.c | 32 --------------- .../drivers/radeonsi/si_nir_lower_abi.c | 2 +- src/gallium/drivers/radeonsi/si_shader.c | 2 +- .../drivers/radeonsi/si_shader_internal.h | 1 - src/gallium/drivers/radeonsi/si_state.h | 3 ++ .../drivers/radeonsi/si_state_shaders.cpp | 41 +++++++++++++++++++ 6 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c b/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c index 714db413663..d4c65166a02 100644 --- a/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c +++ b/src/gallium/drivers/radeonsi/gfx10_shader_ngg.c @@ -8,38 +8,6 @@ #include "si_query.h" #include "si_shader_internal.h" -unsigned gfx10_ngg_get_vertices_per_prim(struct si_shader *shader) -{ - const struct si_shader_info *info = &shader->selector->info; - - if (shader->selector->stage == MESA_SHADER_GEOMETRY) - return mesa_vertices_per_prim(info->base.gs.output_primitive); - else if (shader->selector->stage == MESA_SHADER_VERTEX) { - if (info->base.vs.blit_sgprs_amd) { - /* Blits always use axis-aligned rectangles with 3 vertices. */ - return 3; - } else if (shader->key.ge.opt.ngg_culling & SI_NGG_CULL_VS_LINES) - return 2; - else { - /* The shader compiler replaces 0 with 3. The generated code will be correct regardless - * of the draw primitive type, but it's less efficient. - * - * Computing prim export values for non-existent vertices has no effect. - */ - return 0; /* unknown */ - } - } else { - assert(shader->selector->stage == MESA_SHADER_TESS_EVAL); - - if (info->base.tess.point_mode) - return 1; - else if (info->base.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES) - return 2; - else - return 3; - } -} - bool gfx10_ngg_export_prim_early(struct si_shader *shader) { struct si_shader_selector *sel = shader->selector; diff --git a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c index 57410f423ea..da6a7b99a38 100644 --- a/src/gallium/drivers/radeonsi/si_nir_lower_abi.c +++ b/src/gallium/drivers/radeonsi/si_nir_lower_abi.c @@ -254,7 +254,7 @@ static void preload_reusable_variables(nir_builder *b, struct lower_abi_state *s static nir_def *get_num_vertices_per_prim(nir_builder *b, struct lower_abi_state *s) { struct si_shader_args *args = s->args; - unsigned num_vertices = gfx10_ngg_get_vertices_per_prim(s->shader); + unsigned num_vertices = si_get_num_vertices_per_output_prim(s->shader); if (num_vertices) return nir_imm_int(b, num_vertices); diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 067becb1baf..77f24a8501c 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1942,7 +1942,7 @@ static void si_lower_ngg(struct si_shader *shader, nir_shader *nir) unsigned clip_plane_enable = SI_NGG_CULL_GET_CLIP_PLANE_ENABLE(key->ge.opt.ngg_culling); - unsigned num_vertices = gfx10_ngg_get_vertices_per_prim(shader); + unsigned num_vertices = si_get_num_vertices_per_output_prim(shader); options.num_vertices_per_primitive = num_vertices ? num_vertices : 3; options.early_prim_export = gfx10_ngg_export_prim_early(shader); diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index dc416cce09e..5bff6e2771f 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -117,7 +117,6 @@ void si_get_ps_epilog_args(struct si_shader_args *args, struct ac_arg *sample_mask); /* gfx10_shader_ngg.c */ -unsigned gfx10_ngg_get_vertices_per_prim(struct si_shader *shader); bool gfx10_ngg_export_prim_early(struct si_shader *shader); unsigned gfx10_ngg_get_scratch_dw_size(struct si_shader *shader); bool gfx10_ngg_calculate_subgroup_info(struct si_shader *shader); diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index d35e34cb99c..8b7fd03e77e 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -678,6 +678,9 @@ void si_update_ps_inputs_read_or_disabled(struct si_context *sctx); void si_update_vrs_flat_shading(struct si_context *sctx); unsigned si_get_input_prim(const struct si_shader_selector *gs, const union si_shader_key *key, bool return_unknown); +unsigned si_get_output_prim_simplified(const struct si_shader_selector *sel, + const union si_shader_key *key); +unsigned si_get_num_vertices_per_output_prim(struct si_shader *shader); bool si_update_ngg(struct si_context *sctx); void si_vs_ps_key_update_rast_prim_smooth_stipple(struct si_context *sctx); void si_ps_key_update_framebuffer(struct si_context *sctx); diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.cpp b/src/gallium/drivers/radeonsi/si_state_shaders.cpp index 7fc86482b1f..37c92cd42b6 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.cpp +++ b/src/gallium/drivers/radeonsi/si_state_shaders.cpp @@ -1377,6 +1377,47 @@ unsigned si_get_input_prim(const struct si_shader_selector *gs, const union si_s return MESA_PRIM_TRIANGLES; /* worst case for all callers */ } +/* Return a simplified primitive type, e.g. don't return *_STRIP and *_FAN. + * This returns MESA_PRIM_UNKNOWN if the primitive type is not known at compile time. + */ +unsigned si_get_output_prim_simplified(const struct si_shader_selector *sel, + const union si_shader_key *key) +{ + if (sel->stage == MESA_SHADER_GEOMETRY) { + if (util_rast_prim_is_triangles(sel->info.base.gs.output_primitive)) + return MESA_PRIM_TRIANGLES; + else if (util_prim_is_lines(sel->info.base.gs.output_primitive)) + return MESA_PRIM_LINES; + else + return MESA_PRIM_POINTS; + } + + if (sel->stage == MESA_SHADER_VERTEX && sel->info.base.vs.blit_sgprs_amd) + return SI_PRIM_RECTANGLE_LIST; + + /* It's the same as the input primitive type for VS and TES. */ + return si_get_input_prim(sel, key, true); +} + +unsigned si_get_num_vertices_per_output_prim(struct si_shader *shader) +{ + unsigned prim = si_get_output_prim_simplified(shader->selector, &shader->key); + + switch (prim) { + case MESA_PRIM_TRIANGLES: + case SI_PRIM_RECTANGLE_LIST: + return 3; + case MESA_PRIM_LINES: + return 2; + case MESA_PRIM_POINTS: + return 1; + case MESA_PRIM_UNKNOWN: + return 0; + default: + unreachable("unexpected prim type"); + } +} + static unsigned si_get_vs_out_cntl(const struct si_shader_selector *sel, const struct si_shader *shader, bool ngg) {