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