diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index 23e9cf14c6d..d16c5d50f43 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -36,6 +36,87 @@ * the counter-part glsl/linker.cpp */ +void +gl_nir_opts(nir_shader *nir) +{ + bool progress; + + do { + progress = false; + + NIR_PASS_V(nir, nir_lower_vars_to_ssa); + + /* Linking deals with unused inputs/outputs, but here we can remove + * things local to the shader in the hopes that we can cleanup other + * things. This pass will also remove variables with only stores, so we + * might be able to make progress after it. + */ + NIR_PASS(progress, nir, nir_remove_dead_variables, + nir_var_function_temp | nir_var_shader_temp | + nir_var_mem_shared, + NULL); + + NIR_PASS(progress, nir, nir_opt_copy_prop_vars); + NIR_PASS(progress, nir, nir_opt_dead_write_vars); + + if (nir->options->lower_to_scalar) { + NIR_PASS_V(nir, nir_lower_alu_to_scalar, + nir->options->lower_to_scalar_filter, NULL); + NIR_PASS_V(nir, nir_lower_phis_to_scalar, false); + } + + NIR_PASS_V(nir, nir_lower_alu); + NIR_PASS_V(nir, nir_lower_pack); + NIR_PASS(progress, nir, nir_copy_prop); + NIR_PASS(progress, nir, nir_opt_remove_phis); + NIR_PASS(progress, nir, nir_opt_dce); + if (nir_opt_trivial_continues(nir)) { + progress = true; + NIR_PASS(progress, nir, nir_copy_prop); + NIR_PASS(progress, nir, nir_opt_dce); + } + NIR_PASS(progress, nir, nir_opt_if, false); + NIR_PASS(progress, nir, nir_opt_dead_cf); + NIR_PASS(progress, nir, nir_opt_cse); + NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true); + + NIR_PASS(progress, nir, nir_opt_phi_precision); + NIR_PASS(progress, nir, nir_opt_algebraic); + NIR_PASS(progress, nir, nir_opt_constant_folding); + + if (!nir->info.flrp_lowered) { + unsigned lower_flrp = + (nir->options->lower_flrp16 ? 16 : 0) | + (nir->options->lower_flrp32 ? 32 : 0) | + (nir->options->lower_flrp64 ? 64 : 0); + + if (lower_flrp) { + bool lower_flrp_progress = false; + + NIR_PASS(lower_flrp_progress, nir, nir_lower_flrp, + lower_flrp, + false /* always_precise */); + if (lower_flrp_progress) { + NIR_PASS(progress, nir, + nir_opt_constant_folding); + progress = true; + } + } + + /* Nothing should rematerialize any flrps, so we only need to do this + * lowering once. + */ + nir->info.flrp_lowered = true; + } + + NIR_PASS(progress, nir, nir_opt_undef); + NIR_PASS(progress, nir, nir_opt_conditional_discard); + if (nir->options->max_unroll_iterations) { + NIR_PASS(progress, nir, nir_opt_loop_unroll); + } + } while (progress); +} + static bool can_remove_uniform(nir_variable *var, UNUSED void *data) { diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index 211909294ca..f45b6f7bb0a 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -42,6 +42,8 @@ struct gl_nir_linker_options { nir_var_mem_ssbo | \ nir_var_image) +void gl_nir_opts(nir_shader *nir); + bool gl_nir_link_spirv(const struct gl_constants *consts, struct gl_shader_program *prog, const struct gl_nir_linker_options *options); diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 30ff77b2dae..cd52f34fec7 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -249,87 +249,6 @@ st_nir_assign_uniform_locations(struct gl_context *ctx, } } -void -st_nir_opts(nir_shader *nir) -{ - bool progress; - - do { - progress = false; - - NIR_PASS_V(nir, nir_lower_vars_to_ssa); - - /* Linking deals with unused inputs/outputs, but here we can remove - * things local to the shader in the hopes that we can cleanup other - * things. This pass will also remove variables with only stores, so we - * might be able to make progress after it. - */ - NIR_PASS(progress, nir, nir_remove_dead_variables, - nir_var_function_temp | nir_var_shader_temp | - nir_var_mem_shared, - NULL); - - NIR_PASS(progress, nir, nir_opt_copy_prop_vars); - NIR_PASS(progress, nir, nir_opt_dead_write_vars); - - if (nir->options->lower_to_scalar) { - NIR_PASS_V(nir, nir_lower_alu_to_scalar, - nir->options->lower_to_scalar_filter, NULL); - NIR_PASS_V(nir, nir_lower_phis_to_scalar, false); - } - - NIR_PASS_V(nir, nir_lower_alu); - NIR_PASS_V(nir, nir_lower_pack); - NIR_PASS(progress, nir, nir_copy_prop); - NIR_PASS(progress, nir, nir_opt_remove_phis); - NIR_PASS(progress, nir, nir_opt_dce); - if (nir_opt_trivial_continues(nir)) { - progress = true; - NIR_PASS(progress, nir, nir_copy_prop); - NIR_PASS(progress, nir, nir_opt_dce); - } - NIR_PASS(progress, nir, nir_opt_if, false); - NIR_PASS(progress, nir, nir_opt_dead_cf); - NIR_PASS(progress, nir, nir_opt_cse); - NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true); - - NIR_PASS(progress, nir, nir_opt_phi_precision); - NIR_PASS(progress, nir, nir_opt_algebraic); - NIR_PASS(progress, nir, nir_opt_constant_folding); - - if (!nir->info.flrp_lowered) { - unsigned lower_flrp = - (nir->options->lower_flrp16 ? 16 : 0) | - (nir->options->lower_flrp32 ? 32 : 0) | - (nir->options->lower_flrp64 ? 64 : 0); - - if (lower_flrp) { - bool lower_flrp_progress = false; - - NIR_PASS(lower_flrp_progress, nir, nir_lower_flrp, - lower_flrp, - false /* always_precise */); - if (lower_flrp_progress) { - NIR_PASS(progress, nir, - nir_opt_constant_folding); - progress = true; - } - } - - /* Nothing should rematerialize any flrps, so we only need to do this - * lowering once. - */ - nir->info.flrp_lowered = true; - } - - NIR_PASS(progress, nir, nir_opt_undef); - NIR_PASS(progress, nir, nir_opt_conditional_discard); - if (nir->options->max_unroll_iterations) { - NIR_PASS(progress, nir, nir_opt_loop_unroll); - } - } while (progress); -} - static void shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align) { @@ -564,7 +483,7 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog, NIR_PASS_V(nir, nir_opt_vectorize, nullptr, nullptr); if (revectorize || lowered_64bit_ops) - st_nir_opts(nir); + gl_nir_opts(nir); } nir_variable_mode mask = @@ -631,11 +550,11 @@ st_nir_link_shaders(nir_shader *producer, nir_shader *consumer) nir_lower_io_arrays_to_elements(producer, consumer); - st_nir_opts(producer); - st_nir_opts(consumer); + gl_nir_opts(producer); + gl_nir_opts(consumer); if (nir_link_opt_varyings(producer, consumer)) - st_nir_opts(consumer); + gl_nir_opts(consumer); NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out, NULL); NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in, NULL); @@ -644,8 +563,8 @@ st_nir_link_shaders(nir_shader *producer, nir_shader *consumer) NIR_PASS_V(producer, nir_lower_global_vars_to_local); NIR_PASS_V(consumer, nir_lower_global_vars_to_local); - st_nir_opts(producer); - st_nir_opts(consumer); + gl_nir_opts(producer); + gl_nir_opts(consumer); /* Optimizations can cause varyings to become unused. * nir_compact_varyings() depends on all dead varyings being removed so @@ -795,7 +714,7 @@ st_link_nir(struct gl_context *ctx, * optimized here. */ if (num_shaders == 1) - st_nir_opts(linked_shader[0]->Program->nir); + gl_nir_opts(linked_shader[0]->Program->nir); if (shader_program->data->spirv) { static const gl_nir_linker_options opts = { diff --git a/src/mesa/state_tracker/st_nir.h b/src/mesa/state_tracker/st_nir.h index 384ee653722..74c644f6817 100644 --- a/src/mesa/state_tracker/st_nir.h +++ b/src/mesa/state_tracker/st_nir.h @@ -46,8 +46,6 @@ char *st_finalize_nir(struct st_context *st, struct gl_program *prog, struct nir_shader *nir, bool finalize_by_driver, bool is_before_variants); -void st_nir_opts(struct nir_shader *nir); - bool st_link_nir(struct gl_context *ctx, struct gl_shader_program *shader_program); diff --git a/src/mesa/state_tracker/st_nir_builtins.c b/src/mesa/state_tracker/st_nir_builtins.c index 1e52f337b93..06959dcd078 100644 --- a/src/mesa/state_tracker/st_nir_builtins.c +++ b/src/mesa/state_tracker/st_nir_builtins.c @@ -26,6 +26,7 @@ #include "compiler/nir/nir_builder.h" #include "compiler/glsl/gl_nir.h" +#include "compiler/glsl/gl_nir_linker.h" #include "tgsi/tgsi_parse.h" struct pipe_shader_state * @@ -72,7 +73,7 @@ st_nir_finish_builtin_shader(struct st_context *st, char *msg = screen->finalize_nir(screen, nir); free(msg); } else { - st_nir_opts(nir); + gl_nir_opts(nir); } struct pipe_shader_state state = { diff --git a/src/mesa/state_tracker/st_pbo_compute.c b/src/mesa/state_tracker/st_pbo_compute.c index 46390b907e4..6895d8c4a60 100644 --- a/src/mesa/state_tracker/st_pbo_compute.c +++ b/src/mesa/state_tracker/st_pbo_compute.c @@ -35,6 +35,7 @@ #include "compiler/nir/nir_builder.h" #include "compiler/nir/nir_format_convert.h" #include "compiler/glsl/gl_nir.h" +#include "compiler/glsl/gl_nir_linker.h" #include "util/u_sampler.h" #define BGR_FORMAT(NAME) \ @@ -649,7 +650,7 @@ create_conversion_shader(struct st_context *st, enum pipe_texture_target target, nir_pop_if(&b, NULL); nir_validate_shader(b.shader, NULL); - st_nir_opts(b.shader); + gl_nir_opts(b.shader); return st_nir_finish_builtin_shader(st, b.shader); } diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index ad78069c3fc..d3985a44c71 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -41,6 +41,7 @@ #include "program/programopt.h" #include "compiler/glsl/gl_nir.h" +#include "compiler/glsl/gl_nir_linker.h" #include "compiler/nir/nir.h" #include "compiler/nir/nir_serialize.h" #include "draw/draw_context.h" @@ -386,7 +387,7 @@ st_prog_to_nir_postprocess(struct st_context *st, nir_shader *nir, /* Optimise NIR */ NIR_PASS_V(nir, nir_opt_constant_folding); - st_nir_opts(nir); + gl_nir_opts(nir); st_finalize_nir_before_variants(nir); if (st->allow_st_finalize_nir_twice) {