1 /*
2 * Copyright © 2013 Intel Corporation
3 * Copyright © 2024 Valve Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * Linker support for GLSL's interface blocks.
27 */
28
29 #include "gl_nir_linker.h"
30 #include "linker_util.h"
31 #include "nir.h"
32 #include "main/macros.h"
33 #include "main/shader_types.h"
34 #include "util/hash_table.h"
35 #include "util/u_string.h"
36
37 /**
38 * Change var->interface_type on a variable that previously had a
39 * different, but compatible, interface_type. This is used during linking
40 * to set the size of arrays in interface blocks.
41 */
42 static void
change_interface_type(nir_variable * var,const struct glsl_type * type)43 change_interface_type(nir_variable *var, const struct glsl_type *type)
44 {
45 if (var->max_ifc_array_access != NULL) {
46 /* max_ifc_array_access has already been allocated, so make sure the
47 * new interface has the same number of fields as the old one.
48 */
49 assert(var->interface_type->length == type->length);
50 }
51 var->interface_type = type;
52 }
53
54 /**
55 * If the type pointed to by \c type represents an unsized array, replace
56 * it with a sized array whose size is determined by max_array_access.
57 */
58 static void
fixup_type(const struct glsl_type ** type,unsigned max_array_access,bool from_ssbo_unsized_array,bool * implicit_sized)59 fixup_type(const struct glsl_type **type, unsigned max_array_access,
60 bool from_ssbo_unsized_array, bool *implicit_sized)
61 {
62 if (!from_ssbo_unsized_array && glsl_type_is_unsized_array(*type)) {
63 *type = glsl_array_type((*type)->fields.array,
64 max_array_access + 1, (*type)->explicit_stride);
65 *implicit_sized = true;
66 assert(*type != NULL);
67 }
68 }
69
70 static void
fixup_unnamed_interface_type(const void * key,void * data,UNUSED void * closure)71 fixup_unnamed_interface_type(const void *key, void *data,
72 UNUSED void *closure)
73 {
74 const struct glsl_type *ifc_type = (const struct glsl_type *) key;
75 nir_variable **interface_vars = (nir_variable **) data;
76 unsigned num_fields = ifc_type->length;
77 glsl_struct_field *fields = malloc(sizeof(glsl_struct_field) * num_fields);
78 memcpy(fields, ifc_type->fields.structure,
79 num_fields * sizeof(*fields));
80 bool interface_type_changed = false;
81 for (unsigned i = 0; i < num_fields; i++) {
82 if (interface_vars[i] != NULL &&
83 fields[i].type != interface_vars[i]->type) {
84 fields[i].type = interface_vars[i]->type;
85 interface_type_changed = true;
86 }
87 }
88 if (!interface_type_changed) {
89 free(fields);
90 return;
91 }
92 enum glsl_interface_packing packing =
93 (enum glsl_interface_packing) ifc_type->interface_packing;
94 bool row_major = (bool) ifc_type->interface_row_major;
95 const struct glsl_type *new_ifc_type =
96 glsl_interface_type(fields, num_fields, packing,
97 row_major, glsl_get_type_name(ifc_type));
98 free(fields);
99 for (unsigned i = 0; i < num_fields; i++) {
100 if (interface_vars[i] != NULL)
101 change_interface_type(interface_vars[i], new_ifc_type);
102 }
103 }
104
105 /**
106 * Create a new interface type based on the given type, with unsized arrays
107 * replaced by sized arrays whose size is determined by
108 * max_ifc_array_access.
109 */
110 static const glsl_type *
resize_interface_members(const struct glsl_type * type,const int * max_ifc_array_access,bool is_ssbo)111 resize_interface_members(const struct glsl_type *type,
112 const int *max_ifc_array_access,
113 bool is_ssbo)
114 {
115 unsigned num_fields = type->length;
116 glsl_struct_field *fields = malloc(sizeof(glsl_struct_field) * num_fields); //new glsl_struct_field[num_fields];
117 memcpy(fields, type->fields.structure,
118 num_fields * sizeof(*fields));
119 for (unsigned i = 0; i < num_fields; i++) {
120 bool implicit_sized_array = fields[i].implicit_sized_array;
121 /* If SSBO last member is unsized array, we don't replace it by a sized
122 * array.
123 */
124 if (is_ssbo && i == (num_fields - 1))
125 fixup_type(&fields[i].type, max_ifc_array_access[i],
126 true, &implicit_sized_array);
127 else
128 fixup_type(&fields[i].type, max_ifc_array_access[i],
129 false, &implicit_sized_array);
130 fields[i].implicit_sized_array = implicit_sized_array;
131 }
132 enum glsl_interface_packing packing =
133 (enum glsl_interface_packing) type->interface_packing;
134 bool row_major = (bool) type->interface_row_major;
135 const struct glsl_type *new_ifc_type =
136 glsl_interface_type(fields, num_fields,
137 packing, row_major, glsl_get_type_name(type));
138 free(fields);
139 return new_ifc_type;
140 }
141
142 /**
143 * Determine whether the given interface type contains unsized arrays (if
144 * it doesn't, array_sizing_visitor doesn't need to process it).
145 */
146 static bool
interface_contains_unsized_arrays(const glsl_type * type)147 interface_contains_unsized_arrays(const glsl_type *type)
148 {
149 for (unsigned i = 0; i < type->length; i++) {
150 const struct glsl_type *elem_type = type->fields.structure[i].type;
151 if (glsl_type_is_unsized_array(elem_type))
152 return true;
153 }
154
155 return false;
156 }
157
158 static const glsl_type *
update_interface_members_array(const glsl_type * type,const glsl_type * new_interface_type)159 update_interface_members_array(const glsl_type *type,
160 const glsl_type *new_interface_type)
161 {
162 const struct glsl_type *element_type = type->fields.array;
163 if (glsl_type_is_array(element_type)) {
164 const glsl_type *new_array_type =
165 update_interface_members_array(element_type, new_interface_type);
166 return glsl_array_type(new_array_type, type->length,
167 type->explicit_stride);
168 } else {
169 return glsl_array_type(new_interface_type, type->length,
170 type->explicit_stride);
171 }
172 }
173
174 static void
size_variable_array(void * mem_ctx,nir_variable * var,struct hash_table * unnamed_interfaces)175 size_variable_array(void *mem_ctx, nir_variable *var,
176 struct hash_table *unnamed_interfaces)
177 {
178 const struct glsl_type *type_without_array;
179 const struct glsl_type *ifc_type = var->interface_type;
180 bool implicit_sized_array = var->data.implicit_sized_array;
181
182 fixup_type(&var->type, var->data.max_array_access,
183 var->data.from_ssbo_unsized_array,
184 &implicit_sized_array);
185 var->data.implicit_sized_array = implicit_sized_array;
186 type_without_array = glsl_without_array(var->type);
187 if (glsl_type_is_interface(var->type)) {
188 if (interface_contains_unsized_arrays(var->type)) {
189 const struct glsl_type *new_type =
190 resize_interface_members(var->type,
191 var->max_ifc_array_access,
192 var->data.mode == nir_var_mem_ssbo);
193 var->type = new_type;
194 change_interface_type(var, new_type);
195 }
196 } else if (glsl_type_is_interface(type_without_array)) {
197 if (interface_contains_unsized_arrays(type_without_array)) {
198 const struct glsl_type *new_type =
199 resize_interface_members(type_without_array,
200 var->max_ifc_array_access,
201 var->data.mode == nir_var_mem_ssbo);
202 change_interface_type(var, new_type);
203 var->type = update_interface_members_array(var->type, new_type);
204 }
205 } else if (ifc_type) {
206 /* Store a pointer to the variable in the unnamed_interfaces
207 * hashtable.
208 */
209 struct hash_entry *entry =
210 _mesa_hash_table_search(unnamed_interfaces, ifc_type);
211
212 nir_variable **interface_vars =
213 entry ? (nir_variable **) entry->data : NULL;
214
215 if (interface_vars == NULL) {
216 interface_vars = rzalloc_array(mem_ctx, nir_variable *,
217 ifc_type->length);
218 _mesa_hash_table_insert(unnamed_interfaces, ifc_type,
219 interface_vars);
220 }
221 unsigned index = glsl_get_field_index(ifc_type, var->name);
222 assert(index < ifc_type->length);
223 assert(interface_vars[index] == NULL);
224 interface_vars[index] = var;
225 }
226 }
227
228 void
gl_nir_linker_size_arrays(nir_shader * shader)229 gl_nir_linker_size_arrays(nir_shader *shader)
230 {
231 void *mem_ctx = ralloc_context(NULL);
232
233 /**
234 * Hash table from const glsl_type * to an array of nir_variable *'s
235 * pointing to the nir_variables constituting each unnamed interface block.
236 */
237 struct hash_table *unnamed_interfaces =
238 _mesa_pointer_hash_table_create(NULL);
239
240 nir_foreach_variable_in_shader(var, shader) {
241 size_variable_array(mem_ctx, var, unnamed_interfaces);
242 }
243
244 nir_foreach_function_impl(impl, shader) {
245 nir_foreach_variable_in_list(var, &impl->locals) {
246 size_variable_array(mem_ctx, var, unnamed_interfaces);
247 }
248 }
249
250 /**
251 * For each unnamed interface block that was discovered while running the
252 * visitor, adjust the interface type to reflect the newly assigned array
253 * sizes, and fix up the nir_variable nodes to point to the new interface
254 * type.
255 */
256 hash_table_call_foreach(unnamed_interfaces,
257 fixup_unnamed_interface_type, NULL);
258
259 _mesa_hash_table_destroy(unnamed_interfaces, NULL);
260 ralloc_free(mem_ctx);
261 }
262
263 /**
264 * Return true if interface members mismatch and its not allowed by GLSL.
265 */
266 static bool
interstage_member_mismatch(struct gl_shader_program * prog,const struct glsl_type * c,const struct glsl_type * p)267 interstage_member_mismatch(struct gl_shader_program *prog,
268 const struct glsl_type *c,
269 const struct glsl_type *p)
270 {
271 if (c->length != p->length)
272 return true;
273
274 for (unsigned i = 0; i < c->length; i++) {
275 if (c->fields.structure[i].type != p->fields.structure[i].type)
276 return true;
277 if (strcmp(c->fields.structure[i].name,
278 p->fields.structure[i].name) != 0)
279 return true;
280 if (c->fields.structure[i].location !=
281 p->fields.structure[i].location)
282 return true;
283 if (c->fields.structure[i].component !=
284 p->fields.structure[i].component)
285 return true;
286 if (c->fields.structure[i].patch !=
287 p->fields.structure[i].patch)
288 return true;
289
290 /* From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
291 *
292 * "It is a link-time error if, within the same stage, the
293 * interpolation qualifiers of variables of the same name do not
294 * match."
295 */
296 if (prog->IsES || prog->GLSL_Version < 440)
297 if (c->fields.structure[i].interpolation !=
298 p->fields.structure[i].interpolation)
299 return true;
300
301 /* From Section 4.3.4 (Input Variables) of the GLSL ES 3.0 spec:
302 *
303 * "The output of the vertex shader and the input of the fragment
304 * shader form an interface. For this interface, vertex shader
305 * output variables and fragment shader input variables of the same
306 * name must match in type and qualification (other than precision
307 * and out matching to in).
308 *
309 * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.1 spec
310 * says that centroid no longer needs to match for varyings.
311 *
312 * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.2 spec
313 * says that sample need not match for varyings.
314 */
315 if (!prog->IsES || prog->GLSL_Version < 310)
316 if (c->fields.structure[i].centroid !=
317 p->fields.structure[i].centroid)
318 return true;
319 if (!prog->IsES)
320 if (c->fields.structure[i].sample !=
321 p->fields.structure[i].sample)
322 return true;
323 }
324
325 return false;
326 }
327
328 static bool
is_interface_instance(nir_variable * var)329 is_interface_instance(nir_variable *var)
330 {
331 return glsl_without_array(var->type) == var->interface_type;
332 }
333
334 /**
335 * Check if two interfaces match, according to intrastage interface matching
336 * rules. If they do, and the first interface uses an unsized array, it will
337 * be updated to reflect the array size declared in the second interface.
338 */
339 static bool
intrastage_match(nir_variable * a,nir_variable * b,struct gl_shader_program * prog,nir_shader * a_shader,bool match_precision)340 intrastage_match(nir_variable *a,
341 nir_variable *b,
342 struct gl_shader_program *prog,
343 nir_shader *a_shader,
344 bool match_precision)
345 {
346 /* From section 4.7 "Precision and Precision Qualifiers" in GLSL 4.50:
347 *
348 * "For the purposes of determining if an output from one shader
349 * stage matches an input of the next stage, the precision qualifier
350 * need not match."
351 */
352 bool interface_type_match =
353 (prog->IsES ? a->interface_type == b->interface_type :
354 glsl_type_compare_no_precision(a->interface_type, b->interface_type));
355
356 /* Types must match. */
357 if (!interface_type_match) {
358 /* Exception: if both the interface blocks are implicitly declared,
359 * don't force their types to match. They might mismatch due to the two
360 * shaders using different GLSL versions, and that's ok.
361 */
362 if ((a->data.how_declared != nir_var_declared_implicitly ||
363 b->data.how_declared != nir_var_declared_implicitly) &&
364 (!prog->IsES ||
365 interstage_member_mismatch(prog, a->interface_type,
366 b->interface_type)))
367 return false;
368 }
369
370 /* Presence/absence of interface names must match. */
371 if (is_interface_instance(a) != is_interface_instance(b))
372 return false;
373
374 /* For uniforms, instance names need not match. For shader ins/outs,
375 * it's not clear from the spec whether they need to match, but
376 * Mesa's implementation relies on them matching.
377 */
378 if (is_interface_instance(a) && b->data.mode != nir_var_mem_ubo &&
379 b->data.mode != nir_var_mem_ssbo &&
380 strcmp(a->name, b->name) != 0) {
381 return false;
382 }
383
384 bool type_match = (match_precision ?
385 a->type == b->type :
386 glsl_type_compare_no_precision(a->type, b->type));
387
388 /* If a block is an array then it must match across the shader.
389 * Unsized arrays are also processed and matched agaist sized arrays.
390 */
391 if (!type_match && (glsl_type_is_array(b->type) || glsl_type_is_array(a->type)) &&
392 (is_interface_instance(b) || is_interface_instance(a)) &&
393 !gl_nir_validate_intrastage_arrays(prog, b, a, a_shader,
394 match_precision))
395 return false;
396
397 return true;
398 }
399
400 /**
401 * Check if two interfaces match, according to interstage (in/out) interface
402 * matching rules.
403 *
404 * If \c extra_array_level is true, the consumer interface is required to be
405 * an array and the producer interface is required to be a non-array.
406 * This is used for tessellation control and geometry shader consumers.
407 */
408 static bool
interstage_match(struct gl_shader_program * prog,nir_variable * producer,nir_variable * consumer,bool extra_array_level)409 interstage_match(struct gl_shader_program *prog, nir_variable *producer,
410 nir_variable *consumer, bool extra_array_level)
411 {
412 /* Types must match. */
413 if (consumer->interface_type != producer->interface_type) {
414 /* Exception: if both the interface blocks are implicitly declared,
415 * don't force their types to match. They might mismatch due to the two
416 * shaders using different GLSL versions, and that's ok.
417 *
418 * Also we store some member information such as interpolation in
419 * glsl_type that doesn't always have to match across shader stages.
420 * Therefore we make a pass over the members glsl_struct_field to make
421 * sure we don't reject shaders where fields don't need to match.
422 */
423 if ((consumer->data.how_declared != nir_var_declared_implicitly ||
424 producer->data.how_declared != nir_var_declared_implicitly) &&
425 interstage_member_mismatch(prog, consumer->interface_type,
426 producer->interface_type))
427 return false;
428 }
429
430 /* Ignore outermost array if geom shader */
431 const glsl_type *consumer_instance_type;
432 if (extra_array_level) {
433 consumer_instance_type = glsl_get_array_element(consumer->type);
434 } else {
435 consumer_instance_type = consumer->type;
436 }
437
438 /* If a block is an array then it must match across shaders.
439 * Since unsized arrays have been ruled out, we can check this by just
440 * making sure the types are equal.
441 */
442 if ((is_interface_instance(consumer) &&
443 glsl_type_is_array(consumer_instance_type)) ||
444 (is_interface_instance(producer) &&
445 glsl_type_is_array(producer->type))) {
446 if (consumer_instance_type != producer->type)
447 return false;
448 }
449
450 return true;
451 }
452
453 struct ifc_var {
454 nir_shader *shader;
455 nir_variable *var;
456 };
457
458 /**
459 * Lookup the interface definition. Return NULL if none is found.
460 */
461 static struct ifc_var *
ifc_lookup(struct hash_table * ht,nir_variable * var)462 ifc_lookup(struct hash_table *ht, nir_variable *var)
463 {
464 if (var->data.explicit_location &&
465 var->data.location >= VARYING_SLOT_VAR0) {
466 char location_str[11];
467 snprintf(location_str, 11, "%d", var->data.location);
468
469 const struct hash_entry *entry =
470 _mesa_hash_table_search(ht, location_str);
471 return entry ? (struct ifc_var *) entry->data : NULL;
472 } else {
473 const struct hash_entry *entry =
474 _mesa_hash_table_search(ht,
475 glsl_get_type_name(glsl_without_array(var->interface_type)));
476 return entry ? (struct ifc_var *) entry->data : NULL;
477 }
478 }
479
480 /**
481 * Add a new interface definition.
482 */
483 static void
ifc_store(void * mem_ctx,struct hash_table * ht,nir_variable * var,nir_shader * shader)484 ifc_store(void *mem_ctx, struct hash_table *ht, nir_variable *var,
485 nir_shader *shader)
486 {
487 struct ifc_var *ifc_var = ralloc(mem_ctx, struct ifc_var);
488 ifc_var->var = var;
489 ifc_var->shader = shader;
490
491 if (var->data.explicit_location &&
492 var->data.location >= VARYING_SLOT_VAR0) {
493 /* If explicit location is given then lookup the variable by location.
494 * We turn the location into a string and use this as the hash key
495 * rather than the name. Note: We allocate enough space for a 32-bit
496 * unsigned location value which is overkill but future proof.
497 */
498 char location_str[11];
499 snprintf(location_str, 11, "%d", var->data.location);
500 _mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), ifc_var);
501 } else {
502 _mesa_hash_table_insert(ht,
503 glsl_get_type_name(glsl_without_array(var->interface_type)), ifc_var);
504 }
505 }
506
507 static const glsl_type *
get_interface(const struct gl_linked_shader * shader,char * name,nir_variable_mode mode)508 get_interface(const struct gl_linked_shader *shader, char *name,
509 nir_variable_mode mode)
510 {
511 nir_foreach_variable_with_modes(var, shader->Program->nir, mode) {
512 if (var->type == var->interface_type) {
513 const char *ifc_name = glsl_get_type_name(var->interface_type);
514 if (strcmp(name, ifc_name) == 0)
515 return var->interface_type;
516 }
517 }
518
519 return NULL;
520 }
521
522 void
gl_nir_validate_intrastage_interface_blocks(struct gl_shader_program * prog,const struct gl_shader ** shader_list,unsigned num_shaders)523 gl_nir_validate_intrastage_interface_blocks(struct gl_shader_program *prog,
524 const struct gl_shader **shader_list,
525 unsigned num_shaders)
526 {
527 void *mem_ctx = ralloc_context(NULL);
528
529 struct hash_table *in_interfaces =
530 _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
531 _mesa_key_string_equal);
532 struct hash_table *out_interfaces =
533 _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
534 _mesa_key_string_equal);
535 struct hash_table *uniform_interfaces =
536 _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
537 _mesa_key_string_equal);
538 struct hash_table *buffer_interfaces =
539 _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
540 _mesa_key_string_equal);
541
542 for (unsigned int i = 0; i < num_shaders; i++) {
543 if (shader_list[i] == NULL)
544 continue;
545
546 nir_foreach_variable_in_shader(var, shader_list[i]->nir) {
547 if (!var->interface_type)
548 continue;
549
550 struct hash_table *definitions;
551 switch (var->data.mode) {
552 case nir_var_shader_in:
553 definitions = in_interfaces;
554 break;
555 case nir_var_shader_out:
556 definitions = out_interfaces;
557 break;
558 case nir_var_mem_ubo:
559 definitions = uniform_interfaces;
560 break;
561 case nir_var_mem_ssbo:
562 definitions = buffer_interfaces;
563 break;
564 default:
565 /* Only in, out, and uniform interfaces are legal, so we should
566 * never get here.
567 */
568 assert(!"illegal interface type");
569 continue;
570 }
571
572 struct ifc_var *ifc_var = ifc_lookup(definitions, var);
573 if (ifc_var == NULL) {
574 /* This is the first time we've seen the interface, so save
575 * it into the appropriate data structure.
576 */
577 ifc_store(mem_ctx, definitions, var,
578 shader_list[i]->nir);
579 } else {
580 nir_variable *prev_def = ifc_var->var;
581 if (!intrastage_match(prev_def, var, prog, ifc_var->shader,
582 true /* match_precision */)) {
583 linker_error(prog, "definitions of interface block `%s' do not"
584 " match\n", glsl_get_type_name(var->interface_type));
585 goto fail;
586 }
587 }
588 }
589 }
590
591 fail:
592 ralloc_free(mem_ctx);
593 }
594
595 static bool
is_builtin_gl_in_block(nir_variable * var,int consumer_stage)596 is_builtin_gl_in_block(nir_variable *var, int consumer_stage)
597 {
598 return !strcmp(var->name, "gl_in") &&
599 (consumer_stage == MESA_SHADER_TESS_CTRL ||
600 consumer_stage == MESA_SHADER_TESS_EVAL ||
601 consumer_stage == MESA_SHADER_GEOMETRY);
602 }
603
604 void
gl_nir_validate_interstage_inout_blocks(struct gl_shader_program * prog,const struct gl_linked_shader * producer,const struct gl_linked_shader * consumer)605 gl_nir_validate_interstage_inout_blocks(struct gl_shader_program *prog,
606 const struct gl_linked_shader *producer,
607 const struct gl_linked_shader *consumer)
608 {
609 void *mem_ctx = ralloc_context(NULL);
610 struct hash_table *ht = _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
611 _mesa_key_string_equal);
612
613 /* VS -> GS, VS -> TCS, VS -> TES, TES -> GS */
614 const bool extra_array_level = (producer->Stage == MESA_SHADER_VERTEX &&
615 consumer->Stage != MESA_SHADER_FRAGMENT) ||
616 consumer->Stage == MESA_SHADER_GEOMETRY;
617
618 /* Check that block re-declarations of gl_PerVertex are compatible
619 * across shaders: From OpenGL Shading Language 4.5, section
620 * "7.1 Built-In Language Variables", page 130 of the PDF:
621 *
622 * "If multiple shaders using members of a built-in block belonging
623 * to the same interface are linked together in the same program,
624 * they must all redeclare the built-in block in the same way, as
625 * described in section 4.3.9 “Interface Blocks” for interface-block
626 * matching, or a link-time error will result."
627 *
628 * This is done explicitly outside of iterating the member variable
629 * declarations because it is possible that the variables are not used and
630 * so they would have been optimised out.
631 */
632 const glsl_type *consumer_iface =
633 get_interface(consumer, "gl_PerVertex", nir_var_shader_in);
634
635 const glsl_type *producer_iface =
636 get_interface(producer, "gl_PerVertex", nir_var_shader_out);
637
638 if (producer_iface && consumer_iface &&
639 interstage_member_mismatch(prog, consumer_iface, producer_iface)) {
640 linker_error(prog, "Incompatible or missing gl_PerVertex re-declaration "
641 "in consecutive shaders");
642 ralloc_free(mem_ctx);
643 return;
644 }
645
646 /* Desktop OpenGL requires redeclaration of the built-in interfaces for
647 * SSO programs. Passes above implement following rules:
648 *
649 * From Section 7.4 (Program Pipeline Objects) of the OpenGL 4.6 Core
650 * spec:
651 *
652 * "To use any built-in input or output in the gl_PerVertex and
653 * gl_PerFragment blocks in separable program objects, shader code
654 * must redeclare those blocks prior to use. A separable program
655 * will fail to link if:
656 *
657 * it contains multiple shaders of a single type with different
658 * redeclarations of these built-in input and output blocks; or
659 *
660 * any shader uses a built-in block member not found in the
661 * redeclaration of that block."
662 *
663 * ARB_separate_shader_objects issues section (issue #28) states that
664 * redeclaration is not required for GLSL shaders using #version 140 or
665 * earlier (since interface blocks are not possible with older versions).
666 *
667 * From Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1
668 * spec:
669 *
670 * "Built-in inputs or outputs do not affect interface matching."
671 *
672 * GL_OES_shader_io_blocks adds following:
673 *
674 * "When using any built-in input or output in the gl_PerVertex block
675 * in separable program objects, shader code may redeclare that block
676 * prior to use. If the shader does not redeclare the block, the
677 * intrinsically declared definition of that block will be used."
678 */
679
680 /* Add output interfaces from the producer to the symbol table. */
681 nir_foreach_shader_out_variable(var, producer->Program->nir) {
682 if (!var->interface_type)
683 continue;
684
685 /* Built-in interface redeclaration check. */
686 if (prog->SeparateShader && !prog->IsES && prog->GLSL_Version >= 150 &&
687 var->data.how_declared == nir_var_declared_implicitly &&
688 var->data.used && !producer_iface) {
689 linker_error(prog, "missing output builtin block %s redeclaration "
690 "in separable shader program",
691 glsl_get_type_name(var->interface_type));
692 ralloc_free(mem_ctx);
693 return;
694 }
695
696 ifc_store(mem_ctx, ht, var, producer->Program->nir);
697 }
698
699 /* Verify that the consumer's input interfaces match. */
700 nir_foreach_shader_in_variable(var, consumer->Program->nir) {
701 if (!var->interface_type)
702 continue;
703
704 struct ifc_var *ifc_var = ifc_lookup(ht, var);
705 nir_variable *producer_def = ifc_var ? ifc_var->var : NULL;
706
707 /* Built-in interface redeclaration check. */
708 if (prog->SeparateShader && !prog->IsES && prog->GLSL_Version >= 150 &&
709 var->data.how_declared == nir_var_declared_implicitly &&
710 var->data.used && !producer_iface) {
711 linker_error(prog, "missing input builtin block %s redeclaration "
712 "in separable shader program",
713 glsl_get_type_name(var->interface_type));
714 ralloc_free(mem_ctx);
715 return;
716 }
717
718 /* The producer doesn't generate this input: fail to link. Skip built-in
719 * 'gl_in[]' since that may not be present if the producer does not
720 * write to any of the pre-defined outputs (e.g. if the vertex shader
721 * does not write to gl_Position, etc), which is allowed and results in
722 * undefined behavior.
723 *
724 * From Section 4.3.4 (Inputs) of the GLSL 1.50 spec:
725 *
726 * "Only the input variables that are actually read need to be written
727 * by the previous stage; it is allowed to have superfluous
728 * declarations of input variables."
729 */
730 if (producer_def == NULL &&
731 !is_builtin_gl_in_block(var, consumer->Stage) && var->data.used) {
732 linker_error(prog, "Input block `%s' is not an output of "
733 "the previous stage\n", glsl_get_type_name(var->interface_type));
734 ralloc_free(mem_ctx);
735 return;
736 }
737
738 if (producer_def &&
739 !interstage_match(prog, producer_def, var, extra_array_level)) {
740 linker_error(prog, "definitions of interface block `%s' do not "
741 "match\n", glsl_get_type_name(var->interface_type));
742 ralloc_free(mem_ctx);
743 return;
744 }
745 }
746
747 ralloc_free(mem_ctx);
748 }
749
750 void
gl_nir_validate_interstage_uniform_blocks(struct gl_shader_program * prog,struct gl_linked_shader ** stages)751 gl_nir_validate_interstage_uniform_blocks(struct gl_shader_program *prog,
752 struct gl_linked_shader **stages)
753 {
754 void *mem_ctx = ralloc_context(NULL);
755
756 /* Hash table mapping interface block name to a nir_variable */
757 struct hash_table *ht = _mesa_hash_table_create(mem_ctx, _mesa_hash_string,
758 _mesa_key_string_equal);
759
760 for (int i = 0; i < MESA_SHADER_STAGES; i++) {
761 if (stages[i] == NULL)
762 continue;
763
764 const struct gl_linked_shader *stage = stages[i];
765 nir_foreach_variable_in_shader(var, stage->Program->nir) {
766 if (!var->interface_type ||
767 (var->data.mode != nir_var_mem_ubo &&
768 var->data.mode != nir_var_mem_ssbo))
769 continue;
770
771 struct ifc_var *ifc_var = ifc_lookup(ht, var);
772 if (ifc_var == NULL) {
773 ifc_store(mem_ctx, ht, var, stage->Program->nir);
774 } else {
775 /* Interstage uniform matching rules are the same as intrastage
776 * uniform matchin rules (for uniforms, it is as though all
777 * shaders are in the same shader stage).
778 */
779 nir_variable *old_def = ifc_var->var;
780 if (!intrastage_match(old_def, var, prog, ifc_var->shader, false)) {
781 linker_error(prog, "definitions of uniform block `%s' do not "
782 "match\n", glsl_get_type_name(var->interface_type));
783 ralloc_free(mem_ctx);
784 return;
785 }
786 }
787 }
788 }
789
790 ralloc_free(mem_ctx);
791 }
792