diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc index 75f9a592fe9..25a9db3e46c 100644 --- a/src/freedreno/vulkan/tu_shader.cc +++ b/src/freedreno/vulkan/tu_shader.cc @@ -2766,6 +2766,45 @@ tu_shader_create(struct tu_device *dev, return VK_SUCCESS; } +static void +lower_io_to_scalar_early(nir_shader *nir, nir_variable_mode mask) +{ + bool progress = false; + NIR_PASS(progress, nir, nir_lower_io_to_scalar_early, mask); + + if (progress) { + /* Optimize the new vector code and then remove dead vars. */ + NIR_PASS(_, nir, nir_copy_prop); + + if (mask & nir_var_shader_out) { + /* Optimize swizzled movs of load_const for nir_link_opt_varyings's + * constant propagation. + */ + NIR_PASS(_, nir, nir_opt_constant_folding); + + /* For nir_link_opt_varyings's duplicate input opt. */ + NIR_PASS(_, nir, nir_opt_cse); + } + + /* Run copy-propagation to help remove dead output variables (some + * shaders have useless copies to/from an output), so compaction later + * will be more effective. + * + * This will have been done earlier but it might not have worked because + * the outputs were vector. + */ + NIR_PASS(_, nir, nir_opt_copy_prop_vars); + + NIR_PASS(_, nir, nir_opt_dce); + + const nir_remove_dead_variables_options var_opts = { + .can_remove_var = + (mask & nir_var_shader_out) ? nir_vk_is_not_xfb_output : NULL, + }; + NIR_PASS(_, nir, nir_remove_dead_variables, mask, &var_opts); + } +} + static void tu_link_shaders(nir_shader **shaders, unsigned shaders_count) { @@ -2781,6 +2820,9 @@ tu_link_shaders(nir_shader **shaders, unsigned shaders_count) continue; } + lower_io_to_scalar_early(producer, nir_var_shader_out); + lower_io_to_scalar_early(consumer, nir_var_shader_in); + if (nir_link_opt_varyings(producer, consumer)) { NIR_PASS(_, consumer, nir_opt_constant_folding); NIR_PASS(_, consumer, nir_opt_algebraic); @@ -2809,6 +2851,8 @@ tu_link_shaders(nir_shader **shaders, unsigned shaders_count) nir_lower_global_vars_to_local(consumer); } + NIR_PASS(_, producer, nir_lower_io_to_vector, nir_var_shader_out); + NIR_PASS(_, consumer, nir_lower_io_to_vector, nir_var_shader_in); consumer = producer; }