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