1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2010 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 "ast.h"
25b8e80941Smrg#include "compiler/glsl_types.h"
26b8e80941Smrg#include "ir.h"
27b8e80941Smrg
28b8e80941Smrgvoid
29b8e80941Smrgast_array_specifier::print(void) const
30b8e80941Smrg{
31b8e80941Smrg   foreach_list_typed (ast_node, array_dimension, link, &this->array_dimensions) {
32b8e80941Smrg      printf("[ ");
33b8e80941Smrg      if (((ast_expression*)array_dimension)->oper != ast_unsized_array_dim)
34b8e80941Smrg         array_dimension->print();
35b8e80941Smrg      printf("] ");
36b8e80941Smrg   }
37b8e80941Smrg}
38b8e80941Smrg
39b8e80941Smrg/**
40b8e80941Smrg * If \c ir is a reference to an array for which we are tracking the max array
41b8e80941Smrg * element accessed, track that the given element has been accessed.
42b8e80941Smrg * Otherwise do nothing.
43b8e80941Smrg *
44b8e80941Smrg * This function also checks whether the array is a built-in array whose
45b8e80941Smrg * maximum size is too small to accommodate the given index, and if so uses
46b8e80941Smrg * loc and state to report the error.
47b8e80941Smrg */
48b8e80941Smrgstatic void
49b8e80941Smrgupdate_max_array_access(ir_rvalue *ir, int idx, YYLTYPE *loc,
50b8e80941Smrg                        struct _mesa_glsl_parse_state *state)
51b8e80941Smrg{
52b8e80941Smrg   if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) {
53b8e80941Smrg      ir_variable *var = deref_var->var;
54b8e80941Smrg      if (idx > (int)var->data.max_array_access) {
55b8e80941Smrg         var->data.max_array_access = idx;
56b8e80941Smrg
57b8e80941Smrg         /* Check whether this access will, as a side effect, implicitly cause
58b8e80941Smrg          * the size of a built-in array to be too large.
59b8e80941Smrg          */
60b8e80941Smrg         check_builtin_array_max_size(var->name, idx+1, *loc, state);
61b8e80941Smrg      }
62b8e80941Smrg   } else if (ir_dereference_record *deref_record =
63b8e80941Smrg              ir->as_dereference_record()) {
64b8e80941Smrg      /* There are three possibilities we need to consider:
65b8e80941Smrg       *
66b8e80941Smrg       * - Accessing an element of an array that is a member of a named
67b8e80941Smrg       *   interface block (e.g. ifc.foo[i])
68b8e80941Smrg       *
69b8e80941Smrg       * - Accessing an element of an array that is a member of a named
70b8e80941Smrg       *   interface block array (e.g. ifc[j].foo[i]).
71b8e80941Smrg       *
72b8e80941Smrg       * - Accessing an element of an array that is a member of a named
73b8e80941Smrg       *   interface block array of arrays (e.g. ifc[j][k].foo[i]).
74b8e80941Smrg       */
75b8e80941Smrg      ir_dereference_variable *deref_var =
76b8e80941Smrg         deref_record->record->as_dereference_variable();
77b8e80941Smrg      if (deref_var == NULL) {
78b8e80941Smrg         ir_dereference_array *deref_array =
79b8e80941Smrg            deref_record->record->as_dereference_array();
80b8e80941Smrg         ir_dereference_array *deref_array_prev = NULL;
81b8e80941Smrg         while (deref_array != NULL) {
82b8e80941Smrg            deref_array_prev = deref_array;
83b8e80941Smrg            deref_array = deref_array->array->as_dereference_array();
84b8e80941Smrg         }
85b8e80941Smrg         if (deref_array_prev != NULL)
86b8e80941Smrg            deref_var = deref_array_prev->array->as_dereference_variable();
87b8e80941Smrg      }
88b8e80941Smrg
89b8e80941Smrg      if (deref_var != NULL) {
90b8e80941Smrg         if (deref_var->var->is_interface_instance()) {
91b8e80941Smrg            unsigned field_idx = deref_record->field_idx;
92b8e80941Smrg            assert(field_idx < deref_var->var->get_interface_type()->length);
93b8e80941Smrg
94b8e80941Smrg            int *const max_ifc_array_access =
95b8e80941Smrg               deref_var->var->get_max_ifc_array_access();
96b8e80941Smrg
97b8e80941Smrg            assert(max_ifc_array_access != NULL);
98b8e80941Smrg
99b8e80941Smrg            if (idx > max_ifc_array_access[field_idx]) {
100b8e80941Smrg               max_ifc_array_access[field_idx] = idx;
101b8e80941Smrg
102b8e80941Smrg               /* Check whether this access will, as a side effect, implicitly
103b8e80941Smrg                * cause the size of a built-in array to be too large.
104b8e80941Smrg                */
105b8e80941Smrg               const char *field_name =
106b8e80941Smrg                  deref_record->record->type->fields.structure[field_idx].name;
107b8e80941Smrg               check_builtin_array_max_size(field_name, idx+1, *loc, state);
108b8e80941Smrg            }
109b8e80941Smrg         }
110b8e80941Smrg      }
111b8e80941Smrg   }
112b8e80941Smrg}
113b8e80941Smrg
114b8e80941Smrg
115b8e80941Smrgstatic int
116b8e80941Smrgget_implicit_array_size(struct _mesa_glsl_parse_state *state,
117b8e80941Smrg                        ir_rvalue *array)
118b8e80941Smrg{
119b8e80941Smrg   ir_variable *var = array->variable_referenced();
120b8e80941Smrg
121b8e80941Smrg   /* Inputs in control shader are implicitly sized
122b8e80941Smrg    * to the maximum patch size.
123b8e80941Smrg    */
124b8e80941Smrg   if (state->stage == MESA_SHADER_TESS_CTRL &&
125b8e80941Smrg       var->data.mode == ir_var_shader_in) {
126b8e80941Smrg      return state->Const.MaxPatchVertices;
127b8e80941Smrg   }
128b8e80941Smrg
129b8e80941Smrg   /* Non-patch inputs in evaluation shader are implicitly sized
130b8e80941Smrg    * to the maximum patch size.
131b8e80941Smrg    */
132b8e80941Smrg   if (state->stage == MESA_SHADER_TESS_EVAL &&
133b8e80941Smrg       var->data.mode == ir_var_shader_in &&
134b8e80941Smrg       !var->data.patch) {
135b8e80941Smrg      return state->Const.MaxPatchVertices;
136b8e80941Smrg   }
137b8e80941Smrg
138b8e80941Smrg   return 0;
139b8e80941Smrg}
140b8e80941Smrg
141b8e80941Smrg
142b8e80941Smrgir_rvalue *
143b8e80941Smrg_mesa_ast_array_index_to_hir(void *mem_ctx,
144b8e80941Smrg                             struct _mesa_glsl_parse_state *state,
145b8e80941Smrg                             ir_rvalue *array, ir_rvalue *idx,
146b8e80941Smrg                             YYLTYPE &loc, YYLTYPE &idx_loc)
147b8e80941Smrg{
148b8e80941Smrg   if (!array->type->is_error()
149b8e80941Smrg       && !array->type->is_array()
150b8e80941Smrg       && !array->type->is_matrix()
151b8e80941Smrg       && !array->type->is_vector()) {
152b8e80941Smrg      _mesa_glsl_error(& idx_loc, state,
153b8e80941Smrg                       "cannot dereference non-array / non-matrix / "
154b8e80941Smrg                       "non-vector");
155b8e80941Smrg   }
156b8e80941Smrg
157b8e80941Smrg   if (!idx->type->is_error()) {
158b8e80941Smrg      if (!idx->type->is_integer()) {
159b8e80941Smrg         _mesa_glsl_error(& idx_loc, state, "array index must be integer type");
160b8e80941Smrg      } else if (!idx->type->is_scalar()) {
161b8e80941Smrg         _mesa_glsl_error(& idx_loc, state, "array index must be scalar");
162b8e80941Smrg      }
163b8e80941Smrg   }
164b8e80941Smrg
165b8e80941Smrg   /* If the array index is a constant expression and the array has a
166b8e80941Smrg    * declared size, ensure that the access is in-bounds.  If the array
167b8e80941Smrg    * index is not a constant expression, ensure that the array has a
168b8e80941Smrg    * declared size.
169b8e80941Smrg    */
170b8e80941Smrg   ir_constant *const const_index = idx->constant_expression_value(mem_ctx);
171b8e80941Smrg   if (const_index != NULL && idx->type->is_integer()) {
172b8e80941Smrg      const int idx = const_index->value.i[0];
173b8e80941Smrg      const char *type_name = "error";
174b8e80941Smrg      unsigned bound = 0;
175b8e80941Smrg
176b8e80941Smrg      /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec:
177b8e80941Smrg       *
178b8e80941Smrg       *    "It is illegal to declare an array with a size, and then
179b8e80941Smrg       *    later (in the same shader) index the same array with an
180b8e80941Smrg       *    integral constant expression greater than or equal to the
181b8e80941Smrg       *    declared size. It is also illegal to index an array with a
182b8e80941Smrg       *    negative constant expression."
183b8e80941Smrg       */
184b8e80941Smrg      if (array->type->is_matrix()) {
185b8e80941Smrg         if (array->type->row_type()->vector_elements <= idx) {
186b8e80941Smrg            type_name = "matrix";
187b8e80941Smrg            bound = array->type->row_type()->vector_elements;
188b8e80941Smrg         }
189b8e80941Smrg      } else if (array->type->is_vector()) {
190b8e80941Smrg         if (array->type->vector_elements <= idx) {
191b8e80941Smrg            type_name = "vector";
192b8e80941Smrg            bound = array->type->vector_elements;
193b8e80941Smrg         }
194b8e80941Smrg      } else {
195b8e80941Smrg         /* glsl_type::array_size() returns -1 for non-array types.  This means
196b8e80941Smrg          * that we don't need to verify that the type is an array before
197b8e80941Smrg          * doing the bounds checking.
198b8e80941Smrg          */
199b8e80941Smrg         if ((array->type->array_size() > 0)
200b8e80941Smrg             && (array->type->array_size() <= idx)) {
201b8e80941Smrg            type_name = "array";
202b8e80941Smrg            bound = array->type->array_size();
203b8e80941Smrg         }
204b8e80941Smrg      }
205b8e80941Smrg
206b8e80941Smrg      if (bound > 0) {
207b8e80941Smrg         _mesa_glsl_error(& loc, state, "%s index must be < %u",
208b8e80941Smrg                          type_name, bound);
209b8e80941Smrg      } else if (idx < 0) {
210b8e80941Smrg         _mesa_glsl_error(& loc, state, "%s index must be >= 0", type_name);
211b8e80941Smrg      }
212b8e80941Smrg
213b8e80941Smrg      if (array->type->is_array())
214b8e80941Smrg         update_max_array_access(array, idx, &loc, state);
215b8e80941Smrg   } else if (const_index == NULL && array->type->is_array()) {
216b8e80941Smrg      if (array->type->is_unsized_array()) {
217b8e80941Smrg         int implicit_size = get_implicit_array_size(state, array);
218b8e80941Smrg         if (implicit_size) {
219b8e80941Smrg            ir_variable *v = array->whole_variable_referenced();
220b8e80941Smrg            if (v != NULL)
221b8e80941Smrg               v->data.max_array_access = implicit_size - 1;
222b8e80941Smrg         }
223b8e80941Smrg         else if (state->stage == MESA_SHADER_TESS_CTRL &&
224b8e80941Smrg                  array->variable_referenced()->data.mode == ir_var_shader_out &&
225b8e80941Smrg                  !array->variable_referenced()->data.patch) {
226b8e80941Smrg            /* Tessellation control shader output non-patch arrays are
227b8e80941Smrg             * initially unsized. Despite that, they are allowed to be
228b8e80941Smrg             * indexed with a non-constant expression (typically
229b8e80941Smrg             * "gl_InvocationID"). The array size will be determined
230b8e80941Smrg             * by the linker.
231b8e80941Smrg             */
232b8e80941Smrg         }
233b8e80941Smrg         else if (array->variable_referenced()->data.mode !=
234b8e80941Smrg                  ir_var_shader_storage) {
235b8e80941Smrg            _mesa_glsl_error(&loc, state, "unsized array index must be constant");
236b8e80941Smrg         } else {
237b8e80941Smrg            /* Unsized array non-constant indexing on SSBO is allowed only for
238b8e80941Smrg             * the last member of the SSBO definition.
239b8e80941Smrg             */
240b8e80941Smrg            ir_variable *var = array->variable_referenced();
241b8e80941Smrg            const glsl_type *iface_type = var->get_interface_type();
242b8e80941Smrg            int field_index = iface_type->field_index(var->name);
243b8e80941Smrg            /* Field index can be < 0 for instance arrays */
244b8e80941Smrg            if (field_index >= 0 &&
245b8e80941Smrg                field_index != (int) iface_type->length - 1) {
246b8e80941Smrg               _mesa_glsl_error(&loc, state, "Indirect access on unsized "
247b8e80941Smrg                                "array is limited to the last member of "
248b8e80941Smrg                                "SSBO.");
249b8e80941Smrg            }
250b8e80941Smrg         }
251b8e80941Smrg      } else if (array->type->without_array()->is_interface()
252b8e80941Smrg                 && ((array->variable_referenced()->data.mode == ir_var_uniform
253b8e80941Smrg                      && !state->is_version(400, 320)
254b8e80941Smrg                      && !state->ARB_gpu_shader5_enable
255b8e80941Smrg                      && !state->EXT_gpu_shader5_enable
256b8e80941Smrg                      && !state->OES_gpu_shader5_enable) ||
257b8e80941Smrg                     (array->variable_referenced()->data.mode == ir_var_shader_storage
258b8e80941Smrg                      && !state->is_version(400, 0)
259b8e80941Smrg                      && !state->ARB_gpu_shader5_enable))) {
260b8e80941Smrg         /* Page 50 in section 4.3.9 of the OpenGL ES 3.10 spec says:
261b8e80941Smrg          *
262b8e80941Smrg          *     "All indices used to index a uniform or shader storage block
263b8e80941Smrg          *     array must be constant integral expressions."
264b8e80941Smrg          *
265b8e80941Smrg          * But OES_gpu_shader5 (and ESSL 3.20) relax this to allow indexing
266b8e80941Smrg          * on uniform blocks but not shader storage blocks.
267b8e80941Smrg          *
268b8e80941Smrg          */
269b8e80941Smrg         _mesa_glsl_error(&loc, state, "%s block array index must be constant",
270b8e80941Smrg                          array->variable_referenced()->data.mode
271b8e80941Smrg                          == ir_var_uniform ? "uniform" : "shader storage");
272b8e80941Smrg      } else {
273b8e80941Smrg         /* whole_variable_referenced can return NULL if the array is a
274b8e80941Smrg          * member of a structure.  In this case it is safe to not update
275b8e80941Smrg          * the max_array_access field because it is never used for fields
276b8e80941Smrg          * of structures.
277b8e80941Smrg          */
278b8e80941Smrg         ir_variable *v = array->whole_variable_referenced();
279b8e80941Smrg         if (v != NULL)
280b8e80941Smrg            v->data.max_array_access = array->type->array_size() - 1;
281b8e80941Smrg      }
282b8e80941Smrg
283b8e80941Smrg      /* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
284b8e80941Smrg       *
285b8e80941Smrg       *    "Samplers aggregated into arrays within a shader (using square
286b8e80941Smrg       *    brackets [ ]) can only be indexed with integral constant
287b8e80941Smrg       *    expressions [...]."
288b8e80941Smrg       *
289b8e80941Smrg       * This restriction was added in GLSL 1.30.  Shaders using earlier
290b8e80941Smrg       * version of the language should not be rejected by the compiler
291b8e80941Smrg       * front-end for using this construct.  This allows useful things such
292b8e80941Smrg       * as using a loop counter as the index to an array of samplers.  If the
293b8e80941Smrg       * loop in unrolled, the code should compile correctly.  Instead, emit a
294b8e80941Smrg       * warning.
295b8e80941Smrg       *
296b8e80941Smrg       * In GLSL 4.00 / ARB_gpu_shader5, this requirement is relaxed again to allow
297b8e80941Smrg       * indexing with dynamically uniform expressions. Note that these are not
298b8e80941Smrg       * required to be uniforms or expressions based on them, but merely that the
299b8e80941Smrg       * values must not diverge between shader invocations run together. If the
300b8e80941Smrg       * values *do* diverge, then the behavior of the operation requiring a
301b8e80941Smrg       * dynamically uniform expression is undefined.
302b8e80941Smrg       *
303b8e80941Smrg       * From section 4.1.7 of the ARB_bindless_texture spec:
304b8e80941Smrg       *
305b8e80941Smrg       *    "Samplers aggregated into arrays within a shader (using square
306b8e80941Smrg       *    brackets []) can be indexed with arbitrary integer expressions."
307b8e80941Smrg       */
308b8e80941Smrg      if (array->type->without_array()->is_sampler()) {
309b8e80941Smrg         if (!state->is_version(400, 320) &&
310b8e80941Smrg             !state->ARB_gpu_shader5_enable &&
311b8e80941Smrg             !state->EXT_gpu_shader5_enable &&
312b8e80941Smrg             !state->OES_gpu_shader5_enable &&
313b8e80941Smrg             !state->has_bindless()) {
314b8e80941Smrg            if (state->is_version(130, 300))
315b8e80941Smrg               _mesa_glsl_error(&loc, state,
316b8e80941Smrg                                "sampler arrays indexed with non-constant "
317b8e80941Smrg                                "expressions are forbidden in GLSL %s "
318b8e80941Smrg                                "and later",
319b8e80941Smrg                                state->es_shader ? "ES 3.00" : "1.30");
320b8e80941Smrg            else if (state->es_shader)
321b8e80941Smrg               _mesa_glsl_warning(&loc, state,
322b8e80941Smrg                                  "sampler arrays indexed with non-constant "
323b8e80941Smrg                                  "expressions will be forbidden in GLSL "
324b8e80941Smrg                                  "3.00 and later");
325b8e80941Smrg            else
326b8e80941Smrg               _mesa_glsl_warning(&loc, state,
327b8e80941Smrg                                  "sampler arrays indexed with non-constant "
328b8e80941Smrg                                  "expressions will be forbidden in GLSL "
329b8e80941Smrg                                  "1.30 and later");
330b8e80941Smrg         }
331b8e80941Smrg      }
332b8e80941Smrg
333b8e80941Smrg      /* From page 27 of the GLSL ES 3.1 specification:
334b8e80941Smrg       *
335b8e80941Smrg       * "When aggregated into arrays within a shader, images can only be
336b8e80941Smrg       *  indexed with a constant integral expression."
337b8e80941Smrg       *
338b8e80941Smrg       * On the other hand the desktop GL specification extension allows
339b8e80941Smrg       * non-constant indexing of image arrays, but behavior is left undefined
340b8e80941Smrg       * in cases where the indexing expression is not dynamically uniform.
341b8e80941Smrg       */
342b8e80941Smrg      if (state->es_shader && array->type->without_array()->is_image()) {
343b8e80941Smrg         _mesa_glsl_error(&loc, state,
344b8e80941Smrg                          "image arrays indexed with non-constant "
345b8e80941Smrg                          "expressions are forbidden in GLSL ES.");
346b8e80941Smrg      }
347b8e80941Smrg   }
348b8e80941Smrg
349b8e80941Smrg   /* After performing all of the error checking, generate the IR for the
350b8e80941Smrg    * expression.
351b8e80941Smrg    */
352b8e80941Smrg   if (array->type->is_array()
353b8e80941Smrg       || array->type->is_matrix()
354b8e80941Smrg       || array->type->is_vector()) {
355b8e80941Smrg      return new(mem_ctx) ir_dereference_array(array, idx);
356b8e80941Smrg   } else if (array->type->is_error()) {
357b8e80941Smrg      return array;
358b8e80941Smrg   } else {
359b8e80941Smrg      ir_rvalue *result = new(mem_ctx) ir_dereference_array(array, idx);
360b8e80941Smrg      result->type = glsl_type::error_type;
361b8e80941Smrg
362b8e80941Smrg      return result;
363b8e80941Smrg   }
364b8e80941Smrg}
365