From bf80d510c030be3c57d381ff09b7bd1a9a676126 Mon Sep 17 00:00:00 2001 From: Utku Iseri Date: Mon, 26 Jan 2026 10:10:15 +0100 Subject: [PATCH] zink: switch to using unlower_io_to_vars Part-of: --- src/gallium/drivers/zink/ci/traces-zink.yml | 18 +-- src/gallium/drivers/zink/zink_compiler.c | 124 ++++++++++++++------ 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/src/gallium/drivers/zink/ci/traces-zink.yml b/src/gallium/drivers/zink/ci/traces-zink.yml index d75e7cec77e..055ad731e72 100644 --- a/src/gallium/drivers/zink/ci/traces-zink.yml +++ b/src/gallium/drivers/zink/ci/traces-zink.yml @@ -11,9 +11,9 @@ traces: gl-zink-anv-tgl: checksum: 0d04e54fa259d407433a7925c739900a zink-radv-vangogh: - checksum: 52cabbe16a14628f92df31e0fb4c109e + checksum: af9bfe82e2183ce2c3c30be9b8630069 zink-radv-gfx1201: - checksum: 52cabbe16a14628f92df31e0fb4c109e + checksum: af9bfe82e2183ce2c3c30be9b8630069 behdad-glyphy/glyphy-v2.trace: gl-zink-anv-adl: @@ -44,7 +44,7 @@ traces: checksum: 58e2d6ea105ca2735b05ce06709691fb text: "Clear color for the background can be black or grey" zink-radv-gfx1201: - checksum: de4ba8c453cd97c46d0921ddccb4b48b + checksum: c65527b7db55687e3c2741c0286b70e2 blender/blender-demo-ellie_pose.trace: gl-zink-anv-adl: @@ -151,9 +151,9 @@ traces: gl-zink-anv-tgl: checksum: 04a5a9b7cbc88d8a66c33b5f1c08294d zink-radv-vangogh: - checksum: a3249012049c14506894584e649c5274 + checksum: d796864337326ef64526d2218f4504d2 zink-radv-gfx1201: - checksum: a3249012049c14506894584e649c5274 + checksum: d796864337326ef64526d2218f4504d2 humus/AmbientAperture-v2.trace: gl-zink-anv-adl: @@ -326,9 +326,9 @@ traces: checksum: 0af2faa0d9183c1bc4dc7612befe1f0a text: "'egl_platform.cpp( 227) - Error - Couldn't find a suitable EGL config' -- revisit when we can turn on X11?" zink-radv-vangogh: - checksum: d4f1b9d7d6183b95624d9c119e8cfa4c + checksum: cd8285e5886a0406daff110ac5087de6 zink-radv-gfx1201: - checksum: bffa1d53704afb2e1e9407313a7805a9 + checksum: 512c7aaa91c6b37971da696a7b168149 supertuxkart/supertuxkart-menu.rdc: gl-zink-anv-adl: @@ -354,9 +354,9 @@ traces: checksum: ca0b64f1a62e01765146be8391eae636 text: "'egl_platform.cpp( 227) - Error - Couldn't find a suitable EGL config' -- revisit when we can turn on X11?" zink-radv-vangogh: - checksum: ee5bc60979e40f7c314ae90fd50815c9 + checksum: 1301e76c2fb69438e8cfb2f81dcc6611 zink-radv-gfx1201: - checksum: ffc7d4219aaed854c60263ca6627bf3f + checksum: f01f909e9af079efa388f275526f809f unvanquished/unvanquished-lowest.trace: gl-zink-anv-adl: diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 54b2ecdae48..8f18388da68 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -2895,6 +2895,28 @@ scalarize_vars_instr_filter(const nir_intrinsic_instr * intrin, const void *data return (scalarize_var_locations & BITFIELD64_BIT(semantics.location)) != 0; } +static void +fix_var_int_floatness(nir_shader *producer, nir_shader *consumer) +{ + nir_foreach_shader_out_variable(output_var, producer) { + const enum glsl_base_type output_base = + glsl_without_array_or_matrix(output_var->type)->base_type; + nir_foreach_shader_in_variable(input_var, consumer) { + if (input_var->data.location != output_var->data.location || + input_var->data.location_frac != output_var->data.location_frac) + continue; + const glsl_type *vec_type = glsl_without_array_or_matrix(input_var->type); + if (vec_type->base_type != output_base) { + const glsl_type *element = + glsl_vector_type(output_base, vec_type->vector_elements); + input_var->type = nir_is_arrayed_io(input_var, consumer->info.stage) + ? glsl_array_type(element, glsl_array_size(input_var->type), input_var->type->explicit_stride) + : element; + } + } + } +} + void zink_compiler_assign_io(struct zink_screen *screen, nir_shader *producer, nir_shader *consumer) { @@ -2913,6 +2935,7 @@ zink_compiler_assign_io(struct zink_screen *screen, nir_shader *producer, nir_sh .patch_reserved = 0, }; bool do_fixup = false; + fix_var_int_floatness(producer, consumer); nir_shader *nir = producer->info.stage == MESA_SHADER_TESS_CTRL ? producer : consumer; nir_variable *var = nir_find_variable_with_location(producer, nir_var_shader_out, VARYING_SLOT_PSIZ); if (var) { @@ -3755,7 +3778,7 @@ add_derefs_instr(nir_builder *b, nir_intrinsic_instr *intr, void *data) /* filter access that isn't specific to this variable */ if (var->data.location > location || var->data.location + slot_count <= location) continue; - if (var->data.fb_fetch_output != nir_intrinsic_io_semantics(intr).fb_fetch_output) + if ((var->data.fb_fetch_output != nir_intrinsic_io_semantics(intr).fb_fetch_output) && is_input) continue; if (b->shader->info.stage == MESA_SHADER_FRAGMENT && !is_load && nir_intrinsic_io_semantics(intr).dual_source_blend_index != var->data.index) continue; @@ -4092,10 +4115,6 @@ zink_shader_compile(struct zink_screen *screen, bool can_shobj, struct zink_shad if (nir->info.fs.uses_fbfetch_output) { nir_variable *fbfetch = NULL; NIR_PASS(_, nir, lower_fbfetch, &fbfetch, zink_fs_key_base(key)->fbfetch_ms); - /* old variable must be deleted to avoid spirv errors */ - fbfetch->data.mode = nir_var_shader_temp; - nir_fixup_deref_modes(nir); - NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_shader_temp, NULL); need_optimize = true; } nir_foreach_shader_in_variable_safe(var, nir) { @@ -4757,21 +4776,6 @@ scan_nir(struct zink_screen *screen, nir_shader *shader, struct zink_shader *zs) else zs->arrayed_outputs |= BITFIELD64_BIT(s.location); } - /* TODO: delete this once #10826 is fixed */ - if (!(is_input && shader->info.stage == MESA_SHADER_VERTEX)) { - if (is_clipcull_dist(s.location)) { - unsigned frac = nir_intrinsic_component(intr) + 1; - if (s.location < VARYING_SLOT_CULL_DIST0) { - if (s.location == VARYING_SLOT_CLIP_DIST1) - frac += 4; - shader->info.clip_distance_array_size = MAX3(shader->info.clip_distance_array_size, frac, s.num_slots); - } else { - if (s.location == VARYING_SLOT_CULL_DIST1) - frac += 4; - shader->info.cull_distance_array_size = MAX3(shader->info.cull_distance_array_size, frac, s.num_slots); - } - } - } } static bool warned = false; @@ -5100,13 +5104,13 @@ fixup_io_locations(nir_shader *nir) * - any location can be present or not * - it just has to work * - * VAR0 is the only user varying that mesa can produce in this case, so overwrite POS + * VAR0/COL0 are the only user varying that mesa can produce in this case, so overwrite POS * since it's a builtin and yolo it with all the other legacy crap */ nir_foreach_variable_with_modes(var, nir, m) { if (nir_slot_is_sysval_output(var->data.location, MESA_SHADER_NONE)) continue; - if (var->data.location == VARYING_SLOT_VAR0) + if (var->data.location == VARYING_SLOT_VAR0 || var->data.location == VARYING_SLOT_COL0) var->data.driver_location = 0; else if (var->data.patch) var->data.driver_location = var->data.location - VARYING_SLOT_PATCH0; @@ -5813,6 +5817,7 @@ fix_vertex_input_locations_instr(nir_builder *b, nir_intrinsic_instr *intr, void if (sem.location < VERT_ATTRIB_GENERIC0) return false; sem.location = VERT_ATTRIB_GENERIC0 + nir_intrinsic_base(intr); + sem.high_dvec2 = false; /* no 64-bit vertex inputs, that has been lowered already. */ nir_intrinsic_set_io_semantics(intr, sem); return true; } @@ -6175,6 +6180,51 @@ bound_image_arrays(nir_shader *nir) return nir_shader_instructions_pass(nir, bound_image_arrays_instr, nir_metadata_control_flow, NULL); } +static void +separate_clipcull_array(nir_shader *nir, nir_variable *var) +{ + /* if we only have cull distance, just move the var to culldist_0 */ + if (nir->info.clip_distance_array_size == 0) { + var->data.location = VARYING_SLOT_CULL_DIST0; + return; + } + + const glsl_type *cull_array_type = + glsl_array_type(glsl_float_type(), nir->info.cull_distance_array_size, 4); + nir_variable* culldist_var = nir_variable_clone(var, nir); + culldist_var->type = nir_is_arrayed_io(var, nir->info.stage) + ? glsl_array_type(cull_array_type, glsl_array_size(var->type), 0) + : cull_array_type; + culldist_var->data.location = VARYING_SLOT_CULL_DIST0; + culldist_var->data.location_frac = 0; + culldist_var->name = "gl_CullDistance"; + nir_shader_add_variable(nir, culldist_var); + + /* shrink the original clip distance array as well */ + const glsl_type *clip_array_type = + glsl_array_type(glsl_float_type(), nir->info.clip_distance_array_size, 4); + var->type = nir_is_arrayed_io(var, nir->info.stage) + ? glsl_array_type(clip_array_type, glsl_array_size(var->type), 0) + : clip_array_type; +} + +static void +separate_clipcull_arrays(nir_shader *nir) +{ + /* if we don't have cull distances, don't touch anything. */ + if (nir->info.cull_distance_array_size == 0) + return; + /* everything except VS inputs and FS outputs need to be separated */ + nir_variable* output_var = + nir_find_variable_with_location(nir, nir_var_shader_out, VARYING_SLOT_CLIP_DIST0); + if (output_var && nir->info.stage != MESA_SHADER_FRAGMENT) + separate_clipcull_array(nir, output_var); + nir_variable* input_var = + nir_find_variable_with_location(nir, nir_var_shader_in, VARYING_SLOT_CLIP_DIST0); + if (input_var && nir->info.stage != MESA_SHADER_VERTEX) + separate_clipcull_array(nir, input_var); +} + struct zink_shader * zink_shader_create(struct zink_screen *screen, struct nir_shader *nir) { @@ -6254,8 +6304,6 @@ zink_shader_init(struct zink_screen *screen, struct zink_shader *zs) NIR_PASS(_, nir, nir_lower_alu_vec8_16_srcs); } - NIR_PASS(_, nir, nir_lower_io_to_scalar, nir_var_shader_in | nir_var_shader_out, NULL, NULL); - NIR_PASS(_, nir, nir_separate_merged_clip_cull_io); optimize_nir(nir, NULL, true); NIR_PASS(_, nir, bound_image_arrays); NIR_PASS(_, nir, flatten_image_arrays); @@ -6270,22 +6318,32 @@ zink_shader_init(struct zink_screen *screen, struct zink_shader *zs) NIR_PASS(_, nir, fix_vertex_input_locations); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); scan_nir(screen, nir, zs); + NIR_PASS(_, nir, nir_opt_vectorize, NULL, NULL); - NIR_PASS(_, nir, trivial_revectorize); if (nir->info.io_lowered) { - rework_io_vars(nir, nir_var_shader_in, zs); - rework_io_vars(nir, nir_var_shader_out, zs); - nir_sort_variables_by_location(nir, nir_var_shader_in); - nir_sort_variables_by_location(nir, nir_var_shader_out); + NIR_PASS(_, nir, nir_opt_dce); + /* for compute and separate shaders without xfb, ignore the intrinsics and generate derefs. */ + const bool keep_intrinsics = !(mesa_shader_stage_is_compute(nir->info.stage) || nir->info.separate_shader) || + (nir->info.has_transform_feedback_varyings); + NIR_PASS(_, nir, nir_unlower_io_to_vars, keep_intrinsics); + optimize_nir(nir, NULL, true); } + /* NOTE/TODO: this can be removed after add_derefs rework */ + const struct scalarize_vars_instr_filter_data filter_data = { + .location_mask = BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0) | BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1) | + BITFIELD64_BIT(VARYING_SLOT_CULL_DIST0) | BITFIELD64_BIT(VARYING_SLOT_CULL_DIST1) | + BITFIELD64_BIT(VARYING_SLOT_TESS_LEVEL_OUTER) | BITFIELD64_BIT(VARYING_SLOT_TESS_LEVEL_INNER) + }; + NIR_PASS(_, nir, nir_lower_io_to_scalar, nir_var_shader_in | nir_var_shader_out, + scalarize_vars_instr_filter, (void*)&filter_data); + NIR_PASS(_, nir, nir_separate_merged_clip_cull_io); + + separate_clipcull_arrays(nir); + if (nir->info.stage < MESA_SHADER_COMPUTE) create_gfx_pushconst(nir); - if (nir->info.stage == MESA_SHADER_TESS_CTRL || - nir->info.stage == MESA_SHADER_TESS_EVAL) - NIR_PASS(_, nir, nir_lower_io_array_vars_to_elements_no_indirects, false); - if (nir->info.stage < MESA_SHADER_FRAGMENT) have_psiz = check_psiz(nir); if (nir->info.stage == MESA_SHADER_FRAGMENT)