• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2011 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
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "main/core.h"
25 #include "ir.h"
26 #include "linker.h"
27 #include "ir_uniform.h"
28 #include "glsl_symbol_table.h"
29 #include "program.h"
30 #include "util/string_to_uint_map.h"
31 #include "ir_array_refcount.h"
32 
33 /**
34  * \file link_uniforms.cpp
35  * Assign locations for GLSL uniforms.
36  *
37  * \author Ian Romanick <ian.d.romanick@intel.com>
38  */
39 
40 /**
41  * Used by linker to indicate uniforms that have no location set.
42  */
43 #define UNMAPPED_UNIFORM_LOC ~0u
44 
45 /**
46  * Count the backing storage requirements for a type
47  */
48 static unsigned
values_for_type(const glsl_type * type)49 values_for_type(const glsl_type *type)
50 {
51    if (type->is_sampler()) {
52       return 1;
53    } else if (type->is_array() && type->fields.array->is_sampler()) {
54       return type->array_size();
55    } else {
56       return type->component_slots();
57    }
58 }
59 
60 void
process(const glsl_type * type,const char * name)61 program_resource_visitor::process(const glsl_type *type, const char *name)
62 {
63    assert(type->without_array()->is_record()
64           || type->without_array()->is_interface());
65 
66    unsigned record_array_count = 1;
67    char *name_copy = ralloc_strdup(NULL, name);
68    enum glsl_interface_packing packing = type->get_interface_packing();
69 
70    recursion(type, &name_copy, strlen(name), false, NULL, packing, false,
71              record_array_count, NULL);
72    ralloc_free(name_copy);
73 }
74 
75 void
process(ir_variable * var)76 program_resource_visitor::process(ir_variable *var)
77 {
78    unsigned record_array_count = 1;
79    const bool row_major =
80       var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
81 
82    const enum glsl_interface_packing packing = var->get_interface_type() ?
83       var->get_interface_type_packing() :
84       var->type->get_interface_packing();
85 
86    const glsl_type *t =
87       var->data.from_named_ifc_block ? var->get_interface_type() : var->type;
88    const glsl_type *t_without_array = t->without_array();
89 
90    /* false is always passed for the row_major parameter to the other
91     * processing functions because no information is available to do
92     * otherwise.  See the warning in linker.h.
93     */
94    if (t_without_array->is_record() ||
95               (t->is_array() && t->fields.array->is_array())) {
96       char *name = ralloc_strdup(NULL, var->name);
97       recursion(var->type, &name, strlen(name), row_major, NULL, packing,
98                 false, record_array_count, NULL);
99       ralloc_free(name);
100    } else if (t_without_array->is_interface()) {
101       char *name = ralloc_strdup(NULL, t_without_array->name);
102       const glsl_struct_field *ifc_member = var->data.from_named_ifc_block ?
103          &t_without_array->
104             fields.structure[t_without_array->field_index(var->name)] : NULL;
105 
106       recursion(t, &name, strlen(name), row_major, NULL, packing,
107                 false, record_array_count, ifc_member);
108       ralloc_free(name);
109    } else {
110       this->set_record_array_count(record_array_count);
111       this->visit_field(t, var->name, row_major, NULL, packing, false);
112    }
113 }
114 
115 void
recursion(const glsl_type * t,char ** name,size_t name_length,bool row_major,const glsl_type * record_type,const enum glsl_interface_packing packing,bool last_field,unsigned record_array_count,const glsl_struct_field * named_ifc_member)116 program_resource_visitor::recursion(const glsl_type *t, char **name,
117                                     size_t name_length, bool row_major,
118                                     const glsl_type *record_type,
119                                     const enum glsl_interface_packing packing,
120                                     bool last_field,
121                                     unsigned record_array_count,
122                                     const glsl_struct_field *named_ifc_member)
123 {
124    /* Records need to have each field processed individually.
125     *
126     * Arrays of records need to have each array element processed
127     * individually, then each field of the resulting array elements processed
128     * individually.
129     */
130    if (t->is_interface() && named_ifc_member) {
131       ralloc_asprintf_rewrite_tail(name, &name_length, ".%s",
132                                    named_ifc_member->name);
133       recursion(named_ifc_member->type, name, name_length, row_major, NULL,
134                 packing, false, record_array_count, NULL);
135    } else if (t->is_record() || t->is_interface()) {
136       if (record_type == NULL && t->is_record())
137          record_type = t;
138 
139       if (t->is_record())
140          this->enter_record(t, *name, row_major, packing);
141 
142       for (unsigned i = 0; i < t->length; i++) {
143          const char *field = t->fields.structure[i].name;
144          size_t new_length = name_length;
145 
146          if (t->fields.structure[i].type->is_record())
147             this->visit_field(&t->fields.structure[i]);
148 
149          if (t->is_interface() && t->fields.structure[i].offset != -1)
150             this->set_buffer_offset(t->fields.structure[i].offset);
151 
152          /* Append '.field' to the current variable name. */
153          if (name_length == 0) {
154             ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field);
155          } else {
156             ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field);
157          }
158 
159          /* The layout of structures at the top level of the block is set
160           * during parsing.  For matrices contained in multiple levels of
161           * structures in the block, the inner structures have no layout.
162           * These cases must potentially inherit the layout from the outer
163           * levels.
164           */
165          bool field_row_major = row_major;
166          const enum glsl_matrix_layout matrix_layout =
167             glsl_matrix_layout(t->fields.structure[i].matrix_layout);
168          if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {
169             field_row_major = true;
170          } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) {
171             field_row_major = false;
172          }
173 
174          recursion(t->fields.structure[i].type, name, new_length,
175                    field_row_major,
176                    record_type,
177                    packing,
178                    (i + 1) == t->length, record_array_count, NULL);
179 
180          /* Only the first leaf-field of the record gets called with the
181           * record type pointer.
182           */
183          record_type = NULL;
184       }
185 
186       if (t->is_record()) {
187          (*name)[name_length] = '\0';
188          this->leave_record(t, *name, row_major, packing);
189       }
190    } else if (t->without_array()->is_record() ||
191               t->without_array()->is_interface() ||
192               (t->is_array() && t->fields.array->is_array())) {
193       if (record_type == NULL && t->fields.array->is_record())
194          record_type = t->fields.array;
195 
196       unsigned length = t->length;
197 
198       /* Shader storage block unsized arrays: add subscript [0] to variable
199        * names.
200        */
201       if (t->is_unsized_array())
202          length = 1;
203 
204       record_array_count *= length;
205 
206       for (unsigned i = 0; i < length; i++) {
207          size_t new_length = name_length;
208 
209          /* Append the subscript to the current variable name */
210          ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
211 
212          recursion(t->fields.array, name, new_length, row_major,
213                    record_type,
214                    packing,
215                    (i + 1) == t->length, record_array_count,
216                    named_ifc_member);
217 
218          /* Only the first leaf-field of the record gets called with the
219           * record type pointer.
220           */
221          record_type = NULL;
222       }
223    } else {
224       this->set_record_array_count(record_array_count);
225       this->visit_field(t, *name, row_major, record_type, packing, last_field);
226    }
227 }
228 
229 void
visit_field(const glsl_struct_field *)230 program_resource_visitor::visit_field(const glsl_struct_field *)
231 {
232 }
233 
234 void
enter_record(const glsl_type *,const char *,bool,const enum glsl_interface_packing)235 program_resource_visitor::enter_record(const glsl_type *, const char *, bool,
236                                        const enum glsl_interface_packing)
237 {
238 }
239 
240 void
leave_record(const glsl_type *,const char *,bool,const enum glsl_interface_packing)241 program_resource_visitor::leave_record(const glsl_type *, const char *, bool,
242                                        const enum glsl_interface_packing)
243 {
244 }
245 
246 void
set_buffer_offset(unsigned)247 program_resource_visitor::set_buffer_offset(unsigned)
248 {
249 }
250 
251 void
set_record_array_count(unsigned)252 program_resource_visitor::set_record_array_count(unsigned)
253 {
254 }
255 
256 namespace {
257 
258 /**
259  * Class to help calculate the storage requirements for a set of uniforms
260  *
261  * As uniforms are added to the active set the number of active uniforms and
262  * the storage requirements for those uniforms are accumulated.  The active
263  * uniforms are added to the hash table supplied to the constructor.
264  *
265  * If the same uniform is added multiple times (i.e., once for each shader
266  * target), it will only be accounted once.
267  */
268 class count_uniform_size : public program_resource_visitor {
269 public:
count_uniform_size(struct string_to_uint_map * map,struct string_to_uint_map * hidden_map)270    count_uniform_size(struct string_to_uint_map *map,
271                       struct string_to_uint_map *hidden_map)
272       : num_active_uniforms(0), num_hidden_uniforms(0), num_values(0),
273         num_shader_samplers(0), num_shader_images(0),
274         num_shader_uniform_components(0), num_shader_subroutines(0),
275         is_buffer_block(false), is_shader_storage(false), map(map),
276         hidden_map(hidden_map)
277    {
278       /* empty */
279    }
280 
start_shader()281    void start_shader()
282    {
283       this->num_shader_samplers = 0;
284       this->num_shader_images = 0;
285       this->num_shader_uniform_components = 0;
286       this->num_shader_subroutines = 0;
287    }
288 
process(ir_variable * var)289    void process(ir_variable *var)
290    {
291       this->current_var = var;
292       this->is_buffer_block = var->is_in_buffer_block();
293       this->is_shader_storage = var->is_in_shader_storage_block();
294       if (var->is_interface_instance())
295          program_resource_visitor::process(var->get_interface_type(),
296                                            var->get_interface_type()->name);
297       else
298          program_resource_visitor::process(var);
299    }
300 
301    /**
302     * Total number of active uniforms counted
303     */
304    unsigned num_active_uniforms;
305 
306    unsigned num_hidden_uniforms;
307 
308    /**
309     * Number of data values required to back the storage for the active uniforms
310     */
311    unsigned num_values;
312 
313    /**
314     * Number of samplers used
315     */
316    unsigned num_shader_samplers;
317 
318    /**
319     * Number of images used
320     */
321    unsigned num_shader_images;
322 
323    /**
324     * Number of uniforms used in the current shader
325     */
326    unsigned num_shader_uniform_components;
327 
328    /**
329     * Number of subroutine uniforms used
330     */
331    unsigned num_shader_subroutines;
332 
333    bool is_buffer_block;
334    bool is_shader_storage;
335 
336    struct string_to_uint_map *map;
337 
338 private:
visit_field(const glsl_type * type,const char * name,bool,const glsl_type *,const enum glsl_interface_packing,bool)339    virtual void visit_field(const glsl_type *type, const char *name,
340                             bool /* row_major */,
341                             const glsl_type * /* record_type */,
342                             const enum glsl_interface_packing,
343                             bool /* last_field */)
344    {
345       assert(!type->without_array()->is_record());
346       assert(!type->without_array()->is_interface());
347       assert(!(type->is_array() && type->fields.array->is_array()));
348 
349       /* Count the number of samplers regardless of whether the uniform is
350        * already in the hash table.  The hash table prevents adding the same
351        * uniform for multiple shader targets, but in this case we want to
352        * count it for each shader target.
353        */
354       const unsigned values = values_for_type(type);
355       if (type->contains_subroutine()) {
356          this->num_shader_subroutines += values;
357       } else if (type->contains_sampler()) {
358          this->num_shader_samplers += values;
359       } else if (type->contains_image()) {
360          this->num_shader_images += values;
361 
362          /* As drivers are likely to represent image uniforms as
363           * scalar indices, count them against the limit of uniform
364           * components in the default block.  The spec allows image
365           * uniforms to use up no more than one scalar slot.
366           */
367          if (!is_shader_storage)
368             this->num_shader_uniform_components += values;
369       } else {
370          /* Accumulate the total number of uniform slots used by this shader.
371           * Note that samplers do not count against this limit because they
372           * don't use any storage on current hardware.
373           */
374          if (!is_buffer_block)
375             this->num_shader_uniform_components += values;
376       }
377 
378       /* If the uniform is already in the map, there's nothing more to do.
379        */
380       unsigned id;
381       if (this->map->get(id, name))
382          return;
383 
384       if (this->current_var->data.how_declared == ir_var_hidden) {
385          this->hidden_map->put(this->num_hidden_uniforms, name);
386          this->num_hidden_uniforms++;
387       } else {
388          this->map->put(this->num_active_uniforms-this->num_hidden_uniforms,
389                         name);
390       }
391 
392       /* Each leaf uniform occupies one entry in the list of active
393        * uniforms.
394        */
395       this->num_active_uniforms++;
396 
397       if(!is_gl_identifier(name) && !is_shader_storage && !is_buffer_block)
398          this->num_values += values;
399    }
400 
401    struct string_to_uint_map *hidden_map;
402 
403    /**
404     * Current variable being processed.
405     */
406    ir_variable *current_var;
407 };
408 
409 } /* anonymous namespace */
410 
411 /**
412  * Class to help parcel out pieces of backing storage to uniforms
413  *
414  * Each uniform processed has some range of the \c gl_constant_value
415  * structures associated with it.  The association is done by finding
416  * the uniform in the \c string_to_uint_map and using the value from
417  * the map to connect that slot in the \c gl_uniform_storage table
418  * with the next available slot in the \c gl_constant_value array.
419  *
420  * \warning
421  * This class assumes that every uniform that will be processed is
422  * already in the \c string_to_uint_map.  In addition, it assumes that
423  * the \c gl_uniform_storage and \c gl_constant_value arrays are "big
424  * enough."
425  */
426 class parcel_out_uniform_storage : public program_resource_visitor {
427 public:
parcel_out_uniform_storage(struct gl_shader_program * prog,struct string_to_uint_map * map,struct gl_uniform_storage * uniforms,union gl_constant_value * values)428    parcel_out_uniform_storage(struct gl_shader_program *prog,
429                               struct string_to_uint_map *map,
430                               struct gl_uniform_storage *uniforms,
431                               union gl_constant_value *values)
432       : prog(prog), map(map), uniforms(uniforms), values(values)
433    {
434    }
435 
start_shader(gl_shader_stage shader_type)436    void start_shader(gl_shader_stage shader_type)
437    {
438       assert(shader_type < MESA_SHADER_STAGES);
439       this->shader_type = shader_type;
440 
441       this->shader_samplers_used = 0;
442       this->shader_shadow_samplers = 0;
443       this->next_sampler = 0;
444       this->next_image = 0;
445       this->next_subroutine = 0;
446       this->record_array_count = 1;
447       memset(this->targets, 0, sizeof(this->targets));
448    }
449 
set_and_process(ir_variable * var)450    void set_and_process(ir_variable *var)
451    {
452       current_var = var;
453       field_counter = 0;
454       this->record_next_sampler = new string_to_uint_map;
455 
456       buffer_block_index = -1;
457       if (var->is_in_buffer_block()) {
458          struct gl_uniform_block *blks = var->is_in_shader_storage_block() ?
459             prog->data->ShaderStorageBlocks : prog->data->UniformBlocks;
460          unsigned num_blks = var->is_in_shader_storage_block() ?
461             prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks;
462 
463          if (var->is_interface_instance() && var->type->is_array()) {
464             unsigned l = strlen(var->get_interface_type()->name);
465 
466             for (unsigned i = 0; i < num_blks; i++) {
467                if (strncmp(var->get_interface_type()->name, blks[i].Name, l)
468                    == 0 && blks[i].Name[l] == '[') {
469                   buffer_block_index = i;
470                   break;
471                }
472             }
473          } else {
474             for (unsigned i = 0; i < num_blks; i++) {
475                if (strcmp(var->get_interface_type()->name, blks[i].Name) == 0) {
476                   buffer_block_index = i;
477                   break;
478                }
479             }
480          }
481          assert(buffer_block_index != -1);
482 
483          /* Uniform blocks that were specified with an instance name must be
484           * handled a little bit differently.  The name of the variable is the
485           * name used to reference the uniform block instead of being the name
486           * of a variable within the block.  Therefore, searching for the name
487           * within the block will fail.
488           */
489          if (var->is_interface_instance()) {
490             ubo_byte_offset = 0;
491             process(var->get_interface_type(),
492                     var->get_interface_type()->name);
493          } else {
494             const struct gl_uniform_block *const block =
495                &blks[buffer_block_index];
496 
497             assert(var->data.location != -1);
498 
499             const struct gl_uniform_buffer_variable *const ubo_var =
500                &block->Uniforms[var->data.location];
501 
502             ubo_byte_offset = ubo_var->Offset;
503             process(var);
504          }
505       } else {
506          /* Store any explicit location and reset data location so we can
507           * reuse this variable for storing the uniform slot number.
508           */
509          this->explicit_location = current_var->data.location;
510          current_var->data.location = -1;
511 
512          process(var);
513       }
514       delete this->record_next_sampler;
515    }
516 
517    int buffer_block_index;
518    int ubo_byte_offset;
519    gl_shader_stage shader_type;
520 
521 private:
handle_samplers(const glsl_type * base_type,struct gl_uniform_storage * uniform,const char * name)522    void handle_samplers(const glsl_type *base_type,
523                         struct gl_uniform_storage *uniform, const char *name)
524    {
525       if (base_type->is_sampler()) {
526          uniform->opaque[shader_type].active = true;
527 
528          /* Handle multiple samplers inside struct arrays */
529          if (this->record_array_count > 1) {
530             unsigned inner_array_size = MAX2(1, uniform->array_elements);
531             char *name_copy = ralloc_strdup(NULL, name);
532 
533             /* Remove all array subscripts from the sampler name */
534             char *str_start;
535             const char *str_end;
536             while((str_start = strchr(name_copy, '[')) &&
537                   (str_end = strchr(name_copy, ']'))) {
538                memmove(str_start, str_end + 1, 1 + strlen(str_end + 1));
539             }
540 
541             unsigned index = 0;
542             if (this->record_next_sampler->get(index, name_copy)) {
543                /* In this case, we've already seen this uniform so we just use
544                 * the next sampler index recorded the last time we visited.
545                 */
546                uniform->opaque[shader_type].index = index;
547                index = inner_array_size + uniform->opaque[shader_type].index;
548                this->record_next_sampler->put(index, name_copy);
549 
550                ralloc_free(name_copy);
551                /* Return as everything else has already been initialised in a
552                 * previous pass.
553                 */
554                return;
555             } else {
556                /* We've never seen this uniform before so we need to allocate
557                 * enough indices to store it.
558                 *
559                 * Nested struct arrays behave like arrays of arrays so we need
560                 * to increase the index by the total number of elements of the
561                 * sampler in case there is more than one sampler inside the
562                 * structs. This allows the offset to be easily calculated for
563                 * indirect indexing.
564                 */
565                uniform->opaque[shader_type].index = this->next_sampler;
566                this->next_sampler +=
567                   inner_array_size * this->record_array_count;
568 
569                /* Store the next index for future passes over the struct array
570                 */
571                index = uniform->opaque[shader_type].index + inner_array_size;
572                this->record_next_sampler->put(index, name_copy);
573                ralloc_free(name_copy);
574             }
575          } else {
576             /* Increment the sampler by 1 for non-arrays and by the number of
577              * array elements for arrays.
578              */
579             uniform->opaque[shader_type].index = this->next_sampler;
580             this->next_sampler += MAX2(1, uniform->array_elements);
581          }
582 
583          const gl_texture_index target = base_type->sampler_index();
584          const unsigned shadow = base_type->sampler_shadow;
585          for (unsigned i = uniform->opaque[shader_type].index;
586               i < MIN2(this->next_sampler, MAX_SAMPLERS);
587               i++) {
588             this->targets[i] = target;
589             this->shader_samplers_used |= 1U << i;
590             this->shader_shadow_samplers |= shadow << i;
591          }
592       }
593    }
594 
handle_images(const glsl_type * base_type,struct gl_uniform_storage * uniform)595    void handle_images(const glsl_type *base_type,
596                       struct gl_uniform_storage *uniform)
597    {
598       if (base_type->is_image()) {
599          uniform->opaque[shader_type].index = this->next_image;
600          uniform->opaque[shader_type].active = true;
601 
602          /* Set image access qualifiers */
603          const GLenum access =
604             (current_var->data.image_read_only ? GL_READ_ONLY :
605              current_var->data.image_write_only ? GL_WRITE_ONLY :
606                 GL_READ_WRITE);
607 
608          const unsigned first = this->next_image;
609 
610          /* Increment the image index by 1 for non-arrays and by the
611           * number of array elements for arrays.
612           */
613          this->next_image += MAX2(1, uniform->array_elements);
614 
615          for (unsigned i = first; i < MIN2(next_image, MAX_IMAGE_UNIFORMS); i++)
616             prog->_LinkedShaders[shader_type]->Program->sh.ImageAccess[i] = access;
617       }
618    }
619 
handle_subroutines(const glsl_type * base_type,struct gl_uniform_storage * uniform)620    void handle_subroutines(const glsl_type *base_type,
621                            struct gl_uniform_storage *uniform)
622    {
623       if (base_type->is_subroutine()) {
624          uniform->opaque[shader_type].index = this->next_subroutine;
625          uniform->opaque[shader_type].active = true;
626 
627          prog->_LinkedShaders[shader_type]->Program->sh.NumSubroutineUniforms++;
628 
629          /* Increment the subroutine index by 1 for non-arrays and by the
630           * number of array elements for arrays.
631           */
632          this->next_subroutine += MAX2(1, uniform->array_elements);
633 
634       }
635    }
636 
set_buffer_offset(unsigned offset)637    virtual void set_buffer_offset(unsigned offset)
638    {
639       this->ubo_byte_offset = offset;
640    }
641 
set_record_array_count(unsigned record_array_count)642    virtual void set_record_array_count(unsigned record_array_count)
643    {
644       this->record_array_count = record_array_count;
645    }
646 
enter_record(const glsl_type * type,const char *,bool row_major,const enum glsl_interface_packing packing)647    virtual void enter_record(const glsl_type *type, const char *,
648                              bool row_major,
649                              const enum glsl_interface_packing packing)
650    {
651       assert(type->is_record());
652       if (this->buffer_block_index == -1)
653          return;
654       if (packing == GLSL_INTERFACE_PACKING_STD430)
655          this->ubo_byte_offset = glsl_align(
656             this->ubo_byte_offset, type->std430_base_alignment(row_major));
657       else
658          this->ubo_byte_offset = glsl_align(
659             this->ubo_byte_offset, type->std140_base_alignment(row_major));
660    }
661 
leave_record(const glsl_type * type,const char *,bool row_major,const enum glsl_interface_packing packing)662    virtual void leave_record(const glsl_type *type, const char *,
663                              bool row_major,
664                              const enum glsl_interface_packing packing)
665    {
666       assert(type->is_record());
667       if (this->buffer_block_index == -1)
668          return;
669       if (packing == GLSL_INTERFACE_PACKING_STD430)
670          this->ubo_byte_offset = glsl_align(
671             this->ubo_byte_offset, type->std430_base_alignment(row_major));
672       else
673          this->ubo_byte_offset = glsl_align(
674             this->ubo_byte_offset, type->std140_base_alignment(row_major));
675    }
676 
visit_field(const glsl_type * type,const char * name,bool row_major,const glsl_type *,const enum glsl_interface_packing packing,bool)677    virtual void visit_field(const glsl_type *type, const char *name,
678                             bool row_major, const glsl_type * /* record_type */,
679                             const enum glsl_interface_packing packing,
680                             bool /* last_field */)
681    {
682       assert(!type->without_array()->is_record());
683       assert(!type->without_array()->is_interface());
684       assert(!(type->is_array() && type->fields.array->is_array()));
685 
686       unsigned id;
687       bool found = this->map->get(id, name);
688       assert(found);
689 
690       if (!found)
691          return;
692 
693       const glsl_type *base_type;
694       if (type->is_array()) {
695          this->uniforms[id].array_elements = type->length;
696          base_type = type->fields.array;
697       } else {
698          this->uniforms[id].array_elements = 0;
699          base_type = type;
700       }
701 
702       /* Initialise opaque data */
703       this->uniforms[id].opaque[shader_type].index = ~0;
704       this->uniforms[id].opaque[shader_type].active = false;
705 
706       /* This assigns uniform indices to sampler and image uniforms. */
707       handle_samplers(base_type, &this->uniforms[id], name);
708       handle_images(base_type, &this->uniforms[id]);
709       handle_subroutines(base_type, &this->uniforms[id]);
710 
711       /* For array of arrays or struct arrays the base location may have
712        * already been set so don't set it again.
713        */
714       if (buffer_block_index == -1 && current_var->data.location == -1) {
715          current_var->data.location = id;
716       }
717 
718       /* If there is already storage associated with this uniform or if the
719        * uniform is set as builtin, it means that it was set while processing
720        * an earlier shader stage.  For example, we may be processing the
721        * uniform in the fragment shader, but the uniform was already processed
722        * in the vertex shader.
723        */
724       if (this->uniforms[id].storage != NULL || this->uniforms[id].builtin) {
725          return;
726       }
727 
728       /* Assign explicit locations. */
729       if (current_var->data.explicit_location) {
730          /* Set sequential locations for struct fields. */
731          if (current_var->type->without_array()->is_record() ||
732              current_var->type->is_array_of_arrays()) {
733             const unsigned entries = MAX2(1, this->uniforms[id].array_elements);
734             this->uniforms[id].remap_location =
735                this->explicit_location + field_counter;
736             field_counter += entries;
737          } else {
738             this->uniforms[id].remap_location = this->explicit_location;
739          }
740       } else {
741          /* Initialize to to indicate that no location is set */
742          this->uniforms[id].remap_location = UNMAPPED_UNIFORM_LOC;
743       }
744 
745       this->uniforms[id].name = ralloc_strdup(this->uniforms, name);
746       this->uniforms[id].type = base_type;
747       this->uniforms[id].num_driver_storage = 0;
748       this->uniforms[id].driver_storage = NULL;
749       this->uniforms[id].atomic_buffer_index = -1;
750       this->uniforms[id].hidden =
751          current_var->data.how_declared == ir_var_hidden;
752       this->uniforms[id].builtin = is_gl_identifier(name);
753 
754       this->uniforms[id].is_shader_storage =
755          current_var->is_in_shader_storage_block();
756 
757       /* Do not assign storage if the uniform is a builtin or buffer object */
758       if (!this->uniforms[id].builtin &&
759           !this->uniforms[id].is_shader_storage &&
760           this->buffer_block_index == -1)
761          this->uniforms[id].storage = this->values;
762 
763       if (this->buffer_block_index != -1) {
764          this->uniforms[id].block_index = this->buffer_block_index;
765 
766          unsigned alignment = type->std140_base_alignment(row_major);
767          if (packing == GLSL_INTERFACE_PACKING_STD430)
768             alignment = type->std430_base_alignment(row_major);
769          this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment);
770          this->uniforms[id].offset = this->ubo_byte_offset;
771          if (packing == GLSL_INTERFACE_PACKING_STD430)
772             this->ubo_byte_offset += type->std430_size(row_major);
773          else
774             this->ubo_byte_offset += type->std140_size(row_major);
775 
776          if (type->is_array()) {
777             if (packing == GLSL_INTERFACE_PACKING_STD430)
778                this->uniforms[id].array_stride =
779                   type->without_array()->std430_array_stride(row_major);
780             else
781                this->uniforms[id].array_stride =
782                   glsl_align(type->without_array()->std140_size(row_major),
783                              16);
784          } else {
785             this->uniforms[id].array_stride = 0;
786          }
787 
788          if (type->without_array()->is_matrix()) {
789             const glsl_type *matrix = type->without_array();
790             const unsigned N = matrix->base_type == GLSL_TYPE_DOUBLE ? 8 : 4;
791             const unsigned items =
792                row_major ? matrix->matrix_columns : matrix->vector_elements;
793 
794             assert(items <= 4);
795             if (packing == GLSL_INTERFACE_PACKING_STD430)
796                this->uniforms[id].matrix_stride = items < 3 ? items * N :
797                                                     glsl_align(items * N, 16);
798             else
799                this->uniforms[id].matrix_stride = glsl_align(items * N, 16);
800             this->uniforms[id].row_major = row_major;
801          } else {
802             this->uniforms[id].matrix_stride = 0;
803             this->uniforms[id].row_major = false;
804          }
805       } else {
806          this->uniforms[id].block_index = -1;
807          this->uniforms[id].offset = -1;
808          this->uniforms[id].array_stride = -1;
809          this->uniforms[id].matrix_stride = -1;
810          this->uniforms[id].row_major = false;
811       }
812 
813       if (!this->uniforms[id].builtin &&
814           !this->uniforms[id].is_shader_storage &&
815           this->buffer_block_index == -1)
816          this->values += values_for_type(type);
817    }
818 
819    /**
820     * Current program being processed.
821     */
822    struct gl_shader_program *prog;
823 
824    struct string_to_uint_map *map;
825 
826    struct gl_uniform_storage *uniforms;
827    unsigned next_sampler;
828    unsigned next_image;
829    unsigned next_subroutine;
830 
831    /**
832     * Field counter is used to take care that uniform structures
833     * with explicit locations get sequential locations.
834     */
835    unsigned field_counter;
836 
837    /**
838     * Current variable being processed.
839     */
840    ir_variable *current_var;
841 
842    /* Used to store the explicit location from current_var so that we can
843     * reuse the location field for storing the uniform slot id.
844     */
845    int explicit_location;
846 
847    /* Stores total struct array elements including nested structs */
848    unsigned record_array_count;
849 
850    /* Map for temporarily storing next sampler index when handling samplers in
851     * struct arrays.
852     */
853    struct string_to_uint_map *record_next_sampler;
854 
855 public:
856    union gl_constant_value *values;
857 
858    gl_texture_index targets[MAX_SAMPLERS];
859 
860    /**
861     * Mask of samplers used by the current shader stage.
862     */
863    unsigned shader_samplers_used;
864 
865    /**
866     * Mask of samplers used by the current shader stage for shadows.
867     */
868    unsigned shader_shadow_samplers;
869 };
870 
871 static bool
variable_is_referenced(ir_array_refcount_visitor & v,ir_variable * var)872 variable_is_referenced(ir_array_refcount_visitor &v, ir_variable *var)
873 {
874    ir_array_refcount_entry *const entry = v.get_variable_entry(var);
875 
876    return entry->is_referenced;
877 
878 }
879 
880 /**
881  * Walks the IR and update the references to uniform blocks in the
882  * ir_variables to point at linked shader's list (previously, they
883  * would point at the uniform block list in one of the pre-linked
884  * shaders).
885  */
886 static void
link_update_uniform_buffer_variables(struct gl_linked_shader * shader,unsigned stage)887 link_update_uniform_buffer_variables(struct gl_linked_shader *shader,
888                                      unsigned stage)
889 {
890    ir_array_refcount_visitor v;
891 
892    v.run(shader->ir);
893 
894    foreach_in_list(ir_instruction, node, shader->ir) {
895       ir_variable *const var = node->as_variable();
896 
897       if (var == NULL || !var->is_in_buffer_block())
898          continue;
899 
900       assert(var->data.mode == ir_var_uniform ||
901              var->data.mode == ir_var_shader_storage);
902 
903       unsigned num_blocks = var->data.mode == ir_var_uniform ?
904          shader->Program->info.num_ubos : shader->Program->info.num_ssbos;
905       struct gl_uniform_block **blks = var->data.mode == ir_var_uniform ?
906          shader->Program->sh.UniformBlocks :
907          shader->Program->sh.ShaderStorageBlocks;
908 
909       if (var->is_interface_instance()) {
910          const ir_array_refcount_entry *const entry = v.get_variable_entry(var);
911 
912          if (entry->is_referenced) {
913             /* Since this is an interface instance, the instance type will be
914              * same as the array-stripped variable type.  If the variable type
915              * is an array, then the block names will be suffixed with [0]
916              * through [n-1].  Unlike for non-interface instances, there will
917              * not be structure types here, so the only name sentinel that we
918              * have to worry about is [.
919              */
920             assert(var->type->without_array() == var->get_interface_type());
921             const char sentinel = var->type->is_array() ? '[' : '\0';
922 
923             const ptrdiff_t len = strlen(var->get_interface_type()->name);
924             for (unsigned i = 0; i < num_blocks; i++) {
925                const char *const begin = blks[i]->Name;
926                const char *const end = strchr(begin, sentinel);
927 
928                if (end == NULL)
929                   continue;
930 
931                if (len != (end - begin))
932                   continue;
933 
934                /* Even when a match is found, do not "break" here.  This could
935                 * be an array of instances, and all elements of the array need
936                 * to be marked as referenced.
937                 */
938                if (strncmp(begin, var->get_interface_type()->name, len) == 0 &&
939                    (!var->type->is_array() ||
940                     entry->is_linearized_index_referenced(blks[i]->linearized_array_index))) {
941                   blks[i]->stageref |= 1U << stage;
942                }
943             }
944          }
945 
946          var->data.location = 0;
947          continue;
948       }
949 
950       bool found = false;
951       char sentinel = '\0';
952 
953       if (var->type->is_record()) {
954          sentinel = '.';
955       } else if (var->type->is_array() && (var->type->fields.array->is_array()
956                  || var->type->without_array()->is_record())) {
957          sentinel = '[';
958       }
959 
960       const unsigned l = strlen(var->name);
961       for (unsigned i = 0; i < num_blocks; i++) {
962          for (unsigned j = 0; j < blks[i]->NumUniforms; j++) {
963             if (sentinel) {
964                const char *begin = blks[i]->Uniforms[j].Name;
965                const char *end = strchr(begin, sentinel);
966 
967                if (end == NULL)
968                   continue;
969 
970                if ((ptrdiff_t) l != (end - begin))
971                   continue;
972 
973                found = strncmp(var->name, begin, l) == 0;
974             } else {
975                found = strcmp(var->name, blks[i]->Uniforms[j].Name) == 0;
976             }
977 
978             if (found) {
979                var->data.location = j;
980 
981                if (variable_is_referenced(v, var))
982                   blks[i]->stageref |= 1U << stage;
983 
984                break;
985             }
986          }
987 
988          if (found)
989             break;
990       }
991       assert(found);
992    }
993 }
994 
995 /**
996  * Combine the hidden uniform hash map with the uniform hash map so that the
997  * hidden uniforms will be given indicies at the end of the uniform storage
998  * array.
999  */
1000 static void
assign_hidden_uniform_slot_id(const char * name,unsigned hidden_id,void * closure)1001 assign_hidden_uniform_slot_id(const char *name, unsigned hidden_id,
1002                               void *closure)
1003 {
1004    count_uniform_size *uniform_size = (count_uniform_size *) closure;
1005    unsigned hidden_uniform_start = uniform_size->num_active_uniforms -
1006       uniform_size->num_hidden_uniforms;
1007 
1008    uniform_size->map->put(hidden_uniform_start + hidden_id, name);
1009 }
1010 
1011 /**
1012  * Search through the list of empty blocks to find one that fits the current
1013  * uniform.
1014  */
1015 static int
find_empty_block(struct gl_shader_program * prog,struct gl_uniform_storage * uniform)1016 find_empty_block(struct gl_shader_program *prog,
1017                  struct gl_uniform_storage *uniform)
1018 {
1019    const unsigned entries = MAX2(1, uniform->array_elements);
1020 
1021    foreach_list_typed(struct empty_uniform_block, block, link,
1022                       &prog->EmptyUniformLocations) {
1023       /* Found a block with enough slots to fit the uniform */
1024       if (block->slots == entries) {
1025          unsigned start = block->start;
1026          exec_node_remove(&block->link);
1027          ralloc_free(block);
1028 
1029          return start;
1030       /* Found a block with more slots than needed. It can still be used. */
1031       } else if (block->slots > entries) {
1032          unsigned start = block->start;
1033          block->start += entries;
1034          block->slots -= entries;
1035 
1036          return start;
1037       }
1038    }
1039 
1040    return -1;
1041 }
1042 
1043 static void
link_setup_uniform_remap_tables(struct gl_context * ctx,struct gl_shader_program * prog,unsigned num_explicit_uniform_locs)1044 link_setup_uniform_remap_tables(struct gl_context *ctx,
1045                                 struct gl_shader_program *prog,
1046                                 unsigned num_explicit_uniform_locs)
1047 {
1048    unsigned total_entries = num_explicit_uniform_locs;
1049    unsigned empty_locs =
1050       prog->NumUniformRemapTable - num_explicit_uniform_locs;
1051 
1052    /* Reserve all the explicit locations of the active uniforms. */
1053    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1054       if (prog->data->UniformStorage[i].type->is_subroutine() ||
1055           prog->data->UniformStorage[i].is_shader_storage)
1056          continue;
1057 
1058       if (prog->data->UniformStorage[i].remap_location !=
1059           UNMAPPED_UNIFORM_LOC) {
1060          /* How many new entries for this uniform? */
1061          const unsigned entries =
1062             MAX2(1, prog->data->UniformStorage[i].array_elements);
1063 
1064          /* Set remap table entries point to correct gl_uniform_storage. */
1065          for (unsigned j = 0; j < entries; j++) {
1066             unsigned element_loc =
1067                prog->data->UniformStorage[i].remap_location + j;
1068             assert(prog->UniformRemapTable[element_loc] ==
1069                    INACTIVE_UNIFORM_EXPLICIT_LOCATION);
1070             prog->UniformRemapTable[element_loc] =
1071                &prog->data->UniformStorage[i];
1072          }
1073       }
1074    }
1075 
1076    /* Reserve locations for rest of the uniforms. */
1077    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1078 
1079       if (prog->data->UniformStorage[i].type->is_subroutine() ||
1080           prog->data->UniformStorage[i].is_shader_storage)
1081          continue;
1082 
1083       /* Built-in uniforms should not get any location. */
1084       if (prog->data->UniformStorage[i].builtin)
1085          continue;
1086 
1087       /* Explicit ones have been set already. */
1088       if (prog->data->UniformStorage[i].remap_location != UNMAPPED_UNIFORM_LOC)
1089          continue;
1090 
1091       /* how many new entries for this uniform? */
1092       const unsigned entries =
1093          MAX2(1, prog->data->UniformStorage[i].array_elements);
1094 
1095       /* Find UniformRemapTable for empty blocks where we can fit this uniform. */
1096       int chosen_location = -1;
1097 
1098       if (empty_locs)
1099          chosen_location = find_empty_block(prog, &prog->data->UniformStorage[i]);
1100 
1101       /* Add new entries to the total amount of entries. */
1102       total_entries += entries;
1103 
1104       if (chosen_location != -1) {
1105          empty_locs -= entries;
1106       } else {
1107          chosen_location = prog->NumUniformRemapTable;
1108 
1109          /* resize remap table to fit new entries */
1110          prog->UniformRemapTable =
1111             reralloc(prog,
1112                      prog->UniformRemapTable,
1113                      gl_uniform_storage *,
1114                      prog->NumUniformRemapTable + entries);
1115          prog->NumUniformRemapTable += entries;
1116       }
1117 
1118       /* set pointers for this uniform */
1119       for (unsigned j = 0; j < entries; j++)
1120          prog->UniformRemapTable[chosen_location + j] =
1121             &prog->data->UniformStorage[i];
1122 
1123       /* set the base location in remap table for the uniform */
1124       prog->data->UniformStorage[i].remap_location = chosen_location;
1125    }
1126 
1127    /* Verify that total amount of entries for explicit and implicit locations
1128     * is less than MAX_UNIFORM_LOCATIONS.
1129     */
1130 
1131    if (total_entries > ctx->Const.MaxUserAssignableUniformLocations) {
1132       linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"
1133                    "(%u > %u)", total_entries,
1134                    ctx->Const.MaxUserAssignableUniformLocations);
1135    }
1136 
1137    /* Reserve all the explicit locations of the active subroutine uniforms. */
1138    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1139       if (!prog->data->UniformStorage[i].type->is_subroutine())
1140          continue;
1141 
1142       if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)
1143          continue;
1144 
1145       /* How many new entries for this uniform? */
1146       const unsigned entries =
1147          MAX2(1, prog->data->UniformStorage[i].array_elements);
1148 
1149       unsigned mask = prog->data->linked_stages;
1150       while (mask) {
1151          const int j = u_bit_scan(&mask);
1152          struct gl_program *p = prog->_LinkedShaders[j]->Program;
1153 
1154          if (!prog->data->UniformStorage[i].opaque[j].active)
1155             continue;
1156 
1157          /* Set remap table entries point to correct gl_uniform_storage. */
1158          for (unsigned k = 0; k < entries; k++) {
1159             unsigned element_loc =
1160                prog->data->UniformStorage[i].remap_location + k;
1161             assert(p->sh.SubroutineUniformRemapTable[element_loc] ==
1162                    INACTIVE_UNIFORM_EXPLICIT_LOCATION);
1163             p->sh.SubroutineUniformRemapTable[element_loc] =
1164                &prog->data->UniformStorage[i];
1165          }
1166       }
1167    }
1168 
1169    /* reserve subroutine locations */
1170    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1171       if (!prog->data->UniformStorage[i].type->is_subroutine())
1172          continue;
1173 
1174       if (prog->data->UniformStorage[i].remap_location !=
1175           UNMAPPED_UNIFORM_LOC)
1176          continue;
1177 
1178       const unsigned entries =
1179          MAX2(1, prog->data->UniformStorage[i].array_elements);
1180 
1181       unsigned mask = prog->data->linked_stages;
1182       while (mask) {
1183          const int j = u_bit_scan(&mask);
1184          struct gl_program *p = prog->_LinkedShaders[j]->Program;
1185 
1186          if (!prog->data->UniformStorage[i].opaque[j].active)
1187             continue;
1188 
1189          p->sh.SubroutineUniformRemapTable =
1190             reralloc(p,
1191                      p->sh.SubroutineUniformRemapTable,
1192                      gl_uniform_storage *,
1193                      p->sh.NumSubroutineUniformRemapTable + entries);
1194 
1195          for (unsigned k = 0; k < entries; k++) {
1196             p->sh.SubroutineUniformRemapTable[p->sh.NumSubroutineUniformRemapTable + k] =
1197                &prog->data->UniformStorage[i];
1198          }
1199          prog->data->UniformStorage[i].remap_location =
1200             p->sh.NumSubroutineUniformRemapTable;
1201          p->sh.NumSubroutineUniformRemapTable += entries;
1202       }
1203    }
1204 }
1205 
1206 static void
link_assign_uniform_storage(struct gl_context * ctx,struct gl_shader_program * prog,const unsigned num_data_slots,unsigned num_explicit_uniform_locs)1207 link_assign_uniform_storage(struct gl_context *ctx,
1208                             struct gl_shader_program *prog,
1209                             const unsigned num_data_slots,
1210                             unsigned num_explicit_uniform_locs)
1211 {
1212    /* On the outside chance that there were no uniforms, bail out.
1213     */
1214    if (prog->data->NumUniformStorage == 0)
1215       return;
1216 
1217    unsigned int boolean_true = ctx->Const.UniformBooleanTrue;
1218 
1219    prog->data->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage,
1220                                               prog->data->NumUniformStorage);
1221    union gl_constant_value *data = rzalloc_array(prog->data->UniformStorage,
1222                                                  union gl_constant_value,
1223                                                  num_data_slots);
1224 #ifndef NDEBUG
1225    union gl_constant_value *data_end = &data[num_data_slots];
1226 #endif
1227 
1228    parcel_out_uniform_storage parcel(prog, prog->UniformHash,
1229                                      prog->data->UniformStorage, data);
1230 
1231    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
1232       if (prog->_LinkedShaders[i] == NULL)
1233          continue;
1234 
1235       parcel.start_shader((gl_shader_stage)i);
1236 
1237       foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
1238          ir_variable *const var = node->as_variable();
1239 
1240          if ((var == NULL) || (var->data.mode != ir_var_uniform &&
1241                                var->data.mode != ir_var_shader_storage))
1242             continue;
1243 
1244          parcel.set_and_process(var);
1245       }
1246 
1247       prog->_LinkedShaders[i]->Program->SamplersUsed =
1248          parcel.shader_samplers_used;
1249       prog->_LinkedShaders[i]->shadow_samplers = parcel.shader_shadow_samplers;
1250 
1251       STATIC_ASSERT(sizeof(prog->_LinkedShaders[i]->Program->sh.SamplerTargets) ==
1252                     sizeof(parcel.targets));
1253       memcpy(prog->_LinkedShaders[i]->Program->sh.SamplerTargets,
1254              parcel.targets,
1255              sizeof(prog->_LinkedShaders[i]->Program->sh.SamplerTargets));
1256    }
1257 
1258 #ifndef NDEBUG
1259    for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1260       assert(prog->data->UniformStorage[i].storage != NULL ||
1261              prog->data->UniformStorage[i].builtin ||
1262              prog->data->UniformStorage[i].is_shader_storage ||
1263              prog->data->UniformStorage[i].block_index != -1);
1264    }
1265 
1266    assert(parcel.values == data_end);
1267 #endif
1268 
1269    link_setup_uniform_remap_tables(ctx, prog, num_explicit_uniform_locs);
1270 
1271    link_set_uniform_initializers(prog, boolean_true);
1272 }
1273 
1274 void
link_assign_uniform_locations(struct gl_shader_program * prog,struct gl_context * ctx,unsigned int num_explicit_uniform_locs)1275 link_assign_uniform_locations(struct gl_shader_program *prog,
1276                               struct gl_context *ctx,
1277                               unsigned int num_explicit_uniform_locs)
1278 {
1279    ralloc_free(prog->data->UniformStorage);
1280    prog->data->UniformStorage = NULL;
1281    prog->data->NumUniformStorage = 0;
1282 
1283    if (prog->UniformHash != NULL) {
1284       prog->UniformHash->clear();
1285    } else {
1286       prog->UniformHash = new string_to_uint_map;
1287    }
1288 
1289    /* First pass: Count the uniform resources used by the user-defined
1290     * uniforms.  While this happens, each active uniform will have an index
1291     * assigned to it.
1292     *
1293     * Note: this is *NOT* the index that is returned to the application by
1294     * glGetUniformLocation.
1295     */
1296    struct string_to_uint_map *hiddenUniforms = new string_to_uint_map;
1297    count_uniform_size uniform_size(prog->UniformHash, hiddenUniforms);
1298    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
1299       struct gl_linked_shader *sh = prog->_LinkedShaders[i];
1300 
1301       if (sh == NULL)
1302          continue;
1303 
1304       link_update_uniform_buffer_variables(sh, i);
1305 
1306       /* Reset various per-shader target counts.
1307        */
1308       uniform_size.start_shader();
1309 
1310       foreach_in_list(ir_instruction, node, sh->ir) {
1311          ir_variable *const var = node->as_variable();
1312 
1313          if ((var == NULL) || (var->data.mode != ir_var_uniform &&
1314                                var->data.mode != ir_var_shader_storage))
1315             continue;
1316 
1317          uniform_size.process(var);
1318       }
1319 
1320       sh->Program->info.num_textures = uniform_size.num_shader_samplers;
1321       sh->Program->info.num_images = uniform_size.num_shader_images;
1322       sh->num_uniform_components = uniform_size.num_shader_uniform_components;
1323       sh->num_combined_uniform_components = sh->num_uniform_components;
1324 
1325       for (unsigned i = 0; i < sh->Program->info.num_ubos; i++) {
1326          sh->num_combined_uniform_components +=
1327             sh->Program->sh.UniformBlocks[i]->UniformBufferSize / 4;
1328       }
1329    }
1330 
1331    prog->data->NumUniformStorage = uniform_size.num_active_uniforms;
1332    prog->data->NumHiddenUniforms = uniform_size.num_hidden_uniforms;
1333 
1334    /* assign hidden uniforms a slot id */
1335    hiddenUniforms->iterate(assign_hidden_uniform_slot_id, &uniform_size);
1336    delete hiddenUniforms;
1337 
1338    link_assign_uniform_storage(ctx, prog, uniform_size.num_values,
1339                                num_explicit_uniform_locs);
1340 }
1341