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 "ir.h"
25#include "linker.h"
26#include "ir_uniform.h"
27#include "glsl_symbol_table.h"
28#include "program.h"
29#include "string_to_uint_map.h"
30#include "ir_array_refcount.h"
31
32#include "main/shader_types.h"
33#include "main/consts_exts.h"
34#include "util/strndup.h"
35
36/**
37 * \file link_uniforms.cpp
38 * Assign locations for GLSL uniforms.
39 *
40 * \author Ian Romanick <ian.d.romanick@intel.com>
41 */
42
43void
44program_resource_visitor::process(const glsl_type *type, const char *name,
45                                  bool use_std430_as_default)
46{
47   assert(type->without_array()->is_struct()
48          || type->without_array()->is_interface());
49
50   unsigned record_array_count = 1;
51   char *name_copy = ralloc_strdup(NULL, name);
52
53   enum glsl_interface_packing packing =
54      type->get_internal_ifc_packing(use_std430_as_default);
55
56   recursion(type, &name_copy, strlen(name), false, NULL, packing, false,
57             record_array_count, NULL);
58   ralloc_free(name_copy);
59}
60
61void
62program_resource_visitor::process(ir_variable *var, bool use_std430_as_default)
63{
64   const glsl_type *t =
65      var->data.from_named_ifc_block ? var->get_interface_type() : var->type;
66   process(var, t, use_std430_as_default);
67}
68
69void
70program_resource_visitor::process(ir_variable *var, const glsl_type *var_type,
71                                  bool use_std430_as_default)
72{
73   unsigned record_array_count = 1;
74   const bool row_major =
75      var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
76
77   enum glsl_interface_packing packing = var->get_interface_type() ?
78      var->get_interface_type()->
79         get_internal_ifc_packing(use_std430_as_default) :
80      var->type->get_internal_ifc_packing(use_std430_as_default);
81
82   const glsl_type *t = var_type;
83   const glsl_type *t_without_array = t->without_array();
84
85   /* false is always passed for the row_major parameter to the other
86    * processing functions because no information is available to do
87    * otherwise.  See the warning in linker.h.
88    */
89   if (t_without_array->is_struct() ||
90              (t->is_array() && t->fields.array->is_array())) {
91      char *name = ralloc_strdup(NULL, var->name);
92      recursion(var->type, &name, strlen(name), row_major, NULL, packing,
93                false, record_array_count, NULL);
94      ralloc_free(name);
95   } else if (t_without_array->is_interface()) {
96      char *name = ralloc_strdup(NULL, t_without_array->name);
97      const glsl_struct_field *ifc_member = var->data.from_named_ifc_block ?
98         &t_without_array->
99            fields.structure[t_without_array->field_index(var->name)] : NULL;
100
101      recursion(t, &name, strlen(name), row_major, NULL, packing,
102                false, record_array_count, ifc_member);
103      ralloc_free(name);
104   } else {
105      this->set_record_array_count(record_array_count);
106      this->visit_field(t, var->name, row_major, NULL, packing, false);
107   }
108}
109
110void
111program_resource_visitor::recursion(const glsl_type *t, char **name,
112                                    size_t name_length, bool row_major,
113                                    const glsl_type *record_type,
114                                    const enum glsl_interface_packing packing,
115                                    bool last_field,
116                                    unsigned record_array_count,
117                                    const glsl_struct_field *named_ifc_member)
118{
119   /* Records need to have each field processed individually.
120    *
121    * Arrays of records need to have each array element processed
122    * individually, then each field of the resulting array elements processed
123    * individually.
124    */
125   if (t->is_interface() && named_ifc_member) {
126      ralloc_asprintf_rewrite_tail(name, &name_length, ".%s",
127                                   named_ifc_member->name);
128      recursion(named_ifc_member->type, name, name_length, row_major, NULL,
129                packing, false, record_array_count, NULL);
130   } else if (t->is_struct() || t->is_interface()) {
131      if (record_type == NULL && t->is_struct())
132         record_type = t;
133
134      if (t->is_struct())
135         this->enter_record(t, *name, row_major, packing);
136
137      for (unsigned i = 0; i < t->length; i++) {
138         const char *field = t->fields.structure[i].name;
139         size_t new_length = name_length;
140
141         if (t->is_interface() && t->fields.structure[i].offset != -1)
142            this->set_buffer_offset(t->fields.structure[i].offset);
143
144         /* Append '.field' to the current variable name. */
145         if (name_length == 0) {
146            ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field);
147         } else {
148            ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field);
149         }
150
151         /* The layout of structures at the top level of the block is set
152          * during parsing.  For matrices contained in multiple levels of
153          * structures in the block, the inner structures have no layout.
154          * These cases must potentially inherit the layout from the outer
155          * levels.
156          */
157         bool field_row_major = row_major;
158         const enum glsl_matrix_layout matrix_layout =
159            glsl_matrix_layout(t->fields.structure[i].matrix_layout);
160         if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {
161            field_row_major = true;
162         } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) {
163            field_row_major = false;
164         }
165
166         recursion(t->fields.structure[i].type, name, new_length,
167                   field_row_major,
168                   record_type,
169                   packing,
170                   (i + 1) == t->length, record_array_count, NULL);
171
172         /* Only the first leaf-field of the record gets called with the
173          * record type pointer.
174          */
175         record_type = NULL;
176      }
177
178      if (t->is_struct()) {
179         (*name)[name_length] = '\0';
180         this->leave_record(t, *name, row_major, packing);
181      }
182   } else if (t->without_array()->is_struct() ||
183              t->without_array()->is_interface() ||
184              (t->is_array() && t->fields.array->is_array())) {
185      if (record_type == NULL && t->fields.array->is_struct())
186         record_type = t->fields.array;
187
188      unsigned length = t->length;
189
190      /* Shader storage block unsized arrays: add subscript [0] to variable
191       * names.
192       */
193      if (t->is_unsized_array())
194         length = 1;
195
196      record_array_count *= length;
197
198      for (unsigned i = 0; i < length; i++) {
199         size_t new_length = name_length;
200
201         /* Append the subscript to the current variable name */
202         ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
203
204         recursion(t->fields.array, name, new_length, row_major,
205                   record_type,
206                   packing,
207                   (i + 1) == t->length, record_array_count,
208                   named_ifc_member);
209
210         /* Only the first leaf-field of the record gets called with the
211          * record type pointer.
212          */
213         record_type = NULL;
214      }
215   } else {
216      this->set_record_array_count(record_array_count);
217      this->visit_field(t, *name, row_major, record_type, packing, last_field);
218   }
219}
220
221void
222program_resource_visitor::enter_record(const glsl_type *, const char *, bool,
223                                       const enum glsl_interface_packing)
224{
225}
226
227void
228program_resource_visitor::leave_record(const glsl_type *, const char *, bool,
229                                       const enum glsl_interface_packing)
230{
231}
232
233void
234program_resource_visitor::set_buffer_offset(unsigned)
235{
236}
237
238void
239program_resource_visitor::set_record_array_count(unsigned)
240{
241}
242
243unsigned
244link_calculate_matrix_stride(const glsl_type *matrix, bool row_major,
245                             enum glsl_interface_packing packing)
246{
247   const unsigned N = matrix->is_double() ? 8 : 4;
248   const unsigned items =
249      row_major ? matrix->matrix_columns : matrix->vector_elements;
250
251   assert(items <= 4);
252
253   /* Matrix stride for std430 mat2xY matrices are not rounded up to
254    * vec4 size.
255    *
256    * Section 7.6.2.2 "Standard Uniform Block Layout" of the OpenGL 4.3 spec
257    * says:
258    *
259    *    2. If the member is a two- or four-component vector with components
260    *       consuming N basic machine units, the base alignment is 2N or 4N,
261    *       respectively.
262    *    ...
263    *    4. If the member is an array of scalars or vectors, the base
264    *       alignment and array stride are set to match the base alignment of
265    *       a single array element, according to rules (1), (2), and (3), and
266    *       rounded up to the base alignment of a vec4.
267    *    ...
268    *    7. If the member is a row-major matrix with C columns and R rows, the
269    *       matrix is stored identically to an array of R row vectors with C
270    *       components each, according to rule (4).
271    *    ...
272    *
273    *    When using the std430 storage layout, shader storage blocks will be
274    *    laid out in buffer storage identically to uniform and shader storage
275    *    blocks using the std140 layout, except that the base alignment and
276    *    stride of arrays of scalars and vectors in rule 4 and of structures
277    *    in rule 9 are not rounded up a multiple of the base alignment of a
278    *    vec4.
279    */
280   return packing == GLSL_INTERFACE_PACKING_STD430
281      ? (items < 3 ? items * N : glsl_align(items * N, 16))
282      : glsl_align(items * N, 16);
283}
284