nir/opt_varyings: reduce stack usage

Avoid put a huge struct on stack to fix a stack overflow on musl libc.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10988
Fixes: c66967b5cb (nir: add nir_opt_varyings, new pass optimizing and compacting varyings)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29375>
This commit is contained in:
Natanael Copa 2024-05-24 11:56:46 +02:00 committed by Marge Bot
parent f7a262cd6d
commit 0274518615

View file

@ -485,6 +485,7 @@
#include "nir.h"
#include "nir_builder.h"
#include "util/u_math.h"
#include "util/u_memory.h"
/* nir_opt_varyings works at scalar 16-bit granularity across all varyings.
*
@ -4205,11 +4206,12 @@ free_linkage(struct linkage_info *linkage)
static void
print_shader_linkage(nir_shader *producer, nir_shader *consumer)
{
struct linkage_info linkage;
struct linkage_info *linkage = MALLOC_STRUCT(linkage_info);
init_linkage(producer, consumer, false, 0, 0, &linkage);
print_linkage(&linkage);
free_linkage(&linkage);
init_linkage(producer, consumer, false, 0, 0, linkage);
print_linkage(linkage);
free_linkage(linkage);
FREE(linkage);
}
/**
@ -4226,6 +4228,11 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
if (producer->info.stage == MESA_SHADER_TASK)
return 0;
nir_opt_varyings_progress progress = 0;
struct linkage_info *linkage = MALLOC_STRUCT(linkage_info);
if (linkage == NULL)
return 0;
/* Producers before a fragment shader must have up-to-date vertex
* divergence information.
*/
@ -4235,19 +4242,17 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
nir_vertex_divergence_analysis(producer);
}
nir_opt_varyings_progress progress = 0;
struct linkage_info linkage;
init_linkage(producer, consumer, spirv, max_uniform_components,
max_ubos_per_stage, &linkage);
max_ubos_per_stage, linkage);
/* Part 1: Run optimizations that only remove varyings. (they can move
* instructions between shaders)
*/
remove_dead_varyings(&linkage, &progress);
propagate_uniform_expressions(&linkage, &progress);
remove_dead_varyings(linkage, &progress);
propagate_uniform_expressions(linkage, &progress);
/* Part 2: Deduplicate outputs. */
deduplicate_outputs(&linkage, &progress);
deduplicate_outputs(linkage, &progress);
/* Run CSE on the consumer after output deduplication because duplicated
* loads can prevent finding the post-dominator for inter-shader code
@ -4256,17 +4261,17 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
NIR_PASS(_, consumer, nir_opt_cse);
/* Re-gather linkage info after CSE. */
free_linkage(&linkage);
free_linkage(linkage);
init_linkage(producer, consumer, spirv, max_uniform_components,
max_ubos_per_stage, &linkage);
max_ubos_per_stage, linkage);
/* This must be done again to clean up bitmasks in linkage. */
remove_dead_varyings(&linkage, &progress);
remove_dead_varyings(linkage, &progress);
/* This must be done after deduplication and before inter-shader code
* motion.
*/
tidy_up_convergent_varyings(&linkage);
find_open_coded_tes_input_interpolation(&linkage);
tidy_up_convergent_varyings(linkage);
find_open_coded_tes_input_interpolation(linkage);
/* Part 3: Run optimizations that completely change varyings. */
#if PRINT
@ -4278,31 +4283,32 @@ nir_opt_varyings(nir_shader *producer, nir_shader *consumer, bool spirv,
puts("");
#endif
while (backward_inter_shader_code_motion(&linkage, &progress)) {
while (backward_inter_shader_code_motion(linkage, &progress)) {
#if PRINT
i++;
printf("Finished: %i\n", i);
nir_print_shader(linkage.producer_builder.shader, stdout);
nir_print_shader(linkage.consumer_builder.shader, stdout);
print_linkage(&linkage);
nir_print_shader(linkage->producer_builder.shader, stdout);
nir_print_shader(linkage->consumer_builder.shader, stdout);
print_linkage(linkage);
puts("");
#endif
}
/* Part 4: Do compaction. */
compact_varyings(&linkage, &progress);
compact_varyings(linkage, &progress);
nir_metadata_preserve(linkage.producer_builder.impl,
nir_metadata_preserve(linkage->producer_builder.impl,
progress & nir_progress_producer ?
(nir_metadata_block_index |
nir_metadata_dominance) :
nir_metadata_all);
nir_metadata_preserve(linkage.consumer_builder.impl,
nir_metadata_preserve(linkage->consumer_builder.impl,
progress & nir_progress_consumer ?
(nir_metadata_block_index |
nir_metadata_dominance) :
nir_metadata_all);
free_linkage(&linkage);
free_linkage(linkage);
FREE(linkage);
if (progress & nir_progress_producer)
nir_validate_shader(producer, "nir_opt_varyings");