xref: /aosp_15_r20/external/mesa3d/src/compiler/glsl/gl_nir_link_uniform_blocks.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2019 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "nir.h"
25 #include "nir_deref.h"
26 #include "gl_nir_linker.h"
27 #include "ir_uniform.h" /* for gl_uniform_storage */
28 #include "linker_util.h"
29 #include "main/consts_exts.h"
30 #include "main/shader_types.h"
31 #include "util/u_math.h"
32 
33 /**
34  * This file contains code to do a nir-based linking for uniform blocks. This
35  * includes ubos and ssbos.
36  *
37  * For the case of ARB_gl_spirv there are some differences compared with GLSL:
38  *
39  * 1. Linking doesn't use names: GLSL linking use names as core concept. But
40  *    on SPIR-V, uniform block name, fields names, and other names are
41  *    considered optional debug infor so could not be present. So the linking
42  *    should work without it, and it is optional to not handle them at
43  *    all. From ARB_gl_spirv spec.
44  *
45  *    "19. How should the program interface query operations behave for program
46  *         objects created from SPIR-V shaders?
47  *
48  *     DISCUSSION: we previously said we didn't need reflection to work for
49  *     SPIR-V shaders (at least for the first version), however we are left
50  *     with specifying how it should "not work". The primary issue is that
51  *     SPIR-V binaries are not required to have names associated with
52  *     variables. They can be associated in debug information, but there is no
53  *     requirement for that to be present, and it should not be relied upon.
54  *
55  *     Options:
56  *
57  *     <skip>
58  *
59  *    C) Allow as much as possible to work "naturally". You can query for the
60  *    number of active resources, and for details about them. Anything that
61  *    doesn't query by name will work as expected. Queries for maximum length
62  *    of names return one. Queries for anything "by name" return INVALID_INDEX
63  *    (or -1). Querying the name property of a resource returns an empty
64  *    string. This may allow many queries to work, but it's not clear how
65  *    useful it would be if you can't actually know which specific variable
66  *    you are retrieving information on. If everything is specified a-priori
67  *    by location/binding/offset/index/component in the shader, this may be
68  *    sufficient.
69  *
70  *    RESOLVED.  Pick (c), but also allow debug names to be returned if an
71  *    implementation wants to."
72  *
73  * When linking SPIR-V shaders this implemention doesn't care for the names,
74  * as the main objective is functional, and not support optional debug
75  * features.
76  *
77  * 2. Terminology: this file handles both UBO and SSBO, including both as
78  *    "uniform blocks" analogously to what is done in the GLSL (IR) path.
79  *
80  *    From ARB_gl_spirv spec:
81  *      "Mapping of Storage Classes:
82  *       <skip>
83  *       uniform blockN { ... } ...;  -> Uniform, with Block decoration
84  *       <skip>
85  *       buffer  blockN { ... } ...;  -> Uniform, with BufferBlock decoration"
86  *
87  * 3. Explicit data: for the SPIR-V path the code assumes that all structure
88  *    members have an Offset decoration, all arrays have an ArrayStride and
89  *    all matrices have a MatrixStride, even for nested structures. That way
90  *    we don’t have to worry about the different layout modes. This is
91  *    explicitly required in the SPIR-V spec:
92  *
93  *    "Composite objects in the UniformConstant, Uniform, and PushConstant
94  *     Storage Classes must be explicitly laid out. The following apply to all
95  *     the aggregate and matrix types describing such an object, recursively
96  *     through their nested types:
97  *
98  *    – Each structure-type member must have an Offset Decoration.
99  *    – Each array type must have an ArrayStride Decoration.
100  *    – Each structure-type member that is a matrix or array-of-matrices must
101  *      have be decorated with a MatrixStride Decoration, and one of the
102  *      RowMajor or ColMajor Decorations."
103  *
104  *    Additionally, the structure members are expected to be presented in
105  *    increasing offset order:
106  *
107  *   "a structure has lower-numbered members appearing at smaller offsets than
108  *    higher-numbered members"
109  */
110 
111 enum block_type {
112    BLOCK_UBO,
113    BLOCK_SSBO
114 };
115 
116 struct uniform_block_array_elements {
117    unsigned *array_elements;
118    unsigned num_array_elements;
119    /**
120     * Size of the array before array-trimming optimizations.
121     *
122     * Locations are only assigned to active array elements, but the location
123     * values are calculated as if all elements are active. The total number
124     * of elements in an array including the elements in arrays of arrays before
125     * inactive elements are removed is needed to be perform that calculation.
126     */
127    unsigned aoa_size;
128 
129    struct uniform_block_array_elements *array;
130 };
131 
132 struct link_uniform_block_active {
133    const struct glsl_type *type;
134    nir_variable *var;
135 
136    struct uniform_block_array_elements *array;
137 
138    unsigned binding;
139 
140    bool has_instance_name;
141    bool has_binding;
142    bool is_shader_storage;
143 };
144 
145 /*
146  * It is worth to note that ARB_gl_spirv spec doesn't require us to do this
147  * validation, but at the same time, it allow us to do it.
148  */
149 static bool
link_blocks_are_compatible(const struct gl_uniform_block * a,const struct gl_uniform_block * b)150 link_blocks_are_compatible(const struct gl_uniform_block *a,
151                            const struct gl_uniform_block *b)
152 {
153    /*
154     *   "7.4.2. SPIR-V Shader Interface Matching":
155     *    "Uniform and shader storage block variables must also be decorated
156     *     with a Binding"
157     */
158    if (a->Binding != b->Binding)
159       return false;
160 
161    assert((a->name.string == NULL && b->name.string == NULL) ||
162           strcmp(a->name.string, b->name.string) == 0);
163 
164    if (a->NumUniforms != b->NumUniforms)
165       return false;
166 
167    if (a->_Packing != b->_Packing)
168       return false;
169 
170    if (a->_RowMajor != b->_RowMajor)
171       return false;
172 
173    for (unsigned i = 0; i < a->NumUniforms; i++) {
174       if (a->Uniforms[i].Name != NULL && b->Uniforms[i].Name != NULL &&
175           strcmp(a->Uniforms[i].Name, b->Uniforms[i].Name) != 0)
176          return false;
177 
178       if (a->Uniforms[i].Type != b->Uniforms[i].Type)
179          return false;
180 
181       if (a->Uniforms[i].RowMajor != b->Uniforms[i].RowMajor)
182          return false;
183 
184       if (a->Uniforms[i].Offset != b->Uniforms[i].Offset)
185          return false;
186    }
187 
188    return true;
189 }
190 
191 /**
192  * Merges a buffer block into an array of buffer blocks that may or may not
193  * already contain a copy of it.
194  *
195  * Returns the index of the block in the array (new if it was needed, or the
196  * index of the copy of it). -1 if there are two incompatible block
197  * definitions with the same binding.
198  *
199  */
200 static int
link_cross_validate_uniform_block(void * mem_ctx,struct gl_uniform_block ** linked_blocks,unsigned int * num_linked_blocks,struct gl_uniform_block * new_block,bool is_spirv)201 link_cross_validate_uniform_block(void *mem_ctx,
202                                   struct gl_uniform_block **linked_blocks,
203                                   unsigned int *num_linked_blocks,
204                                   struct gl_uniform_block *new_block,
205                                   bool is_spirv)
206 {
207    /* We first check if new_block was already linked */
208    for (unsigned int i = 0; i < *num_linked_blocks; i++) {
209       struct gl_uniform_block *old_block = &(*linked_blocks)[i];
210 
211       if ((is_spirv && old_block->Binding == new_block->Binding) ||
212           (!is_spirv && (strcmp(old_block->name.string, new_block->name.string) == 0)))
213          return link_blocks_are_compatible(old_block, new_block) ? i : -1;
214    }
215 
216    *linked_blocks = reralloc(mem_ctx, *linked_blocks,
217                              struct gl_uniform_block,
218                              *num_linked_blocks + 1);
219    int linked_block_index = (*num_linked_blocks)++;
220    struct gl_uniform_block *linked_block = &(*linked_blocks)[linked_block_index];
221 
222    memcpy(linked_block, new_block, sizeof(*new_block));
223    linked_block->Uniforms = ralloc_array(*linked_blocks,
224                                          struct gl_uniform_buffer_variable,
225                                          linked_block->NumUniforms);
226 
227    memcpy(linked_block->Uniforms,
228           new_block->Uniforms,
229           sizeof(*linked_block->Uniforms) * linked_block->NumUniforms);
230 
231    /* If we mem copied a pointer to a string above we need to create our own
232     * copy of the string.
233     */
234    if (linked_block->name.string) {
235       linked_block->name.string =
236          ralloc_strdup(*linked_blocks, linked_block->name.string);
237       resource_name_updated(&linked_block->name);
238 
239       for (unsigned int i = 0; i < linked_block->NumUniforms; i++) {
240         struct gl_uniform_buffer_variable *ubo_var =
241            &linked_block->Uniforms[i];
242 
243          if (ubo_var->Name == ubo_var->IndexName) {
244             ubo_var->Name = ralloc_strdup(*linked_blocks, ubo_var->Name);
245             ubo_var->IndexName = ubo_var->Name;
246          } else {
247             ubo_var->Name = ralloc_strdup(*linked_blocks, ubo_var->Name);
248             ubo_var->IndexName =
249                ralloc_strdup(*linked_blocks, ubo_var->IndexName);
250          }
251       }
252    }
253 
254    return linked_block_index;
255 }
256 
257 
258 /**
259  * Accumulates the array of buffer blocks and checks that all definitions of
260  * blocks agree on their contents.
261  */
262 static bool
nir_interstage_cross_validate_uniform_blocks(struct gl_shader_program * prog,enum block_type block_type)263 nir_interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
264                                              enum block_type block_type)
265 {
266    int *interfaceBlockStageIndex[MESA_SHADER_STAGES];
267    struct gl_uniform_block *blks = NULL;
268    unsigned *num_blks = block_type == BLOCK_SSBO ? &prog->data->NumShaderStorageBlocks :
269       &prog->data->NumUniformBlocks;
270 
271    unsigned max_num_buffer_blocks = 0;
272    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
273       if (prog->_LinkedShaders[i]) {
274          if (block_type == BLOCK_SSBO) {
275             max_num_buffer_blocks +=
276                prog->_LinkedShaders[i]->Program->info.num_ssbos;
277          } else {
278             max_num_buffer_blocks +=
279                prog->_LinkedShaders[i]->Program->info.num_ubos;
280          }
281       }
282    }
283 
284    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
285       struct gl_linked_shader *sh = prog->_LinkedShaders[i];
286 
287       interfaceBlockStageIndex[i] = malloc(max_num_buffer_blocks * sizeof(int));
288       for (unsigned int j = 0; j < max_num_buffer_blocks; j++)
289          interfaceBlockStageIndex[i][j] = -1;
290 
291       if (sh == NULL)
292          continue;
293 
294       unsigned sh_num_blocks;
295       struct gl_uniform_block **sh_blks;
296       if (block_type == BLOCK_SSBO) {
297          sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ssbos;
298          sh_blks = sh->Program->sh.ShaderStorageBlocks;
299       } else {
300          sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ubos;
301          sh_blks = sh->Program->sh.UniformBlocks;
302       }
303 
304       for (unsigned int j = 0; j < sh_num_blocks; j++) {
305          int index = link_cross_validate_uniform_block(prog->data, &blks,
306                                                        num_blks, sh_blks[j],
307                                                        !!prog->data->spirv);
308 
309          if (index == -1) {
310             /* We use the binding as we are ignoring the names */
311             linker_error(prog, "buffer block with binding `%i' has mismatching "
312                          "definitions\n", sh_blks[j]->Binding);
313 
314             for (unsigned k = 0; k <= i; k++) {
315                free(interfaceBlockStageIndex[k]);
316             }
317 
318             /* Reset the block count. This will help avoid various segfaults
319              * from api calls that assume the array exists due to the count
320              * being non-zero.
321              */
322             *num_blks = 0;
323             return false;
324          }
325 
326          interfaceBlockStageIndex[i][index] = j;
327       }
328    }
329 
330    /* Update per stage block pointers to point to the program list.
331     */
332    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
333       for (unsigned j = 0; j < *num_blks; j++) {
334          int stage_index = interfaceBlockStageIndex[i][j];
335 
336          if (stage_index != -1) {
337             struct gl_linked_shader *sh = prog->_LinkedShaders[i];
338 
339             struct gl_uniform_block **sh_blks = block_type == BLOCK_SSBO ?
340                sh->Program->sh.ShaderStorageBlocks :
341                sh->Program->sh.UniformBlocks;
342 
343             blks[j].stageref |= sh_blks[stage_index]->stageref;
344             sh_blks[stage_index] = &blks[j];
345          }
346       }
347    }
348 
349    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
350       free(interfaceBlockStageIndex[i]);
351    }
352 
353    if (block_type == BLOCK_SSBO)
354       prog->data->ShaderStorageBlocks = blks;
355    else {
356       prog->data->NumUniformBlocks = *num_blks;
357       prog->data->UniformBlocks = blks;
358    }
359 
360    return true;
361 }
362 
363 /*
364  * Iterates @type in order to compute how many individual leaf variables
365  * contains.
366  */
367 static void
iterate_type_count_variables(const struct glsl_type * type,unsigned int * num_variables)368 iterate_type_count_variables(const struct glsl_type *type,
369                              unsigned int *num_variables)
370 {
371    unsigned length = glsl_get_length(type);
372    if (glsl_type_is_unsized_array(type))
373       length = 1;
374 
375    for (unsigned i = 0; i < length; i++) {
376       const struct glsl_type *field_type;
377 
378       if (glsl_type_is_struct_or_ifc(type))
379          field_type = glsl_get_struct_field(type, i);
380       else
381          field_type = glsl_get_array_element(type);
382 
383       if (glsl_type_is_leaf(field_type))
384          (*num_variables)++;
385       else
386          iterate_type_count_variables(field_type, num_variables);
387    }
388 }
389 
390 static void
fill_individual_variable(void * mem_ctx,const char * name,const struct glsl_type * type,struct gl_uniform_buffer_variable * variables,unsigned int * variable_index,unsigned int * offset,unsigned * buffer_size,struct gl_shader_program * prog,struct gl_uniform_block * block,const enum glsl_interface_packing packing,bool is_array_instance,bool last_field)391 fill_individual_variable(void *mem_ctx, const char *name,
392                          const struct glsl_type *type,
393                          struct gl_uniform_buffer_variable *variables,
394                          unsigned int *variable_index,
395                          unsigned int *offset,
396                          unsigned *buffer_size,
397                          struct gl_shader_program *prog,
398                          struct gl_uniform_block *block,
399                          const enum glsl_interface_packing packing,
400                          bool is_array_instance,
401                          bool last_field)
402 {
403    struct gl_uniform_buffer_variable *v = &variables[*variable_index];
404    v->Type = type;
405 
406    const struct glsl_type *t_without_array = glsl_without_array(type);
407    if (glsl_type_is_matrix(glsl_without_array(t_without_array))) {
408       v->RowMajor = glsl_matrix_type_is_row_major(t_without_array);
409    } else {
410       /* default value, better that potential meaningless garbage */
411       v->RowMajor = false;
412    }
413 
414    if (!prog->data->spirv) {
415       v->Name = ralloc_strdup(mem_ctx, name);
416 
417       if (is_array_instance) {
418          v->IndexName = ralloc_strdup(mem_ctx, name);
419 
420          char *open_bracket = strchr(v->IndexName, '[');
421          assert(open_bracket != NULL);
422 
423          char *close_bracket = strchr(open_bracket, '.') - 1;
424          assert(close_bracket != NULL);
425 
426          /* Length of the tail without the ']' but with the NUL. */
427          unsigned len = strlen(close_bracket + 1) + 1;
428 
429          memmove(open_bracket, close_bracket + 1, len);
430       } else {
431          v->IndexName = v->Name;
432       }
433 
434       unsigned alignment = 0;
435       unsigned size = 0;
436 
437       /* The ARB_program_interface_query spec says:
438        *
439        *    If the final member of an active shader storage block is array
440        *    with no declared size, the minimum buffer size is computed
441        *    assuming the array was declared as an array with one element.
442        *
443        * For that reason, we use the base type of the unsized array to
444        * calculate its size. We don't need to check if the unsized array is
445        * the last member of a shader storage block (that check was already
446        * done by the parser).
447        */
448       const struct glsl_type *type_for_size = type;
449       if (glsl_type_is_unsized_array(type)) {
450          if (!last_field) {
451             linker_error(prog, "unsized array `%s' definition: "
452                          "only last member of a shader storage block "
453                          "can be defined as unsized array",
454                          name);
455          }
456 
457          type_for_size = glsl_get_array_element(type);
458       }
459 
460       if (packing == GLSL_INTERFACE_PACKING_STD430) {
461          alignment = glsl_get_std430_base_alignment(type, v->RowMajor);
462          size = glsl_get_std430_size(type_for_size, v->RowMajor);
463       } else {
464          alignment = glsl_get_std140_base_alignment(type, v->RowMajor);
465          size = glsl_get_std140_size(type_for_size, v->RowMajor);
466       }
467 
468       *offset = align(*offset, alignment);
469       v->Offset = *offset;
470 
471       *offset += size;
472 
473       /* The ARB_uniform_buffer_object spec says:
474        *
475        *    For uniform blocks laid out according to [std140] rules, the
476        *    minimum buffer object size returned by the UNIFORM_BLOCK_DATA_SIZE
477        *    query is derived by taking the offset of the last basic machine
478        *    unit consumed by the last uniform of the uniform block (including
479        *    any end-of-array or end-of-structure padding), adding one, and
480        *    rounding up to the next multiple of the base alignment required
481        *    for a vec4.
482        */
483       *buffer_size = align(*offset, 16);
484    } else {
485       /**
486        * Although ARB_gl_spirv points that the offsets need to be included
487        * (see "Mappings of layouts"), in the end those are only valid for
488        * root-variables, and we would need to recompute offsets when we iterate
489        * over non-trivial types, like aoa. So we compute the offset always.
490        */
491       v->Offset = *offset;
492       (*offset) += glsl_get_explicit_size(type, true);
493    }
494 
495    (*variable_index)++;
496 }
497 
498 static void
enter_or_leave_record(struct gl_uniform_block * block,unsigned * offset,const struct gl_constants * consts,const struct glsl_type * type,bool row_major,enum glsl_interface_packing internal_packing)499 enter_or_leave_record(struct gl_uniform_block *block, unsigned *offset,
500                       const struct gl_constants *consts,
501                       const struct glsl_type *type,
502                       bool row_major,
503                       enum glsl_interface_packing internal_packing)
504 {
505    assert(glsl_type_is_struct(type));
506 
507    if (internal_packing == GLSL_INTERFACE_PACKING_STD430) {
508       *offset = align(
509          *offset, glsl_get_std430_base_alignment(type, row_major));
510    } else
511       *offset = align(
512          *offset, glsl_get_std140_base_alignment(type, row_major));
513 }
514 
515 static void
iterate_type_fill_variables(void * mem_ctx,char ** name,size_t name_length,const struct gl_constants * consts,const struct glsl_type * type,struct gl_uniform_buffer_variable * variables,unsigned int * variable_index,unsigned int * offset,unsigned * buffer_size,struct gl_shader_program * prog,struct gl_uniform_block * block,const struct glsl_type * blk_type,bool is_array_instance,bool row_major,enum glsl_interface_packing internal_packing)516 iterate_type_fill_variables(void *mem_ctx, char **name,
517                             size_t name_length,
518                             const struct gl_constants *consts,
519                             const struct glsl_type *type,
520                             struct gl_uniform_buffer_variable *variables,
521                             unsigned int *variable_index,
522                             unsigned int *offset,
523                             unsigned *buffer_size,
524                             struct gl_shader_program *prog,
525                             struct gl_uniform_block *block,
526                             const struct glsl_type *blk_type,
527                             bool is_array_instance, bool row_major,
528                             enum glsl_interface_packing internal_packing)
529 {
530    unsigned struct_base_offset;
531 
532    bool struct_or_ifc = glsl_type_is_struct_or_ifc(type);
533    if (struct_or_ifc)
534       struct_base_offset = *offset;
535 
536    /* Handle shader storage block unsized arrays */
537    unsigned length = glsl_get_length(type);
538       if (glsl_type_is_unsized_array(type))
539          length = 1;
540 
541    if (glsl_type_is_struct(type) && !prog->data->spirv)
542       enter_or_leave_record(block, offset, consts, type, row_major,
543                             internal_packing);
544 
545    bool has_block_name = *name ? strcmp(*name, "") : false;
546    for (unsigned i = 0; i < length; i++) {
547       const struct glsl_type *field_type;
548       size_t new_length = name_length;
549       bool field_row_major = row_major;
550 
551       if (struct_or_ifc) {
552          field_type = glsl_get_struct_field(type, i);
553 
554          if (prog->data->spirv) {
555             *offset = struct_base_offset + glsl_get_struct_field_offset(type, i);
556 
557          } else if (glsl_get_struct_field_offset(type, i) != -1 &&
558                     type == glsl_without_array(blk_type)) {
559             *offset = glsl_get_struct_field_offset(type, i);
560          }
561 
562          /* Append '.field' to the current variable name. */
563          if (*name) {
564             ralloc_asprintf_rewrite_tail(name, &new_length,
565                                          has_block_name ? ".%s" : "%s",
566                                          glsl_get_struct_elem_name(type, i));
567          }
568 
569          /* The layout of structures at the top level of the block is set
570           * during parsing.  For matrices contained in multiple levels of
571           * structures in the block, the inner structures have no layout.
572           * These cases inherit the layout from the outer levels.
573           */
574          const enum glsl_matrix_layout matrix_layout =
575             glsl_get_struct_field_data(type, i)->matrix_layout;
576          if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {
577             field_row_major = true;
578          } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) {
579             field_row_major = false;
580          }
581       } else {
582          field_type = glsl_get_array_element(type);
583 
584          /* Append the subscript to the current variable name */
585          if (*name) {
586             ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
587          }
588       }
589 
590       if (glsl_type_is_leaf(field_type)) {
591          fill_individual_variable(mem_ctx, *name, field_type, variables,
592                                   variable_index, offset, buffer_size, prog,
593                                   block, internal_packing, is_array_instance,
594                                   (i + 1) == glsl_get_length(type));
595       } else {
596          iterate_type_fill_variables(mem_ctx, name, new_length, consts, field_type, variables,
597                                      variable_index, offset, buffer_size,
598                                      prog, block, blk_type, is_array_instance,
599                                      field_row_major, internal_packing);
600       }
601    }
602 
603    if (glsl_type_is_struct(type) && !prog->data->spirv)
604       enter_or_leave_record(block, offset, consts, type, row_major,
605                             internal_packing);
606 }
607 
608 static struct link_uniform_block_active *
process_block(void * mem_ctx,struct hash_table * ht,nir_variable * var)609 process_block(void *mem_ctx, struct hash_table *ht, nir_variable *var)
610 {
611    const struct hash_entry *existing_block =
612       _mesa_hash_table_search(ht, glsl_get_type_name(var->interface_type));
613 
614    bool is_interface_instance =
615       glsl_without_array(var->type) == var->interface_type;
616    const struct glsl_type *block_type = is_interface_instance ?
617          var->type : var->interface_type;
618 
619    /* If a block with this block-name has not previously been seen, add it.
620     * If a block with this block-name has been seen, it must be identical to
621     * the block currently being examined.
622     */
623    if (existing_block == NULL) {
624       struct link_uniform_block_active *b =
625          rzalloc(mem_ctx, struct link_uniform_block_active);
626 
627       b->var = var;
628       b->type = block_type;
629       b->has_instance_name = is_interface_instance;
630       b->is_shader_storage = var->data.mode == nir_var_mem_ssbo;
631 
632       if (var->data.explicit_binding) {
633          b->has_binding = true;
634          b->binding = var->data.binding;
635       } else {
636          b->has_binding = false;
637          b->binding = 0;
638       }
639 
640       _mesa_hash_table_insert(ht, glsl_get_type_name(var->interface_type),
641                               (void *) b);
642       return b;
643    } else {
644       struct link_uniform_block_active *b =
645          (struct link_uniform_block_active *) existing_block->data;
646 
647       if (b->type != block_type ||
648           b->has_instance_name != is_interface_instance)
649          return NULL;
650       else
651          return b;
652    }
653 
654    assert(!"Should not get here.");
655    return NULL;
656 }
657 
658 /* For arrays of arrays this function will give us a middle ground between
659  * detecting inactive uniform blocks and structuring them in a way that makes
660  * it easy to calculate the offset for indirect indexing.
661  *
662  * For example given the shader:
663  *
664  *   uniform ArraysOfArraysBlock
665  *   {
666  *      vec4 a;
667  *   } i[3][4][5];
668  *
669  *   void main()
670  *   {
671  *      vec4 b = i[0][1][1].a;
672  *      gl_Position = i[2][2][3].a + b;
673  *   }
674  *
675  * There are only 2 active blocks above but for the sake of indirect indexing
676  * and not over complicating the code we will end up with a count of 8.  Here
677  * each dimension has 2 different indices counted so we end up with 2*2*2
678  */
679 static void
process_arrays(void * mem_ctx,nir_deref_instr * deref,struct link_uniform_block_active * block)680 process_arrays(void *mem_ctx, nir_deref_instr *deref,
681                struct link_uniform_block_active *block)
682 {
683    if (!glsl_type_is_array(block->type))
684       return;
685 
686    nir_deref_path path;
687    nir_deref_path_init(&path, deref, NULL);
688 
689    assert(path.path[0]->deref_type == nir_deref_type_var);
690    nir_deref_instr **p = &path.path[1];
691    assert((*p)->deref_type == nir_deref_type_array);
692 
693    const struct glsl_type *type = block->type;
694    struct uniform_block_array_elements **ub_array_ptr = &block->array;
695    for (; *p; p++) {
696       if ((*p)->deref_type == nir_deref_type_array) {
697          if (*ub_array_ptr == NULL) {
698             *ub_array_ptr = rzalloc(mem_ctx,
699                                     struct uniform_block_array_elements);
700             (*ub_array_ptr)->aoa_size = glsl_get_aoa_size(type);
701          }
702 
703          struct uniform_block_array_elements *ub_array = *ub_array_ptr;
704          if (nir_src_is_const((*p)->arr.index)) {
705             /* Index is a constant, so mark just that element used, if not
706              * already.
707              */
708             const unsigned idx = nir_src_as_uint((*p)->arr.index);
709 
710             unsigned i;
711             for (i = 0; i < ub_array->num_array_elements; i++) {
712                if (ub_array->array_elements[i] == idx)
713                   break;
714             }
715 
716             if (i == ub_array->num_array_elements) {
717                ub_array->array_elements = reralloc(mem_ctx,
718                                                    ub_array->array_elements,
719                                                    unsigned,
720                                                    ub_array->num_array_elements + 1);
721 
722                ub_array->array_elements[ub_array->num_array_elements] = idx;
723                ub_array->num_array_elements++;
724             }
725          } else {
726             /* The array index is not a constant, so mark the entire array used.
727              */
728             assert(glsl_type_is_array((*p)->type));
729             if (ub_array->num_array_elements < glsl_get_length(type)) {
730                ub_array->num_array_elements = glsl_get_length(type);
731                ub_array->array_elements = reralloc(mem_ctx,
732                                                    ub_array->array_elements,
733                                                    unsigned,
734                                                    ub_array->num_array_elements);
735 
736                for (unsigned i = 0; i < ub_array->num_array_elements; i++) {
737                   ub_array->array_elements[i] = i;
738                }
739             }
740          }
741          ub_array_ptr = &ub_array->array;
742          type = glsl_get_array_element(type);
743       } else {
744          /* We found the block so break out of loop */
745          assert((*p)->deref_type == nir_deref_type_struct);
746          break;
747       }
748    }
749 
750    nir_deref_path_finish(&path);
751 }
752 
753 /* This function resizes the array types of the block so that later we can use
754  * this new size to correctly calculate the offest for indirect indexing.
755  */
756 static const struct glsl_type *
resize_block_array(const struct glsl_type * type,struct uniform_block_array_elements * ub_array)757 resize_block_array(const struct glsl_type *type,
758                    struct uniform_block_array_elements *ub_array)
759 {
760    if (glsl_type_is_array(type)) {
761       struct uniform_block_array_elements *child_array =
762          glsl_type_is_array(glsl_get_array_element(type)) ? ub_array->array : NULL;
763 
764       const struct glsl_type *new_child_type =
765          resize_block_array(glsl_get_array_element(type), child_array);
766       const struct glsl_type *new_type =
767          glsl_array_type(new_child_type, ub_array->num_array_elements, 0);
768 
769       return new_type;
770    } else {
771       assert(glsl_type_is_struct_or_ifc(type));
772       return type;
773    }
774 }
775 
776 static void
count_block(const struct glsl_type * blk_type,unsigned * num_blocks,unsigned * num_variables)777 count_block(const struct glsl_type *blk_type, unsigned *num_blocks,
778             unsigned *num_variables)
779 {
780    const struct glsl_type *type = glsl_without_array(blk_type);
781    unsigned aoa_size = glsl_get_aoa_size(blk_type);
782    unsigned buffer_count = aoa_size == 0 ? 1 : aoa_size;
783 
784    *num_blocks += buffer_count;
785 
786    unsigned int block_variables = 0;
787    iterate_type_count_variables(type, &block_variables);
788 
789    *num_variables += block_variables * buffer_count;
790 }
791 
792 static bool
gather_packed_block_info(void * mem_ctx,struct gl_shader_program * prog,struct hash_table * block_hash,nir_deref_instr * deref,enum block_type block_type)793 gather_packed_block_info(void *mem_ctx, struct gl_shader_program *prog,
794                          struct hash_table *block_hash,
795                          nir_deref_instr *deref, enum block_type block_type)
796 {
797 
798    nir_variable_mode mask = nir_var_mem_ubo | nir_var_mem_ssbo;
799 
800    if (!nir_deref_mode_is_one_of(deref, mask))
801       return true;
802 
803    nir_variable *var = nir_deref_instr_get_variable(deref);
804 
805    if (block_type == BLOCK_UBO && !nir_variable_is_in_ubo(var))
806       return true;
807 
808    if (block_type == BLOCK_SSBO && !nir_variable_is_in_ssbo(var))
809       return true;
810 
811    /* Process the block.  Bail if there was an error. */
812    struct link_uniform_block_active *b =
813       process_block(mem_ctx, block_hash, var);
814    if (b == NULL) {
815       linker_error(prog,
816                    "uniform block `%s' has mismatching definitions",
817                    glsl_without_array(var->type) == var->interface_type ?
818                       glsl_get_type_name(var->type) :
819                       glsl_get_type_name(var->interface_type));
820       return false;
821    }
822 
823    assert(b->type != NULL);
824 
825    /* If the block was declared with a shared or std140 layout
826     * qualifier, all its instances have been already marked as used.
827     */
828    if (glsl_get_ifc_packing(glsl_without_array(b->type)) ==
829        GLSL_INTERFACE_PACKING_PACKED) {
830       process_arrays(mem_ctx, deref, b);
831    }
832 
833    return true;
834 }
835 
836 static bool
gather_packed_blocks_info(void * mem_ctx,struct gl_shader_program * prog,nir_shader * shader,struct hash_table * block_hash,enum block_type block_type)837 gather_packed_blocks_info(void *mem_ctx, struct gl_shader_program *prog,
838                           nir_shader *shader, struct hash_table *block_hash,
839                           enum block_type block_type)
840 {
841    bool success = true;
842    nir_foreach_function_impl(impl, shader) {
843       nir_foreach_block(block, impl) {
844          nir_foreach_instr(instr, block) {
845             if (instr->type != nir_instr_type_intrinsic)
846                continue;
847 
848             nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
849             if (intr->intrinsic != nir_intrinsic_copy_deref &&
850                 intr->intrinsic != nir_intrinsic_load_deref &&
851                 intr->intrinsic != nir_intrinsic_store_deref &&
852                 intr->intrinsic != nir_intrinsic_deref_buffer_array_length)
853                continue;
854 
855             nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
856             success |=
857                gather_packed_block_info(mem_ctx, prog, block_hash, deref,
858                                         block_type);
859 
860             if (intr->intrinsic == nir_intrinsic_copy_deref) {
861                deref = nir_src_as_deref(intr->src[1]);
862                success |=
863                   gather_packed_block_info(mem_ctx, prog, block_hash, deref,
864                                            block_type);
865             }
866          }
867       }
868    }
869 
870    return success;
871 }
872 
873 static void
allocate_uniform_blocks(void * mem_ctx,struct hash_table * block_hash,struct gl_shader_program * prog,struct gl_linked_shader * shader,struct gl_uniform_block ** out_blks,unsigned * num_blocks,struct gl_uniform_buffer_variable ** out_variables,unsigned * num_variables,enum block_type block_type,bool supports_std430)874 allocate_uniform_blocks(void *mem_ctx, struct hash_table *block_hash,
875                         struct gl_shader_program *prog,
876                         struct gl_linked_shader *shader,
877                         struct gl_uniform_block **out_blks, unsigned *num_blocks,
878                         struct gl_uniform_buffer_variable **out_variables,
879                         unsigned *num_variables, enum block_type block_type,
880                         bool supports_std430)
881 {
882    *num_variables = 0;
883    *num_blocks = 0;
884 
885    /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec says:
886     *
887     *     "All members of a named uniform block declared with a shared or
888     *     std140 layout qualifier are considered active, even if they are not
889     *     referenced in any shader in the program. The uniform block itself is
890     *     also considered active, even if no member of the block is
891     *     referenced."
892     *
893     * So for blocks not defined as packed we simply iterate over the type to
894     * establish a count of active blocks.
895     */
896    nir_foreach_variable_in_shader(var, shader->Program->nir) {
897       if (block_type == BLOCK_UBO && !nir_variable_is_in_ubo(var))
898          continue;
899 
900       if (block_type == BLOCK_SSBO && !nir_variable_is_in_ssbo(var))
901          continue;
902 
903       if (prog->data->spirv) {
904          count_block(var->type, num_blocks, num_variables);
905       } else {
906          /* For UBO and SSBO variables, we need explicit types */
907          const glsl_type *explicit_ifc_type =
908             glsl_get_explicit_interface_type(var->interface_type,
909                                              supports_std430);
910 
911          var->interface_type = explicit_ifc_type;
912 
913          if (glsl_type_is_interface(glsl_without_array(var->type))) {
914             /* If the type contains the interface, wrap the explicit type in
915              * the right number of arrays.
916              */
917             var->type = glsl_type_wrap_in_arrays(explicit_ifc_type, var->type);
918          } else {
919             /* Otherwise, this variable is one entry in the interface */
920             UNUSED bool found = false;
921             for (unsigned i = 0; i < explicit_ifc_type->length; i++) {
922                const glsl_struct_field *field =
923                   &explicit_ifc_type->fields.structure[i];
924                if (strcmp(var->name, field->name) != 0)
925                   continue;
926 
927                var->type = field->type;
928                found = true;
929                break;
930             }
931             assert(found);
932          }
933 
934          /* Process the block.  Bail if there was an error. */
935          struct link_uniform_block_active *b =
936             process_block(mem_ctx, block_hash, var);
937          if (b == NULL) {
938             linker_error(prog, "uniform block `%s' has mismatching definitions",
939                          glsl_get_type_name(var->interface_type));
940             return;
941          }
942 
943          assert(b->array == NULL);
944          assert(b->type != NULL);
945          assert(!glsl_type_is_array(b->type) || b->has_instance_name);
946 
947          /* For uniform block arrays declared with a shared or std140 layout
948           * qualifier, mark all its instances as used.
949           */
950          if (glsl_get_ifc_packing(glsl_without_array(b->type)) ==
951              GLSL_INTERFACE_PACKING_PACKED)
952             continue;
953 
954          const struct glsl_type *type = b->type;
955          struct uniform_block_array_elements **ub_array = &b->array;
956          while (glsl_type_is_array(type)) {
957             assert(glsl_get_length(b->type) > 0);
958 
959             *ub_array = rzalloc(mem_ctx, struct uniform_block_array_elements);
960             (*ub_array)->num_array_elements = glsl_get_length(type);
961             (*ub_array)->array_elements = reralloc(mem_ctx,
962                                                    (*ub_array)->array_elements,
963                                                    unsigned,
964                                                    (*ub_array)->num_array_elements);
965             (*ub_array)->aoa_size = glsl_get_aoa_size(type);
966 
967             for (unsigned i = 0; i < (*ub_array)->num_array_elements; i++) {
968                (*ub_array)->array_elements[i] = i;
969             }
970             ub_array = &(*ub_array)->array;
971             type = glsl_get_array_element(type);
972          }
973       }
974    }
975 
976    if (!prog->data->spirv) {
977       /* Gather packed ubo information by looping over derefs */
978       if (!gather_packed_blocks_info(mem_ctx, prog, shader->Program->nir,
979                                      block_hash, block_type))
980          return;
981 
982       /* Count the number of active uniform blocks.  Count the total number of
983        * active slots in those uniform blocks.
984        */
985       hash_table_foreach(block_hash, entry) {
986          struct link_uniform_block_active *const b =
987             (struct link_uniform_block_active *) entry->data;
988 
989          assert((b->array != NULL) == glsl_type_is_array(b->type));
990 
991          if (b->array != NULL &&
992              (glsl_get_ifc_packing(glsl_without_array(b->type)) ==
993               GLSL_INTERFACE_PACKING_PACKED)) {
994             b->type = resize_block_array(b->type, b->array);
995             b->var->type = b->type;
996          }
997 
998          count_block(b->type, num_blocks, num_variables);
999       }
1000    }
1001 
1002    if (*num_blocks == 0) {
1003       assert(*num_variables == 0);
1004       return;
1005    }
1006 
1007    nir_fixup_deref_types(shader->Program->nir);
1008 
1009    assert(*num_variables != 0);
1010 
1011    struct gl_uniform_block *blocks =
1012       rzalloc_array(mem_ctx, struct gl_uniform_block, *num_blocks);
1013 
1014    struct gl_uniform_buffer_variable *variables =
1015       rzalloc_array(blocks, struct gl_uniform_buffer_variable, *num_variables);
1016 
1017    *out_blks = blocks;
1018    *out_variables = variables;
1019 }
1020 
1021 static void
fill_block(void * mem_ctx,const struct gl_constants * consts,const char * name,struct gl_uniform_block * blocks,unsigned * block_index,nir_variable * var,struct gl_uniform_buffer_variable * variables,unsigned * variable_index,unsigned binding_offset,unsigned linearized_index,struct gl_shader_program * prog,const gl_shader_stage stage,enum block_type block_type)1022 fill_block(void *mem_ctx, const struct gl_constants *consts, const char *name,
1023            struct gl_uniform_block *blocks, unsigned *block_index,
1024            nir_variable *var,
1025            struct gl_uniform_buffer_variable *variables,
1026            unsigned *variable_index,
1027            unsigned binding_offset,
1028            unsigned linearized_index,
1029            struct gl_shader_program *prog,
1030            const gl_shader_stage stage,
1031            enum block_type block_type)
1032 {
1033    struct gl_uniform_block *block = &blocks[*block_index];
1034 
1035    bool is_spirv = prog->data->spirv;
1036 
1037    bool is_interface_instance =
1038       glsl_without_array(var->type) == var->interface_type;
1039    const struct glsl_type *blk_type = is_interface_instance ?
1040          var->type : var->interface_type;
1041    const struct glsl_type *type = glsl_without_array(blk_type);
1042 
1043    block->name.string = is_spirv ? NULL : ralloc_strdup(blocks, name);
1044    resource_name_updated(&block->name);
1045 
1046    /* From ARB_gl_spirv spec:
1047     *    "Vulkan uses only one binding point for a resource array,
1048     *     while OpenGL still uses multiple binding points, so binding
1049     *     numbers are counted differently for SPIR-V used in Vulkan
1050     *     and OpenGL
1051     */
1052    block->Binding =
1053       var->data.explicit_binding ? var->data.binding + binding_offset : 0;
1054 
1055    block->Uniforms = &variables[*variable_index];
1056 
1057    /* FIXME: This sets stageref when a block is declared in a spirv shader
1058     * even when it is not referenced.
1059     */
1060    if (is_spirv)
1061       block->stageref = 1U << stage;
1062 
1063    block->_Packing = glsl_get_ifc_packing(type);
1064    block->_RowMajor = glsl_matrix_type_is_row_major(type);
1065 
1066    block->linearized_array_index = linearized_index;
1067 
1068    const char *ifc_name = is_interface_instance ? block->name.string : "";
1069    char *ifc_name_dup = NULL;
1070    size_t ifc_name_length = 0;
1071    if (!is_spirv) {
1072       ifc_name_dup = ralloc_strdup(NULL, ifc_name);
1073       ifc_name_length = strlen(ifc_name_dup);
1074    }
1075 
1076    unsigned old_variable_index = *variable_index;
1077    unsigned offset = 0;
1078    unsigned buffer_size = 0;
1079    bool is_array_instance =
1080       is_interface_instance && glsl_type_is_array(var->type);
1081    enum glsl_interface_packing packing =
1082       glsl_get_internal_ifc_packing(type, consts->UseSTD430AsDefaultPacking);
1083 
1084    iterate_type_fill_variables(mem_ctx, &ifc_name_dup, ifc_name_length, consts, type, variables, variable_index,
1085                                &offset, &buffer_size, prog, block, blk_type, is_array_instance, block->_RowMajor,
1086                                packing);
1087    ralloc_free(ifc_name_dup);
1088    block->NumUniforms = *variable_index - old_variable_index;
1089 
1090    if (is_spirv) {
1091       block->UniformBufferSize =  glsl_get_explicit_size(type, false);
1092 
1093       /* From OpenGL 4.6 spec, section 7.6.2.3, "SPIR-V Uniform Offsets and
1094        * strides"
1095        *
1096        *   "If the variable is decorated as a BufferBlock , its offsets and
1097        *    strides must not contradict std430 alignment and minimum offset
1098        *    requirements. Otherwise, its offsets and strides must not contradict
1099        *    std140 alignment and minimum offset requirements."
1100        *
1101        * So although we are computing the size based on the offsets and
1102        * array/matrix strides, at the end we need to ensure that the alignment is
1103        * the same that with std140. From ARB_uniform_buffer_object spec:
1104        *
1105        *   "For uniform blocks laid out according to [std140] rules, the minimum
1106        *    buffer object size returned by the UNIFORM_BLOCK_DATA_SIZE query is
1107        *    derived by taking the offset of the last basic machine unit consumed
1108        *    by the last uniform of the uniform block (including any end-of-array
1109        *    or end-of-structure padding), adding one, and rounding up to the next
1110        *    multiple of the base alignment required for a vec4."
1111        */
1112       block->UniformBufferSize = align(block->UniformBufferSize, 16);
1113    } else {
1114       block->UniformBufferSize = buffer_size;
1115    }
1116 
1117    /* Check SSBO size is lower than maximum supported size for SSBO */
1118    if (block_type == BLOCK_SSBO &&
1119        buffer_size > consts->MaxShaderStorageBlockSize) {
1120       linker_error(prog, "shader storage block `%s' has size %d, "
1121                    "which is larger than the maximum allowed (%d)",
1122                    type == var->interface_type ?
1123                       glsl_get_type_name(var->type) :
1124                       glsl_get_type_name(var->interface_type),
1125                    buffer_size,
1126                    consts->MaxShaderStorageBlockSize);
1127    }
1128 
1129    *block_index += 1;
1130 }
1131 
1132 static void
fill_block_array(struct uniform_block_array_elements * ub_array,const struct gl_constants * consts,char ** name,size_t name_length,struct gl_uniform_block * blks,nir_variable * var,struct gl_uniform_buffer_variable * variables,unsigned * variable_index,unsigned binding_offset,struct gl_shader_program * prog,const gl_shader_stage stage,enum block_type block_type,unsigned * block_index,unsigned first_index)1133 fill_block_array(struct uniform_block_array_elements *ub_array,
1134                  const struct gl_constants *consts, char **name,
1135                  size_t name_length, struct gl_uniform_block *blks,
1136                  nir_variable *var,
1137                  struct gl_uniform_buffer_variable *variables,
1138                  unsigned *variable_index, unsigned binding_offset,
1139                  struct gl_shader_program *prog,
1140                  const gl_shader_stage stage, enum block_type block_type,
1141                  unsigned *block_index, unsigned first_index)
1142 {
1143    for (unsigned j = 0; j < ub_array->num_array_elements; j++) {
1144       size_t new_length = name_length;
1145 
1146       unsigned int element_idx = ub_array->array_elements[j];
1147       /* Append the subscript to the current variable name */
1148       ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", element_idx);
1149 
1150       if (ub_array->array) {
1151          unsigned binding_stride = binding_offset +
1152             (element_idx * ub_array->array->aoa_size);
1153          fill_block_array(ub_array->array, consts, name, new_length, blks, var, variables,
1154                           variable_index, binding_stride, prog, stage, block_type, block_index, first_index);
1155       } else {
1156          fill_block(blks, consts, *name,
1157                     blks, block_index, var, variables,
1158                     variable_index, binding_offset + element_idx, *block_index - first_index, prog, stage,
1159                     block_type);
1160       }
1161    }
1162 }
1163 
1164 /*
1165  * Link ubos/ssbos for a given linked_shader/stage.
1166  */
1167 static void
link_linked_shader_uniform_blocks(void * mem_ctx,const struct gl_constants * consts,struct gl_shader_program * prog,struct gl_linked_shader * shader,struct gl_uniform_block ** blocks,unsigned * num_blocks,enum block_type block_type)1168 link_linked_shader_uniform_blocks(void *mem_ctx,
1169                                   const struct gl_constants *consts,
1170                                   struct gl_shader_program *prog,
1171                                   struct gl_linked_shader *shader,
1172                                   struct gl_uniform_block **blocks,
1173                                   unsigned *num_blocks,
1174                                   enum block_type block_type)
1175 {
1176    struct gl_uniform_buffer_variable *variables = NULL;
1177    unsigned num_variables = 0;
1178 
1179    /* This hash table will track all of the uniform blocks that have been
1180     * encountered.  Since blocks with the same block-name must be the same,
1181     * the hash is organized by block-name.
1182     */
1183    struct hash_table *block_hash =
1184       _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
1185                               _mesa_key_string_equal);
1186 
1187    allocate_uniform_blocks(mem_ctx, block_hash, prog, shader,
1188                            blocks, num_blocks,
1189                            &variables, &num_variables,
1190                            block_type, consts->UseSTD430AsDefaultPacking);
1191    if (!prog->data->LinkStatus)
1192       return;
1193 
1194    /* Fill the content of uniforms and variables */
1195    unsigned block_index = 0;
1196    unsigned variable_index = 0;
1197    struct gl_uniform_block *blks = *blocks;
1198 
1199 
1200    if (!prog->data->spirv) {
1201       hash_table_foreach(block_hash, entry) {
1202          struct link_uniform_block_active *const b =
1203             (struct link_uniform_block_active *) entry->data;
1204 
1205          const struct glsl_type *blk_type =
1206             glsl_without_array(b->var->type) == b->var->interface_type ?
1207                b->var->type : b->var->interface_type;
1208 
1209          if (glsl_type_is_array(blk_type)) {
1210              char *name =
1211                ralloc_strdup(NULL,
1212                              glsl_get_type_name(glsl_without_array(blk_type)));
1213             size_t name_length = strlen(name);
1214 
1215             assert(b->has_instance_name);
1216             fill_block_array(b->array, consts, &name, name_length,
1217                              blks, b->var, variables, &variable_index, 0,
1218                              prog, shader->Stage, block_type, &block_index, block_index);
1219             ralloc_free(name);
1220          } else {
1221             fill_block(blks, consts, glsl_get_type_name(blk_type), blks, &block_index, b->var,
1222                        variables, &variable_index, 0, 0, prog, shader->Stage,
1223                        block_type);
1224          }
1225       }
1226    } else {
1227       nir_foreach_variable_in_shader(var, shader->Program->nir) {
1228          if (block_type == BLOCK_UBO && !nir_variable_is_in_ubo(var))
1229             continue;
1230 
1231          if (block_type == BLOCK_SSBO && !nir_variable_is_in_ssbo(var))
1232             continue;
1233 
1234          unsigned aoa_size = glsl_get_aoa_size(var->type);
1235          unsigned buffer_count = aoa_size == 0 ? 1 : aoa_size;
1236          for (unsigned array_index = 0; array_index < buffer_count; array_index++) {
1237             fill_block(NULL, consts, NULL, blks, &block_index, var, variables,
1238                        &variable_index, array_index, array_index, prog, shader->Stage,
1239                        block_type);
1240          }
1241       }
1242    }
1243 
1244    assert(block_index == *num_blocks);
1245    assert(variable_index == num_variables);
1246 }
1247 
1248 bool
gl_nir_link_uniform_blocks(const struct gl_constants * consts,struct gl_shader_program * prog)1249 gl_nir_link_uniform_blocks(const struct gl_constants *consts,
1250                            struct gl_shader_program *prog)
1251 {
1252    void *mem_ctx = ralloc_context(NULL);
1253    bool ret = false;
1254    for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1255       struct gl_linked_shader *const linked = prog->_LinkedShaders[stage];
1256       struct gl_uniform_block *ubo_blocks = NULL;
1257       unsigned num_ubo_blocks = 0;
1258       struct gl_uniform_block *ssbo_blocks = NULL;
1259       unsigned num_ssbo_blocks = 0;
1260 
1261       if (!linked)
1262          continue;
1263 
1264       link_linked_shader_uniform_blocks(mem_ctx, consts, prog, linked,
1265                                         &ubo_blocks, &num_ubo_blocks,
1266                                         BLOCK_UBO);
1267 
1268       link_linked_shader_uniform_blocks(mem_ctx, consts, prog, linked,
1269                                         &ssbo_blocks, &num_ssbo_blocks,
1270                                         BLOCK_SSBO);
1271 
1272       const unsigned max_uniform_blocks =
1273          consts->Program[linked->Stage].MaxUniformBlocks;
1274       if (num_ubo_blocks > max_uniform_blocks) {
1275          linker_error(prog, "Too many %s uniform blocks (%d/%d)\n",
1276                       _mesa_shader_stage_to_string(linked->Stage),
1277                       num_ubo_blocks, max_uniform_blocks);
1278       }
1279 
1280       const unsigned max_shader_storage_blocks =
1281          consts->Program[linked->Stage].MaxShaderStorageBlocks;
1282       if (num_ssbo_blocks > max_shader_storage_blocks) {
1283          linker_error(prog, "Too many %s shader storage blocks (%d/%d)\n",
1284                       _mesa_shader_stage_to_string(linked->Stage),
1285                       num_ssbo_blocks, max_shader_storage_blocks);
1286       }
1287 
1288       if (!prog->data->LinkStatus) {
1289          goto out;
1290       }
1291 
1292       prog->data->linked_stages |= 1 << stage;
1293 
1294       /* Copy ubo blocks to linked shader list */
1295       linked->Program->sh.UniformBlocks =
1296          ralloc_array(linked, struct gl_uniform_block *, num_ubo_blocks);
1297       ralloc_steal(linked, ubo_blocks);
1298       linked->Program->sh.NumUniformBlocks = num_ubo_blocks;
1299       for (unsigned i = 0; i < num_ubo_blocks; i++) {
1300          linked->Program->sh.UniformBlocks[i] = &ubo_blocks[i];
1301       }
1302 
1303       /* We need to set it twice to avoid the value being overwritten by the
1304        * one from nir in brw_shader_gather_info. TODO: get a way to set the
1305        * info once, and being able to gather properly the info.
1306        */
1307       linked->Program->nir->info.num_ubos = num_ubo_blocks;
1308       linked->Program->info.num_ubos = num_ubo_blocks;
1309 
1310       /* Copy ssbo blocks to linked shader list */
1311       linked->Program->sh.ShaderStorageBlocks =
1312          ralloc_array(linked, struct gl_uniform_block *, num_ssbo_blocks);
1313       ralloc_steal(linked, ssbo_blocks);
1314       for (unsigned i = 0; i < num_ssbo_blocks; i++) {
1315          linked->Program->sh.ShaderStorageBlocks[i] = &ssbo_blocks[i];
1316       }
1317 
1318       /* See previous comment on num_ubo_blocks */
1319       linked->Program->nir->info.num_ssbos = num_ssbo_blocks;
1320       linked->Program->info.num_ssbos = num_ssbo_blocks;
1321    }
1322 
1323    if (!nir_interstage_cross_validate_uniform_blocks(prog, BLOCK_UBO))
1324       goto out;
1325 
1326    if (!nir_interstage_cross_validate_uniform_blocks(prog, BLOCK_SSBO))
1327       goto out;
1328 
1329    ret = true;
1330 out:
1331    ralloc_free(mem_ctx);
1332    return ret;
1333 }
1334