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.cpp203
1 files changed, 158 insertions, 45 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index c89a26bf9..8f6e90174 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -969,6 +969,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
case GLSL_TYPE_ERROR:
case GLSL_TYPE_VOID:
case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_ATOMIC_UINT:
/* I assume a comparison of a struct containing a sampler just
@@ -1796,7 +1797,7 @@ ast_compound_statement::hir(exec_list *instructions,
* Evaluate the given exec_node (which should be an ast_node representing
* a single array dimension) and return its integer value.
*/
-static const unsigned
+static unsigned
process_array_size(exec_node *node,
struct _mesa_glsl_parse_state *state)
{
@@ -2122,11 +2123,16 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
{
bool fail = false;
- /* In the vertex shader only shader inputs can be given explicit
- * locations.
+ /* 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
+ * the correct extension with the correct stage's input / output:
*
- * In the fragment shader only shader outputs can be given explicit
- * locations.
+ * input output
+ * ----- ------
+ * vertex explicit_loc sso
+ * geometry sso sso
+ * fragment sso explicit_loc
*/
switch (state->stage) {
case MESA_SHADER_VERTEX:
@@ -2137,16 +2143,35 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
break;
}
+ if (var->data.mode == ir_var_shader_out) {
+ if (!state->check_separate_shader_objects_allowed(loc, var))
+ return;
+
+ break;
+ }
+
fail = true;
break;
case MESA_SHADER_GEOMETRY:
- _mesa_glsl_error(loc, state,
- "geometry shader variables cannot be given "
- "explicit locations");
- return;
+ if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) {
+ if (!state->check_separate_shader_objects_allowed(loc, var))
+ return;
+
+ break;
+ }
+
+ fail = true;
+ break;
case MESA_SHADER_FRAGMENT:
+ if (var->data.mode == ir_var_shader_in) {
+ if (!state->check_separate_shader_objects_allowed(loc, var))
+ return;
+
+ break;
+ }
+
if (var->data.mode == ir_var_shader_out) {
if (!state->check_explicit_attrib_location_allowed(loc, var))
return;
@@ -2180,9 +2205,26 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
* ensures that negative values stay negative.
*/
if (qual->location >= 0) {
- var->data.location = (state->stage == MESA_SHADER_VERTEX)
- ? (qual->location + VERT_ATTRIB_GENERIC0)
- : (qual->location + FRAG_RESULT_DATA0);
+ switch (state->stage) {
+ case MESA_SHADER_VERTEX:
+ var->data.location = (var->data.mode == ir_var_shader_in)
+ ? (qual->location + VERT_ATTRIB_GENERIC0)
+ : (qual->location + VARYING_SLOT_VAR0);
+ break;
+
+ case MESA_SHADER_GEOMETRY:
+ var->data.location = qual->location + VARYING_SLOT_VAR0;
+ break;
+
+ case MESA_SHADER_FRAGMENT:
+ var->data.location = (var->data.mode == ir_var_shader_out)
+ ? (qual->location + FRAG_RESULT_DATA0)
+ : (qual->location + VARYING_SLOT_VAR0);
+ break;
+ case MESA_SHADER_COMPUTE:
+ assert(!"Unexpected shader type");
+ break;
+ }
} else {
var->data.location = qual->location;
}
@@ -2206,8 +2248,54 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
}
}
}
+}
+
+static void
+apply_image_qualifier_to_variable(const struct ast_type_qualifier *qual,
+ ir_variable *var,
+ struct _mesa_glsl_parse_state *state,
+ YYLTYPE *loc)
+{
+ const glsl_type *base_type =
+ (var->type->is_array() ? var->type->element_type() : var->type);
+
+ if (base_type->is_image()) {
+ if (var->data.mode != ir_var_uniform &&
+ var->data.mode != ir_var_function_in) {
+ _mesa_glsl_error(loc, state, "image variables may only be declared as "
+ "function parameters or uniform-qualified "
+ "global variables");
+ }
+
+ var->data.image.read_only |= qual->flags.q.read_only;
+ var->data.image.write_only |= qual->flags.q.write_only;
+ var->data.image.coherent |= qual->flags.q.coherent;
+ var->data.image._volatile |= qual->flags.q._volatile;
+ var->data.image.restrict_flag |= qual->flags.q.restrict_flag;
+ var->data.read_only = true;
+
+ if (qual->flags.q.explicit_image_format) {
+ if (var->data.mode == ir_var_function_in) {
+ _mesa_glsl_error(loc, state, "format qualifiers cannot be "
+ "used on image function parameters");
+ }
+
+ if (qual->image_base_type != base_type->sampler_type) {
+ _mesa_glsl_error(loc, state, "format qualifier doesn't match the "
+ "base data type of the image");
+ }
+
+ var->data.image.format = qual->image_format;
+ } else {
+ if (var->data.mode == ir_var_uniform && !qual->flags.q.write_only) {
+ _mesa_glsl_error(loc, state, "uniforms not qualified with "
+ "`writeonly' must have a format layout "
+ "qualifier");
+ }
- return;
+ var->data.image.format = GL_NONE;
+ }
+ }
}
static void
@@ -2500,6 +2588,9 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
if (qual->flags.q.row_major || qual->flags.q.column_major) {
validate_matrix_layout_for_type(state, loc, var->type, var);
}
+
+ if (var->type->contains_image())
+ apply_image_qualifier_to_variable(qual, var, state, loc);
}
/**
@@ -2659,9 +2750,15 @@ process_initializer(ir_variable *var, ast_declaration *decl,
"cannot initialize uniforms");
}
- if (var->type->is_sampler()) {
+ /* From section 4.1.7 of the GLSL 4.40 spec:
+ *
+ * "Opaque variables [...] are initialized only through the
+ * OpenGL API; they cannot be declared with an initializer in a
+ * shader."
+ */
+ if (var->type->contains_opaque()) {
_mesa_glsl_error(& initializer_loc, state,
- "cannot initialize samplers");
+ "cannot initialize opaque variable");
}
if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) {
@@ -2784,7 +2881,7 @@ handle_geometry_shader_input_decl(struct _mesa_glsl_parse_state *state,
{
unsigned num_vertices = 0;
if (state->gs_input_prim_type_specified) {
- num_vertices = vertices_per_prim(state->gs_input_prim_type);
+ num_vertices = vertices_per_prim(state->in_qualifier->prim_type);
}
/* Geometry shader input variables must be arrays. Caller should have
@@ -2870,10 +2967,17 @@ validate_identifier(const char *identifier, YYLTYPE loc,
* "In addition, all identifiers containing two
* consecutive underscores (__) are reserved as
* possible future keywords."
+ *
+ * The intention is that names containing __ are reserved for internal
+ * use by the implementation, and names prefixed with GL_ are reserved
+ * for use by Khronos. Names simply containing __ are dangerous to use,
+ * but should be allowed.
+ *
+ * A future version of the GLSL specification will clarify this.
*/
- _mesa_glsl_error(&loc, state,
- "identifier `%s' uses reserved `__' string",
- identifier);
+ _mesa_glsl_warning(&loc, state,
+ "identifier `%s' uses reserved `__' string",
+ identifier);
}
}
@@ -3082,6 +3186,7 @@ ast_declarator_list::hir(exec_list *instructions,
*/
if (!state->is_version(130, 300)
&& !state->has_explicit_attrib_location()
+ && !state->has_separate_shader_objects()
&& !state->ARB_fragment_coord_conventions_enable) {
if (this->type->qualifier.flags.q.out) {
_mesa_glsl_error(& loc, state,
@@ -3421,15 +3526,15 @@ ast_declarator_list::hir(exec_list *instructions,
", integer and sampler types");
}
- /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+ /* From section 4.1.7 of the GLSL 4.40 spec:
*
- * "[Sampler types] can only be declared as function
- * parameters or uniform variables (see Section 4.3.5
- * "Uniform")".
+ * "[Opaque types] can only be declared as function
+ * parameters or uniform-qualified variables."
*/
- if (var_type->contains_sampler() &&
+ if (var_type->contains_opaque() &&
!this->type->qualifier.flags.q.uniform) {
- _mesa_glsl_error(&loc, state, "samplers must be declared uniform");
+ _mesa_glsl_error(&loc, state,
+ "opaque variables must be declared uniform");
}
/* Process the initializer and add its instructions to a temporary
@@ -3621,15 +3726,16 @@ ast_parameter_declarator::hir(exec_list *instructions,
apply_type_qualifier_to_variable(& this->type->qualifier, var, state, & loc,
true);
- /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+ /* From section 4.1.7 of the GLSL 4.40 spec:
*
- * "Samplers cannot be treated as l-values; hence cannot be used
- * as out or inout function parameters, nor can they be assigned
- * into."
+ * "Opaque variables cannot be treated as l-values; hence cannot
+ * be used as out or inout function parameters, nor can they be
+ * assigned into."
*/
if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
- && type->contains_sampler()) {
- _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
+ && type->contains_opaque()) {
+ _mesa_glsl_error(&loc, state, "out and inout parameters cannot "
+ "contain opaque variables");
type = glsl_type::error_type;
}
@@ -3784,15 +3890,15 @@ ast_function::hir(exec_list *instructions,
"sized", name);
}
- /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
+ /* From section 4.1.7 of the GLSL 4.40 spec:
*
- * "[Sampler types] can only be declared as function parameters
- * or uniform variables (see Section 4.3.5 "Uniform")".
+ * "[Opaque types] can only be declared as function parameters
+ * or uniform-qualified variables."
*/
- if (return_type->contains_sampler()) {
+ if (return_type->contains_opaque()) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(&loc, state,
- "function `%s' return type can't contain a sampler",
+ "function `%s' return type can't contain an opaque type",
name);
}
@@ -4693,12 +4799,9 @@ ast_process_structure_or_interface_block(exec_list *instructions,
if (!allow_reserved_names)
validate_identifier(decl->identifier, loc, state);
- /* From the GL_ARB_uniform_buffer_object spec:
+ /* From section 4.3.9 of the GLSL 4.40 spec:
*
- * "Sampler types are not allowed inside of uniform
- * blocks. All other types, arrays, and structures
- * allowed for uniforms are allowed within a uniform
- * block."
+ * "[In interface blocks] opaque types are not allowed."
*
* It should be impossible for decl_type to be NULL here. Cases that
* might naturally lead to decl_type being NULL, especially for the
@@ -4708,10 +4811,11 @@ ast_process_structure_or_interface_block(exec_list *instructions,
const struct glsl_type *field_type =
decl_type != NULL ? decl_type : glsl_type::error_type;
- if (is_interface && field_type->contains_sampler()) {
+ if (is_interface && field_type->contains_opaque()) {
YYLTYPE loc = decl_list->get_location();
_mesa_glsl_error(&loc, state,
- "uniform in non-default uniform block contains sampler");
+ "uniform in non-default uniform block contains "
+ "opaque variable");
}
if (field_type->contains_atomic()) {
@@ -4725,6 +4829,16 @@ ast_process_structure_or_interface_block(exec_list *instructions,
"uniform block");
}
+ if (field_type->contains_image()) {
+ /* FINISHME: Same problem as with atomic counters.
+ * FINISHME: Request clarification from Khronos and add
+ * FINISHME: spec quotation here.
+ */
+ YYLTYPE loc = decl_list->get_location();
+ _mesa_glsl_error(&loc, state,
+ "image in structure or uniform block");
+ }
+
const struct ast_type_qualifier *const qual =
& decl_list->type->qualifier;
if (qual->flags.q.std140 ||
@@ -5258,7 +5372,7 @@ ast_gs_input_layout::hir(exec_list *instructions,
* was consistent with this one.
*/
if (state->gs_input_prim_type_specified &&
- state->gs_input_prim_type != this->prim_type) {
+ state->in_qualifier->prim_type != this->prim_type) {
_mesa_glsl_error(&loc, state,
"geometry shader input layout does not match"
" previous declaration");
@@ -5279,7 +5393,6 @@ ast_gs_input_layout::hir(exec_list *instructions,
}
state->gs_input_prim_type_specified = true;
- state->gs_input_prim_type = this->prim_type;
/* If any shader inputs occurred before this declaration and did not
* specify an array size, their size is determined now.