From 1f8b22a208c18349fb7dbc791b735c10a2ef222a Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 21 Jul 2025 13:01:44 -0400 Subject: [PATCH] hk: optimize varyings Stats are all over the place for some apps. PERCENTAGE DELTAS Shaders MaxWaves Instrs CodeSize Spills Fills Scratch ALU FSCIB IC GPRs Uniforms Preamble instrs detroit_become_human 995 +0.12% -1.21% -1.27% +77.42% +71.67% +78.82% -1.11% -1.11% -1.03% -3.22% -1.40% -2.07% god_of_war 1029 -0.04% -5.05% -4.73% . . . -4.32% -4.32% -2.48% -1.64% -4.61% -5.13% total_warhammer_3 642 +7.28% -14.66% -13.45% -49.23% -49.04% -34.78% -14.25% -14.25% -10.50% -8.72% -7.98% -8.57% But probably a win overall. Improves Control fps by a few %. Totals: MaxWaves: 53068992 -> 53195520 (+0.24%); split: +0.39%, -0.16% Instrs: 23793021 -> 22776261 (-4.27%); split: -4.41%, +0.14% CodeSize: 169869654 -> 163433116 (-3.79%); split: -3.96%, +0.17% Spills: 66100 -> 66124 (+0.04%); split: -0.67%, +0.71% Fills: 43755 -> 43471 (-0.65%); split: -2.05%, +1.40% Scratch: 403698 -> 403754 (+0.01%); split: -0.31%, +0.32% ALU: 18510167 -> 17814743 (-3.76%); split: -3.95%, +0.19% FSCIB: 18454849 -> 17759392 (-3.77%); split: -3.96%, +0.19% IC: 5279176 -> 5184542 (-1.79%); split: -1.82%, +0.03% GPRs: 3833103 -> 3751058 (-2.14%); split: -4.12%, +1.97% Uniforms: 10528625 -> 10271771 (-2.44%); split: -2.52%, +0.08% Preamble instrs: 10289152 -> 10008570 (-2.73%); split: -2.95%, +0.23% Totals from 42844 (79.31% of 54019) affected shaders: MaxWaves: 42014720 -> 42141248 (+0.30%); split: +0.50%, -0.20% Instrs: 18406093 -> 17389333 (-5.52%); split: -5.70%, +0.18% CodeSize: 131343714 -> 124907176 (-4.90%); split: -5.13%, +0.23% Spills: 21479 -> 21503 (+0.11%); split: -2.06%, +2.17% Fills: 5488 -> 5204 (-5.17%); split: -16.31%, +11.13% Scratch: 332144 -> 332200 (+0.02%); split: -0.37%, +0.39% ALU: 14476764 -> 13781340 (-4.80%); split: -5.05%, +0.25% FSCIB: 14476671 -> 13781214 (-4.80%); split: -5.05%, +0.25% IC: 3930760 -> 3836126 (-2.41%); split: -2.45%, +0.04% GPRs: 3158947 -> 3076902 (-2.60%); split: -4.99%, +2.40% Uniforms: 8660650 -> 8403796 (-2.97%); split: -3.06%, +0.09% Preamble instrs: 8304828 -> 8024246 (-3.38%); split: -3.66%, +0.28% Signed-off-by: Alyssa Rosenzweig Reviewed-by: Mary Guillemard Part-of: --- src/asahi/vulkan/hk_shader.c | 77 +++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/src/asahi/vulkan/hk_shader.c b/src/asahi/vulkan/hk_shader.c index 64593461855..378a9416b0b 100644 --- a/src/asahi/vulkan/hk_shader.c +++ b/src/asahi/vulkan/hk_shader.c @@ -2,6 +2,8 @@ * Copyright 2024 Valve Corporation * Copyright 2024 Alyssa Rosenzweig * Copyright 2022-2023 Collabora Ltd. and Red Hat Inc. + * Copyright 2023 Advanced Micro Devices, Inc. + * Copyright 2018 Intel Corporation * SPDX-License-Identifier: MIT */ #include "hk_shader.h" @@ -1178,6 +1180,7 @@ hk_compile_nir(struct hk_device *dev, const VkAllocationCallbacks *pAllocator, if (lock) simple_mtx_lock(lock); + assert(nir->info.io_lowered); agx_compile_shader_nir(nir, &backend_key, &shader->b); if (lock) @@ -1296,11 +1299,10 @@ hk_compile_shader(struct hk_device *dev, struct vk_shader_compile_info *info, return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); } - /* TODO: Multiview with ESO */ - const bool is_multiview = state && state->rp->view_mask != 0; - - hk_lower_nir(dev, nir, info->robustness, is_multiview, - info->set_layout_count, info->set_layouts, features); + if (!nir->info.io_lowered) { + hk_lower_nir(dev, nir, info->robustness, false, info->set_layout_count, + info->set_layouts, features); + } gl_shader_stage sw_stage = nir->info.stage; @@ -1483,6 +1485,41 @@ hk_compile_shader(struct hk_device *dev, struct vk_shader_compile_info *info, return VK_SUCCESS; } +static void +nir_opts(nir_shader *nir) +{ + bool progress; + + do { + progress = false; + + NIR_PASS(progress, nir, nir_opt_loop); + NIR_PASS(progress, nir, nir_copy_prop); + NIR_PASS(progress, nir, nir_opt_remove_phis); + NIR_PASS(progress, nir, nir_opt_dce); + + NIR_PASS(progress, nir, nir_opt_if, 0); + NIR_PASS(progress, nir, nir_opt_dead_cf); + NIR_PASS(progress, nir, nir_opt_cse); + + NIR_PASS(progress, nir, nir_opt_peephole_select, + &(nir_opt_peephole_select_options){ + .limit = 8, + .expensive_alu_ok = true, + .discard_ok = true, + }); + + NIR_PASS(progress, nir, nir_opt_phi_precision); + NIR_PASS(progress, nir, nir_opt_algebraic); + NIR_PASS(progress, nir, nir_opt_constant_folding); + NIR_PASS(progress, nir, nir_io_add_const_offset_to_base, + nir_var_shader_in | nir_var_shader_out); + + NIR_PASS(progress, nir, nir_opt_undef); + NIR_PASS(progress, nir, nir_opt_loop_unroll); + } while (progress); +} + static VkResult hk_compile_shaders(struct vk_device *vk_dev, uint32_t shader_count, struct vk_shader_compile_info *infos, @@ -1492,8 +1529,38 @@ hk_compile_shaders(struct vk_device *vk_dev, uint32_t shader_count, struct vk_shader **shaders_out) { struct hk_device *dev = container_of(vk_dev, struct hk_device, vk); + nir_shader *shaders[shader_count]; + + /* Lower shaders, notably lowering I/O. This is a prerequisite for + * intershader optimization. + */ + for (uint32_t i = 0; i < shader_count; i++) { + const struct vk_shader_compile_info *info = &infos[i]; + /* TODO: Multiview with ESO */ + const bool is_multiview = state && state->rp->view_mask != 0; + enum hk_feature_key hk_features = hk_make_feature_key(features); + nir_shader *nir = info->nir; + + hk_lower_nir(dev, nir, info->robustness, is_multiview, + info->set_layout_count, info->set_layouts, hk_features); + + if (nir->xfb_info) { + nir_io_add_const_offset_to_base( + nir, nir_var_shader_in | nir_var_shader_out); + + nir_io_add_intrinsic_xfb_info(nir); + } + + shaders[i] = nir; + } + + nir_opt_varyings_bulk(shaders, shader_count, true, UINT32_MAX, UINT32_MAX, + nir_opts); for (uint32_t i = 0; i < shader_count; i++) { + nir_shader_gather_info(infos[i].nir, + nir_shader_get_entrypoint(infos[i].nir)); + VkResult result = hk_compile_shader(dev, &infos[i], state, features, pAllocator, (struct hk_api_shader **)&shaders_out[i]);