• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gl.h"
26 #include "gl_nir.h"
27 #include "gl_nir_linker.h"
28 #include "linker_util.h"
29 #include "main/shader_types.h"
30 #include "main/consts_exts.h"
31 #include "main/shaderobj.h"
32 #include "ir_uniform.h" /* for gl_uniform_storage */
33 
34 /**
35  * This file included general link methods, using NIR, instead of IR as
36  * the counter-part glsl/linker.cpp
37  */
38 
39 void
gl_nir_opts(nir_shader * nir)40 gl_nir_opts(nir_shader *nir)
41 {
42    bool progress;
43 
44    do {
45       progress = false;
46 
47       NIR_PASS_V(nir, nir_lower_vars_to_ssa);
48 
49       /* Linking deals with unused inputs/outputs, but here we can remove
50        * things local to the shader in the hopes that we can cleanup other
51        * things. This pass will also remove variables with only stores, so we
52        * might be able to make progress after it.
53        */
54       NIR_PASS(progress, nir, nir_remove_dead_variables,
55                nir_var_function_temp | nir_var_shader_temp |
56                nir_var_mem_shared,
57                NULL);
58 
59       NIR_PASS(progress, nir, nir_opt_copy_prop_vars);
60       NIR_PASS(progress, nir, nir_opt_dead_write_vars);
61 
62       if (nir->options->lower_to_scalar) {
63          NIR_PASS_V(nir, nir_lower_alu_to_scalar,
64                     nir->options->lower_to_scalar_filter, NULL);
65          NIR_PASS_V(nir, nir_lower_phis_to_scalar, false);
66       }
67 
68       NIR_PASS_V(nir, nir_lower_alu);
69       NIR_PASS_V(nir, nir_lower_pack);
70       NIR_PASS(progress, nir, nir_copy_prop);
71       NIR_PASS(progress, nir, nir_opt_remove_phis);
72       NIR_PASS(progress, nir, nir_opt_dce);
73       if (nir_opt_trivial_continues(nir)) {
74          progress = true;
75          NIR_PASS(progress, nir, nir_copy_prop);
76          NIR_PASS(progress, nir, nir_opt_dce);
77       }
78       NIR_PASS(progress, nir, nir_opt_if, 0);
79       NIR_PASS(progress, nir, nir_opt_dead_cf);
80       NIR_PASS(progress, nir, nir_opt_cse);
81       NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
82 
83       NIR_PASS(progress, nir, nir_opt_phi_precision);
84       NIR_PASS(progress, nir, nir_opt_algebraic);
85       NIR_PASS(progress, nir, nir_opt_constant_folding);
86 
87       if (!nir->info.flrp_lowered) {
88          unsigned lower_flrp =
89             (nir->options->lower_flrp16 ? 16 : 0) |
90             (nir->options->lower_flrp32 ? 32 : 0) |
91             (nir->options->lower_flrp64 ? 64 : 0);
92 
93          if (lower_flrp) {
94             bool lower_flrp_progress = false;
95 
96             NIR_PASS(lower_flrp_progress, nir, nir_lower_flrp,
97                      lower_flrp,
98                      false /* always_precise */);
99             if (lower_flrp_progress) {
100                NIR_PASS(progress, nir,
101                         nir_opt_constant_folding);
102                progress = true;
103             }
104          }
105 
106          /* Nothing should rematerialize any flrps, so we only need to do this
107           * lowering once.
108           */
109          nir->info.flrp_lowered = true;
110       }
111 
112       NIR_PASS(progress, nir, nir_opt_undef);
113       NIR_PASS(progress, nir, nir_opt_conditional_discard);
114       if (nir->options->max_unroll_iterations) {
115          NIR_PASS(progress, nir, nir_opt_loop_unroll);
116       }
117    } while (progress);
118 }
119 
120 static void
gl_nir_link_opts(nir_shader * producer,nir_shader * consumer)121 gl_nir_link_opts(nir_shader *producer, nir_shader *consumer)
122 {
123    if (producer->options->lower_to_scalar) {
124       NIR_PASS_V(producer, nir_lower_io_to_scalar_early, nir_var_shader_out);
125       NIR_PASS_V(consumer, nir_lower_io_to_scalar_early, nir_var_shader_in);
126    }
127 
128    nir_lower_io_arrays_to_elements(producer, consumer);
129 
130    gl_nir_opts(producer);
131    gl_nir_opts(consumer);
132 
133    if (nir_link_opt_varyings(producer, consumer))
134       gl_nir_opts(consumer);
135 
136    NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out, NULL);
137    NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in, NULL);
138 
139    if (nir_remove_unused_varyings(producer, consumer)) {
140       NIR_PASS_V(producer, nir_lower_global_vars_to_local);
141       NIR_PASS_V(consumer, nir_lower_global_vars_to_local);
142 
143       gl_nir_opts(producer);
144       gl_nir_opts(consumer);
145 
146       /* Optimizations can cause varyings to become unused.
147        * nir_compact_varyings() depends on all dead varyings being removed so
148        * we need to call nir_remove_dead_variables() again here.
149        */
150       NIR_PASS_V(producer, nir_remove_dead_variables, nir_var_shader_out,
151                  NULL);
152       NIR_PASS_V(consumer, nir_remove_dead_variables, nir_var_shader_in,
153                  NULL);
154    }
155 
156    nir_link_varying_precision(producer, consumer);
157 }
158 
159 static bool
can_remove_uniform(nir_variable * var,UNUSED void * data)160 can_remove_uniform(nir_variable *var, UNUSED void *data)
161 {
162    /* Section 2.11.6 (Uniform Variables) of the OpenGL ES 3.0.3 spec
163     * says:
164     *
165     *     "All members of a named uniform block declared with a shared or
166     *     std140 layout qualifier are considered active, even if they are not
167     *     referenced in any shader in the program. The uniform block itself is
168     *     also considered active, even if no member of the block is
169     *     referenced."
170     *
171     * Although the spec doesn't state it std430 layouts are expect to behave
172     * the same way. If the variable is in a uniform block with one of those
173     * layouts, do not eliminate it.
174     */
175    if (nir_variable_is_in_block(var) &&
176        (glsl_get_ifc_packing(var->interface_type) !=
177         GLSL_INTERFACE_PACKING_PACKED))
178       return false;
179 
180    if (glsl_get_base_type(glsl_without_array(var->type)) ==
181        GLSL_TYPE_SUBROUTINE)
182       return false;
183 
184    /* Uniform initializers could get used by another stage. However if its a
185     * hidden uniform then it should be safe to remove as this was a constant
186     * variable that has been lowered to a uniform.
187     */
188    if (var->constant_initializer && var->data.how_declared != nir_var_hidden)
189       return false;
190 
191    return true;
192 }
193 
194 /**
195  * Built-in / reserved GL variables names start with "gl_"
196  */
197 static inline bool
is_gl_identifier(const char * s)198 is_gl_identifier(const char *s)
199 {
200    return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';
201 }
202 
203 static bool
inout_has_same_location(const nir_variable * var,unsigned stage)204 inout_has_same_location(const nir_variable *var, unsigned stage)
205 {
206    if (!var->data.patch &&
207        ((var->data.mode == nir_var_shader_out &&
208          stage == MESA_SHADER_TESS_CTRL) ||
209         (var->data.mode == nir_var_shader_in &&
210          (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL ||
211           stage == MESA_SHADER_GEOMETRY))))
212       return true;
213    else
214       return false;
215 }
216 
217 /**
218  * Create gl_shader_variable from nir_variable.
219  */
220 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)221 create_shader_variable(struct gl_shader_program *shProg,
222                        const nir_variable *in,
223                        const char *name, const struct glsl_type *type,
224                        const struct glsl_type *interface_type,
225                        bool use_implicit_location, int location,
226                        const struct glsl_type *outermost_struct_type)
227 {
228    /* Allocate zero-initialized memory to ensure that bitfield padding
229     * is zero.
230     */
231    struct gl_shader_variable *out = rzalloc(shProg,
232                                             struct gl_shader_variable);
233    if (!out)
234       return NULL;
235 
236    /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications
237     * expect to see gl_VertexID in the program resource list.  Pretend.
238     */
239    if (in->data.mode == nir_var_system_value &&
240        in->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
241       out->name.string = ralloc_strdup(shProg, "gl_VertexID");
242    } else if ((in->data.mode == nir_var_shader_out &&
243                in->data.location == VARYING_SLOT_TESS_LEVEL_OUTER) ||
244               (in->data.mode == nir_var_system_value &&
245                in->data.location == SYSTEM_VALUE_TESS_LEVEL_OUTER)) {
246       out->name.string = ralloc_strdup(shProg, "gl_TessLevelOuter");
247       type = glsl_array_type(glsl_float_type(), 4, 0);
248    } else if ((in->data.mode == nir_var_shader_out &&
249                in->data.location == VARYING_SLOT_TESS_LEVEL_INNER) ||
250               (in->data.mode == nir_var_system_value &&
251                in->data.location == SYSTEM_VALUE_TESS_LEVEL_INNER)) {
252       out->name.string = ralloc_strdup(shProg, "gl_TessLevelInner");
253       type = glsl_array_type(glsl_float_type(), 2, 0);
254    } else {
255       out->name.string = ralloc_strdup(shProg, name);
256    }
257 
258    resource_name_updated(&out->name);
259 
260    if (!out->name.string)
261       return NULL;
262 
263    /* The ARB_program_interface_query spec says:
264     *
265     *     "Not all active variables are assigned valid locations; the
266     *     following variables will have an effective location of -1:
267     *
268     *      * uniforms declared as atomic counters;
269     *
270     *      * members of a uniform block;
271     *
272     *      * built-in inputs, outputs, and uniforms (starting with "gl_"); and
273     *
274     *      * inputs or outputs not declared with a "location" layout
275     *        qualifier, except for vertex shader inputs and fragment shader
276     *        outputs."
277     */
278    if (glsl_get_base_type(in->type) == GLSL_TYPE_ATOMIC_UINT ||
279        is_gl_identifier(in->name) ||
280        !(in->data.explicit_location || use_implicit_location)) {
281       out->location = -1;
282    } else {
283       out->location = location;
284    }
285 
286    out->type = type;
287    out->outermost_struct_type = outermost_struct_type;
288    out->interface_type = interface_type;
289    out->component = in->data.location_frac;
290    out->index = in->data.index;
291    out->patch = in->data.patch;
292    out->mode = in->data.mode;
293    out->interpolation = in->data.interpolation;
294    out->precision = in->data.precision;
295    out->explicit_location = in->data.explicit_location;
296 
297    return out;
298 }
299 
300 static bool
add_shader_variable(const struct gl_constants * consts,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)301 add_shader_variable(const struct gl_constants *consts,
302                     struct gl_shader_program *shProg,
303                     struct set *resource_set,
304                     unsigned stage_mask,
305                     GLenum programInterface, nir_variable *var,
306                     const char *name, const struct glsl_type *type,
307                     bool use_implicit_location, int location,
308                     bool inouts_share_location,
309                     const struct glsl_type *outermost_struct_type)
310 {
311    const struct glsl_type *interface_type = var->interface_type;
312 
313    if (outermost_struct_type == NULL) {
314       if (var->data.from_named_ifc_block) {
315          const char *interface_name = glsl_get_type_name(interface_type);
316 
317          if (glsl_type_is_array(interface_type)) {
318             /* Issue #16 of the ARB_program_interface_query spec says:
319              *
320              * "* If a variable is a member of an interface block without an
321              *    instance name, it is enumerated using just the variable name.
322              *
323              *  * If a variable is a member of an interface block with an
324              *    instance name, it is enumerated as "BlockName.Member", where
325              *    "BlockName" is the name of the interface block (not the
326              *    instance name) and "Member" is the name of the variable."
327              *
328              * In particular, it indicates that it should be "BlockName",
329              * not "BlockName[array length]".  The conformance suite and
330              * dEQP both require this behavior.
331              *
332              * Here, we unwrap the extra array level added by named interface
333              * block array lowering so we have the correct variable type.  We
334              * also unwrap the interface type when constructing the name.
335              *
336              * We leave interface_type the same so that ES 3.x SSO pipeline
337              * validation can enforce the rules requiring array length to
338              * match on interface blocks.
339              */
340             type = glsl_get_array_element(type);
341 
342             interface_name =
343                glsl_get_type_name(glsl_get_array_element(interface_type));
344          }
345 
346          name = ralloc_asprintf(shProg, "%s.%s", interface_name, name);
347       }
348    }
349 
350    switch (glsl_get_base_type(type)) {
351    case GLSL_TYPE_STRUCT: {
352       /* The ARB_program_interface_query spec says:
353        *
354        *     "For an active variable declared as a structure, a separate entry
355        *     will be generated for each active structure member.  The name of
356        *     each entry is formed by concatenating the name of the structure,
357        *     the "."  character, and the name of the structure member.  If a
358        *     structure member to enumerate is itself a structure or array,
359        *     these enumeration rules are applied recursively."
360        */
361       if (outermost_struct_type == NULL)
362          outermost_struct_type = type;
363 
364       unsigned field_location = location;
365       for (unsigned i = 0; i < glsl_get_length(type); i++) {
366          const struct glsl_type *field_type = glsl_get_struct_field(type, i);
367          const struct glsl_struct_field *field =
368             glsl_get_struct_field_data(type, i);
369 
370          char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name);
371          if (!add_shader_variable(consts, shProg, resource_set,
372                                   stage_mask, programInterface,
373                                   var, field_name, field_type,
374                                   use_implicit_location, field_location,
375                                   false, outermost_struct_type))
376             return false;
377 
378          field_location += glsl_count_attribute_slots(field_type, false);
379       }
380       return true;
381    }
382 
383    case GLSL_TYPE_ARRAY: {
384       /* The ARB_program_interface_query spec says:
385        *
386        *     "For an active variable declared as an array of basic types, a
387        *      single entry will be generated, with its name string formed by
388        *      concatenating the name of the array and the string "[0]"."
389        *
390        *     "For an active variable declared as an array of an aggregate data
391        *      type (structures or arrays), a separate entry will be generated
392        *      for each active array element, unless noted immediately below.
393        *      The name of each entry is formed by concatenating the name of
394        *      the array, the "[" character, an integer identifying the element
395        *      number, and the "]" character.  These enumeration rules are
396        *      applied recursively, treating each enumerated array element as a
397        *      separate active variable."
398        */
399       const struct glsl_type *array_type = glsl_get_array_element(type);
400       if (glsl_get_base_type(array_type) == GLSL_TYPE_STRUCT ||
401           glsl_get_base_type(array_type) == GLSL_TYPE_ARRAY) {
402          unsigned elem_location = location;
403          unsigned stride = inouts_share_location ? 0 :
404                            glsl_count_attribute_slots(array_type, false);
405          for (unsigned i = 0; i < glsl_get_length(type); i++) {
406             char *elem = ralloc_asprintf(shProg, "%s[%d]", name, i);
407             if (!add_shader_variable(consts, shProg, resource_set,
408                                      stage_mask, programInterface,
409                                      var, elem, array_type,
410                                      use_implicit_location, elem_location,
411                                      false, outermost_struct_type))
412                return false;
413             elem_location += stride;
414          }
415          return true;
416       }
417    }
418    FALLTHROUGH;
419 
420    default: {
421       /* The ARB_program_interface_query spec says:
422        *
423        *     "For an active variable declared as a single instance of a basic
424        *     type, a single entry will be generated, using the variable name
425        *     from the shader source."
426        */
427       struct gl_shader_variable *sha_v =
428          create_shader_variable(shProg, var, name, type, interface_type,
429                                 use_implicit_location, location,
430                                 outermost_struct_type);
431       if (!sha_v)
432          return false;
433 
434       return link_util_add_program_resource(shProg, resource_set,
435                                             programInterface, sha_v, stage_mask);
436    }
437    }
438 }
439 
440 static bool
add_vars_with_modes(const struct gl_constants * consts,struct gl_shader_program * prog,struct set * resource_set,nir_shader * nir,nir_variable_mode modes,unsigned stage,GLenum programInterface)441 add_vars_with_modes(const struct gl_constants *consts,
442                     struct gl_shader_program *prog, struct set *resource_set,
443                     nir_shader *nir, nir_variable_mode modes,
444                     unsigned stage, GLenum programInterface)
445 {
446    nir_foreach_variable_with_modes(var, nir, modes) {
447       if (var->data.how_declared == nir_var_hidden)
448          continue;
449 
450       int loc_bias = 0;
451       switch(var->data.mode) {
452       case nir_var_system_value:
453       case nir_var_shader_in:
454          if (programInterface != GL_PROGRAM_INPUT)
455             continue;
456          loc_bias = (stage == MESA_SHADER_VERTEX) ? VERT_ATTRIB_GENERIC0
457                                                   : VARYING_SLOT_VAR0;
458          break;
459       case nir_var_shader_out:
460          if (programInterface != GL_PROGRAM_OUTPUT)
461             continue;
462          loc_bias = (stage == MESA_SHADER_FRAGMENT) ? FRAG_RESULT_DATA0
463                                                     : VARYING_SLOT_VAR0;
464          break;
465       default:
466          continue;
467       }
468 
469       if (var->data.patch)
470          loc_bias = VARYING_SLOT_PATCH0;
471 
472       if (prog->data->spirv) {
473          struct gl_shader_variable *sh_var =
474             rzalloc(prog, struct gl_shader_variable);
475 
476          /* In the ARB_gl_spirv spec, names are considered optional debug info, so
477           * the linker needs to work without them. Returning them is optional.
478           * For simplicity, we ignore names.
479           */
480          sh_var->name.string = NULL;
481          resource_name_updated(&sh_var->name);
482          sh_var->type = var->type;
483          sh_var->location = var->data.location - loc_bias;
484          sh_var->index = var->data.index;
485 
486          if (!link_util_add_program_resource(prog, resource_set,
487                                              programInterface,
488                                              sh_var, 1 << stage)) {
489            return false;
490          }
491       } else {
492          /* Skip packed varyings, packed varyings are handled separately
493           * by add_packed_varyings in the GLSL IR
494           * build_program_resource_list() call.
495           * TODO: handle packed varyings here instead. We likely want a NIR
496           * based packing pass first.
497           */
498          if (strncmp(var->name, "packed:", 7) == 0)
499             continue;
500 
501          const bool vs_input_or_fs_output =
502             (stage == MESA_SHADER_VERTEX &&
503              var->data.mode == nir_var_shader_in) ||
504             (stage == MESA_SHADER_FRAGMENT &&
505              var->data.mode == nir_var_shader_out);
506 
507          if (!add_shader_variable(consts, prog, resource_set,
508                                   1 << stage, programInterface,
509                                   var, var->name, var->type,
510                                   vs_input_or_fs_output,
511                                   var->data.location - loc_bias,
512                                   inout_has_same_location(var, stage),
513                                   NULL))
514             return false;
515       }
516    }
517 
518    return true;
519 }
520 
521 static bool
add_interface_variables(const struct gl_constants * consts,struct gl_shader_program * prog,struct set * resource_set,unsigned stage,GLenum programInterface)522 add_interface_variables(const struct gl_constants *consts,
523                         struct gl_shader_program *prog,
524                         struct set *resource_set,
525                         unsigned stage, GLenum programInterface)
526 {
527    struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
528    if (!sh)
529       return true;
530 
531    nir_shader *nir = sh->Program->nir;
532    assert(nir);
533 
534    switch (programInterface) {
535    case GL_PROGRAM_INPUT: {
536       return add_vars_with_modes(consts, prog, resource_set,
537                                  nir, nir_var_shader_in | nir_var_system_value,
538                                  stage, programInterface);
539    }
540    case GL_PROGRAM_OUTPUT:
541       return add_vars_with_modes(consts, prog, resource_set,
542                                  nir, nir_var_shader_out,
543                                  stage, programInterface);
544    default:
545       assert("!Should not get here");
546       break;
547    }
548 
549    return false;
550 }
551 
552 bool
nir_add_packed_var_to_resource_list(const struct gl_constants * consts,struct gl_shader_program * shProg,struct set * resource_set,nir_variable * var,unsigned stage,GLenum type)553 nir_add_packed_var_to_resource_list(const struct gl_constants *consts,
554                                     struct gl_shader_program *shProg,
555                                     struct set *resource_set,
556                                     nir_variable *var,
557                                     unsigned stage, GLenum type)
558 {
559    if (!add_shader_variable(consts, shProg, resource_set, 1 << stage,
560                             type, var, var->name, var->type, false,
561                             var->data.location - VARYING_SLOT_VAR0,
562                             inout_has_same_location(var, stage), NULL))
563       return false;
564 
565    return true;
566 }
567 
568 /**
569  * Initilise list of program resources that point to resource data.
570  */
571 void
init_program_resource_list(struct gl_shader_program * prog)572 init_program_resource_list(struct gl_shader_program *prog)
573 {
574    /* Rebuild resource list. */
575    if (prog->data->ProgramResourceList) {
576       ralloc_free(prog->data->ProgramResourceList);
577       prog->data->ProgramResourceList = NULL;
578       prog->data->NumProgramResourceList = 0;
579    }
580 }
581 
582 /* TODO: as we keep adding features, this method is becoming more and more
583  * similar to its GLSL counterpart at linker.cpp. Eventually it would be good
584  * to check if they could be refactored, and reduce code duplication somehow
585  */
586 void
nir_build_program_resource_list(const struct gl_constants * consts,struct gl_shader_program * prog,bool rebuild_resourse_list)587 nir_build_program_resource_list(const struct gl_constants *consts,
588                                 struct gl_shader_program *prog,
589                                 bool rebuild_resourse_list)
590 {
591    /* Rebuild resource list. */
592    if (rebuild_resourse_list)
593       init_program_resource_list(prog);
594 
595    int input_stage = MESA_SHADER_STAGES, output_stage = 0;
596 
597    /* Determine first input and final output stage. These are used to
598     * detect which variables should be enumerated in the resource list
599     * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
600     */
601    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
602       if (!prog->_LinkedShaders[i])
603          continue;
604       if (input_stage == MESA_SHADER_STAGES)
605          input_stage = i;
606       output_stage = i;
607    }
608 
609    /* Empty shader, no resources. */
610    if (input_stage == MESA_SHADER_STAGES && output_stage == 0)
611       return;
612 
613    struct set *resource_set = _mesa_pointer_set_create(NULL);
614 
615    /* Add inputs and outputs to the resource list. */
616    if (!add_interface_variables(consts, prog, resource_set, input_stage,
617                                 GL_PROGRAM_INPUT)) {
618       return;
619    }
620 
621    if (!add_interface_variables(consts, prog, resource_set, output_stage,
622                                 GL_PROGRAM_OUTPUT)) {
623       return;
624    }
625 
626    /* Add transform feedback varyings and buffers. */
627    if (prog->last_vert_prog) {
628       struct gl_transform_feedback_info *linked_xfb =
629          prog->last_vert_prog->sh.LinkedTransformFeedback;
630 
631       /* Add varyings. */
632       if (linked_xfb->NumVarying > 0) {
633          for (int i = 0; i < linked_xfb->NumVarying; i++) {
634             if (!link_util_add_program_resource(prog, resource_set,
635                                                 GL_TRANSFORM_FEEDBACK_VARYING,
636                                                 &linked_xfb->Varyings[i], 0))
637             return;
638          }
639       }
640 
641       /* Add buffers. */
642       for (unsigned i = 0; i < consts->MaxTransformFeedbackBuffers; i++) {
643          if ((linked_xfb->ActiveBuffers >> i) & 1) {
644             linked_xfb->Buffers[i].Binding = i;
645             if (!link_util_add_program_resource(prog, resource_set,
646                                                 GL_TRANSFORM_FEEDBACK_BUFFER,
647                                                 &linked_xfb->Buffers[i], 0))
648             return;
649          }
650       }
651    }
652 
653    /* Add uniforms
654     *
655     * Here, it is expected that nir_link_uniforms() has already been
656     * called, so that UniformStorage table is already available.
657     */
658    int top_level_array_base_offset = -1;
659    int top_level_array_size_in_bytes = -1;
660    int second_element_offset = -1;
661    int block_index = -1;
662    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
663       struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
664 
665       if (uniform->hidden) {
666          for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) {
667             if (!uniform->opaque[j].active ||
668                 glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)
669                continue;
670 
671             GLenum type =
672                _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j);
673             /* add shader subroutines */
674             if (!link_util_add_program_resource(prog, resource_set,
675                                                 type, uniform, 0))
676                return;
677          }
678 
679          continue;
680       }
681 
682       if (!link_util_should_add_buffer_variable(prog, uniform,
683                                                 top_level_array_base_offset,
684                                                 top_level_array_size_in_bytes,
685                                                 second_element_offset, block_index))
686          continue;
687 
688 
689       if (prog->data->UniformStorage[i].offset >= second_element_offset) {
690          top_level_array_base_offset =
691             prog->data->UniformStorage[i].offset;
692 
693          top_level_array_size_in_bytes =
694             prog->data->UniformStorage[i].top_level_array_size *
695             prog->data->UniformStorage[i].top_level_array_stride;
696 
697          /* Set or reset the second element offset. For non arrays this
698           * will be set to -1.
699           */
700          second_element_offset = top_level_array_size_in_bytes ?
701             top_level_array_base_offset +
702             prog->data->UniformStorage[i].top_level_array_stride : -1;
703       }
704       block_index = uniform->block_index;
705 
706 
707       GLenum interface = uniform->is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM;
708       if (!link_util_add_program_resource(prog, resource_set, interface, uniform,
709                                           uniform->active_shader_mask)) {
710          return;
711       }
712    }
713 
714 
715    for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
716       if (!link_util_add_program_resource(prog, resource_set, GL_UNIFORM_BLOCK,
717                                           &prog->data->UniformBlocks[i],
718                                           prog->data->UniformBlocks[i].stageref))
719          return;
720    }
721 
722    for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
723       if (!link_util_add_program_resource(prog, resource_set, GL_SHADER_STORAGE_BLOCK,
724                                           &prog->data->ShaderStorageBlocks[i],
725                                           prog->data->ShaderStorageBlocks[i].stageref))
726          return;
727    }
728 
729    /* Add atomic counter buffers. */
730    for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {
731       if (!link_util_add_program_resource(prog, resource_set, GL_ATOMIC_COUNTER_BUFFER,
732                                           &prog->data->AtomicBuffers[i], 0))
733          return;
734    }
735 
736    unsigned mask = prog->data->linked_stages;
737    while (mask) {
738       const int i = u_bit_scan(&mask);
739       struct gl_program *p = prog->_LinkedShaders[i]->Program;
740 
741       GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
742       for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
743          if (!link_util_add_program_resource(prog, resource_set,
744                                              type,
745                                              &p->sh.SubroutineFunctions[j],
746                                              0))
747             return;
748       }
749    }
750 
751    _mesa_set_destroy(resource_set, NULL);
752 }
753 
754 bool
gl_nir_link_spirv(const struct gl_constants * consts,struct gl_shader_program * prog,const struct gl_nir_linker_options * options)755 gl_nir_link_spirv(const struct gl_constants *consts,
756                   struct gl_shader_program *prog,
757                   const struct gl_nir_linker_options *options)
758 {
759    struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES];
760    unsigned num_shaders = 0;
761 
762    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
763       if (prog->_LinkedShaders[i])
764          linked_shader[num_shaders++] = prog->_LinkedShaders[i];
765    }
766 
767    /* Linking the stages in the opposite order (from fragment to vertex)
768     * ensures that inter-shader outputs written to in an earlier stage
769     * are eliminated if they are (transitively) not used in a later
770     * stage.
771     */
772    for (int i = num_shaders - 2; i >= 0; i--) {
773       gl_nir_link_opts(linked_shader[i]->Program->nir,
774                        linked_shader[i + 1]->Program->nir);
775    }
776 
777    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
778       struct gl_linked_shader *shader = prog->_LinkedShaders[i];
779       if (shader) {
780          const nir_remove_dead_variables_options opts = {
781             .can_remove_var = can_remove_uniform,
782          };
783          nir_remove_dead_variables(shader->Program->nir,
784                                    nir_var_uniform | nir_var_image,
785                                    &opts);
786       }
787    }
788 
789    if (!gl_nir_link_uniform_blocks(prog))
790       return false;
791 
792    if (!gl_nir_link_uniforms(consts, prog, options->fill_parameters))
793       return false;
794 
795    gl_nir_link_assign_atomic_counter_resources(consts, prog);
796    gl_nir_link_assign_xfb_resources(consts, prog);
797 
798    return true;
799 }
800 
801 /**
802  * Validate shader image resources.
803  */
804 static void
check_image_resources(const struct gl_constants * consts,const struct gl_extensions * exts,struct gl_shader_program * prog)805 check_image_resources(const struct gl_constants *consts,
806                       const struct gl_extensions *exts,
807                       struct gl_shader_program *prog)
808 {
809    unsigned total_image_units = 0;
810    unsigned fragment_outputs = 0;
811    unsigned total_shader_storage_blocks = 0;
812 
813    if (!exts->ARB_shader_image_load_store)
814       return;
815 
816    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
817       struct gl_linked_shader *sh = prog->_LinkedShaders[i];
818       if (!sh)
819          continue;
820 
821       total_image_units += sh->Program->info.num_images;
822       total_shader_storage_blocks += sh->Program->info.num_ssbos;
823    }
824 
825    if (total_image_units > consts->MaxCombinedImageUniforms)
826       linker_error(prog, "Too many combined image uniforms\n");
827 
828    struct gl_linked_shader *frag_sh =
829       prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
830    if (frag_sh) {
831       uint64_t frag_outputs_written = frag_sh->Program->info.outputs_written;
832       fragment_outputs = util_bitcount64(frag_outputs_written);
833    }
834 
835    if (total_image_units + fragment_outputs + total_shader_storage_blocks >
836        consts->MaxCombinedShaderOutputResources)
837       linker_error(prog, "Too many combined image uniforms, shader storage "
838                          " buffers and fragment outputs\n");
839 }
840 
841 static bool
is_sampler_array_accessed_indirectly(nir_deref_instr * deref)842 is_sampler_array_accessed_indirectly(nir_deref_instr *deref)
843 {
844    for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
845       if (d->deref_type != nir_deref_type_array)
846          continue;
847 
848       if (nir_src_is_const(d->arr.index))
849          continue;
850 
851       return true;
852    }
853 
854    return false;
855 }
856 
857 /**
858  * This check is done to make sure we allow only constant expression
859  * indexing and "constant-index-expression" (indexing with an expression
860  * that includes loop induction variable).
861  */
862 static bool
validate_sampler_array_indexing(const struct gl_constants * consts,struct gl_shader_program * prog)863 validate_sampler_array_indexing(const struct gl_constants *consts,
864                                 struct gl_shader_program *prog)
865 {
866    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
867       if (prog->_LinkedShaders[i] == NULL)
868          continue;
869 
870       bool no_dynamic_indexing =
871          consts->ShaderCompilerOptions[i].NirOptions->force_indirect_unrolling_sampler;
872 
873       bool uses_indirect_sampler_array_indexing = false;
874       nir_foreach_function(function, prog->_LinkedShaders[i]->Program->nir) {
875          nir_foreach_block(block, function->impl) {
876             nir_foreach_instr(instr, block) {
877                /* Check if a sampler array is accessed indirectly */
878                if (instr->type == nir_instr_type_tex) {
879                   nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
880                   int sampler_idx =
881                      nir_tex_instr_src_index(tex_instr, nir_tex_src_sampler_deref);
882                   if (sampler_idx >= 0) {
883                      nir_deref_instr *deref =
884                         nir_instr_as_deref(tex_instr->src[sampler_idx].src.ssa->parent_instr);
885                      if (is_sampler_array_accessed_indirectly(deref)) {
886                         uses_indirect_sampler_array_indexing = true;
887                         break;
888                      }
889                   }
890                }
891             }
892 
893             if (uses_indirect_sampler_array_indexing)
894                break;
895          }
896          if (uses_indirect_sampler_array_indexing)
897             break;
898       }
899 
900       if (uses_indirect_sampler_array_indexing) {
901          const char *msg = "sampler arrays indexed with non-constant "
902                            "expressions is forbidden in GLSL %s %u";
903          /* Backend has indicated that it has no dynamic indexing support. */
904          if (no_dynamic_indexing) {
905             linker_error(prog, msg, prog->IsES ? "ES" : "",
906                          prog->data->Version);
907             return false;
908          } else {
909             linker_warning(prog, msg, prog->IsES ? "ES" : "",
910                            prog->data->Version);
911          }
912       }
913    }
914 
915    return true;
916 }
917 
918 bool
gl_nir_link_glsl(const struct gl_constants * consts,const struct gl_extensions * exts,gl_api api,struct gl_shader_program * prog)919 gl_nir_link_glsl(const struct gl_constants *consts,
920                  const struct gl_extensions *exts,
921                  gl_api api,
922                  struct gl_shader_program *prog)
923 {
924    if (prog->NumShaders == 0)
925       return true;
926 
927    if (!gl_nir_link_varyings(consts, exts, api, prog))
928       return false;
929 
930    /* Validation for special cases where we allow sampler array indexing
931     * with loop induction variable. This check emits a warning or error
932     * depending if backend can handle dynamic indexing.
933     */
934    if ((!prog->IsES && prog->data->Version < 130) ||
935        (prog->IsES && prog->data->Version < 300)) {
936       if (!validate_sampler_array_indexing(consts, prog))
937          return false;
938    }
939 
940    if (prog->data->LinkStatus == LINKING_FAILURE)
941       return false;
942 
943    struct gl_linked_shader *linked_shader[MESA_SHADER_STAGES];
944    unsigned num_shaders = 0;
945 
946    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
947       if (prog->_LinkedShaders[i])
948          linked_shader[num_shaders++] = prog->_LinkedShaders[i];
949    }
950 
951    /* Linking the stages in the opposite order (from fragment to vertex)
952     * ensures that inter-shader outputs written to in an earlier stage
953     * are eliminated if they are (transitively) not used in a later
954     * stage.
955     */
956    for (int i = num_shaders - 2; i >= 0; i--) {
957       gl_nir_link_opts(linked_shader[i]->Program->nir,
958                        linked_shader[i + 1]->Program->nir);
959    }
960 
961    /* Tidy up any left overs from the linking process for single shaders.
962     * For example varying arrays that get packed may have dead elements that
963     * can be now be eliminated now that array access has been lowered.
964     */
965    if (num_shaders == 1)
966       gl_nir_opts(linked_shader[0]->Program->nir);
967 
968    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
969       struct gl_linked_shader *shader = prog->_LinkedShaders[i];
970       if (shader) {
971          if (consts->GLSLLowerConstArrays) {
972             nir_lower_const_arrays_to_uniforms(shader->Program->nir,
973                                                consts->Program[i].MaxUniformComponents);
974          }
975 
976          const nir_remove_dead_variables_options opts = {
977             .can_remove_var = can_remove_uniform,
978          };
979          nir_remove_dead_variables(shader->Program->nir,
980                                    nir_var_uniform | nir_var_image,
981                                    &opts);
982       }
983    }
984 
985    if (!gl_nir_link_uniforms(consts, prog, true))
986       return false;
987 
988    link_util_calculate_subroutine_compat(prog);
989    link_util_check_uniform_resources(consts, prog);
990    link_util_check_subroutine_resources(prog);
991    check_image_resources(consts, exts, prog);
992    gl_nir_link_assign_atomic_counter_resources(consts, prog);
993    gl_nir_link_check_atomic_counter_resources(consts, prog);
994 
995    if (prog->data->LinkStatus == LINKING_FAILURE)
996       return false;
997 
998    return true;
999 }
1000