aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/ast_to_hir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/ast_to_hir.cpp')
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp177
1 files changed, 133 insertions, 44 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index d1c77f1ec..7ba04a808 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -49,7 +49,6 @@
* parser (and lexer) sources.
*/
-#include "main/core.h" /* for struct gl_extensions */
#include "glsl_symbol_table.h"
#include "glsl_parser_extras.h"
#include "ast.h"
@@ -2182,6 +2181,41 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
{
bool fail = false;
+ /* Checks for GL_ARB_explicit_uniform_location. */
+ if (qual->flags.q.uniform) {
+ if (!state->check_explicit_uniform_location_allowed(loc, var))
+ return;
+
+ const struct gl_context *const ctx = state->ctx;
+ unsigned max_loc = qual->location + var->type->uniform_locations() - 1;
+
+ /* ARB_explicit_uniform_location specification states:
+ *
+ * "The explicitly defined locations and the generated locations
+ * must be in the range of 0 to MAX_UNIFORM_LOCATIONS minus one."
+ *
+ * "Valid locations for default-block uniform variable locations
+ * are in the range of 0 to the implementation-defined maximum
+ * number of uniform locations."
+ */
+ if (qual->location < 0) {
+ _mesa_glsl_error(loc, state,
+ "explicit location < 0 for uniform %s", var->name);
+ return;
+ }
+
+ if (max_loc >= ctx->Const.MaxUserAssignableUniformLocations) {
+ _mesa_glsl_error(loc, state, "location(s) consumed by uniform %s "
+ ">= MAX_UNIFORM_LOCATIONS (%u)", var->name,
+ ctx->Const.MaxUserAssignableUniformLocations);
+ return;
+ }
+
+ var->data.explicit_location = true;
+ var->data.location = qual->location;
+ return;
+ }
+
/* Between GL_ARB_explicit_attrib_location an
* GL_ARB_separate_shader_objects, the inputs and outputs of any shader
* stage can be assigned explicit locations. The checking here associates
@@ -2435,6 +2469,13 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
_mesa_shader_stage_to_string(state->stage));
}
+ /* Disallow layout qualifiers which may only appear on layout declarations. */
+ if (qual->flags.q.prim_type) {
+ _mesa_glsl_error(loc, state,
+ "Primitive type may only be specified on GS input or output "
+ "layout declaration, not on variables.");
+ }
+
/* Section 6.1.1 (Function Calling Conventions) of the GLSL 1.10 spec says:
*
* "However, the const qualifier cannot be used with out or inout."
@@ -2649,6 +2690,36 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
const bool uses_deprecated_qualifier = qual->flags.q.attribute
|| qual->flags.q.varying;
+
+ /* Validate auxiliary storage qualifiers */
+
+ /* From section 4.3.4 of the GLSL 1.30 spec:
+ * "It is an error to use centroid in in a vertex shader."
+ *
+ * From section 4.3.4 of the GLSL ES 3.00 spec:
+ * "It is an error to use centroid in or interpolation qualifiers in
+ * a vertex shader input."
+ */
+
+ /* Section 4.3.6 of the GLSL 1.30 specification states:
+ * "It is an error to use centroid out in a fragment shader."
+ *
+ * The GL_ARB_shading_language_420pack extension specification states:
+ * "It is an error to use auxiliary storage qualifiers or interpolation
+ * qualifiers on an output in a fragment shader."
+ */
+ if (qual->flags.q.sample && (!is_varying_var(var, state->stage) || uses_deprecated_qualifier)) {
+ _mesa_glsl_error(loc, state,
+ "sample qualifier may only be used on `in` or `out` "
+ "variables between shader stages");
+ }
+ if (qual->flags.q.centroid && !is_varying_var(var, state->stage)) {
+ _mesa_glsl_error(loc, state,
+ "centroid qualifier may only be used with `in', "
+ "`out' or `varying' variables between shader stages");
+ }
+
+
/* Is the 'layout' keyword used with parameters that allow relaxed checking.
* Many implementations of GL_ARB_fragment_coord_conventions_enable and some
* implementations (only Mesa?) GL_ARB_explicit_attrib_location_enable
@@ -3606,45 +3677,6 @@ ast_declarator_list::hir(exec_list *instructions,
}
- /* From section 4.3.4 of the GLSL 1.30 spec:
- * "It is an error to use centroid in in a vertex shader."
- *
- * From section 4.3.4 of the GLSL ES 3.00 spec:
- * "It is an error to use centroid in or interpolation qualifiers in
- * a vertex shader input."
- */
- if (state->is_version(130, 300)
- && this->type->qualifier.flags.q.centroid
- && this->type->qualifier.flags.q.in
- && state->stage == MESA_SHADER_VERTEX) {
-
- _mesa_glsl_error(&loc, state,
- "'centroid in' cannot be used in a vertex shader");
- }
-
- if (state->stage == MESA_SHADER_VERTEX
- && this->type->qualifier.flags.q.sample
- && this->type->qualifier.flags.q.in) {
-
- _mesa_glsl_error(&loc, state,
- "'sample in' cannot be used in a vertex shader");
- }
-
- /* Section 4.3.6 of the GLSL 1.30 specification states:
- * "It is an error to use centroid out in a fragment shader."
- *
- * The GL_ARB_shading_language_420pack extension specification states:
- * "It is an error to use auxiliary storage qualifiers or interpolation
- * qualifiers on an output in a fragment shader."
- */
- if (state->stage == MESA_SHADER_FRAGMENT &&
- this->type->qualifier.flags.q.out &&
- this->type->qualifier.has_auxiliary_storage()) {
- _mesa_glsl_error(&loc, state,
- "auxiliary storage qualifiers cannot be used on "
- "fragment shader outputs");
- }
-
/* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30.
*/
if (this->type->qualifier.precision != ast_precision_none) {
@@ -4632,9 +4664,51 @@ ast_case_label::hir(exec_list *instructions,
ir_dereference_variable *deref_test_var =
new(ctx) ir_dereference_variable(state->switch_state.test_var);
- ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal,
- label_const,
- deref_test_var);
+ ir_expression *test_cond = new(ctx) ir_expression(ir_binop_all_equal,
+ label_const,
+ deref_test_var);
+
+ /*
+ * From GLSL 4.40 specification section 6.2 ("Selection"):
+ *
+ * "The type of the init-expression value in a switch statement must
+ * be a scalar int or uint. The type of the constant-expression value
+ * in a case label also must be a scalar int or uint. When any pair
+ * of these values is tested for "equal value" and the types do not
+ * match, an implicit conversion will be done to convert the int to a
+ * uint (see section 4.1.10 “Implicit Conversions”) before the compare
+ * is done."
+ */
+ if (label_const->type != state->switch_state.test_var->type) {
+ YYLTYPE loc = this->test_value->get_location();
+
+ const glsl_type *type_a = label_const->type;
+ const glsl_type *type_b = state->switch_state.test_var->type;
+
+ /* Check if int->uint implicit conversion is supported. */
+ bool integer_conversion_supported =
+ glsl_type::int_type->can_implicitly_convert_to(glsl_type::uint_type,
+ state);
+
+ if ((!type_a->is_integer() || !type_b->is_integer()) ||
+ !integer_conversion_supported) {
+ _mesa_glsl_error(&loc, state, "type mismatch with switch "
+ "init-expression and case label (%s != %s)",
+ type_a->name, type_b->name);
+ } else {
+ /* Conversion of the case label. */
+ if (type_a->base_type == GLSL_TYPE_INT) {
+ if (!apply_implicit_conversion(glsl_type::uint_type,
+ test_cond->operands[0], state))
+ _mesa_glsl_error(&loc, state, "implicit type conversion error");
+ } else {
+ /* Conversion of the init-expression value. */
+ if (!apply_implicit_conversion(glsl_type::uint_type,
+ test_cond->operands[1], state))
+ _mesa_glsl_error(&loc, state, "implicit type conversion error");
+ }
+ }
+ }
ir_assignment *set_fallthru_on_test =
new(ctx) ir_assignment(deref_fallthru_var, true_val, test_cond);
@@ -5041,6 +5115,13 @@ ast_process_structure_or_interface_block(exec_list *instructions,
"with uniform interface blocks");
}
+ if ((qual->flags.q.uniform || !is_interface) &&
+ qual->has_auxiliary_storage()) {
+ _mesa_glsl_error(&loc, state,
+ "auxiliary storage qualifiers cannot be used "
+ "in uniform blocks or structures.");
+ }
+
if (field_type->is_matrix() ||
(field_type->is_array() && field_type->fields.array->is_matrix())) {
fields[i].row_major = block_row_major;
@@ -5090,7 +5171,7 @@ ast_struct_specifier::hir(exec_list *instructions,
*/
if (state->language_version != 110 && state->struct_specifier_depth != 0)
_mesa_glsl_error(&loc, state,
- "embedded structure declartions are not allowed");
+ "embedded structure declarations are not allowed");
state->struct_specifier_depth++;
@@ -5206,6 +5287,12 @@ ast_interface_block::hir(exec_list *instructions,
bool block_row_major = this->layout.flags.q.row_major;
exec_list declared_variables;
glsl_struct_field *fields;
+
+ /* Treat an interface block as one level of nesting, so that embedded struct
+ * specifiers will be disallowed.
+ */
+ state->struct_specifier_depth++;
+
unsigned int num_variables =
ast_process_structure_or_interface_block(&declared_variables,
state,
@@ -5217,6 +5304,8 @@ ast_interface_block::hir(exec_list *instructions,
redeclaring_per_vertex,
var_mode);
+ state->struct_specifier_depth--;
+
if (!redeclaring_per_vertex)
validate_identifier(this->block_name, loc, state);