diff options
Diffstat (limited to 'mesalib/src/glsl/ast_to_hir.cpp')
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 203 |
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. |