From fb9b2261a1708f4375d68f8f63acf8f2d3a9b70f Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Fri, 21 Feb 2025 10:47:53 -0800 Subject: [PATCH] intel/elk: Move pre-gen6 gl_FragCoord.w -> interpolation lowering to NIR. BRW shader-db: total instructions in shared programs: 4409143 -> 4409146 (<.01%) instructions in affected programs: 330 -> 333 (0.91%) Reviewed-by: Alyssa Rosenzweig Part-of: --- src/intel/compiler/elk/elk_fs_nir.cpp | 2 ++ src/intel/compiler/elk/elk_nir.c | 41 +++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/intel/compiler/elk/elk_fs_nir.cpp b/src/intel/compiler/elk/elk_fs_nir.cpp index c09d02c47c7..da239cda24e 100644 --- a/src/intel/compiler/elk/elk_fs_nir.cpp +++ b/src/intel/compiler/elk/elk_fs_nir.cpp @@ -3930,6 +3930,8 @@ fs_nir_emit_fs_intrinsic(nir_to_elk_state &ntb, break; case nir_intrinsic_load_frag_coord_w: + /* Lowered to interpolation pre-gen6. */ + assert(devinfo->ver >= 6); bld.MOV(dest, s.wpos_w); break; diff --git a/src/intel/compiler/elk/elk_nir.c b/src/intel/compiler/elk/elk_nir.c index 67cc8fd9150..0642880064d 100644 --- a/src/intel/compiler/elk/elk_nir.c +++ b/src/intel/compiler/elk/elk_nir.c @@ -488,6 +488,35 @@ lower_barycentric_at_offset(nir_builder *b, nir_intrinsic_instr *intrin, return true; } +static bool +elk_nir_lower_load_frag_coord_w_gfx4_instr(nir_builder *b, nir_intrinsic_instr *intr, void *_data) +{ + if (intr->intrinsic != nir_intrinsic_load_frag_coord_w) + return false; + + nir_variable *pos = nir_get_variable_with_location(b->shader, nir_var_shader_in, + VARYING_SLOT_POS, glsl_vec4_type()); + + /* See elk_nir_lower_fs_inputs(), which did this for other vars already. */ + pos->data.driver_location = VARYING_SLOT_POS; + + b->cursor = nir_instr_remove(&intr->instr); + nir_def_rewrite_uses(&intr->def, nir_channel(b, nir_load_var(b, pos), 3)); + + return true; +} + +/* No actual sysval for gl_FragCoord.w on this hardware, promote it to a varying + * interpolation. + */ +static bool +elk_nir_lower_load_frag_coord_w_gfx4(nir_shader *shader) +{ + return nir_shader_intrinsics_pass(shader, elk_nir_lower_load_frag_coord_w_gfx4_instr, + nir_metadata_block_index | nir_metadata_dominance, + NULL); +} + void elk_nir_lower_fs_inputs(nir_shader *nir, const struct intel_device_info *devinfo, @@ -520,6 +549,13 @@ elk_nir_lower_fs_inputs(nir_shader *nir, } } + /* This needs to run late, after lower_wpos_center and lower_input_attachments. */ + NIR_PASS(_, nir, nir_lower_frag_coord_to_pixel_coord); + if (devinfo->ver < 6) { + /* Needs to be run before nir_lower_io. */ + NIR_PASS(_, nir, elk_nir_lower_load_frag_coord_w_gfx4); + } + nir_lower_io(nir, nir_var_shader_in, elk_type_size_vec4, nir_lower_io_lower_64bit_to_32 | nir_lower_io_use_interpolated_input_intrinsics); @@ -1374,11 +1410,6 @@ elk_postprocess_nir(nir_shader *nir, const struct elk_compiler *compiler, OPT(intel_nir_lower_sparse_intrinsics); - if (nir->info.stage == MESA_SHADER_FRAGMENT) { - /* This needs to run late, after lower_wpos_center and lower_input_attachments. */ - OPT(nir_lower_frag_coord_to_pixel_coord); - } - OPT(nir_lower_bit_size, lower_bit_size_callback, (void *)compiler); OPT(nir_opt_combine_barriers, combine_all_memory_barriers, NULL);