lavapipe: run optimize loop before krangling pipeline layout

in scenarios like:

vec1 32 ssa_151 = deref_var &shadow_map (uniform sampler2D)
vec1 32 ssa_152 = deref_var &shadow_map (uniform sampler2D)
vec2 32 ssa_153 = vec2 ssa_151, ssa_152
vec1 32 ssa_154 = deref_var &param@4 (function_temp uvec2)
intrinsic store_deref (ssa_154, ssa_153) (wrmask=xy /*3*/, access=0)
vec1 32 ssa_160 = deref_var &param@4 (function_temp uvec2)
vec2 32 ssa_164 = intrinsic load_deref (ssa_160) (access=0)
vec1 32 ssa_167 = mov ssa_164.x
vec1 32 ssa_168 = deref_cast (texture2D *)ssa_167 (uniform texture2D)  /* ptr_stride=0, align_mul=0, align_offset=0 */
vec1 32 ssa_169 = mov ssa_164.y
vec1 32 ssa_170 = deref_cast (sampler *)ssa_169 (uniform sampler)  /* ptr_stride=0, align_mul=0, align_offset=0 */
vec1 32 ssa_172 = (float32)tex ssa_168 (texture_deref), ssa_170 (sampler_deref), ssa_171 (coord), ssa_166 (comparator)

the real variable is stored to a function_temp and then loaded back again,
which means it isn't a direct deref and lower_vri_instr_tex_deref() will
crash because the variable can't be found

BUT running only the passes needed to eliminate derefs will break other tests,
so just run the whole optimize loop again here to avoid such issues

for #5945

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15511>
This commit is contained in:
Mike Blumenkrantz 2022-03-22 16:46:23 -04:00 committed by Marge Bot
parent 6158e9448a
commit 3b39e4d913

View file

@ -620,6 +620,53 @@ lower_demote(nir_shader *nir)
return nir_shader_instructions_pass(nir, lower_demote_impl, nir_metadata_dominance, NULL);
}
static void
optimize(nir_shader *nir)
{
bool progress = false;
do {
progress = false;
NIR_PASS(progress, nir, nir_lower_flrp, 32|64, true);
NIR_PASS(progress, nir, nir_split_array_vars, nir_var_function_temp);
NIR_PASS(progress, nir, nir_shrink_vec_array_vars, nir_var_function_temp);
NIR_PASS(progress, nir, nir_opt_deref);
NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
NIR_PASS(progress, nir, nir_copy_prop);
NIR_PASS(progress, nir, nir_opt_dce);
NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
NIR_PASS(progress, nir, nir_opt_algebraic);
NIR_PASS(progress, nir, nir_opt_constant_folding);
NIR_PASS(progress, nir, nir_opt_remove_phis);
bool trivial_continues = false;
NIR_PASS(trivial_continues, nir, nir_opt_trivial_continues);
progress |= trivial_continues;
if (trivial_continues) {
/* If nir_opt_trivial_continues makes progress, then we need to clean
* things up if we want any hope of nir_opt_if or nir_opt_loop_unroll
* to make progress.
*/
NIR_PASS(progress, nir, nir_copy_prop);
NIR_PASS(progress, nir, nir_opt_dce);
NIR_PASS(progress, nir, nir_opt_remove_phis);
}
NIR_PASS(progress, nir, nir_opt_if, true);
NIR_PASS(progress, nir, nir_opt_dead_cf);
NIR_PASS(progress, nir, nir_opt_conditional_discard);
NIR_PASS(progress, nir, nir_opt_remove_phis);
NIR_PASS(progress, nir, nir_opt_cse);
NIR_PASS(progress, nir, nir_opt_undef);
NIR_PASS(progress, nir, nir_opt_deref);
NIR_PASS(progress, nir, nir_lower_alu_to_scalar, NULL, NULL);
} while (progress);
}
static void
lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
struct vk_shader_module *module,
@ -629,7 +676,6 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
{
nir_shader *nir;
const nir_shader_compiler_options *drv_options = pipeline->device->pscreen->get_compiler_options(pipeline->device->pscreen, PIPE_SHADER_IR_NIR, st_shader_stage_to_ptarget(stage));
bool progress;
uint32_t *spirv = (uint32_t *) module->data;
assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
assert(module->size % 4 == 0);
@ -736,6 +782,7 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
scan_pipeline_info(pipeline, nir);
optimize(nir);
lvp_lower_pipeline_layout(pipeline->device, pipeline->layout, nir);
NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, true);
@ -767,47 +814,7 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, true);
}
do {
progress = false;
NIR_PASS(progress, nir, nir_lower_flrp, 32|64, true);
NIR_PASS(progress, nir, nir_split_array_vars, nir_var_function_temp);
NIR_PASS(progress, nir, nir_shrink_vec_array_vars, nir_var_function_temp);
NIR_PASS(progress, nir, nir_opt_deref);
NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
NIR_PASS(progress, nir, nir_copy_prop);
NIR_PASS(progress, nir, nir_opt_dce);
NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
NIR_PASS(progress, nir, nir_opt_algebraic);
NIR_PASS(progress, nir, nir_opt_constant_folding);
NIR_PASS(progress, nir, nir_opt_remove_phis);
bool trivial_continues = false;
NIR_PASS(trivial_continues, nir, nir_opt_trivial_continues);
progress |= trivial_continues;
if (trivial_continues) {
/* If nir_opt_trivial_continues makes progress, then we need to clean
* things up if we want any hope of nir_opt_if or nir_opt_loop_unroll
* to make progress.
*/
NIR_PASS(progress, nir, nir_copy_prop);
NIR_PASS(progress, nir, nir_opt_dce);
NIR_PASS(progress, nir, nir_opt_remove_phis);
}
NIR_PASS(progress, nir, nir_opt_if, true);
NIR_PASS(progress, nir, nir_opt_dead_cf);
NIR_PASS(progress, nir, nir_opt_conditional_discard);
NIR_PASS(progress, nir, nir_opt_remove_phis);
NIR_PASS(progress, nir, nir_opt_cse);
NIR_PASS(progress, nir, nir_opt_undef);
NIR_PASS(progress, nir, nir_opt_deref);
NIR_PASS(progress, nir, nir_lower_alu_to_scalar, NULL, NULL);
} while (progress);
optimize(nir);
NIR_PASS_V(nir, nir_lower_var_copies);
NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_function_temp, NULL);