From f4fcfa80164530ad852bfd9e088274a05c9ddbe8 Mon Sep 17 00:00:00 2001 From: Caterina Shablia Date: Thu, 12 Dec 2024 21:22:11 +0000 Subject: [PATCH] pan,nir: introduce load_attribute_pan load_attribute_pan is a panfrost-specific intrinsic for loading vertex attributes. Takes explicit vertex and instance IDs which we need in order to implement vertex attribute divisor with non-zero base instance on v9+. Passes which are used by panvk are modified to be aware of load_attribute_pan. Reviewed-by: Boris Brezillon Reviewed-by: Mary Guillemard Part-of: --- src/compiler/nir/nir_divergence_analysis.c | 6 ++++++ src/compiler/nir/nir_gather_info.c | 1 + src/compiler/nir/nir_intrinsics.py | 6 ++++++ src/compiler/nir/nir_lower_io.c | 1 + src/compiler/nir/nir_opt_shrink_vectors.c | 3 ++- src/compiler/nir/nir_opt_sink.c | 1 + src/compiler/nir/nir_print.c | 1 + src/compiler/nir/nir_validate.c | 1 + src/panfrost/compiler/bi_lower_divergent_indirects.c | 1 + 9 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index fe8f266ad58..33079237c2b 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -384,6 +384,12 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) is_divergent = true; } break; + case nir_intrinsic_load_attribute_pan: + assert(stage == MESA_SHADER_VERTEX); + is_divergent = src_divergent(instr->src[0], state) || + src_divergent(instr->src[1], state) || + src_divergent(instr->src[2], state); + break; case nir_intrinsic_load_per_vertex_input: is_divergent = src_divergent(instr->src[0], state) || src_divergent(instr->src[1], state); diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index b6ecba36ecb..94624dee960 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -543,6 +543,7 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader, case nir_intrinsic_load_input_vertex: case nir_intrinsic_load_interpolated_input: case nir_intrinsic_load_per_primitive_input: + case nir_intrinsic_load_attribute_pan: if (shader->info.stage == MESA_SHADER_TESS_EVAL && instr->intrinsic == nir_intrinsic_load_input && !is_patch_special) { diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index b3508f099d3..276da0a63f2 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -1476,6 +1476,12 @@ intrinsic("prefetch_sam_ir3", [1, 1], flags=[CAN_REORDER]) intrinsic("prefetch_tex_ir3", [1], flags=[CAN_REORDER]) intrinsic("prefetch_ubo_ir3", [1], flags=[CAN_REORDER]) +# Panfrost-specific intrinsic for loading vertex attributes. Takes explicit +# vertex and instance IDs which we need in order to implement vertex attribute +# divisor with non-zero base instance on v9+. +# src[] = { vertex_id, instance_id, offset } +load("attribute_pan", [1, 1, 1], [BASE, COMPONENT, DEST_TYPE, IO_SEMANTICS], [CAN_ELIMINATE, CAN_REORDER]) + # Intrinsics used by the Midgard/Bifrost blend pipeline. These are defined # within a blend shader to read/write the raw value from the tile buffer, # without applying any format conversion in the process. If the shader needs diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index 10b11173d80..b96de5d5fe1 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -2870,6 +2870,7 @@ nir_get_io_offset_src_number(const nir_intrinsic_instr *instr) case nir_intrinsic_store_per_vertex_output: case nir_intrinsic_store_per_view_output: case nir_intrinsic_store_per_primitive_output: + case nir_intrinsic_load_attribute_pan: return 2; default: return -1; diff --git a/src/compiler/nir/nir_opt_shrink_vectors.c b/src/compiler/nir/nir_opt_shrink_vectors.c index 573e6ee60e5..5311e29f8af 100644 --- a/src/compiler/nir/nir_opt_shrink_vectors.c +++ b/src/compiler/nir/nir_opt_shrink_vectors.c @@ -332,7 +332,8 @@ opt_shrink_vectors_intrinsic(nir_builder *b, nir_intrinsic_instr *instr, case nir_intrinsic_load_global: case nir_intrinsic_load_global_constant: case nir_intrinsic_load_kernel_input: - case nir_intrinsic_load_scratch: { + case nir_intrinsic_load_scratch: + case nir_intrinsic_load_attribute_pan: { /* Must be a vectorized intrinsic that we can resize. */ assert(instr->num_components != 0); diff --git a/src/compiler/nir/nir_opt_sink.c b/src/compiler/nir/nir_opt_sink.c index b871c8f035b..bc028226b4f 100644 --- a/src/compiler/nir/nir_opt_sink.c +++ b/src/compiler/nir/nir_opt_sink.c @@ -109,6 +109,7 @@ can_sink_instr(nir_instr *instr, nir_move_options options, bool *can_mov_out_of_ case nir_intrinsic_load_frag_coord: case nir_intrinsic_load_frag_coord_zw: case nir_intrinsic_load_pixel_coord: + case nir_intrinsic_load_attribute_pan: return options & nir_move_load_input; case nir_intrinsic_load_uniform: case nir_intrinsic_load_kernel_input: diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 6eb04eff4f0..28274b0dfd0 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -1364,6 +1364,7 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) case nir_intrinsic_load_per_vertex_input: case nir_intrinsic_load_input_vertex: case nir_intrinsic_load_coefficients_agx: + case nir_intrinsic_load_attribute_pan: mode = nir_var_shader_in; break; diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 99befd17e47..e4351b2942c 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -621,6 +621,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state) case nir_intrinsic_load_per_view_output: case nir_intrinsic_load_per_primitive_output: case nir_intrinsic_load_push_constant: + case nir_intrinsic_load_attribute_pan: /* All memory load operations must load at least a byte */ validate_assert(state, instr->def.bit_size >= 8); break; diff --git a/src/panfrost/compiler/bi_lower_divergent_indirects.c b/src/panfrost/compiler/bi_lower_divergent_indirects.c index 54fb34d07c5..a93ed36db25 100644 --- a/src/panfrost/compiler/bi_lower_divergent_indirects.c +++ b/src/panfrost/compiler/bi_lower_divergent_indirects.c @@ -48,6 +48,7 @@ bi_lower_divergent_indirects_impl(nir_builder *b, nir_intrinsic_instr *intr, switch (intr->intrinsic) { case nir_intrinsic_load_input: case nir_intrinsic_load_interpolated_input: + case nir_intrinsic_load_attribute_pan: /* Attributes and varyings */ offset = nir_get_io_offset_src(intr); break;