#include "ast.h"
#include "compiler/glsl_types.h"
#include "util/hash_table.h"
+#include "main/mtypes.h"
#include "main/macros.h"
#include "main/shaderobj.h"
#include "ir.h"
static void
detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
exec_list *instructions);
+static void
+verify_subroutine_associated_funcs(struct _mesa_glsl_parse_state *state);
+
static void
remove_per_vertex_blocks(exec_list *instructions,
_mesa_glsl_parse_state *state, ir_variable_mode mode);
foreach_list_typed (ast_node, ast, link, & state->translation_unit)
ast->hir(instructions, state);
+ verify_subroutine_associated_funcs(state);
detect_recursion_unlinked(state, instructions);
detect_conflicting_assignments(state, instructions);
}
case GLSL_TYPE_UINT:
- if (!state->is_version(400, 0) && !state->ARB_gpu_shader5_enable
- && !state->MESA_shader_integer_functions_enable)
+ if (!state->has_implicit_int_to_uint_conversion())
return (ir_expression_operation)0;
switch (from->base_type) {
case GLSL_TYPE_INT: return ir_unop_i2u;
return true;
/* Prior to GLSL 1.20, there are no implicit conversions */
- if (!state->is_version(120, 0))
- return false;
-
- /* ESSL does not allow implicit conversions */
- if (state->es_shader)
+ if (!state->has_implicit_conversions())
return false;
/* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec:
const glsl_type *type_a = value_a->type;
const glsl_type *type_b = value_b->type;
- if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) {
+ if (!state->EXT_gpu_shader4_enable &&
+ !state->check_version(130, 300, loc, "operator '%%' is reserved")) {
return glsl_type::error_type;
}
return glsl_type::error_type;
}
- if (!type_b->is_integer()) {
+ if (!type_b->is_integer_32()) {
_mesa_glsl_error(loc, state, "RHS of operator %s must be an integer or "
"integer vector", ast_expression::operator_string(op));
return glsl_type::error_type;
}
if (unsized_array) {
if (is_initializer) {
- return rhs;
+ if (rhs->type->get_scalar_type() == lhs->type->get_scalar_type())
+ return rhs;
} else {
_mesa_glsl_error(&loc, state,
"implicitly sized arrays cannot be assigned");
lhs_var->name);
error_emitted = true;
} else if (lhs->type->is_array() &&
- !state->check_version(120, 300, &lhs_loc,
+ !state->check_version(state->allow_glsl_120_subset_in_110 ? 110 : 120,
+ 300, &lhs_loc,
"whole array assignment forbidden")) {
/* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec:
*
mark_whole_array_access(rhs);
mark_whole_array_access(lhs);
}
+ } else {
+ error_emitted = true;
}
/* Most callers of do_assignment (assign, add_assign, pre_inc/dec,
case GLSL_TYPE_INT64:
case GLSL_TYPE_UINT16:
case GLSL_TYPE_INT16:
+ case GLSL_TYPE_UINT8:
+ case GLSL_TYPE_INT8:
return new(mem_ctx) ir_expression(operation, op0, op1);
case GLSL_TYPE_ARRAY: {
switch (this->oper) {
case ast_aggregate:
- assert(!"ast_aggregate: Should never get here.");
- break;
+ unreachable("ast_aggregate: Should never get here.");
case ast_assign: {
this->subexpressions[0]->set_is_lhs(true);
if (rhs_instructions.is_empty()) {
result = new(ctx) ir_expression(ir_binop_logic_and, op[0], op[1]);
- type = result->type;
} else {
ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
"and_tmp",
stmt->else_instructions.push_tail(else_assign);
result = new(ctx) ir_dereference_variable(tmp);
- type = tmp->type;
}
break;
}
if (rhs_instructions.is_empty()) {
result = new(ctx) ir_expression(ir_binop_logic_or, op[0], op[1]);
- type = result->type;
} else {
ir_variable *const tmp = new(ctx) ir_variable(glsl_type::bool_type,
"or_tmp",
stmt->else_instructions.push_tail(else_assign);
result = new(ctx) ir_dereference_variable(tmp);
- type = tmp->type;
}
break;
}
op[1] = this->subexpressions[1]->hir(instructions, state);
orig_type = op[0]->type;
+
+ /* Break out if operand types were not parsed successfully. */
+ if ((op[0]->type == glsl_type::error_type ||
+ op[1]->type == glsl_type::error_type)) {
+ error_emitted = true;
+ break;
+ }
+
type = arithmetic_result_type(op[0], op[1],
(this->oper == ast_mul_assign),
state, & loc);
* expressions; such use results in a compile-time error."
*/
if (type->contains_opaque()) {
- _mesa_glsl_error(&loc, state, "opaque variables cannot be operands "
- "of the ?: operator");
- error_emitted = true;
+ if (!(state->has_bindless() && (type->is_image() || type->is_sampler()))) {
+ _mesa_glsl_error(&loc, state, "variables of type %s cannot be "
+ "operands of the ?: operator", type->name);
+ error_emitted = true;
+ }
}
ir_constant *cond_val = op[0]->constant_expression_value(ctx);
error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
+ if (error_emitted) {
+ result = ir_rvalue::error_value(ctx);
+ break;
+ }
+
type = arithmetic_result_type(op[0], op[1], false, state, & loc);
ir_rvalue *temp_rhs;
}
case ast_unsized_array_dim:
- assert(!"ast_unsized_array_dim: Should never get here.");
- break;
+ unreachable("ast_unsized_array_dim: Should never get here.");
case ast_function_call:
/* Should *NEVER* get here. ast_function_call should always be handled
* by ast_function_expression::hir.
*/
- assert(0);
- break;
+ unreachable("ast_function_call: handled elsewhere ");
case ast_identifier: {
/* ast_identifier can appear several places in a full abstract syntax
_mesa_glsl_warning(&loc, state, "`%s' used uninitialized",
this->primary_expression.identifier);
}
+
+ /* From the EXT_shader_framebuffer_fetch spec:
+ *
+ * "Unless the GL_EXT_shader_framebuffer_fetch extension has been
+ * enabled in addition, it's an error to use gl_LastFragData if it
+ * hasn't been explicitly redeclared with layout(noncoherent)."
+ */
+ if (var->data.fb_fetch_output && var->data.memory_coherent &&
+ !state->EXT_shader_framebuffer_fetch_enable) {
+ _mesa_glsl_error(&loc, state,
+ "invalid use of framebuffer fetch output not "
+ "qualified with layout(noncoherent)");
+ }
+
} else {
_mesa_glsl_error(& loc, state, "`%s' undeclared",
this->primary_expression.identifier);
}
}
type = NULL; /* use result->type, not type. */
- assert(result != NULL || !needs_rvalue);
+ assert(error_emitted || (result != NULL || !needs_rvalue));
if (result && result->type->is_error() && !error_emitted)
_mesa_glsl_error(& loc, state, "type mismatch");
return 0;
}
- if (!ir->type->is_integer()) {
+ if (!ir->type->is_integer_32()) {
_mesa_glsl_error(& loc, state,
"array size must be integer type");
return 0;
*/
const glsl_type *const t = type->without_array();
- return (t->is_float() || t->is_integer() || t->contains_opaque()) &&
- !t->is_record();
+ return (t->is_float() || t->is_integer_32() || t->contains_opaque()) &&
+ !t->is_struct();
}
const glsl_type *
case MESA_SHADER_VERTEX:
return var->data.mode == ir_var_shader_out;
case MESA_SHADER_FRAGMENT:
- return var->data.mode == ir_var_shader_in;
+ return var->data.mode == ir_var_shader_in ||
+ (var->data.mode == ir_var_system_value &&
+ var->data.location == SYSTEM_VALUE_FRAG_COORD);
default:
return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in;
}
* "Only variables output from a vertex shader can be candidates
* for invariance".
*/
- if (!state->is_version(130, 0))
+ if (!state->is_version(130, 100))
return false;
/*
/* Make sure nested structs don't contain unsized arrays, and validate
* any xfb_offsets on interface members.
*/
- if (t_without_array->is_record() || t_without_array->is_interface())
+ if (t_without_array->is_struct() || t_without_array->is_interface())
for (unsigned int i = 0; i < t_without_array->length; i++) {
const glsl_type *member_t = t_without_array->fields.structure[i].type;
* reasonable way to interpolate a fragment shader input that contains
* an integer. See Khronos bug #15671.
*/
- if (state->is_version(130, 300)
+ if ((state->is_version(130, 300) || state->EXT_gpu_shader4_enable)
&& var_type->contains_integer()) {
_mesa_glsl_error(loc, state, "if a fragment input is (or contains) "
"an integer, then it must be qualified with 'flat'");
* not apply to inputs into a vertex shader or outputs from a
* fragment shader."
*/
- if (state->is_version(130, 300)
+ if ((state->is_version(130, 300) || state->EXT_gpu_shader4_enable)
&& interpolation != INTERP_MODE_NONE) {
const char *i = interpolation_string(interpolation);
if (mode != ir_var_shader_in && mode != ir_var_shader_out)
* to the deprecated storage qualifiers varying or centroid varying."
*
* These deprecated storage qualifiers do not exist in GLSL ES 3.00.
+ *
+ * GL_EXT_gpu_shader4 allows this.
*/
- if (state->is_version(130, 0)
+ if (state->is_version(130, 0) && !state->EXT_gpu_shader4_enable
&& interpolation != INTERP_MODE_NONE
&& qual->flags.q.varying) {
}
var->data.image_format = qual->image_format;
+ } else if (state->has_image_load_formatted()) {
+ if (var->data.mode == ir_var_uniform &&
+ state->EXT_shader_image_load_formatted_warn) {
+ _mesa_glsl_warning(loc, state, "GL_EXT_image_load_formatted used");
+ }
} else {
if (var->data.mode == ir_var_uniform) {
- if (state->es_shader) {
+ if (state->es_shader ||
+ !(state->is_version(420, 310) || state->ARB_shader_image_load_store_enable)) {
_mesa_glsl_error(loc, state, "all image uniforms must have a "
"format layout qualifier");
} else if (!qual->flags.q.write_only) {
"`writeonly' must have a format layout qualifier");
}
}
- var->data.image_format = GL_NONE;
+ var->data.image_format = PIPE_FORMAT_NONE;
}
/* From page 70 of the GLSL ES 3.1 specification:
* readonly or the memory qualifier writeonly."
*/
if (state->es_shader &&
- var->data.image_format != GL_R32F &&
- var->data.image_format != GL_R32I &&
- var->data.image_format != GL_R32UI &&
+ var->data.image_format != PIPE_FORMAT_R32_FLOAT &&
+ var->data.image_format != PIPE_FORMAT_R32_SINT &&
+ var->data.image_format != PIPE_FORMAT_R32_UINT &&
!var->data.memory_read_only &&
!var->data.memory_write_only) {
_mesa_glsl_error(loc, state, "image variables of format other than r32f, "
return false;
}
+static inline bool
+is_conflicting_layer_redeclaration(struct _mesa_glsl_parse_state *state,
+ const struct ast_type_qualifier *qual)
+{
+ if (state->redeclares_gl_layer) {
+ return state->layer_viewport_relative != qual->flags.q.viewport_relative;
+ }
+ return false;
+}
+
static inline void
validate_array_dimensions(const glsl_type *t,
struct _mesa_glsl_parse_state *state,
state->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers;
}
- var->data.pixel_center_integer = qual->flags.q.pixel_center_integer;
- var->data.origin_upper_left = qual->flags.q.origin_upper_left;
if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
&& (strcmp(var->name, "gl_FragCoord") != 0)) {
const char *const qual_string = (qual->flags.q.origin_upper_left)
const glsl_type *type = var->type->without_array();
unsigned components = type->component_slots();
- if (type->is_matrix() || type->is_record()) {
+ if (type->is_matrix() || type->is_struct()) {
_mesa_glsl_error(loc, state, "component layout qualifier "
"cannot be applied to a matrix, a structure, "
"a block, or an array containing any of "
"these.");
+ } else if (components > 4 && type->is_64bit()) {
+ _mesa_glsl_error(loc, state, "component layout qualifier "
+ "cannot be applied to dvec%u.",
+ components / 2);
} else if (qual_component != 0 &&
(qual_component + components - 1) > 3) {
_mesa_glsl_error(loc, state, "component overflow (%u > 3)",
if (state->has_bindless())
apply_bindless_qualifier_to_variable(qual, var, state, loc);
+
+ if (qual->flags.q.pixel_interlock_ordered ||
+ qual->flags.q.pixel_interlock_unordered ||
+ qual->flags.q.sample_interlock_ordered ||
+ qual->flags.q.sample_interlock_unordered) {
+ _mesa_glsl_error(loc, state, "interlock layout qualifiers: "
+ "pixel_interlock_ordered, pixel_interlock_unordered, "
+ "sample_interlock_ordered and sample_interlock_unordered, "
+ "only valid in fragment shader input layout declaration.");
+ }
+
+ if (var->name != NULL && strcmp(var->name, "gl_Layer") == 0) {
+ if (is_conflicting_layer_redeclaration(state, qual)) {
+ _mesa_glsl_error(loc, state, "gl_Layer redeclaration with "
+ "different viewport_relative setting than earlier");
+ }
+ state->redeclares_gl_layer = 1;
+ if (qual->flags.q.viewport_relative) {
+ state->layer_viewport_relative = 1;
+ }
+ } else if (qual->flags.q.viewport_relative) {
+ _mesa_glsl_error(loc, state,
+ "viewport_relative qualifier "
+ "can only be applied to gl_Layer.");
+ }
}
static void
"`invariant' after being used",
var->name);
} else {
- var->data.invariant = 1;
+ var->data.explicit_invariant = true;
+ var->data.invariant = true;
}
}
else if (qual->flags.q.shared_storage)
var->data.mode = ir_var_shader_shared;
- var->data.fb_fetch_output = state->stage == MESA_SHADER_FRAGMENT &&
- qual->flags.q.in && qual->flags.q.out;
+ if (!is_parameter && state->has_framebuffer_fetch() &&
+ state->stage == MESA_SHADER_FRAGMENT) {
+ if (state->is_version(130, 300))
+ var->data.fb_fetch_output = qual->flags.q.in && qual->flags.q.out;
+ else
+ var->data.fb_fetch_output = (strcmp(var->name, "gl_LastFragData") == 0);
+ }
+
+ if (var->data.fb_fetch_output) {
+ var->data.assigned = true;
+ var->data.memory_coherent = !qual->flags.q.non_coherent;
+
+ /* From the EXT_shader_framebuffer_fetch spec:
+ *
+ * "It is an error to declare an inout fragment output not qualified
+ * with layout(noncoherent) if the GL_EXT_shader_framebuffer_fetch
+ * extension hasn't been enabled."
+ */
+ if (var->data.memory_coherent &&
+ !state->EXT_shader_framebuffer_fetch_enable)
+ _mesa_glsl_error(loc, state,
+ "invalid declaration of framebuffer fetch output not "
+ "qualified with layout(noncoherent)");
+
+ } else {
+ /* From the EXT_shader_framebuffer_fetch spec:
+ *
+ * "Fragment outputs declared inout may specify the following layout
+ * qualifier: [...] noncoherent"
+ */
+ if (qual->flags.q.non_coherent)
+ _mesa_glsl_error(loc, state,
+ "invalid layout(noncoherent) qualifier not part of "
+ "framebuffer fetch output declaration");
+ }
if (!is_parameter && is_varying_var(var, state->stage)) {
/* User-defined ins/outs are not permitted in compute shaders. */
break;
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
- if (state->is_version(130, 300))
+ if (state->is_version(130, 300) || state->EXT_gpu_shader4_enable)
break;
_mesa_glsl_error(loc, state,
"varying variables must be of base type float in %s",
}
}
- if (state->all_invariant && var->data.mode == ir_var_shader_out)
+ if (state->all_invariant && var->data.mode == ir_var_shader_out) {
+ var->data.explicit_invariant = true;
var->data.invariant = true;
+ }
var->data.interpolation =
interpret_interpolation_qualifier(qual, var->type,
*is_redeclaration = true;
+ if (earlier->data.how_declared == ir_var_declared_implicitly) {
+ /* Verify that the redeclaration of a built-in does not change the
+ * storage qualifier. There are a couple special cases.
+ *
+ * 1. Some built-in variables that are defined as 'in' in the
+ * specification are implemented as system values. Allow
+ * ir_var_system_value -> ir_var_shader_in.
+ *
+ * 2. gl_LastFragData is implemented as a ir_var_shader_out, but the
+ * specification requires that redeclarations omit any qualifier.
+ * Allow ir_var_shader_out -> ir_var_auto for this one variable.
+ */
+ if (earlier->data.mode != var->data.mode &&
+ !(earlier->data.mode == ir_var_system_value &&
+ var->data.mode == ir_var_shader_in) &&
+ !(strcmp(var->name, "gl_LastFragData") == 0 &&
+ var->data.mode == ir_var_auto)) {
+ _mesa_glsl_error(&loc, state,
+ "redeclaration cannot change qualification of `%s'",
+ var->name);
+ }
+ }
+
/* From page 24 (page 30 of the PDF) of the GLSL 1.50 spec,
*
* "It is legal to declare an array without a size and then
*/
if (earlier->type->is_unsized_array() && var->type->is_array()
&& (var->type->fields.array == earlier->type->fields.array)) {
- /* FINISHME: This doesn't match the qualifiers on the two
- * FINISHME: declarations. It's not 100% clear whether this is
- * FINISHME: required or not.
- */
-
const int size = var->type->array_size();
check_builtin_array_max_size(var->name, size, loc, state);
if ((size > 0) && (size <= earlier->data.max_array_access)) {
delete var;
var = NULL;
*var_ptr = NULL;
+ } else if (earlier->type != var->type) {
+ _mesa_glsl_error(&loc, state,
+ "redeclaration of `%s' has incorrect type",
+ var->name);
} else if ((state->ARB_fragment_coord_conventions_enable ||
state->is_version(150, 0))
- && strcmp(var->name, "gl_FragCoord") == 0
- && earlier->type == var->type
- && var->data.mode == ir_var_shader_in) {
+ && strcmp(var->name, "gl_FragCoord") == 0) {
/* Allow redeclaration of gl_FragCoord for ARB_fcc layout
* qualifiers.
+ *
+ * We don't really need to do anything here, just allow the
+ * redeclaration. Any error on the gl_FragCoord is handled on the ast
+ * level at apply_layout_qualifier_to_variable using the
+ * ast_type_qualifier and _mesa_glsl_parse_state, or later at
+ * linker.cpp.
*/
- earlier->data.origin_upper_left = var->data.origin_upper_left;
- earlier->data.pixel_center_integer = var->data.pixel_center_integer;
-
/* According to section 4.3.7 of the GLSL 1.30 spec,
* the following built-in varaibles can be redeclared with an
* interpolation qualifier:
|| strcmp(var->name, "gl_FrontSecondaryColor") == 0
|| strcmp(var->name, "gl_BackSecondaryColor") == 0
|| strcmp(var->name, "gl_Color") == 0
- || strcmp(var->name, "gl_SecondaryColor") == 0)
- && earlier->type == var->type
- && earlier->data.mode == var->data.mode) {
+ || strcmp(var->name, "gl_SecondaryColor") == 0)) {
earlier->data.interpolation = var->data.interpolation;
/* Layout qualifiers for gl_FragDepth. */
} else if ((state->is_version(420, 0) ||
state->AMD_conservative_depth_enable ||
state->ARB_conservative_depth_enable)
- && strcmp(var->name, "gl_FragDepth") == 0
- && earlier->type == var->type
- && earlier->data.mode == var->data.mode) {
+ && strcmp(var->name, "gl_FragDepth") == 0) {
/** From the AMD_conservative_depth spec:
* Within any shader, the first redeclarations of gl_FragDepth
} else if (state->has_framebuffer_fetch() &&
strcmp(var->name, "gl_LastFragData") == 0 &&
- var->type == earlier->type &&
var->data.mode == ir_var_auto) {
/* According to the EXT_shader_framebuffer_fetch spec:
*
* "By default, gl_LastFragData is declared with the mediump precision
* qualifier. This can be changed by redeclaring the corresponding
* variables with the desired precision qualifier."
+ *
+ * "Fragment shaders may specify the following layout qualifier only for
+ * redeclaring the built-in gl_LastFragData array [...]: noncoherent"
*/
earlier->data.precision = var->data.precision;
+ earlier->data.memory_coherent = var->data.memory_coherent;
+
+ } else if (state->NV_viewport_array2_enable &&
+ strcmp(var->name, "gl_Layer") == 0 &&
+ earlier->data.how_declared == ir_var_declared_implicitly) {
+ /* No need to do anything, just allow it. Qualifier is stored in state */
- } else if (earlier->data.how_declared == ir_var_declared_implicitly &&
- state->allow_builtin_variable_redeclaration) {
+ } else if ((earlier->data.how_declared == ir_var_declared_implicitly &&
+ state->allow_builtin_variable_redeclaration) ||
+ allow_all_redeclarations) {
/* Allow verbatim redeclarations of built-in variables. Not explicitly
* valid, but some applications do it.
*/
- if (earlier->data.mode != var->data.mode &&
- !(earlier->data.mode == ir_var_system_value &&
- var->data.mode == ir_var_shader_in)) {
- _mesa_glsl_error(&loc, state,
- "redeclaration of `%s' with incorrect qualifiers",
- var->name);
- } else if (earlier->type != var->type) {
- _mesa_glsl_error(&loc, state,
- "redeclaration of `%s' has incorrect type",
- var->name);
- }
- } else if (allow_all_redeclarations) {
- if (earlier->data.mode != var->data.mode) {
- _mesa_glsl_error(&loc, state,
- "redeclaration of `%s' with incorrect qualifiers",
- var->name);
- } else if (earlier->type != var->type) {
- _mesa_glsl_error(&loc, state,
- "redeclaration of `%s' has incorrect type",
- var->name);
- }
} else {
_mesa_glsl_error(&loc, state, "`%s' redeclared", var->name);
}
/* Never emit code to initialize a uniform.
*/
const glsl_type *initializer_type;
+ bool error_emitted = false;
if (!type->qualifier.flags.q.uniform) {
- do_assignment(initializer_instructions, state,
- NULL,
- lhs, rhs,
- &result, true,
- true,
- type->get_location());
+ error_emitted =
+ do_assignment(initializer_instructions, state,
+ NULL, lhs, rhs,
+ &result, true, true,
+ type->get_location());
initializer_type = result->type;
} else
initializer_type = rhs->type;
- var->constant_initializer = rhs->constant_expression_value(mem_ctx);
- var->data.has_initializer = true;
-
- /* If the declared variable is an unsized array, it must inherrit
- * its full type from the initializer. A declaration such as
- *
- * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
- *
- * becomes
- *
- * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
- *
- * The assignment generated in the if-statement (below) will also
- * automatically handle this case for non-uniforms.
- *
- * If the declared variable is not an array, the types must
- * already match exactly. As a result, the type assignment
- * here can be done unconditionally. For non-uniforms the call
- * to do_assignment can change the type of the initializer (via
- * the implicit conversion rules). For uniforms the initializer
- * must be a constant expression, and the type of that expression
- * was validated above.
- */
- var->type = initializer_type;
+ if (!error_emitted) {
+ var->constant_initializer = rhs->constant_expression_value(mem_ctx);
+ var->data.has_initializer = true;
+ var->data.is_implicit_initializer = false;
+
+ /* If the declared variable is an unsized array, it must inherrit
+ * its full type from the initializer. A declaration such as
+ *
+ * uniform float a[] = float[](1.0, 2.0, 3.0, 3.0);
+ *
+ * becomes
+ *
+ * uniform float a[4] = float[](1.0, 2.0, 3.0, 3.0);
+ *
+ * The assignment generated in the if-statement (below) will also
+ * automatically handle this case for non-uniforms.
+ *
+ * If the declared variable is not an array, the types must
+ * already match exactly. As a result, the type assignment
+ * here can be done unconditionally. For non-uniforms the call
+ * to do_assignment can change the type of the initializer (via
+ * the implicit conversion rules). For uniforms the initializer
+ * must be a constant expression, and the type of that expression
+ * was validated above.
+ */
+ var->type = initializer_type;
+ }
var->data.read_only = temp;
}
"`invariant' after being used",
earlier->name);
} else {
+ earlier->data.explicit_invariant = true;
earlier->data.invariant = true;
}
}
assert(!this->invariant);
assert(!this->precise);
+ /* GL_EXT_shader_image_load_store base type uses GLSL_TYPE_VOID as a special value to
+ * indicate that it needs to be updated later (see glsl_parser.yy).
+ * This is done here, based on the layout qualifier and the type of the image var
+ */
+ if (this->type->qualifier.flags.q.explicit_image_format &&
+ this->type->specifier->type->is_image() &&
+ this->type->qualifier.image_base_type == GLSL_TYPE_VOID) {
+ /* "The ARB_shader_image_load_store says:
+ * If both extensions are enabled in the shading language, the "size*" layout
+ * qualifiers are treated as format qualifiers, and are mapped to equivalent
+ * format qualifiers in the table below, according to the type of image
+ * variable.
+ * image* iimage* uimage*
+ * -------- -------- --------
+ * size1x8 n/a r8i r8ui
+ * size1x16 r16f r16i r16ui
+ * size1x32 r32f r32i r32ui
+ * size2x32 rg32f rg32i rg32ui
+ * size4x32 rgba32f rgba32i rgba32ui"
+ */
+ if (strncmp(this->type->specifier->type_name, "image", strlen("image")) == 0) {
+ switch (this->type->qualifier.image_format) {
+ case PIPE_FORMAT_R8_SINT:
+ /* The GL_EXT_shader_image_load_store spec says:
+ * A layout of "size1x8" is illegal for image variables associated
+ * with floating-point data types.
+ */
+ _mesa_glsl_error(& loc, state,
+ "size1x8 is illegal for image variables "
+ "with floating-point data types.");
+ return NULL;
+ case PIPE_FORMAT_R16_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R16_FLOAT;
+ break;
+ case PIPE_FORMAT_R32_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R32_FLOAT;
+ break;
+ case PIPE_FORMAT_R32G32_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R32G32_FLOAT;
+ break;
+ case PIPE_FORMAT_R32G32B32A32_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ break;
+ default:
+ unreachable("Unknown image format");
+ }
+ this->type->qualifier.image_base_type = GLSL_TYPE_FLOAT;
+ } else if (strncmp(this->type->specifier->type_name, "uimage", strlen("uimage")) == 0) {
+ switch (this->type->qualifier.image_format) {
+ case PIPE_FORMAT_R8_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R8_UINT;
+ break;
+ case PIPE_FORMAT_R16_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R16_UINT;
+ break;
+ case PIPE_FORMAT_R32_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R32_UINT;
+ break;
+ case PIPE_FORMAT_R32G32_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R32G32_UINT;
+ break;
+ case PIPE_FORMAT_R32G32B32A32_SINT:
+ this->type->qualifier.image_format = PIPE_FORMAT_R32G32B32A32_UINT;
+ break;
+ default:
+ unreachable("Unknown image format");
+ }
+ this->type->qualifier.image_base_type = GLSL_TYPE_UINT;
+ } else if (strncmp(this->type->specifier->type_name, "iimage", strlen("iimage")) == 0) {
+ this->type->qualifier.image_base_type = GLSL_TYPE_INT;
+ } else {
+ assert(false);
+ }
+ }
+
/* The type specifier may contain a structure definition. Process that
* before any of the variable declarations.
*/
&& process_qualifier_constant(state, &loc, "offset",
type->qualifier.offset,
&qual_offset)) {
- state->atomic_counter_offsets[qual_binding] = qual_offset;
+ if (qual_binding < ARRAY_SIZE(state->atomic_counter_offsets))
+ state->atomic_counter_offsets[qual_binding] = qual_offset;
}
}
&& !state->has_explicit_attrib_location()
&& !state->has_separate_shader_objects()
&& !state->ARB_fragment_coord_conventions_enable) {
- if (this->type->qualifier.flags.q.out) {
+ /* GL_EXT_gpu_shader4 only allows "varying out" on fragment shader
+ * outputs. (the varying flag is not set by the parser)
+ */
+ if (this->type->qualifier.flags.q.out &&
+ (!state->EXT_gpu_shader4_enable ||
+ state->stage != MESA_SHADER_FRAGMENT)) {
_mesa_glsl_error(& loc, state,
"`out' qualifier in declaration of `%s' "
"only valid for function parameters in %s",
apply_layout_qualifier_to_variable(&this->type->qualifier, var, state,
&loc);
- if ((var->data.mode == ir_var_auto || var->data.mode == ir_var_temporary)
- && (var->type->is_numeric() || var->type->is_boolean())
- && state->zero_init) {
+ if ((state->zero_init & (1u << var->data.mode)) &&
+ (var->type->is_numeric() || var->type->is_boolean())) {
const ir_constant_data data = { { 0 } };
var->data.has_initializer = true;
+ var->data.is_implicit_initializer = true;
var->constant_initializer = new(var) ir_constant(var->type, &data);
}
var->data.read_only = true;
if (state->stage == MESA_SHADER_VERTEX) {
- bool error_emitted = false;
-
/* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
*
* "Vertex shader inputs can only be float, floating-point
*/
const glsl_type *check_type = var->type->without_array();
+ bool error = false;
switch (check_type->base_type) {
case GLSL_TYPE_FLOAT:
- break;
+ break;
case GLSL_TYPE_UINT64:
case GLSL_TYPE_INT64:
break;
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
- if (state->is_version(120, 300))
- break;
+ error = !state->is_version(120, 300) && !state->EXT_gpu_shader4_enable;
+ break;
case GLSL_TYPE_DOUBLE:
- if (check_type->is_double() && (state->is_version(410, 0) || state->ARB_vertex_attrib_64bit_enable))
- break;
+ error = !state->is_version(410, 0) && !state->ARB_vertex_attrib_64bit_enable;
+ break;
case GLSL_TYPE_SAMPLER:
- if (check_type->is_sampler() && state->has_bindless())
- break;
case GLSL_TYPE_IMAGE:
- if (check_type->is_image() && state->has_bindless())
- break;
- /* FALLTHROUGH */
+ error = !state->has_bindless();
+ break;
default:
+ error = true;
+ }
+
+ if (error) {
_mesa_glsl_error(& loc, state,
"vertex shader input / attribute cannot have "
"type %s`%s'",
var->type->is_array() ? "array of " : "",
check_type->name);
- error_emitted = true;
- }
-
- if (!error_emitted && var->type->is_array() &&
+ } else if (var->type->is_array() &&
!state->check_version(150, 0, &loc,
"vertex shader input / attribute "
"cannot have array type")) {
- error_emitted = true;
}
} else if (state->stage == MESA_SHADER_GEOMETRY) {
/* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
_mesa_shader_stage_to_string(state->stage));
}
if (var->type->is_array() &&
- var->type->fields.array->is_record()) {
+ var->type->fields.array->is_struct()) {
_mesa_glsl_error(&loc, state,
"fragment shader input "
"cannot have an array of structs");
}
- if (var->type->is_record()) {
+ if (var->type->is_struct()) {
for (unsigned i = 0; i < var->type->length; i++) {
if (var->type->fields.structure[i].type->is_array() ||
- var->type->fields.structure[i].type->is_record())
+ var->type->fields.structure[i].type->is_struct())
_mesa_glsl_error(&loc, state,
"fragment shader input cannot have "
"a struct that contains an "
* * A structure
*/
if (state->stage == MESA_SHADER_FRAGMENT) {
- if (check_type->is_record() || check_type->is_matrix())
+ if (check_type->is_struct() || check_type->is_matrix())
_mesa_glsl_error(&loc, state,
"fragment shader output "
"cannot have struct or matrix type");
type = var->type->fields.array;
}
- if (type->is_array() && type->fields.array->is_record()) {
+ if (type->is_array() && type->fields.array->is_struct()) {
_mesa_glsl_error(&loc, state,
"%s shader output cannot have "
"an array of structs",
_mesa_shader_stage_to_string(state->stage));
}
- if (type->is_record()) {
+ if (type->is_struct()) {
for (unsigned i = 0; i < type->length; i++) {
if (type->fields.structure[i].type->is_array() ||
- type->fields.structure[i].type->is_record())
+ type->fields.structure[i].type->is_struct())
_mesa_glsl_error(&loc, state,
"%s shader output cannot have a "
"struct that contains an "
apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
true);
+ if (((1u << var->data.mode) & state->zero_init) &&
+ (var->type->is_numeric() || var->type->is_boolean())) {
+ const ir_constant_data data = { { 0 } };
+ var->data.has_initializer = true;
+ var->data.is_implicit_initializer = true;
+ var->constant_initializer = new(var) ir_constant(var->type, &data);
+ }
+
/* From section 4.1.7 of the GLSL 4.40 spec:
*
* "Opaque variables cannot be treated as l-values; hence cannot
name);
}
+ /* Get the precision for the return type */
+ unsigned return_precision;
+
+ if (state->es_shader) {
+ YYLTYPE loc = this->get_location();
+ return_precision =
+ select_gles_precision(this->return_type->qualifier.precision,
+ return_type,
+ state,
+ &loc);
+ } else {
+ return_precision = GLSL_PRECISION_NONE;
+ }
/* Create an ir_function if one doesn't already exist. */
f = state->symbols->get_function(name);
*/
if (state->es_shader) {
/* Local shader has no exact candidates; check the built-ins. */
- _mesa_glsl_initialize_builtin_functions();
if (state->language_version >= 300 &&
_mesa_glsl_has_builtin_function(state, name)) {
YYLTYPE loc = this->get_location();
"match prototype", name);
}
+ if (sig->return_precision != return_precision) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function `%s' return type precision "
+ "doesn't match prototype", name);
+ }
+
if (sig->is_defined) {
if (is_definition) {
YYLTYPE loc = this->get_location();
*/
if (sig == NULL) {
sig = new(ctx) ir_function_signature(return_type);
+ sig->return_precision = return_precision;
f->add_signature(sig);
}
assert(state->current_function == NULL);
state->current_function = signature;
state->found_return = false;
+ state->found_begin_interlock = false;
+ state->found_end_interlock = false;
/* Duplicate parameters declared in the prototype as concrete variables.
* Add these to the symbol table.
if (state->has_420pack()) {
if (!apply_implicit_conversion(state->current_function->return_type,
- ret, state)) {
+ ret, state)
+ || (ret->type != state->current_function->return_type)) {
_mesa_glsl_error(& loc, state,
"could not implicitly convert return value "
"to %s, in function `%s'",
}
+ir_rvalue *
+ast_demote_statement::hir(exec_list *instructions,
+ struct _mesa_glsl_parse_state *state)
+{
+ void *ctx = state;
+
+ if (state->stage != MESA_SHADER_FRAGMENT) {
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(& loc, state,
+ "`demote' may only appear in a fragment shader");
+ }
+
+ instructions->push_tail(new(ctx) ir_demote);
+
+ return NULL;
+}
+
+
ir_rvalue *
ast_selection_statement::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
* scalar integer."
*/
if (!test_expression->type->is_scalar() ||
- !test_expression->type->is_integer()) {
+ !test_expression->type->is_integer_32()) {
YYLTYPE loc = this->test_expression->get_location();
_mesa_glsl_error(& loc,
* if default should be chosen or not.
*/
if (!default_case.is_empty()) {
- struct hash_entry *entry;
ir_factory body(instructions, state);
ir_expression *cmp = NULL;
glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type,
state);
- if ((!type_a->is_integer() || !type_b->is_integer()) ||
+ if ((!type_a->is_integer_32() || !type_b->is_integer_32()) ||
!integer_conversion_supported) {
_mesa_glsl_error(&loc, state, "type mismatch with switch "
"init-expression and case label (%s != %s)",
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
fields[i].sample = qual->flags.q.sample ? 1 : 0;
fields[i].patch = qual->flags.q.patch ? 1 : 0;
- fields[i].precision = qual->precision;
fields[i].offset = -1;
fields[i].explicit_xfb_buffer = explicit_xfb_buffer;
fields[i].xfb_buffer = xfb_buffer;
"alignment of %s", field_type->name);
}
fields[i].offset = qual_offset;
- next_offset = glsl_align(qual_offset + size, align);
+ next_offset = qual_offset + size;
} else {
_mesa_glsl_error(&loc, state, "offset can only be used "
"with std430 and std140 layouts");
if (member_align == 0 ||
member_align & (member_align - 1)) {
_mesa_glsl_error(&loc, state, "align layout qualifier "
- "in not a power of 2");
+ "is not a power of 2");
} else {
fields[i].offset = glsl_align(offset, member_align);
- next_offset = glsl_align(fields[i].offset + size, align);
+ next_offset = fields[i].offset + size;
}
}
} else {
fields[i].offset = glsl_align(offset, expl_align);
- next_offset = glsl_align(fields[i].offset + size, align);
+ next_offset = fields[i].offset + size;
}
} else if (!qual->flags.q.explicit_offset) {
if (align != 0 && size != 0)
- next_offset = glsl_align(next_offset + size, align);
+ next_offset = glsl_align(next_offset, align) + size;
}
/* From the ARB_enhanced_layouts spec:
if (is_interface && layout &&
(layout->flags.q.uniform || layout->flags.q.buffer) &&
(field_type->without_array()->is_matrix()
- || field_type->without_array()->is_record())) {
+ || field_type->without_array()->is_struct())) {
/* If no layout is specified for the field, inherit the layout
* from the block.
*/
"qualifier");
}
- fields[i].image_format = GL_NONE;
+ fields[i].image_format = PIPE_FORMAT_NONE;
}
}
}
+ /* Precision qualifiers do not hold any meaning in Desktop GLSL */
+ if (state->es_shader) {
+ fields[i].precision = select_gles_precision(qual->precision,
+ field_type,
+ state,
+ &loc);
+ } else {
+ fields[i].precision = qual->precision;
+ }
+
i++;
}
}
validate_identifier(this->name, loc, state);
- type = glsl_type::get_record_instance(fields, decl_count, this->name);
+ type = glsl_type::get_struct_instance(fields, decl_count, this->name);
if (!type->is_anonymous() && !state->symbols->add_type(name, type)) {
const glsl_type *match = state->symbols->get_type(name);
/* allow struct matching for desktop GL - older UE4 does this */
- if (match != NULL && state->is_version(130, 0) && match->record_compare(type, false))
+ if (match != NULL && state->is_version(130, 0) && match->record_compare(type, true, false))
_mesa_glsl_warning(& loc, state, "struct `%s' previously defined", name);
else
_mesa_glsl_error(& loc, state, "struct `%s' previously defined", name);
return NULL;
}
- unsigned qual_xfb_offset;
+ unsigned qual_xfb_offset = 0;
if (layout.flags.q.explicit_xfb_offset) {
if (!process_qualifier_constant(state, &loc, "xfb_offset",
layout.offset, &qual_xfb_offset)) {
}
}
- unsigned qual_xfb_stride;
+ unsigned qual_xfb_stride = 0;
if (layout.flags.q.explicit_xfb_stride) {
if (!process_qualifier_constant(state, &loc, "xfb_stride",
layout.xfb_stride, &qual_xfb_stride)) {
var->constant_initializer =
new(var) ir_constant(glsl_type::uvec3_type, &data);
var->data.has_initializer = true;
+ var->data.is_implicit_initializer = false;
return NULL;
}
if (!var || !var->data.assigned)
continue;
- if (strcmp(var->name, "gl_FragColor") == 0)
+ if (strcmp(var->name, "gl_FragColor") == 0) {
gl_FragColor_assigned = true;
+ if (!var->constant_initializer && state->zero_init) {
+ const ir_constant_data data = { { 0 } };
+ var->data.has_initializer = true;
+ var->data.is_implicit_initializer = true;
+ var->constant_initializer = new(var) ir_constant(var->type, &data);
+ }
+ }
else if (strcmp(var->name, "gl_FragData") == 0)
gl_FragData_assigned = true;
else if (strcmp(var->name, "gl_SecondaryFragColorEXT") == 0)
}
}
+static void
+verify_subroutine_associated_funcs(struct _mesa_glsl_parse_state *state)
+{
+ YYLTYPE loc;
+ memset(&loc, 0, sizeof(loc));
+
+ /* Section 6.1.2 (Subroutines) of the GLSL 4.00 spec says:
+ *
+ * "A program will fail to compile or link if any shader
+ * or stage contains two or more functions with the same
+ * name if the name is associated with a subroutine type."
+ */
+
+ for (int i = 0; i < state->num_subroutines; i++) {
+ unsigned definitions = 0;
+ ir_function *fn = state->subroutines[i];
+ /* Calculate number of function definitions with the same name */
+ foreach_in_list(ir_function_signature, sig, &fn->signatures) {
+ if (sig->is_defined) {
+ if (++definitions > 1) {
+ _mesa_glsl_error(&loc, state,
+ "%s shader contains two or more function "
+ "definitions with name `%s', which is "
+ "associated with a subroutine type.\n",
+ _mesa_shader_stage_to_string(state->stage),
+ fn->name);
+ return;
+ }
+ }
+ }
+ }
+}
static void
remove_per_vertex_blocks(exec_list *instructions,
}
}
}
+
+ir_rvalue *
+ast_warnings_toggle::hir(exec_list *,
+ struct _mesa_glsl_parse_state *state)
+{
+ state->warnings_enabled = enable;
+ return NULL;
+}