From d3a284660e2d2e6bb5a395017878919e10d71779 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Tue, 22 Jul 2025 13:36:23 -0700 Subject: [PATCH] d3d12: Use NIR_PASS instead of NIR_PASS_V Part-of: --- src/gallium/drivers/d3d12/d3d12_compiler.cpp | 82 ++-- .../d3d12/d3d12_compute_transforms.cpp | 2 +- .../drivers/d3d12/d3d12_gs_variant.cpp | 4 +- src/gallium/drivers/d3d12/d3d12_nir_passes.c | 414 +++++++++--------- src/gallium/drivers/d3d12/d3d12_nir_passes.h | 16 +- .../drivers/d3d12/d3d12_tcs_variant.cpp | 2 +- src/microsoft/spirv_to_dxil/dxil_spirv_nir.c | 193 ++++---- 7 files changed, 349 insertions(+), 364 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp index ed5fea6135d..04f3657e70d 100644 --- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp +++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp @@ -91,16 +91,16 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel, shader->nir = nir; sel->current = shader; - NIR_PASS_V(nir, nir_lower_samplers); - NIR_PASS_V(nir, dxil_nir_split_typed_samplers); + NIR_PASS(_, nir, nir_lower_samplers); + NIR_PASS(_, nir, dxil_nir_split_typed_samplers); - NIR_PASS_V(nir, nir_opt_dce); + NIR_PASS(_, nir, nir_opt_dce); struct nir_remove_dead_variables_options dead_var_opts = {}; dead_var_opts.can_remove_var = can_remove_dead_sampler; - NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_uniform, &dead_var_opts); + NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_uniform, &dead_var_opts); if (key->samples_int_textures) - NIR_PASS_V(nir, dxil_lower_sample_to_txf_for_integer_tex, + NIR_PASS(_, nir, dxil_lower_sample_to_txf_for_integer_tex, key->n_texture_states, key->tex_wrap_states, key->swizzle_state, screen->base.caps.max_texture_lod_bias); @@ -109,19 +109,19 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel, if (key->last_vertex_processing_stage) { if (key->invert_depth) - NIR_PASS_V(nir, d3d12_nir_invert_depth, key->invert_depth, key->halfz); + NIR_PASS(_, nir, d3d12_nir_invert_depth, key->invert_depth, key->halfz); if (!key->halfz) - NIR_PASS_V(nir, nir_lower_clip_halfz); - NIR_PASS_V(nir, d3d12_lower_yflip); + NIR_PASS(_, nir, nir_lower_clip_halfz); + NIR_PASS(_, nir, d3d12_lower_yflip); } - NIR_PASS_V(nir, d3d12_lower_state_vars, shader); + NIR_PASS(_, nir, d3d12_lower_state_vars, shader); const struct dxil_nir_lower_loads_stores_options loads_stores_options = {}; - NIR_PASS_V(nir, dxil_nir_lower_loads_stores_to_dxil, &loads_stores_options); + NIR_PASS(_, nir, dxil_nir_lower_loads_stores_to_dxil, &loads_stores_options); if (key->stage == PIPE_SHADER_FRAGMENT && key->fs.multisample_disabled) - NIR_PASS_V(nir, d3d12_disable_multisampling); + NIR_PASS(_, nir, d3d12_disable_multisampling); struct nir_to_dxil_options opts = {}; opts.interpolate_at_vertex = screen->have_load_at_vertex; @@ -1077,7 +1077,7 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele /* Apply any needed lowering passes */ if (key.stage == PIPE_SHADER_GEOMETRY) { if (key.gs.writes_psize) { - NIR_PASS_V(new_nir_variant, d3d12_lower_point_sprite, + NIR_PASS(_, new_nir_variant, d3d12_lower_point_sprite, !key.gs.sprite_origin_upper_left, key.gs.point_size_per_vertex, key.gs.sprite_coord_enable, @@ -1085,15 +1085,15 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele } if (key.gs.primitive_id) - NIR_PASS_V(new_nir_variant, d3d12_lower_primitive_id); + NIR_PASS(_, new_nir_variant, d3d12_lower_primitive_id); if (key.gs.triangle_strip) - NIR_PASS_V(new_nir_variant, d3d12_lower_triangle_strip); + NIR_PASS(_, new_nir_variant, d3d12_lower_triangle_strip); } else if (key.stage == PIPE_SHADER_FRAGMENT) { if (key.fs.polygon_stipple) { - NIR_PASS_V(new_nir_variant, nir_lower_pstipple_fs, + NIR_PASS(_, new_nir_variant, nir_lower_pstipple_fs, &pstipple_binding, 0, false, nir_type_bool1); } @@ -1101,15 +1101,15 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele dxil_nir_forward_front_face(new_nir_variant); if (key.fs.missing_dual_src_outputs) { - NIR_PASS_V(new_nir_variant, d3d12_add_missing_dual_src_target, + NIR_PASS(_, new_nir_variant, d3d12_add_missing_dual_src_target, key.fs.missing_dual_src_outputs); } else if (key.fs.frag_result_color_lowering) { - NIR_PASS_V(new_nir_variant, nir_lower_fragcolor, + NIR_PASS(_, new_nir_variant, nir_lower_fragcolor, key.fs.frag_result_color_lowering); } if (key.fs.manual_depth_range) - NIR_PASS_V(new_nir_variant, d3d12_lower_depth_range); + NIR_PASS(_, new_nir_variant, d3d12_lower_depth_range); } @@ -1117,7 +1117,7 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele STATIC_ASSERT(sizeof(dxil_texture_swizzle_state) == sizeof(nir_lower_tex_shadow_swizzle)); - NIR_PASS_V(new_nir_variant, + NIR_PASS(_, new_nir_variant, nir_lower_tex_shadow, key.n_texture_states, key.sampler_compare_funcs, @@ -1127,14 +1127,14 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele if (key.stage == PIPE_SHADER_FRAGMENT) { if (key.fs.cast_to_uint) - NIR_PASS_V(new_nir_variant, d3d12_lower_uint_cast, false); + NIR_PASS(_, new_nir_variant, d3d12_lower_uint_cast, false); if (key.fs.cast_to_int) - NIR_PASS_V(new_nir_variant, d3d12_lower_uint_cast, true); + NIR_PASS(_, new_nir_variant, d3d12_lower_uint_cast, true); } if (key.n_images) { d3d12_image_format_conversion_info_arr image_format_arr = { key.n_images, key.image_format_conversion }; - NIR_PASS_V(new_nir_variant, d3d12_lower_image_casts, &image_format_arr); + NIR_PASS(_, new_nir_variant, d3d12_lower_image_casts, &image_format_arr); } if (key.stage == PIPE_SHADER_COMPUTE && sel->workgroup_size_variable) { @@ -1149,7 +1149,7 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele new_nir_variant->info.tess.point_mode = key.hs.point_mode; new_nir_variant->info.tess.spacing = key.hs.spacing; - NIR_PASS_V(new_nir_variant, dxil_nir_set_tcs_patches_in, key.hs.patch_vertices_in); + NIR_PASS(_, new_nir_variant, dxil_nir_set_tcs_patches_in, key.hs.patch_vertices_in); } else if (new_nir_variant->info.stage == MESA_SHADER_TESS_EVAL) { new_nir_variant->info.tess.tcs_vertices_out = static_cast(key.ds.tcs_vertices_out); } @@ -1165,12 +1165,12 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele tex_options.lower_invalid_implicit_lod = true; tex_options.lower_tg4_offsets = true; - NIR_PASS_V(new_nir_variant, nir_lower_tex, &tex_options); + NIR_PASS(_, new_nir_variant, nir_lower_tex, &tex_options); } /* Remove not-written inputs, and re-sort */ if (prev) { - NIR_PASS_V(new_nir_variant, dxil_nir_kill_undefined_varyings, key.prev_varying_outputs, + NIR_PASS(_, new_nir_variant, dxil_nir_kill_undefined_varyings, key.prev_varying_outputs, prev->initial->info.patch_outputs_written, key.prev_varying_frac_outputs); dxil_reassign_driver_locations(new_nir_variant, nir_var_shader_in, key.prev_varying_outputs, key.prev_varying_frac_outputs); @@ -1178,7 +1178,7 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele /* Remove not-read outputs and re-sort */ if (next) { - NIR_PASS_V(new_nir_variant, dxil_nir_kill_unused_outputs, key.next_varying_inputs, + NIR_PASS(_, new_nir_variant, dxil_nir_kill_unused_outputs, key.next_varying_inputs, next->initial->info.patch_inputs_read, key.next_varying_frac_inputs); dxil_reassign_driver_locations(new_nir_variant, nir_var_shader_out, key.next_varying_inputs, key.next_varying_frac_inputs); @@ -1319,10 +1319,10 @@ d3d12_create_shader_impl(struct d3d12_context *ctx, /* Integer cube maps are not supported in DirectX because sampling is not supported * on integer textures and TextureLoad is not supported for cube maps, so we have to * lower integer cube maps to be handled like 2D textures arrays*/ - NIR_PASS_V(nir, dxil_nir_lower_int_cubemaps, true); + NIR_PASS(_, nir, dxil_nir_lower_int_cubemaps, true); - NIR_PASS_V(nir, dxil_nir_lower_subgroup_id); - NIR_PASS_V(nir, dxil_nir_lower_num_subgroups); + NIR_PASS(_, nir, dxil_nir_lower_subgroup_id); + NIR_PASS(_, nir, dxil_nir_lower_num_subgroups); nir_lower_subgroups_options subgroup_options = {}; subgroup_options.ballot_bit_size = 32; @@ -1333,8 +1333,8 @@ d3d12_create_shader_impl(struct d3d12_context *ctx, subgroup_options.lower_inverse_ballot = true; if (nir->info.stage != MESA_SHADER_FRAGMENT && nir->info.stage != MESA_SHADER_COMPUTE) subgroup_options.lower_quad = true; - NIR_PASS_V(nir, nir_lower_subgroups, &subgroup_options); - NIR_PASS_V(nir, nir_lower_bit_size, [](const nir_instr *instr, void *) -> unsigned { + NIR_PASS(_, nir, nir_lower_subgroups, &subgroup_options); + NIR_PASS(_, nir, nir_lower_bit_size, [](const nir_instr *instr, void *) -> unsigned { if (instr->type != nir_instr_type_intrinsic) return 0; nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); @@ -1352,16 +1352,16 @@ d3d12_create_shader_impl(struct d3d12_context *ctx, }, NULL); // Ensure subgroup scans on bools are gone - NIR_PASS_V(nir, nir_opt_dce); - NIR_PASS_V(nir, dxil_nir_lower_unsupported_subgroup_scan); + NIR_PASS(_, nir, nir_opt_dce); + NIR_PASS(_, nir, dxil_nir_lower_unsupported_subgroup_scan); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); if (nir->info.stage == MESA_SHADER_COMPUTE) - NIR_PASS_V(nir, d3d12_lower_compute_state_vars); - NIR_PASS_V(nir, d3d12_lower_load_draw_params); - NIR_PASS_V(nir, d3d12_lower_load_patch_vertices_in); - NIR_PASS_V(nir, dxil_nir_lower_double_math); + NIR_PASS(_, nir, d3d12_lower_compute_state_vars); + NIR_PASS(_, nir, d3d12_lower_load_draw_params); + NIR_PASS(_, nir, d3d12_lower_load_patch_vertices_in); + NIR_PASS(_, nir, dxil_nir_lower_double_math); nir_foreach_variable_with_modes(var, nir, nir_var_shader_in) { if (var->data.location >= VARYING_SLOT_VAR0 && var->data.location_frac) { @@ -1409,8 +1409,8 @@ d3d12_create_shader(struct d3d12_context *ctx, assert(nir != NULL); - NIR_PASS_V(nir, dxil_nir_split_clip_cull_distance); - NIR_PASS_V(nir, d3d12_split_needed_varyings); + NIR_PASS(_, nir, dxil_nir_split_clip_cull_distance); + NIR_PASS(_, nir, d3d12_split_needed_varyings); if (nir->info.stage == MESA_SHADER_TESS_EVAL || nir->info.stage == MESA_SHADER_TESS_CTRL) { /* D3D requires exactly-matching patch constant signatures. Since tess ctrl must write these vars, @@ -1451,8 +1451,8 @@ d3d12_create_shader(struct d3d12_context *ctx, if (nir->info.stage != MESA_SHADER_FRAGMENT) { dxil_reassign_driver_locations(nir, nir_var_shader_out, 0, NULL); } else { - NIR_PASS_V(nir, nir_lower_fragcoord_wtrans); - NIR_PASS_V(nir, dxil_nir_lower_sample_pos); + NIR_PASS(_, nir, nir_lower_fragcoord_wtrans); + NIR_PASS(_, nir, dxil_nir_lower_sample_pos); dxil_sort_ps_outputs(nir); } diff --git a/src/gallium/drivers/d3d12/d3d12_compute_transforms.cpp b/src/gallium/drivers/d3d12/d3d12_compute_transforms.cpp index 049aefe45ba..85a285c55af 100644 --- a/src/gallium/drivers/d3d12/d3d12_compute_transforms.cpp +++ b/src/gallium/drivers/d3d12/d3d12_compute_transforms.cpp @@ -380,7 +380,7 @@ get_query_resolve(const nir_shader_compiler_options *options, const d3d12_comput b.shader->info.num_ssbos = key->query_resolve.num_subqueries + !key->query_resolve.is_resolve_in_place; b.shader->info.num_ubos = 0; - NIR_PASS_V(b.shader, nir_lower_convert_alu_types, NULL); + NIR_PASS(_, b.shader, nir_lower_convert_alu_types, NULL); return b.shader; } diff --git a/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp b/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp index 4706709eeb5..3f5cfbd4568 100644 --- a/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp +++ b/src/gallium/drivers/d3d12/d3d12_gs_variant.cpp @@ -144,7 +144,7 @@ d3d12_make_passthrough_gs(struct d3d12_context *ctx, struct d3d12_gs_variant_key nir_emit_vertex(&b, 0); nir_end_primitive(&b, 0); - NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS(_, nir, nir_lower_var_copies); nir_validate_shader(nir, "in d3d12_create_passthrough_gs"); templ.type = PIPE_SHADER_IR_NIR; @@ -338,7 +338,7 @@ d3d12_finish_emit_primitives_gs(struct emit_primitives_context *emit_ctx, bool e nir_validate_shader(nir, "in d3d12_lower_edge_flags"); - NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS(_, nir, nir_lower_var_copies); templ.type = PIPE_SHADER_IR_NIR; templ.ir.nir = nir; diff --git a/src/gallium/drivers/d3d12/d3d12_nir_passes.c b/src/gallium/drivers/d3d12/d3d12_nir_passes.c index bfe2bfad78e..f54d8333914 100644 --- a/src/gallium/drivers/d3d12/d3d12_nir_passes.c +++ b/src/gallium/drivers/d3d12/d3d12_nir_passes.c @@ -54,22 +54,19 @@ d3d12_get_state_var(nir_builder *b, return nir_load_var(b, *out_var); } -static void -lower_pos_write(nir_builder *b, struct nir_instr *instr, nir_variable **flip) +static bool +lower_pos_write(nir_builder *b, struct nir_intrinsic_instr *intr, void *_flip) { - if (instr->type != nir_instr_type_intrinsic) - return; - - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); if (intr->intrinsic != nir_intrinsic_store_deref) - return; + return false; nir_variable *var = nir_intrinsic_get_var(intr, 0); if (var->data.mode != nir_var_shader_out || var->data.location != VARYING_SLOT_POS) - return; + return false; b->cursor = nir_before_instr(&intr->instr); + nir_variable **flip = (nir_variable **)_flip; nir_def *pos = intr->src[1].ssa; nir_def *flip_y = d3d12_get_state_var(b, D3D12_STATE_VAR_Y_FLIP, "d3d12_FlipY", @@ -80,50 +77,41 @@ lower_pos_write(nir_builder *b, struct nir_instr *instr, nir_variable **flip) nir_channel(b, pos, 2), nir_channel(b, pos, 3)); nir_src_rewrite(intr->src + 1, def); + return true; } -void +bool d3d12_lower_yflip(nir_shader *nir) { nir_variable *flip = NULL; if (nir->info.stage != MESA_SHADER_VERTEX && nir->info.stage != MESA_SHADER_TESS_EVAL && - nir->info.stage != MESA_SHADER_GEOMETRY) - return; - - nir_foreach_function_impl(impl, nir) { - nir_builder b = nir_builder_create(impl); - - nir_foreach_block(block, impl) { - nir_foreach_instr_safe(instr, block) { - lower_pos_write(&b, instr, &flip); - } - } - - nir_progress(true, impl, nir_metadata_control_flow); + nir->info.stage != MESA_SHADER_GEOMETRY) { + nir_shader_preserve_all_metadata(nir); + return false; } + + return nir_shader_intrinsics_pass(nir, lower_pos_write, + nir_metadata_control_flow | nir_metadata_loop_analysis, + &flip); } -static void -lower_pos_read(nir_builder *b, struct nir_instr *instr, - nir_variable **depth_transform_var) +static bool +lower_pos_read(nir_builder *b, struct nir_intrinsic_instr *intr, void *_var) { - if (instr->type != nir_instr_type_intrinsic) - return; - - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); if (intr->intrinsic != nir_intrinsic_load_deref) - return; + return false; nir_variable *var = nir_intrinsic_get_var(intr, 0); if (var->data.mode != nir_var_shader_in || var->data.location != VARYING_SLOT_POS) - return; + return false; - b->cursor = nir_after_instr(instr); + b->cursor = nir_after_instr(&intr->instr); + nir_variable **depth_transform_var = (nir_variable **)_var; - nir_def *pos = nir_instr_def(instr); + nir_def *pos = &intr->def; nir_def *depth = nir_channel(b, pos, 2); assert(depth_transform_var); @@ -136,26 +124,18 @@ lower_pos_read(nir_builder *b, struct nir_instr *instr, pos = nir_vector_insert_imm(b, pos, depth, 2); - nir_def_rewrite_uses_after(&intr->def, pos, - pos->parent_instr); + nir_def_rewrite_uses_after(&intr->def, pos, pos->parent_instr); + return true; } -void +bool d3d12_lower_depth_range(nir_shader *nir) { assert(nir->info.stage == MESA_SHADER_FRAGMENT); nir_variable *depth_transform = NULL; - nir_foreach_function_impl(impl, nir) { - nir_builder b = nir_builder_create(impl); - - nir_foreach_block(block, impl) { - nir_foreach_instr_safe(instr, block) { - lower_pos_read(&b, instr, &depth_transform); - } - } - - nir_progress(true, impl, nir_metadata_control_flow); - } + return nir_shader_intrinsics_pass(nir, lower_pos_read, + nir_metadata_control_flow | nir_metadata_loop_analysis, + &depth_transform); } struct compute_state_vars { @@ -163,27 +143,32 @@ struct compute_state_vars { }; static bool -lower_compute_state_vars(nir_builder *b, nir_instr *instr, void *_state) +is_compute_state_var(const nir_instr *instr, const void *_state) { if (instr->type != nir_instr_type_intrinsic) return false; - - b->cursor = nir_after_instr(instr); nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - struct compute_state_vars *vars = _state; - nir_def *result = NULL; switch (intr->intrinsic) { case nir_intrinsic_load_num_workgroups: - result = d3d12_get_state_var(b, D3D12_STATE_VAR_NUM_WORKGROUPS, "d3d12_NumWorkgroups", - glsl_vec_type(3), &vars->num_workgroups); - break; + return true; default: return false; } +} - nir_def_rewrite_uses(&intr->def, result); - nir_instr_remove(instr); - return true; +static nir_def * +lower_compute_state_vars(nir_builder *b, nir_instr *instr, void *_state) +{ + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + struct compute_state_vars *vars = _state; + switch (intr->intrinsic) { + case nir_intrinsic_load_num_workgroups: + return d3d12_get_state_var(b, D3D12_STATE_VAR_NUM_WORKGROUPS, "d3d12_NumWorkgroups", + glsl_vec_type(3), &vars->num_workgroups); + break; + default: + return NULL; + } } bool @@ -191,8 +176,7 @@ d3d12_lower_compute_state_vars(nir_shader *nir) { assert(nir->info.stage == MESA_SHADER_COMPUTE); struct compute_state_vars vars = { 0 }; - return nir_shader_instructions_pass(nir, lower_compute_state_vars, - nir_metadata_control_flow, &vars); + return nir_shader_lower_instructions(nir, is_compute_state_var, lower_compute_state_vars, &vars); } static bool @@ -203,24 +187,21 @@ is_color_output(nir_variable *var) var->data.location >= FRAG_RESULT_DATA0)); } -static void -lower_uint_color_write(nir_builder *b, struct nir_instr *instr, bool is_signed) +static bool +lower_uint_color_write(nir_builder *b, struct nir_intrinsic_instr *intr, void *_is_signed) { const unsigned NUM_BITS = 8; const unsigned bits[4] = { NUM_BITS, NUM_BITS, NUM_BITS, NUM_BITS }; - if (instr->type != nir_instr_type_intrinsic) - return; - - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - if (intr->intrinsic != nir_intrinsic_store_deref) - return; - - nir_variable *var = nir_intrinsic_get_var(intr, 0); + nir_deref_instr *deref = nir_src_as_deref(intr->src[0]); + if (!deref) + return false; + nir_variable *var = nir_deref_instr_get_variable(deref); if (!is_color_output(var)) - return; + return false; b->cursor = nir_before_instr(&intr->instr); + bool is_signed = *(bool *)_is_signed; nir_def *col = intr->src[1].ssa; nir_def *def = is_signed ? nir_format_float_to_snorm(b, col, bits) : @@ -230,74 +211,76 @@ lower_uint_color_write(nir_builder *b, struct nir_instr *instr, bool is_signed) nir_iadd_imm(b, def, 1ull << NUM_BITS), def); nir_src_rewrite(intr->src + 1, def); + return true; } -void +bool d3d12_lower_uint_cast(nir_shader *nir, bool is_signed) { - if (nir->info.stage != MESA_SHADER_FRAGMENT) - return; - - nir_foreach_function_impl(impl, nir) { - nir_builder b = nir_builder_create(impl); - - nir_foreach_block(block, impl) { - nir_foreach_instr_safe(instr, block) { - lower_uint_color_write(&b, instr, is_signed); - } - } - - nir_progress(true, impl, nir_metadata_control_flow); + if (nir->info.stage != MESA_SHADER_FRAGMENT) { + nir_shader_preserve_all_metadata(nir); + return false; } + + return nir_shader_intrinsics_pass(nir, lower_uint_color_write, + nir_metadata_control_flow | nir_metadata_loop_analysis, + &is_signed); } static bool -lower_load_draw_params(nir_builder *b, nir_intrinsic_instr *intr, - void *draw_params) +is_draw_param(const nir_instr *instr, const void *draw_params) { - if (intr->intrinsic != nir_intrinsic_load_first_vertex && - intr->intrinsic != nir_intrinsic_load_base_instance && - intr->intrinsic != nir_intrinsic_load_draw_id && - intr->intrinsic != nir_intrinsic_load_is_indexed_draw) + if (instr->type != nir_instr_type_intrinsic) return false; + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + switch (intr->intrinsic) { + case nir_intrinsic_load_first_vertex: + case nir_intrinsic_load_base_instance: + case nir_intrinsic_load_draw_id: + case nir_intrinsic_load_is_indexed_draw: + return true; + default: + return false; + } +} - b->cursor = nir_before_instr(&intr->instr); - +static nir_def * +lower_load_draw_params(nir_builder *b, nir_instr *instr, void *draw_params) +{ + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); nir_def *load = d3d12_get_state_var(b, D3D12_STATE_VAR_DRAW_PARAMS, "d3d12_DrawParams", glsl_uvec4_type(), draw_params); unsigned channel = intr->intrinsic == nir_intrinsic_load_first_vertex ? 0 : intr->intrinsic == nir_intrinsic_load_base_instance ? 1 : intr->intrinsic == nir_intrinsic_load_draw_id ? 2 : 3; - nir_def_replace(&intr->def, nir_channel(b, load, channel)); - - return true; + return nir_channel(b, load, channel); } bool d3d12_lower_load_draw_params(struct nir_shader *nir) { nir_variable *draw_params = NULL; - if (nir->info.stage != MESA_SHADER_VERTEX) + if (nir->info.stage != MESA_SHADER_VERTEX) { + nir_shader_preserve_all_metadata(nir); return false; + } - return nir_shader_intrinsics_pass(nir, lower_load_draw_params, - nir_metadata_control_flow, - &draw_params); + return nir_shader_lower_instructions(nir, is_draw_param, lower_load_draw_params, &draw_params); } static bool -lower_load_patch_vertices_in(nir_builder *b, nir_intrinsic_instr *intr, - void *_state) +is_patch_vertices_in(const nir_instr *instr, const void *_state) { - if (intr->intrinsic != nir_intrinsic_load_patch_vertices_in) - return false; + return instr->type == nir_instr_type_intrinsic && + nir_instr_as_intrinsic(instr)->intrinsic == nir_intrinsic_load_patch_vertices_in; +} - b->cursor = nir_before_instr(&intr->instr); - nir_def *load = b->shader->info.stage == MESA_SHADER_TESS_CTRL ? +static nir_def * +lower_load_patch_vertices_in(nir_builder *b, nir_instr *instr, void *_state) +{ + return b->shader->info.stage == MESA_SHADER_TESS_CTRL ? d3d12_get_state_var(b, D3D12_STATE_VAR_PATCH_VERTICES_IN, "d3d12_FirstVertex", glsl_uint_type(), _state) : nir_imm_int(b, b->shader->info.tess.tcs_vertices_out); - nir_def_replace(&intr->def, load); - return true; } bool @@ -306,12 +289,12 @@ d3d12_lower_load_patch_vertices_in(struct nir_shader *nir) nir_variable *var = NULL; if (nir->info.stage != MESA_SHADER_TESS_CTRL && - nir->info.stage != MESA_SHADER_TESS_EVAL) + nir->info.stage != MESA_SHADER_TESS_EVAL) { + nir_shader_preserve_all_metadata(nir); return false; + } - return nir_shader_intrinsics_pass(nir, lower_load_patch_vertices_in, - nir_metadata_control_flow, - &var); + return nir_shader_lower_instructions(nir, is_patch_vertices_in, lower_load_patch_vertices_in, &var); } struct invert_depth_state @@ -322,7 +305,7 @@ struct invert_depth_state nir_instr *store_pos_instr; }; -static void +static bool invert_depth_impl(nir_builder *b, struct invert_depth_state *state) { assert(state->store_pos_instr); @@ -359,28 +342,27 @@ invert_depth_impl(nir_builder *b, struct invert_depth_state *state) state->viewport_index = NULL; state->store_pos_instr = NULL; + return true; } -static void -invert_depth_instr(nir_builder *b, struct nir_instr *instr, struct invert_depth_state *state) +static bool +invert_depth_intr(nir_builder *b, struct nir_intrinsic_instr *intr, void *_state) { - if (instr->type != nir_instr_type_intrinsic) - return; - - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + struct invert_depth_state *state = (struct invert_depth_state *)_state; if (intr->intrinsic == nir_intrinsic_store_deref) { nir_variable *var = nir_intrinsic_get_var(intr, 0); if (var->data.mode != nir_var_shader_out) - return; + return false; if (var->data.location == VARYING_SLOT_VIEWPORT) state->viewport_index = intr->src[1].ssa; if (var->data.location == VARYING_SLOT_POS) - state->store_pos_instr = instr; + state->store_pos_instr = &intr->instr; } else if (intr->intrinsic == nir_intrinsic_emit_vertex) { - b->cursor = nir_before_instr(instr); - invert_depth_impl(b, state); + b->cursor = nir_before_instr(&intr->instr); + return invert_depth_impl(b, state); } + return false; } /* In OpenGL the windows space depth value z_w is evaluated according to "s * z_d + b" @@ -389,31 +371,29 @@ invert_depth_instr(nir_builder *b, struct nir_instr *instr, struct invert_depth_ * to compensate by inverting "z_d' = -z_d" with this lowering pass. * When depth clip is set zero_to_one, we compensate with "z_d' = 1.0f - z_d" instead. */ -void +bool d3d12_nir_invert_depth(nir_shader *shader, unsigned viewport_mask, bool clip_halfz) { if (shader->info.stage != MESA_SHADER_VERTEX && shader->info.stage != MESA_SHADER_TESS_EVAL && shader->info.stage != MESA_SHADER_GEOMETRY) - return; + return false; - struct invert_depth_state state = { viewport_mask, clip_halfz }; + bool progress = false; nir_foreach_function_impl(impl, shader) { + struct invert_depth_state state = { viewport_mask, clip_halfz }; nir_builder b = nir_builder_create(impl); - nir_foreach_block(block, impl) { - nir_foreach_instr_safe(instr, block) { - invert_depth_instr(&b, instr, &state); - } - } + progress |= nir_function_intrinsics_pass(impl, invert_depth_intr, + nir_metadata_none, + &state); if (state.store_pos_instr) { b.cursor = nir_after_block(impl->end_block); - invert_depth_impl(&b, &state); + progress |= nir_progress(invert_depth_impl(&b, &state), impl, nir_metadata_none); } - - nir_progress(true, impl, nir_metadata_control_flow); } + return progress; } @@ -442,54 +422,51 @@ get_state_var_offset(struct d3d12_shader *shader, enum d3d12_state_var var) return offset; } -static bool -lower_instr(nir_intrinsic_instr *instr, nir_builder *b, - struct d3d12_shader *shader, unsigned binding) +struct lower_state_var_state { + struct nir_shader *nir; + struct d3d12_shader *shader; + unsigned binding; +}; + +static nir_variable * +get_state_var_var(nir_shader *nir, nir_intrinsic_instr *intr) { - nir_variable *variable = NULL; - nir_deref_instr *deref = NULL; + if (intr->intrinsic == nir_intrinsic_load_uniform) + return nir_find_variable_with_driver_location(nir, nir_var_uniform, nir_intrinsic_base(intr)); + else if (intr->intrinsic == nir_intrinsic_load_deref) + return nir_deref_instr_get_variable(nir_src_as_deref(intr->src[0])); + else + return NULL; +} - b->cursor = nir_before_instr(&instr->instr); - - if (instr->intrinsic == nir_intrinsic_load_uniform) { - nir_foreach_variable_with_modes(var, b->shader, nir_var_uniform) { - if (var->data.driver_location == (unsigned int) nir_intrinsic_base(instr)) { - variable = var; - break; - } - } - } else if (instr->intrinsic == nir_intrinsic_load_deref) { - deref = nir_src_as_deref(instr->src[0]); - variable = nir_intrinsic_get_var(instr, 0); - } - - if (variable == NULL || - variable->num_state_slots != 1 || - variable->state_slots[0].tokens[0] != STATE_INTERNAL_DRIVER) +static bool +is_state_var_instr(const nir_instr *instr, const void *_state) +{ + if (instr->type != nir_instr_type_intrinsic) return false; + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + nir_variable *variable = get_state_var_var(((struct lower_state_var_state *)_state)->nir, intr); + return variable != NULL && + variable->num_state_slots == 1 && + variable->state_slots[0].tokens[0] == STATE_INTERNAL_DRIVER; +} + +static nir_def * +lower_state_var_instr(nir_builder *b, nir_instr *instr, void *_state) +{ + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + nir_variable *variable = get_state_var_var(b->shader, intr); enum d3d12_state_var var = variable->state_slots[0].tokens[1]; - nir_def *ubo_idx = nir_imm_int(b, binding); - nir_def *ubo_offset = nir_imm_int(b, get_state_var_offset(shader, var) * 4); - nir_def *load = - nir_load_ubo(b, instr->num_components, instr->def.bit_size, - ubo_idx, ubo_offset, - .align_mul = 16, - .align_offset = 0, - .range_base = 0, - .range = ~0, - ); - - nir_def_replace(&instr->def, load); - for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) { - /* If anyone is using this deref, leave it alone */ - if (!list_is_empty(&d->def.uses)) - break; - - nir_instr_remove(&d->instr); - } - - return true; + struct lower_state_var_state *state = (struct lower_state_var_state *)_state; + nir_def *ubo_idx = nir_imm_int(b, state->binding); + nir_def *ubo_offset = nir_imm_int(b, get_state_var_offset(state->shader, var) * 4); + return nir_load_ubo(b, intr->num_components, intr->def.bit_size, + ubo_idx, ubo_offset, + .align_mul = 16, + .align_offset = 0, + .range_base = 0, + .range = ~0); } bool @@ -501,31 +478,21 @@ d3d12_lower_state_vars(nir_shader *nir, struct d3d12_shader *shader) * exists it will be replaced by using the same binding. * In the event there are no other UBO's, use binding slot 1 to * be consistent with other non-default UBO's */ - unsigned binding = MAX2(nir->info.num_ubos, nir->info.first_ubo_is_default_ubo ? 1 : 0); + struct lower_state_var_state state = { + .nir = nir, .shader = shader, + .binding = MAX2(nir->info.num_ubos, nir->info.first_ubo_is_default_ubo ? 1 : 0) + }; nir_foreach_variable_with_modes_safe(var, nir, nir_var_uniform) { if (var->num_state_slots == 1 && var->state_slots[0].tokens[0] == STATE_INTERNAL_DRIVER) { if (var->data.mode == nir_var_mem_ubo) { - binding = var->data.binding; + state.binding = var->data.binding; } } } - nir_foreach_function_impl(impl, nir) { - nir_builder builder = nir_builder_create(impl); - nir_foreach_block(block, impl) { - nir_foreach_instr_safe(instr, block) { - if (instr->type == nir_instr_type_intrinsic) - progress |= lower_instr(nir_instr_as_intrinsic(instr), - &builder, - shader, - binding); - } - } - - nir_progress(true, impl, nir_metadata_control_flow); - } + progress = nir_shader_lower_instructions(nir, is_state_var_instr, lower_state_var_instr, &state); if (progress) { assert(shader->num_state_vars > 0); @@ -546,9 +513,9 @@ d3d12_lower_state_vars(nir_shader *nir, struct d3d12_shader *shader) (unsigned)(shader->state_vars_size / 4), 0); nir_variable *ubo = nir_variable_create(nir, nir_var_mem_ubo, type, "d3d12_state_vars"); - if (binding >= nir->info.num_ubos) - nir->info.num_ubos = (uint8_t) binding + 1; - ubo->data.binding = binding; + if (state.binding >= nir->info.num_ubos) + nir->info.num_ubos = (uint8_t) state.binding + 1; + ubo->data.binding = state.binding; ubo->num_state_slots = 1; ubo->state_slots = ralloc_array(ubo, nir_state_slot, 1); memcpy(ubo->state_slots[0].tokens, tokens, @@ -567,7 +534,7 @@ d3d12_lower_state_vars(nir_shader *nir, struct d3d12_shader *shader) return progress; } -void +bool d3d12_add_missing_dual_src_target(struct nir_shader *s, unsigned missing_mask) { @@ -577,6 +544,7 @@ d3d12_add_missing_dual_src_target(struct nir_shader *s, b = nir_builder_at(nir_before_impl(impl)); nir_def *zero = nir_imm_zero(&b, 4, 32); + bool progress = false; for (unsigned i = 0; i < 2; ++i) { if (!(missing_mask & (1u << i))) @@ -592,10 +560,10 @@ d3d12_add_missing_dual_src_target(struct nir_shader *s, nir_store_var(&b, out, zero, 0xf); } - nir_progress(true, impl, nir_metadata_control_flow); + return nir_progress(progress, impl, nir_metadata_control_flow); } -void +bool d3d12_lower_primitive_id(nir_shader *shader) { nir_builder b; @@ -608,6 +576,7 @@ d3d12_lower_primitive_id(nir_shader *shader) primitive_id_var->data.location = VARYING_SLOT_PRIMITIVE_ID; primitive_id_var->data.interpolation = INTERP_MODE_FLAT; + bool progress = false; nir_foreach_block(block, impl) { b.cursor = nir_before_block_after_phis(block); primitive_id = nir_load_primitive_id(&b); @@ -619,13 +588,14 @@ d3d12_lower_primitive_id(nir_shader *shader) b.cursor = nir_before_instr(instr); nir_store_var(&b, primitive_id_var, primitive_id, 0x1); + progress = true; } } - nir_progress(true, impl, nir_metadata_none); + return nir_progress(progress, impl, nir_metadata_control_flow); } -static void +static bool lower_triangle_strip_store(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *vertex_count_var, struct hash_table *varyings) @@ -638,15 +608,16 @@ lower_triangle_strip_store(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var = nir_intrinsic_get_var(intr, 0); if (var->data.mode != nir_var_shader_out) - return; + return false; nir_deref_instr *deref = nir_build_deref_array(b, nir_build_deref_var(b, _mesa_hash_table_search(varyings, var)->data), index); nir_def *value = intr->src[1].ssa; nir_store_deref(b, deref, value, 0xf); nir_instr_remove(&intr->instr); + return true; } -static void +static bool lower_triangle_strip_emit_vertex(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *vertex_count_var, struct hash_table *varyings) @@ -693,9 +664,10 @@ lower_triangle_strip_emit_vertex(nir_builder *b, nir_intrinsic_instr *intr, nir_store_var(b, vertex_count_var, vertex_count, 0x1); nir_instr_remove(&intr->instr); + return true; } -static void +static bool lower_triangle_strip_end_primitive(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *vertex_count_var) { @@ -704,15 +676,17 @@ lower_triangle_strip_end_primitive(nir_builder *b, nir_intrinsic_instr *intr, */ nir_store_var(b, vertex_count_var, nir_imm_int(b, 0), 0x1); nir_instr_remove(&intr->instr); + return true; } -void +bool d3d12_lower_triangle_strip(nir_shader *shader) { nir_builder b; nir_function_impl *impl = nir_shader_get_entrypoint(shader); struct hash_table *tmp_vars = _mesa_pointer_hash_table_create(NULL); b = nir_builder_create(impl); + bool progress = false; shader->info.gs.vertices_out = (shader->info.gs.vertices_out - 2) * 3; @@ -736,17 +710,17 @@ d3d12_lower_triangle_strip(nir_shader *shader) switch (intrin->intrinsic) { case nir_intrinsic_store_deref: b.cursor = nir_before_instr(instr); - lower_triangle_strip_store(&b, intrin, vertex_count_var, tmp_vars); + progress |= lower_triangle_strip_store(&b, intrin, vertex_count_var, tmp_vars); break; case nir_intrinsic_emit_vertex_with_counter: case nir_intrinsic_emit_vertex: b.cursor = nir_before_instr(instr); - lower_triangle_strip_emit_vertex(&b, intrin, vertex_count_var, tmp_vars); + progress |= lower_triangle_strip_emit_vertex(&b, intrin, vertex_count_var, tmp_vars); break; case nir_intrinsic_end_primitive: case nir_intrinsic_end_primitive_with_counter: b.cursor = nir_before_instr(instr); - lower_triangle_strip_end_primitive(&b, intrin, vertex_count_var); + progress |= lower_triangle_strip_end_primitive(&b, intrin, vertex_count_var); break; default: break; @@ -755,8 +729,9 @@ d3d12_lower_triangle_strip(nir_shader *shader) } _mesa_hash_table_destroy(tmp_vars, NULL); - nir_progress(true, impl, nir_metadata_none); - NIR_PASS_V(shader, nir_lower_var_copies); + nir_progress(progress, impl, nir_metadata_none); + NIR_PASS(progress, shader, nir_lower_var_copies); + return progress; } static bool @@ -980,7 +955,7 @@ d3d12_split_needed_varyings(nir_shader *s) return progress; } -static void +static bool write_0(nir_builder *b, nir_deref_instr *deref) { if (glsl_type_is_array_or_matrix(deref->type)) { @@ -999,22 +974,26 @@ write_0(nir_builder *b, nir_deref_instr *deref) nir_def *zero_val = nir_vec(b, scalar_arr, num_comps); nir_store_deref(b, deref, zero_val, writemask); } + return true; } -void +bool d3d12_write_0_to_new_varying(nir_shader *s, nir_variable *var) { /* Skip per-vertex HS outputs */ - if (s->info.stage == MESA_SHADER_TESS_CTRL && !var->data.patch) - return; + if (s->info.stage == MESA_SHADER_TESS_CTRL && !var->data.patch) { + nir_shader_preserve_all_metadata(s); + return false; + } + bool progress = false; nir_foreach_function_impl(impl, s) { nir_builder b = nir_builder_create(impl); nir_foreach_block(block, impl) { b.cursor = nir_before_block(block); if (s->info.stage != MESA_SHADER_GEOMETRY) { - write_0(&b, nir_build_deref_var(&b, var)); + progress |= write_0(&b, nir_build_deref_var(&b, var)); break; } @@ -1026,10 +1005,11 @@ d3d12_write_0_to_new_varying(nir_shader *s, nir_variable *var) continue; b.cursor = nir_before_instr(instr); - write_0(&b, nir_build_deref_var(&b, var)); + progress |= write_0(&b, nir_build_deref_var(&b, var)); } } - nir_progress(true, impl, nir_metadata_control_flow); + nir_progress(progress, impl, nir_metadata_control_flow); } + return progress; } diff --git a/src/gallium/drivers/d3d12/d3d12_nir_passes.h b/src/gallium/drivers/d3d12/d3d12_nir_passes.h index ee3560dac05..70b44af8ec3 100644 --- a/src/gallium/drivers/d3d12/d3d12_nir_passes.h +++ b/src/gallium/drivers/d3d12/d3d12_nir_passes.h @@ -60,10 +60,10 @@ d3d12_lower_point_sprite(nir_shader *shader, bool d3d12_lower_state_vars(struct nir_shader *s, struct d3d12_shader *shader); -void +bool d3d12_lower_yflip(nir_shader *s); -void +bool d3d12_lower_depth_range(nir_shader *nir); bool @@ -75,23 +75,23 @@ d3d12_lower_load_patch_vertices_in(nir_shader *nir); bool d3d12_lower_compute_state_vars(nir_shader *nir); -void +bool d3d12_lower_uint_cast(nir_shader *nir, bool is_signed); -void +bool d3d12_add_missing_dual_src_target(struct nir_shader *s, unsigned missing_mask); bool d3d12_fix_io_uint_type(struct nir_shader *s, uint64_t in_mask, uint64_t out_mask); -void +bool d3d12_nir_invert_depth(nir_shader *s, unsigned viewport_mask, bool clip_halfz); -void +bool d3d12_lower_primitive_id(nir_shader *shader); -void +bool d3d12_lower_triangle_strip(nir_shader *shader); bool @@ -103,7 +103,7 @@ d3d12_disable_multisampling(nir_shader *s); bool d3d12_split_needed_varyings(nir_shader *s); -void +bool d3d12_write_0_to_new_varying(nir_shader *s, nir_variable *var); #ifdef __cplusplus diff --git a/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp b/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp index 3160af1c07c..e16a6373d6e 100644 --- a/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp +++ b/src/gallium/drivers/d3d12/d3d12_tcs_variant.cpp @@ -137,7 +137,7 @@ create_tess_ctrl_shader_variant(struct d3d12_context *ctx, struct d3d12_tcs_vari nir->info.tess.tcs_vertices_out = static_cast(key->vertices_out); nir_validate_shader(nir, "created"); - NIR_PASS_V(nir, nir_lower_var_copies); + NIR_PASS(_, nir, nir_lower_var_copies); struct pipe_shader_state templ; diff --git a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c index 73cfbb9f3a0..ba8bd417f06 100644 --- a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c +++ b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c @@ -116,11 +116,11 @@ dxil_spirv_nir_prep(nir_shader *nir) * inline functions. That way they get properly initialized at the top * of the function and not at the top of its caller. */ - NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp); - NIR_PASS_V(nir, nir_lower_returns); - NIR_PASS_V(nir, nir_inline_functions); - NIR_PASS_V(nir, nir_copy_prop); - NIR_PASS_V(nir, nir_opt_deref); + NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_function_temp); + NIR_PASS(_, nir, nir_lower_returns); + NIR_PASS(_, nir, nir_inline_functions); + NIR_PASS(_, nir, nir_copy_prop); + NIR_PASS(_, nir, nir_opt_deref); /* Pick off the single entrypoint that we want */ nir_remove_non_entrypoints(nir); @@ -130,20 +130,20 @@ dxil_spirv_nir_prep(nir_shader *nir) * nir_remove_dead_variables and split_per_member_structs below see the * corresponding stores. */ - NIR_PASS_V(nir, nir_lower_variable_initializers, ~0); + NIR_PASS(_, nir, nir_lower_variable_initializers, ~0); /* Split member structs. We do this before lower_io_to_temporaries so that * it doesn't lower system values to temporaries by accident. */ - NIR_PASS_V(nir, nir_split_var_copies); - NIR_PASS_V(nir, nir_split_per_member_structs); + NIR_PASS(_, nir, nir_split_var_copies); + NIR_PASS(_, nir, nir_split_per_member_structs); - NIR_PASS_V(nir, nir_remove_dead_variables, + NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_shader_in | nir_var_shader_out | nir_var_system_value | nir_var_shader_call_data | nir_var_ray_hit_attrib, NULL); - NIR_PASS_V(nir, nir_propagate_invariant, false); + NIR_PASS(_, nir, nir_propagate_invariant, false); } static void @@ -633,16 +633,18 @@ write_pntc_with_pos(nir_builder *b, nir_instr *instr, void *_data) return true; } -static void +static bool dxil_spirv_write_pntc(nir_shader *nir, const struct dxil_spirv_runtime_conf *conf) { struct lower_pntc_data data = { .conf = conf }; data.pntc = nir_variable_create(nir, nir_var_shader_out, glsl_vec4_type(), "gl_PointCoord"); data.pntc->data.location = VARYING_SLOT_PNTC; - nir_shader_instructions_pass(nir, write_pntc_with_pos, - nir_metadata_control_flow | - nir_metadata_loop_analysis, - &data); + bool progress = nir_shader_instructions_pass(nir, write_pntc_with_pos, + nir_metadata_control_flow | + nir_metadata_loop_analysis, + &data); + if (!progress) + return false; nir->info.outputs_written |= VARYING_BIT_PNTC; /* Add the runtime data var if it's not already there */ @@ -654,6 +656,7 @@ dxil_spirv_write_pntc(nir_shader *nir, const struct dxil_spirv_runtime_conf *con nir_variable *ubo_var = nir_get_binding_variable(nir, binding); if (!ubo_var) add_runtime_data_var(nir, conf->runtime_data_cbv.register_space, conf->runtime_data_cbv.base_shader_register); + return true; } static bool @@ -689,7 +692,7 @@ lower_pntc_read(nir_builder *b, nir_intrinsic_instr *intr, void *data) return true; } -static void +static bool dxil_spirv_compute_pntc(nir_shader *nir) { nir_variable *pos = nir_find_variable_with_location(nir, nir_var_shader_in, VARYING_SLOT_POS); @@ -698,10 +701,10 @@ dxil_spirv_compute_pntc(nir_shader *nir) pos->data.location = VARYING_SLOT_POS; pos->data.sample = nir_find_variable_with_location(nir, nir_var_shader_in, VARYING_SLOT_PNTC)->data.sample; } - nir_shader_intrinsics_pass(nir, lower_pntc_read, - nir_metadata_control_flow | - nir_metadata_loop_analysis, - pos); + return nir_shader_intrinsics_pass(nir, lower_pntc_read, + nir_metadata_control_flow | + nir_metadata_loop_analysis, + pos); } static bool @@ -742,7 +745,7 @@ add_layer_write(nir_builder *b, nir_instr *instr, void *data) return true; } -static void +static bool lower_view_index_to_rt_layer(nir_shader *nir) { bool existing_write = @@ -751,21 +754,23 @@ lower_view_index_to_rt_layer(nir_shader *nir) nir_metadata_loop_analysis, NULL); if (existing_write) - return; + return true; nir_variable *var = nir_variable_create(nir, nir_var_shader_out, glsl_uint_type(), "gl_Layer"); var->data.location = VARYING_SLOT_LAYER; var->data.interpolation = INTERP_MODE_FLAT; if (nir->info.stage == MESA_SHADER_GEOMETRY) { - nir_shader_instructions_pass(nir, - add_layer_write, - nir_metadata_control_flow | - nir_metadata_loop_analysis, var); + return nir_shader_instructions_pass(nir, + add_layer_write, + nir_metadata_control_flow | + nir_metadata_loop_analysis, var); } else { nir_function_impl *func = nir_shader_get_entrypoint(nir); nir_builder b = nir_builder_at(nir_after_impl(func)); - add_layer_write(&b, NULL, var); + return nir_progress(add_layer_write(&b, NULL, var), b.impl, + nir_metadata_control_flow | + nir_metadata_loop_analysis); } } @@ -782,14 +787,14 @@ dxil_spirv_nir_link(nir_shader *nir, nir_shader *prev_stage_nir, nir->info.clip_distance_array_size = prev_stage_nir->info.clip_distance_array_size; if (nir->info.inputs_read & VARYING_BIT_PNTC) { - NIR_PASS_V(prev_stage_nir, dxil_spirv_write_pntc, conf); - NIR_PASS_V(nir, dxil_spirv_compute_pntc); + NIR_PASS(_, prev_stage_nir, dxil_spirv_write_pntc, conf); + NIR_PASS(_, nir, dxil_spirv_compute_pntc); metadata->requires_runtime_data = true; } } - NIR_PASS_V(nir, dxil_nir_kill_undefined_varyings, prev_stage_nir->info.outputs_written, prev_stage_nir->info.patch_outputs_written, NULL); - NIR_PASS_V(prev_stage_nir, dxil_nir_kill_unused_outputs, nir->info.inputs_read, nir->info.patch_inputs_read, NULL); + NIR_PASS(_, nir, dxil_nir_kill_undefined_varyings, prev_stage_nir->info.outputs_written, prev_stage_nir->info.patch_outputs_written, NULL); + NIR_PASS(_, prev_stage_nir, dxil_nir_kill_unused_outputs, nir->info.inputs_read, nir->info.patch_inputs_read, NULL); dxil_reassign_driver_locations(nir, nir_var_shader_in, prev_stage_nir->info.outputs_written, NULL); dxil_reassign_driver_locations(prev_stage_nir, nir_var_shader_out, nir->info.inputs_read, NULL); @@ -890,27 +895,27 @@ dxil_spirv_nir_passes(nir_shader *nir, { glsl_type_singleton_init_or_ref(); - NIR_PASS_V(nir, nir_opt_vectorize_io_vars, + NIR_PASS(_, nir, nir_opt_vectorize_io_vars, nir_var_shader_out | (nir->info.stage != MESA_SHADER_VERTEX ? nir_var_shader_in : 0)); - NIR_PASS_V(nir, nir_opt_combine_stores, nir_var_shader_out); - NIR_PASS_V(nir, nir_remove_dead_derefs); + NIR_PASS(_, nir, nir_opt_combine_stores, nir_var_shader_out); + NIR_PASS(_, nir, nir_remove_dead_derefs); const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = { .frag_coord = true, .point_coord = true, .front_face = true, }; - NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings); + NIR_PASS(_, nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings); - NIR_PASS_V(nir, nir_lower_system_values); + NIR_PASS(_, nir, nir_lower_system_values); nir_lower_compute_system_values_options compute_options = { .has_base_workgroup_id = conf->workgroup_id_mode != DXIL_SPIRV_SYSVAL_TYPE_ZERO, }; - NIR_PASS_V(nir, nir_lower_compute_system_values, &compute_options); - NIR_PASS_V(nir, dxil_nir_lower_subgroup_id); - NIR_PASS_V(nir, dxil_nir_lower_num_subgroups); + NIR_PASS(_, nir, nir_lower_compute_system_values, &compute_options); + NIR_PASS(_, nir, dxil_nir_lower_subgroup_id); + NIR_PASS(_, nir, dxil_nir_lower_num_subgroups); nir_lower_subgroups_options subgroup_options = { .ballot_bit_size = 32, @@ -923,12 +928,12 @@ dxil_spirv_nir_passes(nir_shader *nir, if (nir->info.stage != MESA_SHADER_FRAGMENT && nir->info.stage != MESA_SHADER_COMPUTE) subgroup_options.lower_quad = true; - NIR_PASS_V(nir, nir_lower_subgroups, &subgroup_options); - NIR_PASS_V(nir, nir_lower_bit_size, lower_bit_size_callback, NULL); + NIR_PASS(_, nir, nir_lower_subgroups, &subgroup_options); + NIR_PASS(_, nir, nir_lower_bit_size, lower_bit_size_callback, NULL); // Ensure subgroup scans on bools are gone - NIR_PASS_V(nir, nir_opt_dce); - NIR_PASS_V(nir, dxil_nir_lower_unsupported_subgroup_scan); + NIR_PASS(_, nir, nir_opt_dce); + NIR_PASS(_, nir, dxil_nir_lower_unsupported_subgroup_scan); // Force sample-rate shading if we're asked to. if (conf->force_sample_rate_shading) { @@ -943,12 +948,12 @@ dxil_spirv_nir_passes(nir_shader *nir, gl_system_value system_values[] = {SYSTEM_VALUE_FIRST_VERTEX, SYSTEM_VALUE_BASE_VERTEX, SYSTEM_VALUE_BASE_INSTANCE}; - NIR_PASS_V(nir, dxil_nir_lower_system_values_to_zero, system_values, + NIR_PASS(_, nir, dxil_nir_lower_system_values_to_zero, system_values, ARRAY_SIZE(system_values)); } if (conf->lower_view_index_to_rt_layer) - NIR_PASS_V(nir, lower_view_index_to_rt_layer); + NIR_PASS(_, nir, lower_view_index_to_rt_layer); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); metadata->needs_draw_sysvals = BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_FIRST_VERTEX) || @@ -959,80 +964,80 @@ dxil_spirv_nir_passes(nir_shader *nir, conf); if (nir->info.stage == MESA_SHADER_FRAGMENT) { - NIR_PASS_V(nir, nir_lower_input_attachments, + NIR_PASS(_, nir, nir_lower_input_attachments, &(nir_input_attachment_options){ .use_fragcoord_sysval = false, .use_layer_id_sysval = !conf->lower_view_index, .use_view_id_for_layer = !conf->lower_view_index, }); - NIR_PASS_V(nir, dxil_nir_lower_discard_and_terminate); - NIR_PASS_V(nir, nir_lower_returns); - NIR_PASS_V(nir, dxil_nir_lower_sample_pos); - NIR_PASS_V(nir, nir_lower_fragcoord_wtrans); + NIR_PASS(_, nir, dxil_nir_lower_discard_and_terminate); + NIR_PASS(_, nir, nir_lower_returns); + NIR_PASS(_, nir, dxil_nir_lower_sample_pos); + NIR_PASS(_, nir, nir_lower_fragcoord_wtrans); } - NIR_PASS_V(nir, nir_opt_deref); + NIR_PASS(_, nir, nir_opt_deref); - NIR_PASS_V(nir, nir_lower_memory_model); - NIR_PASS_V(nir, dxil_nir_lower_coherent_loads_and_stores); + NIR_PASS(_, nir, nir_lower_memory_model); + NIR_PASS(_, nir, dxil_nir_lower_coherent_loads_and_stores); if (conf->inferred_read_only_images_as_srvs) { const nir_opt_access_options opt_access_options = { .is_vulkan = true, }; - NIR_PASS_V(nir, nir_opt_access, &opt_access_options); + NIR_PASS(_, nir, nir_opt_access, &opt_access_options); } - NIR_PASS_V(nir, dxil_spirv_nir_discard_point_size_var); + NIR_PASS(_, nir, dxil_spirv_nir_discard_point_size_var); - NIR_PASS_V(nir, nir_remove_dead_variables, + NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_shader_in | nir_var_shader_out | nir_var_system_value | nir_var_mem_shared, NULL); uint32_t push_constant_size = 0; - NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const, + NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_push_const, nir_address_format_32bit_offset); - NIR_PASS_V(nir, dxil_spirv_nir_lower_load_push_constant, + NIR_PASS(_, nir, dxil_spirv_nir_lower_load_push_constant, nir_address_format_32bit_index_offset, conf->push_constant_cbv.register_space, conf->push_constant_cbv.base_shader_register, &push_constant_size); - NIR_PASS_V(nir, dxil_spirv_nir_lower_buffer_device_address); - NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_ubo | nir_var_mem_ssbo, + NIR_PASS(_, nir, dxil_spirv_nir_lower_buffer_device_address); + NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo | nir_var_mem_ssbo, nir_address_format_32bit_index_offset); - NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_global, + NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_global, nir_address_format_32bit_index_offset_pack64); if (nir->info.shared_memory_explicit_layout) { - NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, + NIR_PASS(_, nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, shared_var_info); - NIR_PASS_V(nir, dxil_nir_split_unaligned_loads_stores, nir_var_mem_shared); - NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_shared, nir_address_format_32bit_offset); + NIR_PASS(_, nir, dxil_nir_split_unaligned_loads_stores, nir_var_mem_shared); + NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_shared, nir_address_format_32bit_offset); } else { - NIR_PASS_V(nir, nir_split_struct_vars, nir_var_mem_shared); - NIR_PASS_V(nir, dxil_nir_flatten_var_arrays, nir_var_mem_shared); - NIR_PASS_V(nir, dxil_nir_lower_var_bit_size, nir_var_mem_shared, + NIR_PASS(_, nir, nir_split_struct_vars, nir_var_mem_shared); + NIR_PASS(_, nir, dxil_nir_flatten_var_arrays, nir_var_mem_shared); + NIR_PASS(_, nir, dxil_nir_lower_var_bit_size, nir_var_mem_shared, conf->shader_model_max >= SHADER_MODEL_6_2 ? 16 : 32, 64); } - NIR_PASS_V(nir, dxil_nir_lower_int_cubemaps, false); + NIR_PASS(_, nir, dxil_nir_lower_int_cubemaps, false); - NIR_PASS_V(nir, nir_lower_clip_cull_distance_array_vars); - NIR_PASS_V(nir, nir_lower_io_vars_to_temporaries, nir_shader_get_entrypoint(nir), true, true); - NIR_PASS_V(nir, nir_lower_global_vars_to_local); - NIR_PASS_V(nir, nir_split_var_copies); - NIR_PASS_V(nir, nir_lower_var_copies); - NIR_PASS_V(nir, nir_lower_io_array_vars_to_elements_no_indirects, false); + NIR_PASS(_, nir, nir_lower_clip_cull_distance_array_vars); + NIR_PASS(_, nir, nir_lower_io_vars_to_temporaries, nir_shader_get_entrypoint(nir), true, true); + NIR_PASS(_, nir, nir_lower_global_vars_to_local); + NIR_PASS(_, nir, nir_split_var_copies); + NIR_PASS(_, nir, nir_lower_var_copies); + NIR_PASS(_, nir, nir_lower_io_array_vars_to_elements_no_indirects, false); if (conf->yz_flip.mode != DXIL_SPIRV_YZ_FLIP_NONE) { assert(nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_GEOMETRY || nir->info.stage == MESA_SHADER_TESS_EVAL); - NIR_PASS_V(nir, + NIR_PASS(_, nir, dxil_spirv_nir_lower_yz_flip, conf, &metadata->requires_runtime_data); } @@ -1048,10 +1053,10 @@ dxil_spirv_nir_passes(nir_shader *nir, conf->push_constant_cbv.base_shader_register); } - NIR_PASS_V(nir, nir_lower_fp16_casts, nir_lower_fp16_all & ~nir_lower_fp16_rtz); - NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL); - NIR_PASS_V(nir, nir_opt_dce); - NIR_PASS_V(nir, dxil_nir_lower_double_math); + NIR_PASS(_, nir, nir_lower_fp16_casts, nir_lower_fp16_all & ~nir_lower_fp16_rtz); + NIR_PASS(_, nir, nir_lower_alu_to_scalar, NULL, NULL); + NIR_PASS(_, nir, nir_opt_dce); + NIR_PASS(_, nir, dxil_nir_lower_double_math); { bool progress; @@ -1077,36 +1082,36 @@ dxil_spirv_nir_passes(nir_shader *nir, } while (progress); } - NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_function_temp, NULL); - NIR_PASS_V(nir, nir_split_struct_vars, nir_var_function_temp); - NIR_PASS_V(nir, dxil_nir_flatten_var_arrays, nir_var_function_temp); - NIR_PASS_V(nir, dxil_nir_lower_var_bit_size, nir_var_function_temp, + NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_function_temp, NULL); + NIR_PASS(_, nir, nir_split_struct_vars, nir_var_function_temp); + NIR_PASS(_, nir, dxil_nir_flatten_var_arrays, nir_var_function_temp); + NIR_PASS(_, nir, dxil_nir_lower_var_bit_size, nir_var_function_temp, conf->shader_model_max >= SHADER_MODEL_6_2 ? 16 : 32, 64); - NIR_PASS_V(nir, nir_lower_doubles, NULL, nir->options->lower_doubles_options); + NIR_PASS(_, nir, nir_lower_doubles, NULL, nir->options->lower_doubles_options); if (conf->declared_read_only_images_as_srvs) - NIR_PASS_V(nir, nir_lower_readonly_images_to_tex, true); + NIR_PASS(_, nir, nir_lower_readonly_images_to_tex, true); nir_lower_tex_options lower_tex_options = { .lower_txp = UINT32_MAX, .lower_invalid_implicit_lod = true, .lower_tg4_offsets = true, }; - NIR_PASS_V(nir, nir_lower_tex, &lower_tex_options); + NIR_PASS(_, nir, nir_lower_tex, &lower_tex_options); - NIR_PASS_V(nir, dxil_nir_split_clip_cull_distance); + NIR_PASS(_, nir, dxil_nir_split_clip_cull_distance); const struct dxil_nir_lower_loads_stores_options loads_stores_options = { .use_16bit_ssbo = conf->shader_model_max >= SHADER_MODEL_6_2, }; - NIR_PASS_V(nir, dxil_nir_lower_loads_stores_to_dxil, &loads_stores_options); - NIR_PASS_V(nir, dxil_nir_split_typed_samplers); - NIR_PASS_V(nir, dxil_nir_lower_ubo_array_one_to_static); - NIR_PASS_V(nir, nir_opt_dce); - NIR_PASS_V(nir, nir_remove_dead_derefs); - NIR_PASS_V(nir, nir_remove_dead_variables, + NIR_PASS(_, nir, dxil_nir_lower_loads_stores_to_dxil, &loads_stores_options); + NIR_PASS(_, nir, dxil_nir_split_typed_samplers); + NIR_PASS(_, nir, dxil_nir_lower_ubo_array_one_to_static); + NIR_PASS(_, nir, nir_opt_dce); + NIR_PASS(_, nir, nir_remove_dead_derefs); + NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_uniform | nir_var_shader_in | nir_var_shader_out, NULL); - NIR_PASS_V(nir, merge_ubos_and_ssbos); + NIR_PASS(_, nir, merge_ubos_and_ssbos); if (nir->info.stage == MESA_SHADER_FRAGMENT) { dxil_sort_ps_outputs(nir);