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