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