d3d12: Use NIR_PASS instead of NIR_PASS_V

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36299>
This commit is contained in:
Jesse Natalie
2025-07-22 13:36:23 -07:00
parent a8858fc96a
commit d3a284660e
7 changed files with 349 additions and 364 deletions
+41 -41
View File
@@ -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<uint8_t>(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);
}
@@ -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;
}
@@ -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;
+197 -217
View File
@@ -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;
}
+8 -8
View File
@@ -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
@@ -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<uint8_t>(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;
+99 -94
View File
@@ -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);