|
| 1 | +From 3da828d2dd12e20ba2afc152db8d7236c7a48c13 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Ian Romanick <ian.d.romanick@intel.com> |
| 3 | +Date: Fri, 23 Jan 2026 09:58:26 -0800 |
| 4 | +Subject: [PATCH 1/2] spirv: Use STACK_ARRAY instead of NIR_VLA |
| 5 | + |
| 6 | +The number of fields comes from the shader, so it could be a value large |
| 7 | +enough that using alloca would be problematic. |
| 8 | + |
| 9 | +Fixes: 2a023f30a64 ("nir/spirv: Add basic support for types") |
| 10 | +Reviewed-by: Caio Oliveira <caio.oliveira@intel.com> |
| 11 | +Reviewed-by: Ryan Neph <ryanneph@google.com> |
| 12 | +Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> |
| 13 | +Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39866> |
| 14 | + |
| 15 | +Upstream-reference: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39866.patch |
| 16 | +--- |
| 17 | + src/compiler/nir/nir_functions.c | 5 ++-- |
| 18 | + src/compiler/spirv/spirv_to_nir.c | 27 ++++++++++++------- |
| 19 | + src/util/stack_array.h | 45 +++++++++++++++++++++++++++++++ |
| 20 | + 3 files changed, 65 insertions(+), 12 deletions(-) |
| 21 | + create mode 100644 src/util/stack_array.h |
| 22 | + |
| 23 | +diff --git a/src/compiler/nir/nir_functions.c b/src/compiler/nir/nir_functions.c |
| 24 | +index d17ebd8..abd5e8a 100644 |
| 25 | +--- a/src/compiler/nir/nir_functions.c |
| 26 | ++++ b/src/compiler/nir/nir_functions.c |
| 27 | +@@ -21,10 +21,10 @@ |
| 28 | + * IN THE SOFTWARE. |
| 29 | + */ |
| 30 | + |
| 31 | ++#include "util/stack_array.h" |
| 32 | + #include "nir.h" |
| 33 | + #include "nir_builder.h" |
| 34 | + #include "nir_control_flow.h" |
| 35 | +-#include "nir_vla.h" |
| 36 | + |
| 37 | + /* |
| 38 | + * TODO: write a proper inliner for GPUs. |
| 39 | +@@ -177,12 +177,13 @@ static bool inline_functions_pass(nir_builder *b, |
| 40 | + * to an SSA value first. |
| 41 | + */ |
| 42 | + const unsigned num_params = call->num_params; |
| 43 | +- NIR_VLA(nir_def *, params, num_params); |
| 44 | ++ STACK_ARRAY(nir_def *, params, num_params); |
| 45 | + for (unsigned i = 0; i < num_params; i++) { |
| 46 | + params[i] = call->params[i].ssa; |
| 47 | + } |
| 48 | + |
| 49 | + nir_inline_function_impl(b, call->callee->impl, params, NULL); |
| 50 | ++ STACK_ARRAY_FINISH(params); |
| 51 | + return true; |
| 52 | + } |
| 53 | + |
| 54 | +diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c |
| 55 | +index ed2a003..428adea 100644 |
| 56 | +--- a/src/compiler/spirv/spirv_to_nir.c |
| 57 | ++++ b/src/compiler/spirv/spirv_to_nir.c |
| 58 | +@@ -27,7 +27,6 @@ |
| 59 | + |
| 60 | + #include "glsl_types.h" |
| 61 | + #include "vtn_private.h" |
| 62 | +-#include "nir/nir_vla.h" |
| 63 | + #include "nir/nir_control_flow.h" |
| 64 | + #include "nir/nir_constant_expressions.h" |
| 65 | + #include "nir/nir_deref.h" |
| 66 | +@@ -38,6 +37,7 @@ |
| 67 | + #include "util/u_string.h" |
| 68 | + #include "util/u_debug.h" |
| 69 | + |
| 70 | ++#include "util/stack_array.h" |
| 71 | + #include <stdio.h> |
| 72 | + |
| 73 | + #ifndef NDEBUG |
| 74 | +@@ -1013,7 +1013,7 @@ vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type, |
| 75 | + case vtn_base_type_struct: { |
| 76 | + bool need_new_struct = false; |
| 77 | + const uint32_t num_fields = type->length; |
| 78 | +- NIR_VLA(struct glsl_struct_field, fields, num_fields); |
| 79 | ++ STACK_ARRAY(struct glsl_struct_field, fields, num_fields); |
| 80 | + for (unsigned i = 0; i < num_fields; i++) { |
| 81 | + fields[i] = *glsl_get_struct_field_data(type->type, i); |
| 82 | + const struct glsl_type *field_nir_type = |
| 83 | +@@ -1023,20 +1023,25 @@ vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type, |
| 84 | + need_new_struct = true; |
| 85 | + } |
| 86 | + } |
| 87 | ++ |
| 88 | ++ const struct glsl_type *result; |
| 89 | + if (need_new_struct) { |
| 90 | + if (glsl_type_is_interface(type->type)) { |
| 91 | +- return glsl_interface_type(fields, num_fields, |
| 92 | +- /* packing */ 0, false, |
| 93 | +- glsl_get_type_name(type->type)); |
| 94 | ++ result = glsl_interface_type(fields, num_fields, |
| 95 | ++ /* packing */ 0, false, |
| 96 | ++ glsl_get_type_name(type->type)); |
| 97 | + } else { |
| 98 | +- return glsl_struct_type(fields, num_fields, |
| 99 | +- glsl_get_type_name(type->type), |
| 100 | +- glsl_struct_type_is_packed(type->type)); |
| 101 | ++ result = glsl_struct_type(fields, num_fields, |
| 102 | ++ glsl_get_type_name(type->type), |
| 103 | ++ glsl_struct_type_is_packed(type->type)); |
| 104 | + } |
| 105 | + } else { |
| 106 | + /* No changes, just pass it on */ |
| 107 | +- return type->type; |
| 108 | ++ result = type->type; |
| 109 | + } |
| 110 | ++ |
| 111 | ++ STACK_ARRAY_FINISH(fields); |
| 112 | ++ return result; |
| 113 | + } |
| 114 | + |
| 115 | + case vtn_base_type_image: |
| 116 | +@@ -1647,7 +1652,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, |
| 117 | + val->type->offsets = vtn_alloc_array(b, unsigned, num_fields); |
| 118 | + val->type->packed = false; |
| 119 | + |
| 120 | +- NIR_VLA(struct glsl_struct_field, fields, count); |
| 121 | ++ STACK_ARRAY(struct glsl_struct_field, fields, count); |
| 122 | + for (unsigned i = 0; i < num_fields; i++) { |
| 123 | + val->type->members[i] = vtn_get_type(b, w[i + 2]); |
| 124 | + const char *name = NULL; |
| 125 | +@@ -1703,6 +1708,8 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, |
| 126 | + name ? name : "struct", |
| 127 | + val->type->packed); |
| 128 | + } |
| 129 | ++ |
| 130 | ++ STACK_ARRAY_FINISH(fields); |
| 131 | + break; |
| 132 | + } |
| 133 | + |
| 134 | +diff --git a/src/util/stack_array.h b/src/util/stack_array.h |
| 135 | +new file mode 100644 |
| 136 | +index 0000000..e2133bd |
| 137 | +--- /dev/null |
| 138 | ++++ b/src/util/stack_array.h |
| 139 | +@@ -0,0 +1,45 @@ |
| 140 | ++/* |
| 141 | ++ * Copyright © 2025 Collabora, Ltd. |
| 142 | ++ * |
| 143 | ++ * Permission is hereby granted, free of charge, to any person obtaining a |
| 144 | ++ * copy of this software and associated documentation files (the "Software"), |
| 145 | ++ * to deal in the Software without restriction, including without limitation |
| 146 | ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 147 | ++ * and/or sell copies of the Software, and to permit persons to whom the |
| 148 | ++ * Software is furnished to do so, subject to the following conditions: |
| 149 | ++ * |
| 150 | ++ * The above copyright notice and this permission notice (including the next |
| 151 | ++ * paragraph) shall be included in all copies or substantial portions of the |
| 152 | ++ * Software. |
| 153 | ++ * |
| 154 | ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 155 | ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 156 | ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 157 | ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 158 | ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 159 | ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 160 | ++ * IN THE SOFTWARE. |
| 161 | ++ */ |
| 162 | ++ |
| 163 | ++#include <stdlib.h> |
| 164 | ++ |
| 165 | ++#ifndef UTIL_STACK_ARRAY_H |
| 166 | ++#define UTIL_STACK_ARRAY_H |
| 167 | ++ |
| 168 | ++#define STACK_ARRAY_SIZE 8 |
| 169 | ++ |
| 170 | ++/* Sometimes gcc may claim -Wmaybe-uninitialized for the stack array in some |
| 171 | ++ * places it can't verify that when size is 0 nobody down the call chain reads |
| 172 | ++ * the array. Please don't try to fix it by zero-initializing the array here |
| 173 | ++ * since it's used in a lot of different places. An "if (size == 0) return;" |
| 174 | ++ * may work for you. |
| 175 | ++ */ |
| 176 | ++#define STACK_ARRAY(type, name, size) \ |
| 177 | ++ type _stack_##name[STACK_ARRAY_SIZE]; \ |
| 178 | ++ type *const name = \ |
| 179 | ++ ((size) <= STACK_ARRAY_SIZE ? _stack_##name : (type *)malloc((size) * sizeof(type))) |
| 180 | ++ |
| 181 | ++#define STACK_ARRAY_FINISH(name) \ |
| 182 | ++ if (name != _stack_##name) free(name) |
| 183 | ++ |
| 184 | ++#endif /* UTIL_STACK_ARRAY_H */ |
| 185 | +-- |
| 186 | +2.45.4 |
| 187 | + |
0 commit comments