101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2010 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "ast.h" 2501e04c3fSmrg#include "compiler/glsl_types.h" 2601e04c3fSmrg#include "ir.h" 2701e04c3fSmrg 2801e04c3fSmrgvoid 2901e04c3fSmrgast_array_specifier::print(void) const 3001e04c3fSmrg{ 3101e04c3fSmrg foreach_list_typed (ast_node, array_dimension, link, &this->array_dimensions) { 3201e04c3fSmrg printf("[ "); 3301e04c3fSmrg if (((ast_expression*)array_dimension)->oper != ast_unsized_array_dim) 3401e04c3fSmrg array_dimension->print(); 3501e04c3fSmrg printf("] "); 3601e04c3fSmrg } 3701e04c3fSmrg} 3801e04c3fSmrg 3901e04c3fSmrg/** 4001e04c3fSmrg * If \c ir is a reference to an array for which we are tracking the max array 4101e04c3fSmrg * element accessed, track that the given element has been accessed. 4201e04c3fSmrg * Otherwise do nothing. 4301e04c3fSmrg * 4401e04c3fSmrg * This function also checks whether the array is a built-in array whose 4501e04c3fSmrg * maximum size is too small to accommodate the given index, and if so uses 4601e04c3fSmrg * loc and state to report the error. 4701e04c3fSmrg */ 4801e04c3fSmrgstatic void 4901e04c3fSmrgupdate_max_array_access(ir_rvalue *ir, int idx, YYLTYPE *loc, 5001e04c3fSmrg struct _mesa_glsl_parse_state *state) 5101e04c3fSmrg{ 5201e04c3fSmrg if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) { 5301e04c3fSmrg ir_variable *var = deref_var->var; 5401e04c3fSmrg if (idx > (int)var->data.max_array_access) { 5501e04c3fSmrg var->data.max_array_access = idx; 5601e04c3fSmrg 5701e04c3fSmrg /* Check whether this access will, as a side effect, implicitly cause 5801e04c3fSmrg * the size of a built-in array to be too large. 5901e04c3fSmrg */ 6001e04c3fSmrg check_builtin_array_max_size(var->name, idx+1, *loc, state); 6101e04c3fSmrg } 6201e04c3fSmrg } else if (ir_dereference_record *deref_record = 6301e04c3fSmrg ir->as_dereference_record()) { 6401e04c3fSmrg /* There are three possibilities we need to consider: 6501e04c3fSmrg * 6601e04c3fSmrg * - Accessing an element of an array that is a member of a named 6701e04c3fSmrg * interface block (e.g. ifc.foo[i]) 6801e04c3fSmrg * 6901e04c3fSmrg * - Accessing an element of an array that is a member of a named 7001e04c3fSmrg * interface block array (e.g. ifc[j].foo[i]). 7101e04c3fSmrg * 7201e04c3fSmrg * - Accessing an element of an array that is a member of a named 7301e04c3fSmrg * interface block array of arrays (e.g. ifc[j][k].foo[i]). 7401e04c3fSmrg */ 7501e04c3fSmrg ir_dereference_variable *deref_var = 7601e04c3fSmrg deref_record->record->as_dereference_variable(); 7701e04c3fSmrg if (deref_var == NULL) { 7801e04c3fSmrg ir_dereference_array *deref_array = 7901e04c3fSmrg deref_record->record->as_dereference_array(); 8001e04c3fSmrg ir_dereference_array *deref_array_prev = NULL; 8101e04c3fSmrg while (deref_array != NULL) { 8201e04c3fSmrg deref_array_prev = deref_array; 8301e04c3fSmrg deref_array = deref_array->array->as_dereference_array(); 8401e04c3fSmrg } 8501e04c3fSmrg if (deref_array_prev != NULL) 8601e04c3fSmrg deref_var = deref_array_prev->array->as_dereference_variable(); 8701e04c3fSmrg } 8801e04c3fSmrg 8901e04c3fSmrg if (deref_var != NULL) { 9001e04c3fSmrg if (deref_var->var->is_interface_instance()) { 9101e04c3fSmrg unsigned field_idx = deref_record->field_idx; 9201e04c3fSmrg assert(field_idx < deref_var->var->get_interface_type()->length); 9301e04c3fSmrg 9401e04c3fSmrg int *const max_ifc_array_access = 9501e04c3fSmrg deref_var->var->get_max_ifc_array_access(); 9601e04c3fSmrg 9701e04c3fSmrg assert(max_ifc_array_access != NULL); 9801e04c3fSmrg 9901e04c3fSmrg if (idx > max_ifc_array_access[field_idx]) { 10001e04c3fSmrg max_ifc_array_access[field_idx] = idx; 10101e04c3fSmrg 10201e04c3fSmrg /* Check whether this access will, as a side effect, implicitly 10301e04c3fSmrg * cause the size of a built-in array to be too large. 10401e04c3fSmrg */ 10501e04c3fSmrg const char *field_name = 10601e04c3fSmrg deref_record->record->type->fields.structure[field_idx].name; 10701e04c3fSmrg check_builtin_array_max_size(field_name, idx+1, *loc, state); 10801e04c3fSmrg } 10901e04c3fSmrg } 11001e04c3fSmrg } 11101e04c3fSmrg } 11201e04c3fSmrg} 11301e04c3fSmrg 11401e04c3fSmrg 11501e04c3fSmrgstatic int 11601e04c3fSmrgget_implicit_array_size(struct _mesa_glsl_parse_state *state, 11701e04c3fSmrg ir_rvalue *array) 11801e04c3fSmrg{ 11901e04c3fSmrg ir_variable *var = array->variable_referenced(); 12001e04c3fSmrg 12101e04c3fSmrg /* Inputs in control shader are implicitly sized 12201e04c3fSmrg * to the maximum patch size. 12301e04c3fSmrg */ 12401e04c3fSmrg if (state->stage == MESA_SHADER_TESS_CTRL && 12501e04c3fSmrg var->data.mode == ir_var_shader_in) { 12601e04c3fSmrg return state->Const.MaxPatchVertices; 12701e04c3fSmrg } 12801e04c3fSmrg 12901e04c3fSmrg /* Non-patch inputs in evaluation shader are implicitly sized 13001e04c3fSmrg * to the maximum patch size. 13101e04c3fSmrg */ 13201e04c3fSmrg if (state->stage == MESA_SHADER_TESS_EVAL && 13301e04c3fSmrg var->data.mode == ir_var_shader_in && 13401e04c3fSmrg !var->data.patch) { 13501e04c3fSmrg return state->Const.MaxPatchVertices; 13601e04c3fSmrg } 13701e04c3fSmrg 13801e04c3fSmrg return 0; 13901e04c3fSmrg} 14001e04c3fSmrg 14101e04c3fSmrg 14201e04c3fSmrgir_rvalue * 14301e04c3fSmrg_mesa_ast_array_index_to_hir(void *mem_ctx, 14401e04c3fSmrg struct _mesa_glsl_parse_state *state, 14501e04c3fSmrg ir_rvalue *array, ir_rvalue *idx, 14601e04c3fSmrg YYLTYPE &loc, YYLTYPE &idx_loc) 14701e04c3fSmrg{ 14801e04c3fSmrg if (!array->type->is_error() 14901e04c3fSmrg && !array->type->is_array() 15001e04c3fSmrg && !array->type->is_matrix() 15101e04c3fSmrg && !array->type->is_vector()) { 15201e04c3fSmrg _mesa_glsl_error(& idx_loc, state, 15301e04c3fSmrg "cannot dereference non-array / non-matrix / " 15401e04c3fSmrg "non-vector"); 15501e04c3fSmrg } 15601e04c3fSmrg 15701e04c3fSmrg if (!idx->type->is_error()) { 1587ec681f3Smrg if (!idx->type->is_integer_32()) { 15901e04c3fSmrg _mesa_glsl_error(& idx_loc, state, "array index must be integer type"); 16001e04c3fSmrg } else if (!idx->type->is_scalar()) { 16101e04c3fSmrg _mesa_glsl_error(& idx_loc, state, "array index must be scalar"); 16201e04c3fSmrg } 16301e04c3fSmrg } 16401e04c3fSmrg 16501e04c3fSmrg /* If the array index is a constant expression and the array has a 16601e04c3fSmrg * declared size, ensure that the access is in-bounds. If the array 16701e04c3fSmrg * index is not a constant expression, ensure that the array has a 16801e04c3fSmrg * declared size. 16901e04c3fSmrg */ 17001e04c3fSmrg ir_constant *const const_index = idx->constant_expression_value(mem_ctx); 1717ec681f3Smrg if (const_index != NULL && idx->type->is_integer_32()) { 17201e04c3fSmrg const int idx = const_index->value.i[0]; 17301e04c3fSmrg const char *type_name = "error"; 17401e04c3fSmrg unsigned bound = 0; 17501e04c3fSmrg 17601e04c3fSmrg /* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec: 17701e04c3fSmrg * 17801e04c3fSmrg * "It is illegal to declare an array with a size, and then 17901e04c3fSmrg * later (in the same shader) index the same array with an 18001e04c3fSmrg * integral constant expression greater than or equal to the 18101e04c3fSmrg * declared size. It is also illegal to index an array with a 18201e04c3fSmrg * negative constant expression." 18301e04c3fSmrg */ 18401e04c3fSmrg if (array->type->is_matrix()) { 18501e04c3fSmrg if (array->type->row_type()->vector_elements <= idx) { 18601e04c3fSmrg type_name = "matrix"; 18701e04c3fSmrg bound = array->type->row_type()->vector_elements; 18801e04c3fSmrg } 18901e04c3fSmrg } else if (array->type->is_vector()) { 19001e04c3fSmrg if (array->type->vector_elements <= idx) { 19101e04c3fSmrg type_name = "vector"; 19201e04c3fSmrg bound = array->type->vector_elements; 19301e04c3fSmrg } 19401e04c3fSmrg } else { 19501e04c3fSmrg /* glsl_type::array_size() returns -1 for non-array types. This means 19601e04c3fSmrg * that we don't need to verify that the type is an array before 19701e04c3fSmrg * doing the bounds checking. 19801e04c3fSmrg */ 19901e04c3fSmrg if ((array->type->array_size() > 0) 20001e04c3fSmrg && (array->type->array_size() <= idx)) { 20101e04c3fSmrg type_name = "array"; 20201e04c3fSmrg bound = array->type->array_size(); 20301e04c3fSmrg } 20401e04c3fSmrg } 20501e04c3fSmrg 20601e04c3fSmrg if (bound > 0) { 20701e04c3fSmrg _mesa_glsl_error(& loc, state, "%s index must be < %u", 20801e04c3fSmrg type_name, bound); 20901e04c3fSmrg } else if (idx < 0) { 21001e04c3fSmrg _mesa_glsl_error(& loc, state, "%s index must be >= 0", type_name); 21101e04c3fSmrg } 21201e04c3fSmrg 21301e04c3fSmrg if (array->type->is_array()) 21401e04c3fSmrg update_max_array_access(array, idx, &loc, state); 21501e04c3fSmrg } else if (const_index == NULL && array->type->is_array()) { 21601e04c3fSmrg if (array->type->is_unsized_array()) { 21701e04c3fSmrg int implicit_size = get_implicit_array_size(state, array); 21801e04c3fSmrg if (implicit_size) { 21901e04c3fSmrg ir_variable *v = array->whole_variable_referenced(); 22001e04c3fSmrg if (v != NULL) 22101e04c3fSmrg v->data.max_array_access = implicit_size - 1; 22201e04c3fSmrg } 22301e04c3fSmrg else if (state->stage == MESA_SHADER_TESS_CTRL && 22401e04c3fSmrg array->variable_referenced()->data.mode == ir_var_shader_out && 22501e04c3fSmrg !array->variable_referenced()->data.patch) { 22601e04c3fSmrg /* Tessellation control shader output non-patch arrays are 22701e04c3fSmrg * initially unsized. Despite that, they are allowed to be 22801e04c3fSmrg * indexed with a non-constant expression (typically 22901e04c3fSmrg * "gl_InvocationID"). The array size will be determined 23001e04c3fSmrg * by the linker. 23101e04c3fSmrg */ 23201e04c3fSmrg } 23301e04c3fSmrg else if (array->variable_referenced()->data.mode != 23401e04c3fSmrg ir_var_shader_storage) { 23501e04c3fSmrg _mesa_glsl_error(&loc, state, "unsized array index must be constant"); 23601e04c3fSmrg } else { 23701e04c3fSmrg /* Unsized array non-constant indexing on SSBO is allowed only for 23801e04c3fSmrg * the last member of the SSBO definition. 23901e04c3fSmrg */ 24001e04c3fSmrg ir_variable *var = array->variable_referenced(); 24101e04c3fSmrg const glsl_type *iface_type = var->get_interface_type(); 24201e04c3fSmrg int field_index = iface_type->field_index(var->name); 24301e04c3fSmrg /* Field index can be < 0 for instance arrays */ 24401e04c3fSmrg if (field_index >= 0 && 24501e04c3fSmrg field_index != (int) iface_type->length - 1) { 24601e04c3fSmrg _mesa_glsl_error(&loc, state, "Indirect access on unsized " 24701e04c3fSmrg "array is limited to the last member of " 24801e04c3fSmrg "SSBO."); 24901e04c3fSmrg } 25001e04c3fSmrg } 25101e04c3fSmrg } else if (array->type->without_array()->is_interface() 25201e04c3fSmrg && ((array->variable_referenced()->data.mode == ir_var_uniform 25301e04c3fSmrg && !state->is_version(400, 320) 25401e04c3fSmrg && !state->ARB_gpu_shader5_enable 25501e04c3fSmrg && !state->EXT_gpu_shader5_enable 25601e04c3fSmrg && !state->OES_gpu_shader5_enable) || 25701e04c3fSmrg (array->variable_referenced()->data.mode == ir_var_shader_storage 25801e04c3fSmrg && !state->is_version(400, 0) 25901e04c3fSmrg && !state->ARB_gpu_shader5_enable))) { 26001e04c3fSmrg /* Page 50 in section 4.3.9 of the OpenGL ES 3.10 spec says: 26101e04c3fSmrg * 26201e04c3fSmrg * "All indices used to index a uniform or shader storage block 26301e04c3fSmrg * array must be constant integral expressions." 26401e04c3fSmrg * 26501e04c3fSmrg * But OES_gpu_shader5 (and ESSL 3.20) relax this to allow indexing 26601e04c3fSmrg * on uniform blocks but not shader storage blocks. 26701e04c3fSmrg * 26801e04c3fSmrg */ 26901e04c3fSmrg _mesa_glsl_error(&loc, state, "%s block array index must be constant", 27001e04c3fSmrg array->variable_referenced()->data.mode 27101e04c3fSmrg == ir_var_uniform ? "uniform" : "shader storage"); 27201e04c3fSmrg } else { 27301e04c3fSmrg /* whole_variable_referenced can return NULL if the array is a 27401e04c3fSmrg * member of a structure. In this case it is safe to not update 27501e04c3fSmrg * the max_array_access field because it is never used for fields 27601e04c3fSmrg * of structures. 27701e04c3fSmrg */ 27801e04c3fSmrg ir_variable *v = array->whole_variable_referenced(); 27901e04c3fSmrg if (v != NULL) 28001e04c3fSmrg v->data.max_array_access = array->type->array_size() - 1; 28101e04c3fSmrg } 28201e04c3fSmrg 28301e04c3fSmrg /* From page 23 (29 of the PDF) of the GLSL 1.30 spec: 28401e04c3fSmrg * 28501e04c3fSmrg * "Samplers aggregated into arrays within a shader (using square 28601e04c3fSmrg * brackets [ ]) can only be indexed with integral constant 28701e04c3fSmrg * expressions [...]." 28801e04c3fSmrg * 28901e04c3fSmrg * This restriction was added in GLSL 1.30. Shaders using earlier 29001e04c3fSmrg * version of the language should not be rejected by the compiler 29101e04c3fSmrg * front-end for using this construct. This allows useful things such 29201e04c3fSmrg * as using a loop counter as the index to an array of samplers. If the 29301e04c3fSmrg * loop in unrolled, the code should compile correctly. Instead, emit a 29401e04c3fSmrg * warning. 29501e04c3fSmrg * 29601e04c3fSmrg * In GLSL 4.00 / ARB_gpu_shader5, this requirement is relaxed again to allow 29701e04c3fSmrg * indexing with dynamically uniform expressions. Note that these are not 29801e04c3fSmrg * required to be uniforms or expressions based on them, but merely that the 29901e04c3fSmrg * values must not diverge between shader invocations run together. If the 30001e04c3fSmrg * values *do* diverge, then the behavior of the operation requiring a 30101e04c3fSmrg * dynamically uniform expression is undefined. 30201e04c3fSmrg * 30301e04c3fSmrg * From section 4.1.7 of the ARB_bindless_texture spec: 30401e04c3fSmrg * 30501e04c3fSmrg * "Samplers aggregated into arrays within a shader (using square 30601e04c3fSmrg * brackets []) can be indexed with arbitrary integer expressions." 30701e04c3fSmrg */ 30801e04c3fSmrg if (array->type->without_array()->is_sampler()) { 30901e04c3fSmrg if (!state->is_version(400, 320) && 31001e04c3fSmrg !state->ARB_gpu_shader5_enable && 31101e04c3fSmrg !state->EXT_gpu_shader5_enable && 31201e04c3fSmrg !state->OES_gpu_shader5_enable && 31301e04c3fSmrg !state->has_bindless()) { 31401e04c3fSmrg if (state->is_version(130, 300)) 31501e04c3fSmrg _mesa_glsl_error(&loc, state, 31601e04c3fSmrg "sampler arrays indexed with non-constant " 31701e04c3fSmrg "expressions are forbidden in GLSL %s " 31801e04c3fSmrg "and later", 31901e04c3fSmrg state->es_shader ? "ES 3.00" : "1.30"); 32001e04c3fSmrg else if (state->es_shader) 32101e04c3fSmrg _mesa_glsl_warning(&loc, state, 32201e04c3fSmrg "sampler arrays indexed with non-constant " 32301e04c3fSmrg "expressions will be forbidden in GLSL " 32401e04c3fSmrg "3.00 and later"); 32501e04c3fSmrg else 32601e04c3fSmrg _mesa_glsl_warning(&loc, state, 32701e04c3fSmrg "sampler arrays indexed with non-constant " 32801e04c3fSmrg "expressions will be forbidden in GLSL " 32901e04c3fSmrg "1.30 and later"); 33001e04c3fSmrg } 33101e04c3fSmrg } 33201e04c3fSmrg 33301e04c3fSmrg /* From page 27 of the GLSL ES 3.1 specification: 33401e04c3fSmrg * 33501e04c3fSmrg * "When aggregated into arrays within a shader, images can only be 33601e04c3fSmrg * indexed with a constant integral expression." 33701e04c3fSmrg * 33801e04c3fSmrg * On the other hand the desktop GL specification extension allows 33901e04c3fSmrg * non-constant indexing of image arrays, but behavior is left undefined 34001e04c3fSmrg * in cases where the indexing expression is not dynamically uniform. 34101e04c3fSmrg */ 34201e04c3fSmrg if (state->es_shader && array->type->without_array()->is_image()) { 34301e04c3fSmrg _mesa_glsl_error(&loc, state, 34401e04c3fSmrg "image arrays indexed with non-constant " 34501e04c3fSmrg "expressions are forbidden in GLSL ES."); 34601e04c3fSmrg } 34701e04c3fSmrg } 34801e04c3fSmrg 34901e04c3fSmrg /* After performing all of the error checking, generate the IR for the 35001e04c3fSmrg * expression. 35101e04c3fSmrg */ 35201e04c3fSmrg if (array->type->is_array() 35301e04c3fSmrg || array->type->is_matrix() 35401e04c3fSmrg || array->type->is_vector()) { 35501e04c3fSmrg return new(mem_ctx) ir_dereference_array(array, idx); 35601e04c3fSmrg } else if (array->type->is_error()) { 35701e04c3fSmrg return array; 35801e04c3fSmrg } else { 35901e04c3fSmrg ir_rvalue *result = new(mem_ctx) ir_dereference_array(array, idx); 36001e04c3fSmrg result->type = glsl_type::error_type; 36101e04c3fSmrg 36201e04c3fSmrg return result; 36301e04c3fSmrg } 36401e04c3fSmrg} 365