microsoft/compiler: Use NIR_PASS instead of NIR_PASS_V
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36299>
This commit is contained in:
@@ -214,12 +214,8 @@ dxil_nir_lower_constant_to_temp(nir_shader *nir)
|
||||
/* First pass: collect all UBO accesses that could be turned into
|
||||
* shader temp accesses.
|
||||
*/
|
||||
nir_foreach_function(func, nir) {
|
||||
if (!func->is_entrypoint)
|
||||
continue;
|
||||
assert(func->impl);
|
||||
|
||||
nir_foreach_block(block, func->impl) {
|
||||
nir_foreach_function_impl(impl, nir) {
|
||||
nir_foreach_block(block, impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_deref)
|
||||
continue;
|
||||
@@ -246,16 +242,18 @@ dxil_nir_lower_constant_to_temp(nir_shader *nir)
|
||||
progress = true;
|
||||
}
|
||||
|
||||
if (!progress) {
|
||||
nir_shader_preserve_all_metadata(nir);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Second pass: patch all derefs that were accessing the converted UBOs
|
||||
* variables.
|
||||
*/
|
||||
nir_foreach_function(func, nir) {
|
||||
if (!func->is_entrypoint)
|
||||
continue;
|
||||
assert(func->impl);
|
||||
|
||||
nir_builder b = nir_builder_create(func->impl);
|
||||
nir_foreach_block(block, func->impl) {
|
||||
nir_foreach_function_impl(impl, nir) {
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
bool func_progress = false;
|
||||
nir_foreach_block(block, impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_deref)
|
||||
continue;
|
||||
@@ -272,11 +270,13 @@ dxil_nir_lower_constant_to_temp(nir_shader *nir)
|
||||
if (deref->deref_type == nir_deref_type_array) {
|
||||
b.cursor = nir_before_instr(instr);
|
||||
nir_src_rewrite(&deref->arr.index, nir_u2u32(&b, deref->arr.index.ssa));
|
||||
func_progress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nir_progress(func_progress, impl, nir_metadata_control_flow);
|
||||
}
|
||||
|
||||
return progress;
|
||||
@@ -738,61 +738,37 @@ dxil_nir_lower_loads_stores_to_dxil(nir_shader *nir,
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_deref_ssbo(nir_builder *b, nir_deref_instr *deref)
|
||||
is_deref_ssbo(const nir_instr *instr, const void *state)
|
||||
{
|
||||
if (instr->type != nir_instr_type_deref)
|
||||
return false;
|
||||
nir_deref_instr *deref = nir_instr_as_deref(instr);
|
||||
return nir_deref_mode_is(deref, nir_var_mem_ssbo) &&
|
||||
deref->deref_type == nir_deref_type_var;
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
lower_deref_ssbo(nir_builder *b, nir_instr *instr, void *state)
|
||||
{
|
||||
nir_deref_instr *deref = nir_instr_as_deref(instr);
|
||||
assert(nir_deref_mode_is(deref, nir_var_mem_ssbo));
|
||||
assert(deref->deref_type == nir_deref_type_var ||
|
||||
deref->deref_type == nir_deref_type_cast);
|
||||
assert(deref->deref_type == nir_deref_type_var);
|
||||
nir_variable *var = deref->var;
|
||||
|
||||
b->cursor = nir_before_instr(&deref->instr);
|
||||
|
||||
if (deref->deref_type == nir_deref_type_var) {
|
||||
/* We turn all deref_var into deref_cast and build a pointer value based on
|
||||
* the var binding which encodes the UAV id.
|
||||
*/
|
||||
nir_def *ptr = nir_imm_int64(b, (uint64_t)var->data.binding << 32);
|
||||
nir_deref_instr *deref_cast =
|
||||
nir_build_deref_cast(b, ptr, nir_var_mem_ssbo, deref->type,
|
||||
glsl_get_explicit_stride(var->type));
|
||||
nir_def_replace(&deref->def, &deref_cast->def);
|
||||
|
||||
deref = deref_cast;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
/* We turn all deref_var into deref_cast and build a pointer value based on
|
||||
* the var binding which encodes the UAV id.
|
||||
*/
|
||||
nir_def *ptr = nir_imm_int64(b, (uint64_t)var->data.binding << 32);
|
||||
nir_deref_instr *deref_cast =
|
||||
nir_build_deref_cast(b, ptr, nir_var_mem_ssbo, deref->type,
|
||||
glsl_get_explicit_stride(var->type));
|
||||
return &deref_cast->def;
|
||||
}
|
||||
|
||||
bool
|
||||
dxil_nir_lower_deref_ssbo(nir_shader *nir)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
foreach_list_typed(nir_function, func, node, &nir->functions) {
|
||||
if (!func->is_entrypoint)
|
||||
continue;
|
||||
assert(func->impl);
|
||||
|
||||
nir_builder b = nir_builder_create(func->impl);
|
||||
|
||||
nir_foreach_block(block, func->impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_deref)
|
||||
continue;
|
||||
|
||||
nir_deref_instr *deref = nir_instr_as_deref(instr);
|
||||
|
||||
if (!nir_deref_mode_is(deref, nir_var_mem_ssbo) ||
|
||||
(deref->deref_type != nir_deref_type_var &&
|
||||
deref->deref_type != nir_deref_type_cast))
|
||||
continue;
|
||||
|
||||
progress |= lower_deref_ssbo(&b, deref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
return nir_shader_lower_instructions(nir, is_deref_ssbo, lower_deref_ssbo, NULL);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -2043,7 +2019,7 @@ get_cast_type(unsigned bit_size)
|
||||
unreachable("Invalid bit_size");
|
||||
}
|
||||
|
||||
static void
|
||||
static nir_def *
|
||||
split_unaligned_load(nir_builder *b, nir_intrinsic_instr *intrin, unsigned alignment)
|
||||
{
|
||||
enum gl_access_qualifier access = nir_intrinsic_access(intrin);
|
||||
@@ -2064,8 +2040,7 @@ split_unaligned_load(nir_builder *b, nir_intrinsic_instr *intrin, unsigned align
|
||||
srcs[i] = nir_load_deref_with_access(b, elem, access);
|
||||
}
|
||||
|
||||
nir_def *new_dest = nir_extract_bits(b, srcs, num_loads, 0, num_comps, intrin->def.bit_size);
|
||||
nir_def_replace(&intrin->def, new_dest);
|
||||
return nir_extract_bits(b, srcs, num_loads, 0, num_comps, intrin->def.bit_size);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2090,70 +2065,73 @@ split_unaligned_store(nir_builder *b, nir_intrinsic_instr *intrin, unsigned alig
|
||||
nir_deref_instr *elem = nir_build_deref_ptr_as_array(b, cast, nir_imm_intN_t(b, i, cast->def.bit_size));
|
||||
nir_store_deref_with_access(b, elem, substore_val, ~0, access);
|
||||
}
|
||||
}
|
||||
|
||||
nir_instr_remove(&intrin->instr);
|
||||
static bool
|
||||
is_unaligned_load_store(const nir_instr *instr, const void *state)
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
if (intrin->intrinsic != nir_intrinsic_load_deref &&
|
||||
intrin->intrinsic != nir_intrinsic_store_deref)
|
||||
return false;
|
||||
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
|
||||
nir_variable_mode modes = *(nir_variable_mode *)state;
|
||||
if (!nir_deref_mode_may_be(deref, modes))
|
||||
return false;
|
||||
|
||||
unsigned align_mul = 0, align_offset = 0;
|
||||
nir_get_explicit_deref_align(deref, true, &align_mul, &align_offset);
|
||||
|
||||
unsigned alignment = align_offset ? 1 << (ffs(align_offset) - 1) : align_mul;
|
||||
|
||||
/* We can load anything at 4-byte alignment, except for
|
||||
* UBOs (AKA CBs where the granularity is 16 bytes).
|
||||
*/
|
||||
unsigned req_align = (nir_deref_mode_is_one_of(deref, nir_var_mem_ubo | nir_var_mem_push_const) ? 16 : 4);
|
||||
if (alignment >= req_align)
|
||||
return false;
|
||||
|
||||
nir_def *val;
|
||||
if (intrin->intrinsic == nir_intrinsic_load_deref) {
|
||||
val = &intrin->def;
|
||||
} else {
|
||||
val = intrin->src[1].ssa;
|
||||
}
|
||||
|
||||
unsigned scalar_byte_size = glsl_type_is_boolean(deref->type) ? 4 : glsl_get_bit_size(deref->type) / 8;
|
||||
unsigned num_components =
|
||||
/* If the vector stride is larger than the scalar size, lower_explicit_io will
|
||||
* turn this into multiple scalar loads anyway, so we don't have to split it here. */
|
||||
glsl_get_explicit_stride(deref->type) > scalar_byte_size ? 1 :
|
||||
(val->num_components == 3 ? 4 : val->num_components);
|
||||
unsigned natural_alignment = scalar_byte_size * num_components;
|
||||
|
||||
return alignment < natural_alignment;
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
lower_unaligned_load_store(nir_builder *b, nir_instr *instr, void *state)
|
||||
{
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
|
||||
unsigned align_mul = 0, align_offset = 0;
|
||||
nir_get_explicit_deref_align(deref, true, &align_mul, &align_offset);
|
||||
unsigned alignment = align_offset ? 1 << (ffs(align_offset) - 1) : align_mul;
|
||||
|
||||
if (intrin->intrinsic == nir_intrinsic_load_deref)
|
||||
return split_unaligned_load(b, intrin, alignment);
|
||||
else {
|
||||
split_unaligned_store(b, intrin, alignment);
|
||||
return NIR_LOWER_INSTR_PROGRESS_REPLACE;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
dxil_nir_split_unaligned_loads_stores(nir_shader *shader, nir_variable_mode modes)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
nir_foreach_function_impl(impl, shader) {
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
|
||||
nir_foreach_block(block, impl) {
|
||||
nir_foreach_instr_safe(instr, block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
if (intrin->intrinsic != nir_intrinsic_load_deref &&
|
||||
intrin->intrinsic != nir_intrinsic_store_deref)
|
||||
continue;
|
||||
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
|
||||
if (!nir_deref_mode_may_be(deref, modes))
|
||||
continue;
|
||||
|
||||
unsigned align_mul = 0, align_offset = 0;
|
||||
nir_get_explicit_deref_align(deref, true, &align_mul, &align_offset);
|
||||
|
||||
unsigned alignment = align_offset ? 1 << (ffs(align_offset) - 1) : align_mul;
|
||||
|
||||
/* We can load anything at 4-byte alignment, except for
|
||||
* UBOs (AKA CBs where the granularity is 16 bytes).
|
||||
*/
|
||||
unsigned req_align = (nir_deref_mode_is_one_of(deref, nir_var_mem_ubo | nir_var_mem_push_const) ? 16 : 4);
|
||||
if (alignment >= req_align)
|
||||
continue;
|
||||
|
||||
nir_def *val;
|
||||
if (intrin->intrinsic == nir_intrinsic_load_deref) {
|
||||
val = &intrin->def;
|
||||
} else {
|
||||
val = intrin->src[1].ssa;
|
||||
}
|
||||
|
||||
unsigned scalar_byte_size = glsl_type_is_boolean(deref->type) ? 4 : glsl_get_bit_size(deref->type) / 8;
|
||||
unsigned num_components =
|
||||
/* If the vector stride is larger than the scalar size, lower_explicit_io will
|
||||
* turn this into multiple scalar loads anyway, so we don't have to split it here. */
|
||||
glsl_get_explicit_stride(deref->type) > scalar_byte_size ? 1 :
|
||||
(val->num_components == 3 ? 4 : val->num_components);
|
||||
unsigned natural_alignment = scalar_byte_size * num_components;
|
||||
|
||||
if (alignment >= natural_alignment)
|
||||
continue;
|
||||
|
||||
if (intrin->intrinsic == nir_intrinsic_load_deref)
|
||||
split_unaligned_load(&b, intrin, alignment);
|
||||
else
|
||||
split_unaligned_store(&b, intrin, alignment);
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
return nir_shader_lower_instructions(shader, is_unaligned_load_store, lower_unaligned_load_store, &modes);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -69,7 +69,7 @@ void
|
||||
dxil_reassign_driver_locations(nir_shader* s, nir_variable_mode modes,
|
||||
uint64_t other_stage_mask, const BITSET_WORD *other_stage_frac_mask);
|
||||
|
||||
void dxil_nir_split_tess_ctrl(nir_shader *nir, nir_function **patch_const_func);
|
||||
bool dxil_nir_split_tess_ctrl(nir_shader *nir, nir_function **patch_const_func);
|
||||
bool dxil_nir_fixup_tess_level_for_domain(nir_shader *nir);
|
||||
bool dxil_nir_set_tcs_patches_in(nir_shader *nir, unsigned num_control_points);
|
||||
bool dxil_nir_lower_ubo_array_one_to_static(nir_shader *s);
|
||||
|
||||
@@ -185,7 +185,7 @@ end_tcs_loop(nir_builder *b, struct tcs_patch_loop_state *state)
|
||||
* replace gl_InvocationID. This loop can be terminated when a barrier is hit. If
|
||||
* gl_InvocationID is used again after the barrier, then another loop needs to begin.
|
||||
*/
|
||||
void
|
||||
bool
|
||||
dxil_nir_split_tess_ctrl(nir_shader *nir, nir_function **patch_const_func)
|
||||
{
|
||||
assert(nir->info.stage == MESA_SHADER_TESS_CTRL);
|
||||
@@ -288,6 +288,10 @@ dxil_nir_split_tess_ctrl(nir_shader *nir, nir_function **patch_const_func)
|
||||
/* If we have more than one loop, SSA needs to be repaired for one loop to use defs from another. */
|
||||
if (loop_var)
|
||||
nir_repair_ssa_impl(patch_const_func_impl);
|
||||
|
||||
nir_progress(true, patch_const_func_impl, nir_metadata_none);
|
||||
nir_progress(true, entrypoint, nir_metadata_none);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct remove_tess_level_accesses_data {
|
||||
|
||||
@@ -6317,7 +6317,7 @@ optimize_nir(struct nir_shader *s, const struct nir_to_dxil_options *opts)
|
||||
bool progress;
|
||||
do {
|
||||
progress = false;
|
||||
NIR_PASS_V(s, nir_lower_vars_to_ssa);
|
||||
NIR_PASS(progress, s, nir_lower_vars_to_ssa);
|
||||
NIR_PASS(progress, s, nir_lower_indirect_derefs, nir_var_function_temp, 4);
|
||||
NIR_PASS(progress, s, nir_lower_alu_to_scalar, NULL, NULL);
|
||||
NIR_PASS(progress, s, nir_copy_prop);
|
||||
@@ -6353,7 +6353,7 @@ optimize_nir(struct nir_shader *s, const struct nir_to_dxil_options *opts)
|
||||
NIR_PASS(progress, s, nir_opt_loop_unroll);
|
||||
NIR_PASS(progress, s, nir_lower_pack);
|
||||
NIR_PASS(progress, s, dxil_nir_remove_oob_array_accesses);
|
||||
NIR_PASS_V(s, nir_lower_system_values);
|
||||
NIR_PASS(progress, s, nir_lower_system_values);
|
||||
} while (progress);
|
||||
|
||||
do {
|
||||
@@ -6361,7 +6361,7 @@ optimize_nir(struct nir_shader *s, const struct nir_to_dxil_options *opts)
|
||||
NIR_PASS(progress, s, nir_opt_algebraic_late);
|
||||
} while (progress);
|
||||
|
||||
NIR_PASS_V(s, nir_lower_undef_to_zero);
|
||||
NIR_PASS(_, s, nir_lower_undef_to_zero);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -6631,16 +6631,16 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts,
|
||||
((1ull << FRAG_RESULT_STENCIL) | (1ull << FRAG_RESULT_SAMPLE_MASK)) :
|
||||
(VARYING_BIT_PRIMITIVE_ID | VARYING_BIT_VIEWPORT | VARYING_BIT_LAYER);
|
||||
|
||||
NIR_PASS_V(s, dxil_nir_fix_io_uint_type, in_mask, out_mask);
|
||||
NIR_PASS(_, s, dxil_nir_fix_io_uint_type, in_mask, out_mask);
|
||||
}
|
||||
|
||||
NIR_PASS_V(s, dxil_nir_lower_fquantize2f16);
|
||||
NIR_PASS_V(s, nir_lower_frexp);
|
||||
NIR_PASS_V(s, nir_lower_flrp, 16 | 32 | 64, true);
|
||||
NIR_PASS_V(s, nir_lower_io, nir_var_shader_in | nir_var_shader_out, type_size_vec4, nir_lower_io_lower_64bit_to_32);
|
||||
NIR_PASS_V(s, dxil_nir_ensure_position_writes);
|
||||
NIR_PASS_V(s, dxil_nir_lower_system_values);
|
||||
NIR_PASS_V(s, nir_lower_io_to_scalar, nir_var_shader_in | nir_var_system_value | nir_var_shader_out, NULL, NULL);
|
||||
NIR_PASS(_, s, dxil_nir_lower_fquantize2f16);
|
||||
NIR_PASS(_, s, nir_lower_frexp);
|
||||
NIR_PASS(_, s, nir_lower_flrp, 16 | 32 | 64, true);
|
||||
NIR_PASS(_, s, nir_lower_io, nir_var_shader_in | nir_var_shader_out, type_size_vec4, nir_lower_io_lower_64bit_to_32);
|
||||
NIR_PASS(_, s, dxil_nir_ensure_position_writes);
|
||||
NIR_PASS(_, s, dxil_nir_lower_system_values);
|
||||
NIR_PASS(_, s, nir_lower_io_to_scalar, nir_var_shader_in | nir_var_system_value | nir_var_shader_out, NULL, NULL);
|
||||
|
||||
/* Do a round of optimization to try to vectorize loads/stores. Otherwise the addresses used for loads
|
||||
* might be too opaque for the pass to see that they're next to each other. */
|
||||
@@ -6653,7 +6653,7 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts,
|
||||
.callback = vectorize_filter,
|
||||
.modes = nir_var_mem_ubo | nir_var_mem_ssbo,
|
||||
};
|
||||
NIR_PASS_V(s, nir_opt_load_store_vectorize, &vectorize_opts);
|
||||
NIR_PASS(_, s, nir_opt_load_store_vectorize, &vectorize_opts);
|
||||
|
||||
/* Now that they're bloated to the max, address bit size restrictions and overall size limitations for
|
||||
* a single load/store op. */
|
||||
@@ -6664,45 +6664,45 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts,
|
||||
.may_lower_unaligned_stores_to_atomics = true,
|
||||
.cb_data = &mem_size_data
|
||||
};
|
||||
NIR_PASS_V(s, nir_lower_mem_access_bit_sizes, &mem_size_options);
|
||||
NIR_PASS(_, s, nir_lower_mem_access_bit_sizes, &mem_size_options);
|
||||
|
||||
/* Lastly, conver byte-address UBO loads to vec-addressed. This pass can also deal with selecting sub-
|
||||
* components from the load and dealing with vec-straddling loads. */
|
||||
NIR_PASS_V(s, nir_lower_ubo_vec4);
|
||||
NIR_PASS(_, s, nir_lower_ubo_vec4);
|
||||
|
||||
if (opts->shader_model_max < SHADER_MODEL_6_6) {
|
||||
/* In a later pass, load_helper_invocation will be lowered to sample mask based fallback,
|
||||
* so both load- and is- will be emulated eventually.
|
||||
*/
|
||||
NIR_PASS_V(s, nir_lower_is_helper_invocation);
|
||||
NIR_PASS(_, s, nir_lower_is_helper_invocation);
|
||||
}
|
||||
|
||||
if (ctx->mod.shader_kind == DXIL_HULL_SHADER)
|
||||
NIR_PASS_V(s, dxil_nir_split_tess_ctrl, &ctx->tess_ctrl_patch_constant_func);
|
||||
NIR_PASS(_, s, dxil_nir_split_tess_ctrl, &ctx->tess_ctrl_patch_constant_func);
|
||||
|
||||
if (ctx->mod.shader_kind == DXIL_HULL_SHADER ||
|
||||
ctx->mod.shader_kind == DXIL_DOMAIN_SHADER) {
|
||||
/* Make sure any derefs are gone after lower_io before updating tess level vars */
|
||||
NIR_PASS_V(s, nir_opt_dce);
|
||||
NIR_PASS_V(s, dxil_nir_fixup_tess_level_for_domain);
|
||||
NIR_PASS(_, s, nir_opt_dce);
|
||||
NIR_PASS(_, s, dxil_nir_fixup_tess_level_for_domain);
|
||||
}
|
||||
|
||||
optimize_nir(s, opts);
|
||||
|
||||
NIR_PASS_V(s, nir_remove_dead_variables,
|
||||
NIR_PASS(_, s, nir_remove_dead_variables,
|
||||
nir_var_function_temp | nir_var_mem_constant | nir_var_mem_shared, NULL);
|
||||
|
||||
if (!allocate_sysvalues(ctx))
|
||||
return false;
|
||||
|
||||
NIR_PASS_V(s, dxil_nir_lower_sysval_to_load_input, ctx->system_value);
|
||||
NIR_PASS_V(s, nir_opt_dce);
|
||||
NIR_PASS(_, s, dxil_nir_lower_sysval_to_load_input, ctx->system_value);
|
||||
NIR_PASS(_, s, nir_opt_dce);
|
||||
|
||||
/* This needs to be after any copy prop is done to prevent these movs from being erased */
|
||||
NIR_PASS_V(s, dxil_nir_move_consts);
|
||||
NIR_PASS_V(s, nir_opt_dce);
|
||||
NIR_PASS(_, s, dxil_nir_move_consts);
|
||||
NIR_PASS(_, s, nir_opt_dce);
|
||||
|
||||
NIR_PASS_V(s, dxil_nir_guess_image_formats);
|
||||
NIR_PASS(_, s, dxil_nir_guess_image_formats);
|
||||
|
||||
if (debug_dxil & DXIL_DEBUG_VERBOSE)
|
||||
nir_print_shader(s, stderr);
|
||||
|
||||
Reference in New Issue
Block a user