1 /*
2 * Copyright © 2018 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 "gl_nir.h"
26 #include "gl_nir_linker.h"
27 #include "linker_util.h"
28 #include "main/mtypes.h"
29 #include "main/shaderobj.h"
30 #include "ir_uniform.h" /* for gl_uniform_storage */
31
32 /**
33 * This file included general link methods, using NIR, instead of IR as
34 * the counter-part glsl/linker.cpp
35 */
36
37 static bool
can_remove_uniform(nir_variable * var,UNUSED void * data)38 can_remove_uniform(nir_variable *var, UNUSED void *data)
39 {
40 /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec
41 * says:
42 *
43 * "All members of a named uniform block declared with a shared or
44 * std140 layout qualifier are considered active, even if they are not
45 * referenced in any shader in the program. The uniform block itself is
46 * also considered active, even if no member of the block is
47 * referenced."
48 *
49 * Although the spec doesn't state it std430 layouts are expect to behave
50 * the same way. If the variable is in a uniform block with one of those
51 * layouts, do not eliminate it.
52 */
53 if (nir_variable_is_in_block(var) &&
54 (glsl_get_ifc_packing(var->interface_type) !=
55 GLSL_INTERFACE_PACKING_PACKED))
56 return false;
57
58 if (glsl_get_base_type(glsl_without_array(var->type)) ==
59 GLSL_TYPE_SUBROUTINE)
60 return false;
61
62 /* Uniform initializers could get used by another stage */
63 if (var->constant_initializer)
64 return false;
65
66 return true;
67 }
68
69 /**
70 * Built-in / reserved GL variables names start with "gl_"
71 */
72 static inline bool
is_gl_identifier(const char * s)73 is_gl_identifier(const char *s)
74 {
75 return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';
76 }
77
78 static bool
inout_has_same_location(const nir_variable * var,unsigned stage)79 inout_has_same_location(const nir_variable *var, unsigned stage)
80 {
81 if (!var->data.patch &&
82 ((var->data.mode == nir_var_shader_out &&
83 stage == MESA_SHADER_TESS_CTRL) ||
84 (var->data.mode == nir_var_shader_in &&
85 (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL ||
86 stage == MESA_SHADER_GEOMETRY))))
87 return true;
88 else
89 return false;
90 }
91
92 /**
93 * Create gl_shader_variable from nir_variable.
94 */
95 static struct gl_shader_variable *
create_shader_variable(struct gl_shader_program * shProg,const nir_variable * in,const char * name,const struct glsl_type * type,const struct glsl_type * interface_type,bool use_implicit_location,int location,const struct glsl_type * outermost_struct_type)96 create_shader_variable(struct gl_shader_program *shProg,
97 const nir_variable *in,
98 const char *name, const struct glsl_type *type,
99 const struct glsl_type *interface_type,
100 bool use_implicit_location, int location,
101 const struct glsl_type *outermost_struct_type)
102 {
103 /* Allocate zero-initialized memory to ensure that bitfield padding
104 * is zero.
105 */
106 struct gl_shader_variable *out = rzalloc(shProg,
107 struct gl_shader_variable);
108 if (!out)
109 return NULL;
110
111 /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications
112 * expect to see gl_VertexID in the program resource list. Pretend.
113 */
114 if (in->data.mode == nir_var_system_value &&
115 in->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
116 out->name = ralloc_strdup(shProg, "gl_VertexID");
117 } else if ((in->data.mode == nir_var_shader_out &&
118 in->data.location == VARYING_SLOT_TESS_LEVEL_OUTER) ||
119 (in->data.mode == nir_var_system_value &&
120 in->data.location == SYSTEM_VALUE_TESS_LEVEL_OUTER)) {
121 out->name = ralloc_strdup(shProg, "gl_TessLevelOuter");
122 type = glsl_array_type(glsl_float_type(), 4, 0);
123 } else if ((in->data.mode == nir_var_shader_out &&
124 in->data.location == VARYING_SLOT_TESS_LEVEL_INNER) ||
125 (in->data.mode == nir_var_system_value &&
126 in->data.location == SYSTEM_VALUE_TESS_LEVEL_INNER)) {
127 out->name = ralloc_strdup(shProg, "gl_TessLevelInner");
128 type = glsl_array_type(glsl_float_type(), 2, 0);
129 } else {
130 out->name = ralloc_strdup(shProg, name);
131 }
132
133 if (!out->name)
134 return NULL;
135
136 /* The ARB_program_interface_query spec says:
137 *
138 * "Not all active variables are assigned valid locations; the
139 * following variables will have an effective location of -1:
140 *
141 * * uniforms declared as atomic counters;
142 *
143 * * members of a uniform block;
144 *
145 * * built-in inputs, outputs, and uniforms (starting with "gl_"); and
146 *
147 * * inputs or outputs not declared with a "location" layout
148 * qualifier, except for vertex shader inputs and fragment shader
149 * outputs."
150 */
151 if (glsl_get_base_type(in->type) == GLSL_TYPE_ATOMIC_UINT ||
152 is_gl_identifier(in->name) ||
153 !(in->data.explicit_location || use_implicit_location)) {
154 out->location = -1;
155 } else {
156 out->location = location;
157 }
158
159 out->type = type;
160 out->outermost_struct_type = outermost_struct_type;
161 out->interface_type = interface_type;
162 out->component = in->data.location_frac;
163 out->index = in->data.index;
164 out->patch = in->data.patch;
165 out->mode = in->data.mode;
166 out->interpolation = in->data.interpolation;
167 out->precision = in->data.precision;
168 out->explicit_location = in->data.explicit_location;
169
170 return out;
171 }
172
173 static bool
add_shader_variable(const struct gl_context * ctx,struct gl_shader_program * shProg,struct set * resource_set,unsigned stage_mask,GLenum programInterface,nir_variable * var,const char * name,const struct glsl_type * type,bool use_implicit_location,int location,bool inouts_share_location,const struct glsl_type * outermost_struct_type)174 add_shader_variable(const struct gl_context *ctx,
175 struct gl_shader_program *shProg,
176 struct set *resource_set,
177 unsigned stage_mask,
178 GLenum programInterface, nir_variable *var,
179 const char *name, const struct glsl_type *type,
180 bool use_implicit_location, int location,
181 bool inouts_share_location,
182 const struct glsl_type *outermost_struct_type)
183 {
184 const struct glsl_type *interface_type = var->interface_type;
185
186 if (outermost_struct_type == NULL) {
187 if (var->data.from_named_ifc_block) {
188 const char *interface_name = glsl_get_type_name(interface_type);
189
190 if (glsl_type_is_array(interface_type)) {
191 /* Issue #16 of the ARB_program_interface_query spec says:
192 *
193 * "* If a variable is a member of an interface block without an
194 * instance name, it is enumerated using just the variable name.
195 *
196 * * If a variable is a member of an interface block with an
197 * instance name, it is enumerated as "BlockName.Member", where
198 * "BlockName" is the name of the interface block (not the
199 * instance name) and "Member" is the name of the variable."
200 *
201 * In particular, it indicates that it should be "BlockName",
202 * not "BlockName[array length]". The conformance suite and
203 * dEQP both require this behavior.
204 *
205 * Here, we unwrap the extra array level added by named interface
206 * block array lowering so we have the correct variable type. We
207 * also unwrap the interface type when constructing the name.
208 *
209 * We leave interface_type the same so that ES 3.x SSO pipeline
210 * validation can enforce the rules requiring array length to
211 * match on interface blocks.
212 */
213 type = glsl_get_array_element(type);
214
215 interface_name =
216 glsl_get_type_name(glsl_get_array_element(interface_type));
217 }
218
219 name = ralloc_asprintf(shProg, "%s.%s", interface_name, name);
220 }
221 }
222
223 switch (glsl_get_base_type(type)) {
224 case GLSL_TYPE_STRUCT: {
225 /* The ARB_program_interface_query spec says:
226 *
227 * "For an active variable declared as a structure, a separate entry
228 * will be generated for each active structure member. The name of
229 * each entry is formed by concatenating the name of the structure,
230 * the "." character, and the name of the structure member. If a
231 * structure member to enumerate is itself a structure or array,
232 * these enumeration rules are applied recursively."
233 */
234 if (outermost_struct_type == NULL)
235 outermost_struct_type = type;
236
237 unsigned field_location = location;
238 for (unsigned i = 0; i < glsl_get_length(type); i++) {
239 const struct glsl_type *field_type = glsl_get_struct_field(type, i);
240 const struct glsl_struct_field *field =
241 glsl_get_struct_field_data(type, i);
242
243 char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name);
244 if (!add_shader_variable(ctx, shProg, resource_set,
245 stage_mask, programInterface,
246 var, field_name, field_type,
247 use_implicit_location, field_location,
248 false, outermost_struct_type))
249 return false;
250
251 field_location += glsl_count_attribute_slots(field_type, false);
252 }
253 return true;
254 }
255
256 case GLSL_TYPE_ARRAY: {
257 /* The ARB_program_interface_query spec says:
258 *
259 * "For an active variable declared as an array of basic types, a
260 * single entry will be generated, with its name string formed by
261 * concatenating the name of the array and the string "[0]"."
262 *
263 * "For an active variable declared as an array of an aggregate data
264 * type (structures or arrays), a separate entry will be generated
265 * for each active array element, unless noted immediately below.
266 * The name of each entry is formed by concatenating the name of
267 * the array, the "[" character, an integer identifying the element
268 * number, and the "]" character. These enumeration rules are
269 * applied recursively, treating each enumerated array element as a
270 * separate active variable."
271 */
272 const struct glsl_type *array_type = glsl_get_array_element(type);
273 if (glsl_get_base_type(array_type) == GLSL_TYPE_STRUCT ||
274 glsl_get_base_type(array_type) == GLSL_TYPE_ARRAY) {
275 unsigned elem_location = location;
276 unsigned stride = inouts_share_location ? 0 :
277 glsl_count_attribute_slots(array_type, false);
278 for (unsigned i = 0; i < glsl_get_length(type); i++) {
279 char *elem = ralloc_asprintf(shProg, "%s[%d]", name, i);
280 if (!add_shader_variable(ctx, shProg, resource_set,
281 stage_mask, programInterface,
282 var, elem, array_type,
283 use_implicit_location, elem_location,
284 false, outermost_struct_type))
285 return false;
286 elem_location += stride;
287 }
288 return true;
289 }
290 }
291 FALLTHROUGH;
292
293 default: {
294 /* The ARB_program_interface_query spec says:
295 *
296 * "For an active variable declared as a single instance of a basic
297 * type, a single entry will be generated, using the variable name
298 * from the shader source."
299 */
300 struct gl_shader_variable *sha_v =
301 create_shader_variable(shProg, var, name, type, interface_type,
302 use_implicit_location, location,
303 outermost_struct_type);
304 if (!sha_v)
305 return false;
306
307 return link_util_add_program_resource(shProg, resource_set,
308 programInterface, sha_v, stage_mask);
309 }
310 }
311 }
312
313 static bool
add_vars_with_modes(const struct gl_context * ctx,struct gl_shader_program * prog,struct set * resource_set,nir_shader * nir,nir_variable_mode modes,unsigned stage,GLenum programInterface)314 add_vars_with_modes(const struct gl_context *ctx,
315 struct gl_shader_program *prog, struct set *resource_set,
316 nir_shader *nir, nir_variable_mode modes,
317 unsigned stage, GLenum programInterface)
318 {
319 nir_foreach_variable_with_modes(var, nir, modes) {
320 if (var->data.how_declared == nir_var_hidden)
321 continue;
322
323 int loc_bias = 0;
324 switch(var->data.mode) {
325 case nir_var_system_value:
326 case nir_var_shader_in:
327 if (programInterface != GL_PROGRAM_INPUT)
328 continue;
329 loc_bias = (stage == MESA_SHADER_VERTEX) ? VERT_ATTRIB_GENERIC0
330 : VARYING_SLOT_VAR0;
331 break;
332 case nir_var_shader_out:
333 if (programInterface != GL_PROGRAM_OUTPUT)
334 continue;
335 loc_bias = (stage == MESA_SHADER_FRAGMENT) ? FRAG_RESULT_DATA0
336 : VARYING_SLOT_VAR0;
337 break;
338 default:
339 continue;
340 }
341
342 if (var->data.patch)
343 loc_bias = VARYING_SLOT_PATCH0;
344
345 if (prog->data->spirv) {
346 struct gl_shader_variable *sh_var =
347 rzalloc(prog, struct gl_shader_variable);
348
349 /* In the ARB_gl_spirv spec, names are considered optional debug info, so
350 * the linker needs to work without them. Returning them is optional.
351 * For simplicity, we ignore names.
352 */
353 sh_var->name = NULL;
354 sh_var->type = var->type;
355 sh_var->location = var->data.location - loc_bias;
356 sh_var->index = var->data.index;
357
358 if (!link_util_add_program_resource(prog, resource_set,
359 programInterface,
360 sh_var, 1 << stage)) {
361 return false;
362 }
363 } else {
364 /* Skip packed varyings, packed varyings are handled separately
365 * by add_packed_varyings in the GLSL IR
366 * build_program_resource_list() call.
367 * TODO: handle packed varyings here instead. We likely want a NIR
368 * based packing pass first.
369 */
370 if (strncmp(var->name, "packed:", 7) == 0)
371 continue;
372
373 const bool vs_input_or_fs_output =
374 (stage == MESA_SHADER_VERTEX &&
375 var->data.mode == nir_var_shader_in) ||
376 (stage == MESA_SHADER_FRAGMENT &&
377 var->data.mode == nir_var_shader_out);
378
379 if (!add_shader_variable(ctx, prog, resource_set,
380 1 << stage, programInterface,
381 var, var->name, var->type,
382 vs_input_or_fs_output,
383 var->data.location - loc_bias,
384 inout_has_same_location(var, stage),
385 NULL))
386 return false;
387 }
388 }
389
390 return true;
391 }
392
393 static bool
add_interface_variables(const struct gl_context * ctx,struct gl_shader_program * prog,struct set * resource_set,unsigned stage,GLenum programInterface)394 add_interface_variables(const struct gl_context *ctx,
395 struct gl_shader_program *prog,
396 struct set *resource_set,
397 unsigned stage, GLenum programInterface)
398 {
399 struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
400 if (!sh)
401 return true;
402
403 nir_shader *nir = sh->Program->nir;
404 assert(nir);
405
406 switch (programInterface) {
407 case GL_PROGRAM_INPUT: {
408 return add_vars_with_modes(ctx, prog, resource_set,
409 nir, nir_var_shader_in | nir_var_system_value,
410 stage, programInterface);
411 }
412 case GL_PROGRAM_OUTPUT:
413 return add_vars_with_modes(ctx, prog, resource_set,
414 nir, nir_var_shader_out,
415 stage, programInterface);
416 default:
417 assert("!Should not get here");
418 break;
419 }
420
421 return false;
422 }
423
424 /* TODO: as we keep adding features, this method is becoming more and more
425 * similar to its GLSL counterpart at linker.cpp. Eventually it would be good
426 * to check if they could be refactored, and reduce code duplication somehow
427 */
428 void
nir_build_program_resource_list(struct gl_context * ctx,struct gl_shader_program * prog,bool rebuild_resourse_list)429 nir_build_program_resource_list(struct gl_context *ctx,
430 struct gl_shader_program *prog,
431 bool rebuild_resourse_list)
432 {
433 /* Rebuild resource list. */
434 if (prog->data->ProgramResourceList && rebuild_resourse_list) {
435 ralloc_free(prog->data->ProgramResourceList);
436 prog->data->ProgramResourceList = NULL;
437 prog->data->NumProgramResourceList = 0;
438 }
439
440 int input_stage = MESA_SHADER_STAGES, output_stage = 0;
441
442 /* Determine first input and final output stage. These are used to
443 * detect which variables should be enumerated in the resource list
444 * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
445 */
446 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
447 if (!prog->_LinkedShaders[i])
448 continue;
449 if (input_stage == MESA_SHADER_STAGES)
450 input_stage = i;
451 output_stage = i;
452 }
453
454 /* Empty shader, no resources. */
455 if (input_stage == MESA_SHADER_STAGES && output_stage == 0)
456 return;
457
458 struct set *resource_set = _mesa_pointer_set_create(NULL);
459
460 /* Add inputs and outputs to the resource list. */
461 if (!add_interface_variables(ctx, prog, resource_set, input_stage,
462 GL_PROGRAM_INPUT)) {
463 return;
464 }
465
466 if (!add_interface_variables(ctx, prog, resource_set, output_stage,
467 GL_PROGRAM_OUTPUT)) {
468 return;
469 }
470
471 /* Add transform feedback varyings and buffers. */
472 if (prog->last_vert_prog) {
473 struct gl_transform_feedback_info *linked_xfb =
474 prog->last_vert_prog->sh.LinkedTransformFeedback;
475
476 /* Add varyings. */
477 if (linked_xfb->NumVarying > 0) {
478 for (int i = 0; i < linked_xfb->NumVarying; i++) {
479 if (!link_util_add_program_resource(prog, resource_set,
480 GL_TRANSFORM_FEEDBACK_VARYING,
481 &linked_xfb->Varyings[i], 0))
482 return;
483 }
484 }
485
486 /* Add buffers. */
487 for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
488 if ((linked_xfb->ActiveBuffers >> i) & 1) {
489 linked_xfb->Buffers[i].Binding = i;
490 if (!link_util_add_program_resource(prog, resource_set,
491 GL_TRANSFORM_FEEDBACK_BUFFER,
492 &linked_xfb->Buffers[i], 0))
493 return;
494 }
495 }
496 }
497
498 /* Add uniforms
499 *
500 * Here, it is expected that nir_link_uniforms() has already been
501 * called, so that UniformStorage table is already available.
502 */
503 int top_level_array_base_offset = -1;
504 int top_level_array_size_in_bytes = -1;
505 int second_element_offset = -1;
506 int block_index = -1;
507 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
508 struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
509
510 if (uniform->hidden) {
511 for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) {
512 if (!uniform->opaque[j].active ||
513 glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)
514 continue;
515
516 GLenum type =
517 _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j);
518 /* add shader subroutines */
519 if (!link_util_add_program_resource(prog, resource_set,
520 type, uniform, 0))
521 return;
522 }
523
524 continue;
525 }
526
527 if (!link_util_should_add_buffer_variable(prog, uniform,
528 top_level_array_base_offset,
529 top_level_array_size_in_bytes,
530 second_element_offset, block_index))
531 continue;
532
533
534 if (prog->data->UniformStorage[i].offset >= second_element_offset) {
535 top_level_array_base_offset =
536 prog->data->UniformStorage[i].offset;
537
538 top_level_array_size_in_bytes =
539 prog->data->UniformStorage[i].top_level_array_size *
540 prog->data->UniformStorage[i].top_level_array_stride;
541
542 /* Set or reset the second element offset. For non arrays this
543 * will be set to -1.
544 */
545 second_element_offset = top_level_array_size_in_bytes ?
546 top_level_array_base_offset +
547 prog->data->UniformStorage[i].top_level_array_stride : -1;
548 }
549 block_index = uniform->block_index;
550
551
552 GLenum interface = uniform->is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM;
553 if (!link_util_add_program_resource(prog, resource_set, interface, uniform,
554 uniform->active_shader_mask)) {
555 return;
556 }
557 }
558
559
560 for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
561 if (!link_util_add_program_resource(prog, resource_set, GL_UNIFORM_BLOCK,
562 &prog->data->UniformBlocks[i],
563 prog->data->UniformBlocks[i].stageref))
564 return;
565 }
566
567 for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
568 if (!link_util_add_program_resource(prog, resource_set, GL_SHADER_STORAGE_BLOCK,
569 &prog->data->ShaderStorageBlocks[i],
570 prog->data->ShaderStorageBlocks[i].stageref))
571 return;
572 }
573
574 /* Add atomic counter buffers. */
575 for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {
576 if (!link_util_add_program_resource(prog, resource_set, GL_ATOMIC_COUNTER_BUFFER,
577 &prog->data->AtomicBuffers[i], 0))
578 return;
579 }
580
581 unsigned mask = prog->data->linked_stages;
582 while (mask) {
583 const int i = u_bit_scan(&mask);
584 struct gl_program *p = prog->_LinkedShaders[i]->Program;
585
586 GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
587 for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
588 if (!link_util_add_program_resource(prog, resource_set,
589 type,
590 &p->sh.SubroutineFunctions[j],
591 0))
592 return;
593 }
594 }
595
596 _mesa_set_destroy(resource_set, NULL);
597 }
598
599 bool
gl_nir_link_spirv(struct gl_context * ctx,struct gl_shader_program * prog,const struct gl_nir_linker_options * options)600 gl_nir_link_spirv(struct gl_context *ctx, struct gl_shader_program *prog,
601 const struct gl_nir_linker_options *options)
602 {
603 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
604 struct gl_linked_shader *shader = prog->_LinkedShaders[i];
605 if (shader) {
606 const nir_remove_dead_variables_options opts = {
607 .can_remove_var = can_remove_uniform,
608 };
609 nir_remove_dead_variables(shader->Program->nir, nir_var_uniform,
610 &opts);
611 }
612 }
613
614 if (!gl_nir_link_uniform_blocks(ctx, prog))
615 return false;
616
617 if (!gl_nir_link_uniforms(ctx, prog, options->fill_parameters))
618 return false;
619
620 gl_nir_link_assign_atomic_counter_resources(ctx, prog);
621 gl_nir_link_assign_xfb_resources(ctx, prog);
622
623 return true;
624 }
625
626 /**
627 * Validate shader image resources.
628 */
629 static void
check_image_resources(struct gl_context * ctx,struct gl_shader_program * prog)630 check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
631 {
632 unsigned total_image_units = 0;
633 unsigned fragment_outputs = 0;
634 unsigned total_shader_storage_blocks = 0;
635
636 if (!ctx->Extensions.ARB_shader_image_load_store)
637 return;
638
639 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
640 struct gl_linked_shader *sh = prog->_LinkedShaders[i];
641 if (!sh)
642 continue;
643
644 total_image_units += sh->Program->info.num_images;
645 total_shader_storage_blocks += sh->Program->info.num_ssbos;
646 }
647
648 if (total_image_units > ctx->Const.MaxCombinedImageUniforms)
649 linker_error(prog, "Too many combined image uniforms\n");
650
651 struct gl_linked_shader *frag_sh =
652 prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
653 if (frag_sh) {
654 uint64_t frag_outputs_written = frag_sh->Program->info.outputs_written;
655 fragment_outputs = util_bitcount64(frag_outputs_written);
656 }
657
658 if (total_image_units + fragment_outputs + total_shader_storage_blocks >
659 ctx->Const.MaxCombinedShaderOutputResources)
660 linker_error(prog, "Too many combined image uniforms, shader storage "
661 " buffers and fragment outputs\n");
662 }
663
664 bool
gl_nir_link_glsl(struct gl_context * ctx,struct gl_shader_program * prog)665 gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog)
666 {
667 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
668 struct gl_linked_shader *shader = prog->_LinkedShaders[i];
669 if (shader) {
670 const nir_remove_dead_variables_options opts = {
671 .can_remove_var = can_remove_uniform,
672 };
673 nir_remove_dead_variables(shader->Program->nir, nir_var_uniform,
674 &opts);
675 }
676 }
677
678 if (!gl_nir_link_uniforms(ctx, prog, true))
679 return false;
680
681 link_util_calculate_subroutine_compat(prog);
682 link_util_check_uniform_resources(ctx, prog);
683 link_util_check_subroutine_resources(prog);
684 check_image_resources(ctx, prog);
685 gl_nir_link_assign_atomic_counter_resources(ctx, prog);
686 gl_nir_link_check_atomic_counter_resources(ctx, prog);
687
688 if (prog->data->LinkStatus == LINKING_FAILURE)
689 return false;
690
691 return true;
692 }
693