Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/compiler/glsl/gl_nir_linker.c
4545 views
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
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
73
is_gl_identifier(const char *s)
74
{
75
return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';
76
}
77
78
static bool
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 *
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
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
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
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
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
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
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
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
694