diff options
Diffstat (limited to 'mesalib/src/glsl')
25 files changed, 915 insertions, 450 deletions
diff --git a/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am index ea7617685..aff1559e0 100644 --- a/mesalib/src/glsl/Makefile.am +++ b/mesalib/src/glsl/Makefile.am @@ -49,14 +49,16 @@ libglsl_la_LIBADD = glcpp/libglcpp.la libglsl_la_LDFLAGS = glsl_compiler_SOURCES = \ - $(top_srcdir)/src/mesa/program/hash_table.c \ + $(top_srcdir)/src/mesa/main/hash_table.c \ + $(top_srcdir)/src/mesa/program/prog_hash_table.c \ $(top_srcdir)/src/mesa/program/symbol_table.c \ $(GLSL_COMPILER_CXX_FILES) glsl_compiler_LDADD = libglsl.la glsl_test_SOURCES = \ - $(top_srcdir)/src/mesa/program/hash_table.c \ + $(top_srcdir)/src/mesa/main/hash_table.c \ + $(top_srcdir)/src/mesa/program/prog_hash_table.c \ $(top_srcdir)/src/mesa/program/symbol_table.c \ $(GLSL_SRCDIR)/standalone_scaffolding.cpp \ test.cpp \ diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript index 0cf25c07b..6abba2a24 100644 --- a/mesalib/src/glsl/SConscript +++ b/mesalib/src/glsl/SConscript @@ -57,14 +57,18 @@ if env['crosscompile'] and not env['embedded']: Import('builtin_glsl_function') else: # Copy these files to avoid generation object files into src/mesa/program + env.Prepend(CPPPATH = ['#src/mesa/main']) + env.Command('hash_table.c', '#src/mesa/main/hash_table.c', Copy('$TARGET', '$SOURCE')) + # Copy these files to avoid generation object files into src/mesa/program env.Prepend(CPPPATH = ['#src/mesa/program']) - env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE')) + env.Command('prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE')) env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE')) compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES']) mesa_objs = env.StaticObject([ 'hash_table.c', + 'prog_hash_table.c', 'symbol_table.c', ]) diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index ea3282c5f..b56a3c723 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -275,9 +275,10 @@ generate_call(exec_list *instructions, ir_function_signature *sig, /* If the function call is a constant expression, don't generate any * instructions; just generate an ir_constant. * - * Function calls were first allowed to be constant expressions in GLSL 1.20. + * Function calls were first allowed to be constant expressions in GLSL + * 1.20 and GLSL ES 3.00. */ - if (state->language_version >= 120) { + if (state->is_version(120, 300)) { ir_constant *value = sig->constant_expression_value(actual_parameters, NULL); if (value != NULL) { return value; @@ -324,7 +325,8 @@ match_function_by_name(const char *name, goto done; /* no match */ /* Is the function hidden by a variable (impossible in 1.10)? */ - if (state->language_version != 110 && state->symbols->get_variable(name)) + if (!state->symbols->separate_function_namespace + && state->symbols->get_variable(name)) goto done; /* no match */ if (f != NULL) { @@ -1242,9 +1244,8 @@ ast_function_expression::hir(exec_list *instructions, } if (constructor_type->is_array()) { - if (state->language_version <= 110) { - _mesa_glsl_error(& loc, state, - "array constructors forbidden in GLSL 1.10"); + if (!state->check_version(120, 300, &loc, + "array constructors forbidden")) { return ir_rvalue::error_value(ctx); } @@ -1367,11 +1368,11 @@ ast_function_expression::hir(exec_list *instructions, * "It is an error to construct matrices from other matrices. This * is reserved for future use." */ - if (state->language_version == 110 && matrix_parameters > 0 - && constructor_type->is_matrix()) { - _mesa_glsl_error(& loc, state, "cannot construct `%s' from a " - "matrix in GLSL 1.10", - constructor_type->name); + if (matrix_parameters > 0 + && constructor_type->is_matrix() + && !state->check_version(120, 100, &loc, + "cannot construct `%s' from a matrix", + constructor_type->name)) { return ir_rvalue::error_value(ctx); } diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index d450aa1e4..94b63f682 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -66,7 +66,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { _mesa_glsl_initialize_variables(instructions, state); - state->symbols->language_version = state->language_version; + state->symbols->separate_function_namespace = state->language_version == 110; state->current_function = NULL; @@ -121,7 +121,7 @@ apply_implicit_conversion(const glsl_type *to, ir_rvalue * &from, /* This conversion was added in GLSL 1.20. If the compilation mode is * GLSL 1.10, the conversion is skipped. */ - if (state->language_version < 120) + if (!state->is_version(120, 0)) return false; /* From page 27 (page 33 of the PDF) of the GLSL 1.50 spec: @@ -390,8 +390,7 @@ bit_logic_result_type(const struct glsl_type *type_a, ast_operators op, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { - if (state->language_version < 130) { - _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30"); + if (!state->check_bitwise_operations_allowed(loc)) { return glsl_type::error_type; } @@ -446,10 +445,7 @@ modulus_result_type(const struct glsl_type *type_a, const struct glsl_type *type_b, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { - if (state->language_version < 130) { - _mesa_glsl_error(loc, state, - "operator '%%' is reserved in %s", - state->version_string); + if (!state->check_version(130, 300, loc, "operator '%%' is reserved")) { return glsl_type::error_type; } @@ -553,8 +549,7 @@ shift_result_type(const struct glsl_type *type_a, ast_operators op, struct _mesa_glsl_parse_state *state, YYLTYPE *loc) { - if (state->language_version < 130) { - _mesa_glsl_error(loc, state, "bit operations require GLSL 1.30"); + if (!state->check_bitwise_operations_allowed(loc)) { return glsl_type::error_type; } @@ -694,15 +689,17 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, lhs->variable_referenced()->name); error_emitted = true; - } else if (state->language_version <= 110 && lhs->type->is_array()) { + } else if (lhs->type->is_array() && + !state->check_version(120, 300, &lhs_loc, + "whole array assignment forbidden")) { /* From page 32 (page 38 of the PDF) of the GLSL 1.10 spec: * * "Other binary or unary expressions, non-dereferenced * arrays, function names, swizzles with repeated fields, * and constants cannot be l-values." + * + * The restriction on arrays is lifted in GLSL 1.20 and GLSL ES 3.00. */ - _mesa_glsl_error(&lhs_loc, state, "whole array assignment is not " - "allowed in GLSL 1.10 or GLSL ES 1.00."); error_emitted = true; } else if (!lhs->is_lvalue()) { _mesa_glsl_error(& lhs_loc, state, "non-lvalue in assignment"); @@ -1099,9 +1096,7 @@ ast_expression::hir(exec_list *instructions, case ast_lshift: case ast_rshift: - if (state->language_version < 130) { - _mesa_glsl_error(&loc, state, "operator %s requires GLSL 1.30", - operator_string(this->oper)); + if (!state->check_bitwise_operations_allowed(&loc)) { error_emitted = true; } @@ -1155,10 +1150,9 @@ ast_expression::hir(exec_list *instructions, _mesa_glsl_error(& loc, state, "operands of `%s' must have the same " "type", (this->oper == ast_equal) ? "==" : "!="); error_emitted = true; - } else if ((state->language_version <= 110) - && (op[0]->type->is_array() || op[1]->type->is_array())) { - _mesa_glsl_error(& loc, state, "array comparisons forbidden in " - "GLSL 1.10"); + } else if ((op[0]->type->is_array() || op[1]->type->is_array()) && + !state->check_version(120, 300, &loc, + "array comparisons forbidden")) { error_emitted = true; } @@ -1185,8 +1179,7 @@ ast_expression::hir(exec_list *instructions, case ast_bit_not: op[0] = this->subexpressions[0]->hir(instructions, state); - if (state->language_version < 130) { - _mesa_glsl_error(&loc, state, "bit-wise operations require GLSL 1.30"); + if (!state->check_bitwise_operations_allowed(&loc)) { error_emitted = true; } @@ -1424,9 +1417,10 @@ ast_expression::hir(exec_list *instructions, * "The second and third expressions must be the same type, but can * be of any type other than an array." */ - if ((state->language_version <= 110) && type->is_array()) { - _mesa_glsl_error(& loc, state, "Second and third operands of ?: " - "operator must not be arrays."); + if (type->is_array() && + !state->check_version(120, 300, &loc, + "Second and third operands of ?: operator " + "cannot be arrays")) { error_emitted = true; } @@ -1660,15 +1654,18 @@ ast_expression::hir(exec_list *instructions, array->type->element_type()->is_sampler() && const_index == NULL) { - if (state->language_version == 100) { - _mesa_glsl_warning(&loc, state, - "sampler arrays indexed with non-constant " - "expressions is optional in GLSL ES 1.00"); - } else if (state->language_version < 130) { - _mesa_glsl_warning(&loc, state, - "sampler arrays indexed with non-constant " - "expressions is forbidden in GLSL 1.30 and " - "later"); + if (!state->is_version(130, 100)) { + if (state->es_shader) { + _mesa_glsl_warning(&loc, state, + "sampler arrays indexed with non-constant " + "expressions is optional in %s", + state->get_version_string()); + } else { + _mesa_glsl_warning(&loc, state, + "sampler arrays indexed with non-constant " + "expressions will be forbidden in GLSL 1.30 and " + "later"); + } } else { _mesa_glsl_error(&loc, state, "sampler arrays indexed with non-constant " @@ -2288,7 +2285,7 @@ get_variable_being_redeclared(ir_variable *var, ast_declaration *decl, * * gl_Color * * gl_SecondaryColor */ - } else if (state->language_version >= 130 + } else if (state->is_version(130, 0) && (strcmp(var->name, "gl_FrontColor") == 0 || strcmp(var->name, "gl_BackColor") == 0 || strcmp(var->name, "gl_FrontSecondaryColor") == 0 @@ -2355,10 +2352,9 @@ process_initializer(ir_variable *var, ast_declaration *decl, * directly by an application via API commands, or indirectly by * OpenGL." */ - if ((state->language_version <= 110) - && (var->mode == ir_var_uniform)) { - _mesa_glsl_error(& initializer_loc, state, - "cannot initialize uniforms in GLSL 1.10"); + if (var->mode == ir_var_uniform) { + state->check_version(120, 0, &initializer_loc, + "cannot initialize uniforms"); } if (var->type->is_sampler()) { @@ -2608,23 +2604,23 @@ ast_declarator_list::hir(exec_list *instructions, * * Local variables can only use the qualifier const." * - * This is relaxed in GLSL 1.30. It is also relaxed by any extension - * that adds the 'layout' keyword. + * This is relaxed in GLSL 1.30 and GLSL ES 3.00. It is also relaxed by + * any extension that adds the 'layout' keyword. */ - if ((state->language_version < 130) + if (!state->is_version(130, 300) && !state->ARB_explicit_attrib_location_enable && !state->ARB_fragment_coord_conventions_enable) { if (this->type->qualifier.flags.q.out) { _mesa_glsl_error(& loc, state, "`out' qualifier in declaration of `%s' " "only valid for function parameters in %s.", - decl->identifier, state->version_string); + decl->identifier, state->get_version_string()); } if (this->type->qualifier.flags.q.in) { _mesa_glsl_error(& loc, state, "`in' qualifier in declaration of `%s' " "only valid for function parameters in %s.", - decl->identifier, state->version_string); + decl->identifier, state->get_version_string()); } /* FINISHME: Test for other invalid qualifiers. */ } @@ -2703,6 +2699,13 @@ ast_declarator_list::hir(exec_list *instructions, * "The attribute qualifier can be used only with float, * floating-point vectors, and matrices. Attribute variables * cannot be declared as arrays or structures." + * + * From page 33 (page 39 of the PDF) of the GLSL ES 3.00 spec: + * + * "Vertex shader inputs can only be float, floating-point + * vectors, matrices, signed and unsigned integers and integer + * vectors. Vertex shader inputs cannot be arrays or + * structures." */ const glsl_type *check_type = var->type->is_array() ? var->type->fields.array : var->type; @@ -2712,7 +2715,7 @@ ast_declarator_list::hir(exec_list *instructions, break; case GLSL_TYPE_UINT: case GLSL_TYPE_INT: - if (state->language_version > 120) + if (state->is_version(120, 300)) break; /* FALLTHROUGH */ default: @@ -2724,11 +2727,10 @@ ast_declarator_list::hir(exec_list *instructions, error_emitted = true; } - if (!error_emitted && (state->language_version <= 130) - && var->type->is_array()) { - _mesa_glsl_error(& loc, state, - "vertex shader input / attribute cannot have " - "array type"); + if (!error_emitted && var->type->is_array() && + !state->check_version(140, 0, &loc, + "vertex shader input / attribute " + "cannot have array type")) { error_emitted = true; } } @@ -2740,8 +2742,16 @@ ast_declarator_list::hir(exec_list *instructions, * "If a vertex output is a signed or unsigned integer or integer * vector, then it must be qualified with the interpolation qualifier * flat." + * + * From section 4.3.4 of the GLSL 3.00 ES spec: + * "Fragment shader inputs that are signed or unsigned integers or + * integer vectors must be qualified with the interpolation qualifier + * flat." + * + * Since vertex outputs and fragment inputs must have matching + * qualifiers, these two requirements are equivalent. */ - if (state->language_version >= 130 + if (state->is_version(130, 300) && state->target == vertex_shader && state->current_function == NULL && var->type->is_integer() @@ -2760,8 +2770,10 @@ ast_declarator_list::hir(exec_list *instructions, * "interpolation qualifiers may only precede the qualifiers in, * centroid in, out, or centroid out in a declaration. They do not apply * to the deprecated storage qualifiers varying or centroid varying." + * + * These deprecated storage qualifiers do not exist in GLSL ES 3.00. */ - if (state->language_version >= 130 + if (state->is_version(130, 0) && this->type->qualifier.has_interpolation() && this->type->qualifier.flags.q.varying) { @@ -2786,8 +2798,14 @@ ast_declarator_list::hir(exec_list *instructions, * "Outputs from a vertex shader (out) and inputs to a fragment * shader (in) can be further qualified with one or more of these * interpolation qualifiers" + * + * From page 31 (page 37 of the PDF) of the GLSL ES 3.00 spec: + * "These interpolation qualifiers may only precede the qualifiers + * in, centroid in, out, or centroid out in a declaration. They do + * not apply to inputs into a vertex shader or outputs from a + * fragment shader." */ - if (state->language_version >= 130 + if (state->is_version(130, 300) && this->type->qualifier.has_interpolation()) { const char *i = this->type->qualifier.interpolation_string(); @@ -2816,8 +2834,12 @@ 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->language_version >= 130 + if (state->is_version(130, 300) && this->type->qualifier.flags.q.centroid && this->type->qualifier.flags.q.in && state->target == vertex_shader) { @@ -2829,13 +2851,8 @@ ast_declarator_list::hir(exec_list *instructions, /* Precision qualifiers exists only in GLSL versions 1.00 and >= 1.30. */ - if (this->type->specifier->precision != ast_precision_none - && state->language_version != 100 - && state->language_version < 130) { - - _mesa_glsl_error(&loc, state, - "precision qualifiers are supported only in GLSL ES " - "1.00, and GLSL 1.30 and later"); + if (this->type->specifier->precision != ast_precision_none) { + state->check_precision_qualifiers_allowed(&loc); } @@ -3077,8 +3094,9 @@ ast_parameter_declarator::hir(exec_list *instructions, * allowed. This restriction is removed in GLSL 1.20, and in GLSL ES. */ if ((var->mode == ir_var_inout || var->mode == ir_var_out) - && type->is_array() && state->language_version == 110) { - _mesa_glsl_error(&loc, state, "Arrays cannot be out or inout parameters in GLSL 1.10"); + && type->is_array() + && !state->check_version(120, 100, &loc, + "Arrays cannot be out or inout parameters")) { type = glsl_type::error_type; } @@ -3161,7 +3179,8 @@ ast_function::hir(exec_list *instructions, * * Note that this language does not appear in GLSL 1.10. */ - if ((state->current_function != NULL) && (state->language_version != 110)) { + if ((state->current_function != NULL) && + state->is_version(120, 100)) { YYLTYPE loc = this->get_location(); _mesa_glsl_error(&loc, state, "declaration of function `%s' not allowed within " @@ -3872,11 +3891,7 @@ ast_type_specifier::hir(exec_list *instructions, YYLTYPE loc = this->get_location(); if (this->precision != ast_precision_none - && state->language_version != 100 - && state->language_version < 130) { - _mesa_glsl_error(&loc, state, - "precision qualifiers exist only in " - "GLSL ES 1.00, and GLSL 1.30 and later"); + && !state->check_precision_qualifiers_allowed(&loc)) { return NULL; } if (this->precision != ast_precision_none diff --git a/mesalib/src/glsl/builtin_compiler/Makefile.am b/mesalib/src/glsl/builtin_compiler/Makefile.am index d6f85a7f4..d27aca555 100644 --- a/mesalib/src/glsl/builtin_compiler/Makefile.am +++ b/mesalib/src/glsl/builtin_compiler/Makefile.am @@ -55,7 +55,8 @@ builtin_compiler_SOURCES = \ $(GLSL_BUILDDIR)/glsl_parser.cc \ $(LIBGLSL_FILES) \ $(LIBGLSL_CXX_FILES) \ - $(top_srcdir)/src/mesa/program/hash_table.c \ + $(top_srcdir)/src/mesa/main/hash_table.c \ + $(top_srcdir)/src/mesa/program/prog_hash_table.c \ $(top_srcdir)/src/mesa/program/symbol_table.c \ $(GLSL_COMPILER_CXX_FILES) \ builtin_stubs.cpp diff --git a/mesalib/src/glsl/builtin_types.h b/mesalib/src/glsl/builtin_types.h index 92427d8e7..a4c995fd1 100644 --- a/mesalib/src/glsl/builtin_types.h +++ b/mesalib/src/glsl/builtin_types.h @@ -31,6 +31,11 @@ const glsl_type glsl_type::_sampler3D_type = glsl_type(GL_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT, "sampler3D"); +const glsl_type glsl_type::_samplerCubeShadow_type = + glsl_type(GL_SAMPLER_CUBE_SHADOW, + GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT, + "samplerCubeShadow"); + const glsl_type *const glsl_type::error_type = & glsl_type::_error_type; const glsl_type *const glsl_type::void_type = & glsl_type::_void_type; diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index 353805b7f..e7769419f 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -61,6 +61,17 @@ static const builtin_variable builtin_100ES_fs_variables[] = { { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" }, }; +static const builtin_variable builtin_300ES_vs_variables[] = { + { ir_var_system_value, SYSTEM_VALUE_VERTEX_ID, "int", "gl_VertexID" }, +}; + +static const builtin_variable builtin_300ES_fs_variables[] = { + { ir_var_in, FRAG_ATTRIB_WPOS, "vec4", "gl_FragCoord" }, + { ir_var_in, FRAG_ATTRIB_FACE, "bool", "gl_FrontFacing" }, + { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" }, + { ir_var_in, FRAG_ATTRIB_PNTC, "vec2", "gl_PointCoord" }, +}; + static const builtin_variable builtin_110_fs_variables[] = { { ir_var_out, FRAG_RESULT_DEPTH, "float", "gl_FragDepth" }, }; @@ -499,12 +510,15 @@ add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab, return var; } -/* Several constants in GLSL ES have different names than normal desktop GLSL. +/** + * Uniforms that are common to all GLSL ES implementations. + * + * Several constants in GLSL ES have different names than normal desktop GLSL. * Therefore, this function should only be called on the ES path. */ static void -generate_100ES_uniforms(exec_list *instructions, - struct _mesa_glsl_parse_state *state) +generate_common_ES_uniforms(exec_list *instructions, + struct _mesa_glsl_parse_state *state) { glsl_symbol_table *const symtab = state->symbols; @@ -512,8 +526,6 @@ generate_100ES_uniforms(exec_list *instructions, state->Const.MaxVertexAttribs); add_builtin_constant(instructions, symtab, "gl_MaxVertexUniformVectors", state->Const.MaxVertexUniformComponents); - add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors", - state->Const.MaxVaryingFloats / 4); add_builtin_constant(instructions, symtab, "gl_MaxVertexTextureImageUnits", state->Const.MaxVertexTextureImageUnits); add_builtin_constant(instructions, symtab, "gl_MaxCombinedTextureImageUnits", @@ -528,6 +540,36 @@ generate_100ES_uniforms(exec_list *instructions, } static void +generate_100ES_uniforms(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + generate_common_ES_uniforms(instructions, state); + + glsl_symbol_table *const symtab = state->symbols; + + add_builtin_constant(instructions, symtab, "gl_MaxVaryingVectors", + state->Const.MaxVaryingFloats / 4); +} + +static void +generate_300ES_uniforms(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + generate_common_ES_uniforms(instructions, state); + + glsl_symbol_table *const symtab = state->symbols; + + add_builtin_constant(instructions, symtab, "gl_MaxVertexOutputVectors", + state->Const.MaxVaryingFloats / 4); + add_builtin_constant(instructions, symtab, "gl_MaxFragmentInputVectors", + state->Const.MaxVaryingFloats / 4); + add_builtin_constant(instructions, symtab, "gl_MinProgramTexelOffset", + state->Const.MinProgramTexelOffset); + add_builtin_constant(instructions, symtab, "gl_MaxProgramTexelOffset", + state->Const.MaxProgramTexelOffset); +} + +static void generate_110_uniforms(exec_list *instructions, struct _mesa_glsl_parse_state *state, bool add_deprecated) @@ -657,6 +699,26 @@ generate_100ES_vs_variables(exec_list *instructions, vertex_shader); } +static void +generate_300ES_vs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_core_vs_variables[i]); + } + + for (unsigned i = 0; i < Elements(builtin_300ES_vs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_300ES_vs_variables[i]); + } + + generate_300ES_uniforms(instructions, state); + + generate_ARB_draw_buffers_variables(instructions, state, false, + vertex_shader); +} + static void generate_110_vs_variables(exec_list *instructions, @@ -760,23 +822,36 @@ static void initialize_vs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - - switch (state->language_version) { - case 100: - generate_100ES_vs_variables(instructions, state); - break; - case 110: - generate_110_vs_variables(instructions, state, true); - break; - case 120: - generate_120_vs_variables(instructions, state, true); - break; - case 130: - generate_130_vs_variables(instructions, state, true); - break; - case 140: - generate_130_vs_variables(instructions, state, false); - break; + if (state->es_shader) { + switch (state->language_version) { + case 100: + generate_100ES_vs_variables(instructions, state); + break; + case 300: + generate_300ES_vs_variables(instructions, state); + break; + default: + assert(!"Unexpected language version"); + break; + } + } else { + switch (state->language_version) { + case 110: + generate_110_vs_variables(instructions, state, true); + break; + case 120: + generate_120_vs_variables(instructions, state, true); + break; + case 130: + generate_130_vs_variables(instructions, state, true); + break; + case 140: + generate_130_vs_variables(instructions, state, false); + break; + default: + assert(!"Unexpected language version"); + break; + } } generate_ARB_draw_instanced_variables(instructions, state, false, @@ -806,6 +881,25 @@ generate_100ES_fs_variables(exec_list *instructions, } static void +generate_300ES_fs_variables(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + /* Note: we don't add builtin_core_fs_variables, because it contains + * gl_FragColor, which is not in GLSL 3.00 ES. + */ + + for (unsigned i = 0; i < Elements(builtin_300ES_fs_variables); i++) { + add_builtin_variable(instructions, state->symbols, + & builtin_300ES_fs_variables[i]); + } + + generate_300ES_uniforms(instructions, state); + + generate_ARB_draw_buffers_variables(instructions, state, false, + fragment_shader); +} + +static void generate_110_fs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state, bool add_deprecated) @@ -865,8 +959,9 @@ generate_ARB_draw_buffers_variables(exec_list *instructions, mdb->warn_extension = "GL_ARB_draw_buffers"; /* gl_FragData is only available in the fragment shader. + * It is not present in GLSL 3.00 ES. */ - if (target == fragment_shader) { + if (target == fragment_shader && !state->is_version(0, 300)) { const glsl_type *const vec4_array_type = glsl_type::get_array_instance(glsl_type::vec4_type, state->Const.MaxDrawBuffers); @@ -903,7 +998,8 @@ generate_ARB_draw_instanced_variables(exec_list *instructions, inst->warn_extension = "GL_ARB_draw_instanced"; } - if (state->ARB_draw_instanced_enable || state->language_version >= 140) { + bool available_in_core = state->is_version(140, 300); + if (state->ARB_draw_instanced_enable || available_in_core) { /* Originally ARB_draw_instanced only specified that ARB decorated name. * Since no vendor actually implemented that behavior and some apps use * the undecorated name, the extension now specifies that both names are @@ -914,7 +1010,7 @@ generate_ARB_draw_instanced_variables(exec_list *instructions, "gl_InstanceID", glsl_type::int_type, ir_var_system_value, SYSTEM_VALUE_INSTANCE_ID); - if (state->language_version < 140 && warn) + if (!available_in_core && warn) inst->warn_extension = "GL_ARB_draw_instanced"; } } @@ -1016,23 +1112,36 @@ static void initialize_fs_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state) { - - switch (state->language_version) { - case 100: - generate_100ES_fs_variables(instructions, state); - break; - case 110: - generate_110_fs_variables(instructions, state, true); - break; - case 120: - generate_120_fs_variables(instructions, state, true); - break; - case 130: - generate_130_fs_variables(instructions, state); - break; - case 140: - generate_140_fs_variables(instructions, state); - break; + if (state->es_shader) { + switch (state->language_version) { + case 100: + generate_100ES_fs_variables(instructions, state); + break; + case 300: + generate_300ES_fs_variables(instructions, state); + break; + default: + assert(!"Unexpected language version"); + break; + } + } else { + switch (state->language_version) { + case 110: + generate_110_fs_variables(instructions, state, true); + break; + case 120: + generate_120_fs_variables(instructions, state, true); + break; + case 130: + generate_130_fs_variables(instructions, state); + break; + case 140: + generate_140_fs_variables(instructions, state); + break; + default: + assert(!"Unexpected language version"); + break; + } } if (state->ARB_shader_stencil_export_enable) diff --git a/mesalib/src/glsl/glcpp/Makefile.am b/mesalib/src/glsl/glcpp/Makefile.am index 04d8cda01..d8d39d295 100644 --- a/mesalib/src/glsl/glcpp/Makefile.am +++ b/mesalib/src/glsl/glcpp/Makefile.am @@ -46,7 +46,7 @@ libglcpp_la_SOURCES = \ glcpp_SOURCES = \ ../ralloc.c \ - $(top_srcdir)/src/mesa/program/hash_table.c \ + $(top_srcdir)/src/mesa/program/prog_hash_table.c \ glcpp.c glcpp_LDADD = libglcpp.la diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index e7daf7fea..380a1d99c 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -133,6 +133,10 @@ _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, static void _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc); +static void +_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, + const char *ident); + static int glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser); @@ -334,25 +338,10 @@ control_line: _glcpp_parser_skip_stack_pop (parser, & @1); } NEWLINE | HASH_VERSION integer_constant NEWLINE { - macro_t *macro = hash_table_find (parser->defines, "__VERSION__"); - if (macro) { - hash_table_remove (parser->defines, "__VERSION__"); - ralloc_free (macro); - } - add_builtin_define (parser, "__VERSION__", $2); - - if ($2 == 100) - add_builtin_define (parser, "GL_ES", 1); - - /* Currently, all ES2 implementations support highp in the - * fragment shader, so we always define this macro in ES2. - * If we ever get a driver that doesn't support highp, we'll - * need to add a flag to the gl_context and check that here. - */ - if ($2 >= 130 || $2 == 100) - add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); - - ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#version %" PRIiMAX, $2); + _glcpp_parser_handle_version_declaration(parser, $2, NULL); + } +| HASH_VERSION integer_constant IDENTIFIER NEWLINE { + _glcpp_parser_handle_version_declaration(parser, $2, $3); } | HASH NEWLINE ; @@ -2032,3 +2021,38 @@ _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc) parser->skip_stack = node->next; ralloc_free (node); } + +static void +_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, + const char *es_identifier) +{ + /* Note: We assume that if any identifier is present, it means ES. + * The GLSL parser will double-check that the identifier is correct. + */ + bool is_es = es_identifier != NULL; + + macro_t *macro = hash_table_find (parser->defines, "__VERSION__"); + if (macro) { + hash_table_remove (parser->defines, "__VERSION__"); + ralloc_free (macro); + } + add_builtin_define (parser, "__VERSION__", version); + + if (version == 100) + is_es = true; + if (is_es) + add_builtin_define (parser, "GL_ES", 1); + + /* Currently, all ES2/ES3 implementations support highp in the + * fragment shader, so we always define this macro in ES2/ES3. + * If we ever get a driver that doesn't support highp, we'll + * need to add a flag to the gl_context and check that here. + */ + if (version >= 130 || is_es) + add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); + + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, + "#version %" PRIiMAX "%s%s", version, + es_identifier ? " " : "", + es_identifier ? es_identifier : ""); +} diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll index c538d7d8e..2f66c5828 100644 --- a/mesalib/src/glsl/glsl_lexer.ll +++ b/mesalib/src/glsl/glsl_lexer.ll @@ -48,20 +48,34 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); * * Certain words start out as identifiers, become reserved words in * later language revisions, and finally become language keywords. + * This may happen at different times in desktop GLSL and GLSL ES. * * For example, consider the following lexer rule: - * samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER) + * samplerBuffer KEYWORD(130, 0, 140, 0, SAMPLERBUFFER) * * This means that "samplerBuffer" will be treated as: * - a keyword (SAMPLERBUFFER token) ...in GLSL >= 1.40 * - a reserved word - error ...in GLSL >= 1.30 - * - an identifier ...in GLSL < 1.30 + * - an identifier ...in GLSL < 1.30 or GLSL ES */ -#define KEYWORD(reserved_version, allowed_version, token) \ +#define KEYWORD(reserved_glsl, reserved_glsl_es, \ + allowed_glsl, allowed_glsl_es, token) \ + KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es, \ + allowed_glsl, allowed_glsl_es, false, token) + +/** + * Like the KEYWORD macro, but the word is also treated as a keyword + * if the given boolean expression is true. + */ +#define KEYWORD_WITH_ALT(reserved_glsl, reserved_glsl_es, \ + allowed_glsl, allowed_glsl_es, \ + alt_expr, token) \ do { \ - if (yyextra->language_version >= allowed_version) { \ + if (yyextra->is_version(allowed_glsl, allowed_glsl_es) \ + || alt_expr) { \ return token; \ - } else if (yyextra->language_version >= reserved_version) { \ + } else if (yyextra->is_version(reserved_glsl, \ + reserved_glsl_es)) { \ _mesa_glsl_error(yylloc, yyextra, \ "Illegal use of reserved word `%s'", yytext); \ return ERROR_TOK; \ @@ -71,15 +85,20 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *); } \ } while (0) -/* The ES macro can be used in KEYWORD checks: - * - * word KEYWORD(110 || ES, 400, TOKEN) - * ...means the word is reserved in GLSL ES 1.00, while - * - * word KEYWORD(110, 130 || ES, TOKEN) - * ...means the word is a legal keyword in GLSL ES 1.00. +/** + * A macro for handling keywords that have been present in GLSL since + * its origin, but were changed into reserved words in GLSL 3.00 ES. */ -#define ES yyextra->es_shader +#define DEPRECATED_ES_KEYWORD(token) \ + do { \ + if (yyextra->is_version(0, 300)) { \ + _mesa_glsl_error(yylloc, yyextra, \ + "Illegal use of reserved word `%s'", yytext); \ + return ERROR_TOK; \ + } else { \ + return token; \ + } \ + } while (0) static int literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state, @@ -103,7 +122,7 @@ literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state, if (value > UINT_MAX) { /* Note that signed 0xffffffff is valid, not out of range! */ - if (state->language_version >= 130) { + if (state->is_version(130, 300)) { _mesa_glsl_error(lloc, state, "Literal value `%s' out of range", text); } else { @@ -219,12 +238,12 @@ HASH ^{SPC}#{SPC} \n { yylineno++; yycolumn = 0; } -attribute return ATTRIBUTE; +attribute DEPRECATED_ES_KEYWORD(ATTRIBUTE); const return CONST_TOK; bool return BOOL_TOK; float return FLOAT_TOK; int return INT_TOK; -uint KEYWORD(130, 130, UINT_TOK); +uint KEYWORD(130, 300, 130, 300, UINT_TOK); break return BREAK; continue return CONTINUE; @@ -242,59 +261,59 @@ bvec4 return BVEC4; ivec2 return IVEC2; ivec3 return IVEC3; ivec4 return IVEC4; -uvec2 KEYWORD(130, 130, UVEC2); -uvec3 KEYWORD(130, 130, UVEC3); -uvec4 KEYWORD(130, 130, UVEC4); +uvec2 KEYWORD(130, 300, 130, 300, UVEC2); +uvec3 KEYWORD(130, 300, 130, 300, UVEC3); +uvec4 KEYWORD(130, 300, 130, 300, UVEC4); vec2 return VEC2; vec3 return VEC3; vec4 return VEC4; mat2 return MAT2X2; mat3 return MAT3X3; mat4 return MAT4X4; -mat2x2 KEYWORD(120, 120, MAT2X2); -mat2x3 KEYWORD(120, 120, MAT2X3); -mat2x4 KEYWORD(120, 120, MAT2X4); -mat3x2 KEYWORD(120, 120, MAT3X2); -mat3x3 KEYWORD(120, 120, MAT3X3); -mat3x4 KEYWORD(120, 120, MAT3X4); -mat4x2 KEYWORD(120, 120, MAT4X2); -mat4x3 KEYWORD(120, 120, MAT4X3); -mat4x4 KEYWORD(120, 120, MAT4X4); +mat2x2 KEYWORD(120, 300, 120, 300, MAT2X2); +mat2x3 KEYWORD(120, 300, 120, 300, MAT2X3); +mat2x4 KEYWORD(120, 300, 120, 300, MAT2X4); +mat3x2 KEYWORD(120, 300, 120, 300, MAT3X2); +mat3x3 KEYWORD(120, 300, 120, 300, MAT3X3); +mat3x4 KEYWORD(120, 300, 120, 300, MAT3X4); +mat4x2 KEYWORD(120, 300, 120, 300, MAT4X2); +mat4x3 KEYWORD(120, 300, 120, 300, MAT4X3); +mat4x4 KEYWORD(120, 300, 120, 300, MAT4X4); in return IN_TOK; out return OUT_TOK; inout return INOUT_TOK; uniform return UNIFORM; -varying return VARYING; -centroid KEYWORD(120, 120, CENTROID); -invariant KEYWORD(120 || ES, 120 || ES, INVARIANT); -flat KEYWORD(130 || ES, 130, FLAT); -smooth KEYWORD(130, 130, SMOOTH); -noperspective KEYWORD(130, 130, NOPERSPECTIVE); - -sampler1D return SAMPLER1D; +varying DEPRECATED_ES_KEYWORD(VARYING); +centroid KEYWORD(120, 300, 120, 300, CENTROID); +invariant KEYWORD(120, 100, 120, 100, INVARIANT); +flat KEYWORD(130, 100, 130, 300, FLAT); +smooth KEYWORD(130, 300, 130, 300, SMOOTH); +noperspective KEYWORD(130, 300, 130, 0, NOPERSPECTIVE); + +sampler1D DEPRECATED_ES_KEYWORD(SAMPLER1D); sampler2D return SAMPLER2D; sampler3D return SAMPLER3D; samplerCube return SAMPLERCUBE; -sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY); -sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY); -sampler1DShadow return SAMPLER1DSHADOW; +sampler1DArray KEYWORD(130, 300, 130, 0, SAMPLER1DARRAY); +sampler2DArray KEYWORD(130, 300, 130, 300, SAMPLER2DARRAY); +sampler1DShadow DEPRECATED_ES_KEYWORD(SAMPLER1DSHADOW); sampler2DShadow return SAMPLER2DSHADOW; -samplerCubeShadow KEYWORD(130, 130, SAMPLERCUBESHADOW); -sampler1DArrayShadow KEYWORD(130, 130, SAMPLER1DARRAYSHADOW); -sampler2DArrayShadow KEYWORD(130, 130, SAMPLER2DARRAYSHADOW); -isampler1D KEYWORD(130, 130, ISAMPLER1D); -isampler2D KEYWORD(130, 130, ISAMPLER2D); -isampler3D KEYWORD(130, 130, ISAMPLER3D); -isamplerCube KEYWORD(130, 130, ISAMPLERCUBE); -isampler1DArray KEYWORD(130, 130, ISAMPLER1DARRAY); -isampler2DArray KEYWORD(130, 130, ISAMPLER2DARRAY); -usampler1D KEYWORD(130, 130, USAMPLER1D); -usampler2D KEYWORD(130, 130, USAMPLER2D); -usampler3D KEYWORD(130, 130, USAMPLER3D); -usamplerCube KEYWORD(130, 130, USAMPLERCUBE); -usampler1DArray KEYWORD(130, 130, USAMPLER1DARRAY); -usampler2DArray KEYWORD(130, 130, USAMPLER2DARRAY); +samplerCubeShadow KEYWORD(130, 300, 130, 300, SAMPLERCUBESHADOW); +sampler1DArrayShadow KEYWORD(130, 300, 130, 0, SAMPLER1DARRAYSHADOW); +sampler2DArrayShadow KEYWORD(130, 300, 130, 300, SAMPLER2DARRAYSHADOW); +isampler1D KEYWORD(130, 300, 130, 0, ISAMPLER1D); +isampler2D KEYWORD(130, 300, 130, 300, ISAMPLER2D); +isampler3D KEYWORD(130, 300, 130, 300, ISAMPLER3D); +isamplerCube KEYWORD(130, 300, 130, 300, ISAMPLERCUBE); +isampler1DArray KEYWORD(130, 300, 130, 0, ISAMPLER1DARRAY); +isampler2DArray KEYWORD(130, 300, 130, 300, ISAMPLER2DARRAY); +usampler1D KEYWORD(130, 300, 130, 0, USAMPLER1D); +usampler2D KEYWORD(130, 300, 130, 300, USAMPLER2D); +usampler3D KEYWORD(130, 300, 130, 300, USAMPLER3D); +usamplerCube KEYWORD(130, 300, 130, 300, USAMPLERCUBE); +usampler1DArray KEYWORD(130, 300, 130, 0, USAMPLER1DARRAY); +usampler2DArray KEYWORD(130, 300, 130, 300, USAMPLER2DARRAY); samplerCubeArray { if (yyextra->ARB_texture_cube_map_array_enable) @@ -333,7 +352,7 @@ struct return STRUCT; void return VOID_TOK; layout { - if ((yyextra->language_version >= 140) + if ((yyextra->is_version(140, 300)) || yyextra->AMD_conservative_depth_enable || yyextra->ARB_conservative_depth_enable || yyextra->ARB_explicit_attrib_location_enable @@ -411,96 +430,114 @@ false { /* Reserved words in GLSL 1.10. */ -asm KEYWORD(110 || ES, 999, ASM); -class KEYWORD(110 || ES, 999, CLASS); -union KEYWORD(110 || ES, 999, UNION); -enum KEYWORD(110 || ES, 999, ENUM); -typedef KEYWORD(110 || ES, 999, TYPEDEF); -template KEYWORD(110 || ES, 999, TEMPLATE); -this KEYWORD(110 || ES, 999, THIS); -packed KEYWORD(110 || ES, 140 || yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK); -goto KEYWORD(110 || ES, 999, GOTO); -switch KEYWORD(110 || ES, 130, SWITCH); -default KEYWORD(110 || ES, 130, DEFAULT); -inline KEYWORD(110 || ES, 999, INLINE_TOK); -noinline KEYWORD(110 || ES, 999, NOINLINE); -volatile KEYWORD(110 || ES, 999, VOLATILE); -public KEYWORD(110 || ES, 999, PUBLIC_TOK); -static KEYWORD(110 || ES, 999, STATIC); -extern KEYWORD(110 || ES, 999, EXTERN); -external KEYWORD(110 || ES, 999, EXTERNAL); -interface KEYWORD(110 || ES, 999, INTERFACE); -long KEYWORD(110 || ES, 999, LONG_TOK); -short KEYWORD(110 || ES, 999, SHORT_TOK); -double KEYWORD(110 || ES, 400, DOUBLE_TOK); -half KEYWORD(110 || ES, 999, HALF); -fixed KEYWORD(110 || ES, 999, FIXED_TOK); -unsigned KEYWORD(110 || ES, 999, UNSIGNED); -input KEYWORD(110 || ES, 999, INPUT_TOK); -output KEYWORD(110 || ES, 999, OUTPUT); -hvec2 KEYWORD(110 || ES, 999, HVEC2); -hvec3 KEYWORD(110 || ES, 999, HVEC3); -hvec4 KEYWORD(110 || ES, 999, HVEC4); -dvec2 KEYWORD(110 || ES, 400, DVEC2); -dvec3 KEYWORD(110 || ES, 400, DVEC3); -dvec4 KEYWORD(110 || ES, 400, DVEC4); -fvec2 KEYWORD(110 || ES, 999, FVEC2); -fvec3 KEYWORD(110 || ES, 999, FVEC3); -fvec4 KEYWORD(110 || ES, 999, FVEC4); -sampler2DRect return SAMPLER2DRECT; -sampler3DRect KEYWORD(110 || ES, 999, SAMPLER3DRECT); -sampler2DRectShadow return SAMPLER2DRECTSHADOW; -sizeof KEYWORD(110 || ES, 999, SIZEOF); -cast KEYWORD(110 || ES, 999, CAST); -namespace KEYWORD(110 || ES, 999, NAMESPACE); -using KEYWORD(110 || ES, 999, USING); +asm KEYWORD(110, 100, 0, 0, ASM); +class KEYWORD(110, 100, 0, 0, CLASS); +union KEYWORD(110, 100, 0, 0, UNION); +enum KEYWORD(110, 100, 0, 0, ENUM); +typedef KEYWORD(110, 100, 0, 0, TYPEDEF); +template KEYWORD(110, 100, 0, 0, TEMPLATE); +this KEYWORD(110, 100, 0, 0, THIS); +packed KEYWORD_WITH_ALT(110, 100, 140, 300, yyextra->ARB_uniform_buffer_object_enable, PACKED_TOK); +goto KEYWORD(110, 100, 0, 0, GOTO); +switch KEYWORD(110, 100, 130, 300, SWITCH); +default KEYWORD(110, 100, 130, 300, DEFAULT); +inline KEYWORD(110, 100, 0, 0, INLINE_TOK); +noinline KEYWORD(110, 100, 0, 0, NOINLINE); +volatile KEYWORD(110, 100, 0, 0, VOLATILE); +public KEYWORD(110, 100, 0, 0, PUBLIC_TOK); +static KEYWORD(110, 100, 0, 0, STATIC); +extern KEYWORD(110, 100, 0, 0, EXTERN); +external KEYWORD(110, 100, 0, 0, EXTERNAL); +interface KEYWORD(110, 100, 0, 0, INTERFACE); +long KEYWORD(110, 100, 0, 0, LONG_TOK); +short KEYWORD(110, 100, 0, 0, SHORT_TOK); +double KEYWORD(110, 100, 400, 0, DOUBLE_TOK); +half KEYWORD(110, 100, 0, 0, HALF); +fixed KEYWORD(110, 100, 0, 0, FIXED_TOK); +unsigned KEYWORD(110, 100, 0, 0, UNSIGNED); +input KEYWORD(110, 100, 0, 0, INPUT_TOK); +output KEYWORD(110, 100, 0, 0, OUTPUT); +hvec2 KEYWORD(110, 100, 0, 0, HVEC2); +hvec3 KEYWORD(110, 100, 0, 0, HVEC3); +hvec4 KEYWORD(110, 100, 0, 0, HVEC4); +dvec2 KEYWORD(110, 100, 400, 0, DVEC2); +dvec3 KEYWORD(110, 100, 400, 0, DVEC3); +dvec4 KEYWORD(110, 100, 400, 0, DVEC4); +fvec2 KEYWORD(110, 100, 0, 0, FVEC2); +fvec3 KEYWORD(110, 100, 0, 0, FVEC3); +fvec4 KEYWORD(110, 100, 0, 0, FVEC4); +sampler2DRect DEPRECATED_ES_KEYWORD(SAMPLER2DRECT); +sampler3DRect KEYWORD(110, 100, 0, 0, SAMPLER3DRECT); +sampler2DRectShadow DEPRECATED_ES_KEYWORD(SAMPLER2DRECTSHADOW); +sizeof KEYWORD(110, 100, 0, 0, SIZEOF); +cast KEYWORD(110, 100, 0, 0, CAST); +namespace KEYWORD(110, 100, 0, 0, NAMESPACE); +using KEYWORD(110, 100, 0, 0, USING); /* Additional reserved words in GLSL 1.20. */ -lowp KEYWORD(120, 130 || ES, LOWP); -mediump KEYWORD(120, 130 || ES, MEDIUMP); -highp KEYWORD(120, 130 || ES, HIGHP); -precision KEYWORD(120, 130 || ES, PRECISION); +lowp KEYWORD(120, 100, 130, 100, LOWP); +mediump KEYWORD(120, 100, 130, 100, MEDIUMP); +highp KEYWORD(120, 100, 130, 100, HIGHP); +precision KEYWORD(120, 100, 130, 100, PRECISION); /* Additional reserved words in GLSL 1.30. */ -case KEYWORD(130, 130, CASE); -common KEYWORD(130, 999, COMMON); -partition KEYWORD(130, 999, PARTITION); -active KEYWORD(130, 999, ACTIVE); -superp KEYWORD(130 || ES, 999, SUPERP); -samplerBuffer KEYWORD(130, 140, SAMPLERBUFFER); -filter KEYWORD(130, 999, FILTER); -image1D KEYWORD(130, 999, IMAGE1D); -image2D KEYWORD(130, 999, IMAGE2D); -image3D KEYWORD(130, 999, IMAGE3D); -imageCube KEYWORD(130, 999, IMAGECUBE); -iimage1D KEYWORD(130, 999, IIMAGE1D); -iimage2D KEYWORD(130, 999, IIMAGE2D); -iimage3D KEYWORD(130, 999, IIMAGE3D); -iimageCube KEYWORD(130, 999, IIMAGECUBE); -uimage1D KEYWORD(130, 999, UIMAGE1D); -uimage2D KEYWORD(130, 999, UIMAGE2D); -uimage3D KEYWORD(130, 999, UIMAGE3D); -uimageCube KEYWORD(130, 999, UIMAGECUBE); -image1DArray KEYWORD(130, 999, IMAGE1DARRAY); -image2DArray KEYWORD(130, 999, IMAGE2DARRAY); -iimage1DArray KEYWORD(130, 999, IIMAGE1DARRAY); -iimage2DArray KEYWORD(130, 999, IIMAGE2DARRAY); -uimage1DArray KEYWORD(130, 999, UIMAGE1DARRAY); -uimage2DArray KEYWORD(130, 999, UIMAGE2DARRAY); -image1DShadow KEYWORD(130, 999, IMAGE1DSHADOW); -image2DShadow KEYWORD(130, 999, IMAGE2DSHADOW); -image1DArrayShadow KEYWORD(130, 999, IMAGE1DARRAYSHADOW); -image2DArrayShadow KEYWORD(130, 999, IMAGE2DARRAYSHADOW); -imageBuffer KEYWORD(130, 999, IMAGEBUFFER); -iimageBuffer KEYWORD(130, 999, IIMAGEBUFFER); -uimageBuffer KEYWORD(130, 999, UIMAGEBUFFER); -row_major KEYWORD(130, 140 || yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR); +case KEYWORD(130, 300, 130, 300, CASE); +common KEYWORD(130, 300, 0, 0, COMMON); +partition KEYWORD(130, 300, 0, 0, PARTITION); +active KEYWORD(130, 300, 0, 0, ACTIVE); +superp KEYWORD(130, 100, 0, 0, SUPERP); +samplerBuffer KEYWORD(130, 300, 140, 0, SAMPLERBUFFER); +filter KEYWORD(130, 300, 0, 0, FILTER); +image1D KEYWORD(130, 300, 0, 0, IMAGE1D); +image2D KEYWORD(130, 300, 0, 0, IMAGE2D); +image3D KEYWORD(130, 300, 0, 0, IMAGE3D); +imageCube KEYWORD(130, 300, 0, 0, IMAGECUBE); +iimage1D KEYWORD(130, 300, 0, 0, IIMAGE1D); +iimage2D KEYWORD(130, 300, 0, 0, IIMAGE2D); +iimage3D KEYWORD(130, 300, 0, 0, IIMAGE3D); +iimageCube KEYWORD(130, 300, 0, 0, IIMAGECUBE); +uimage1D KEYWORD(130, 300, 0, 0, UIMAGE1D); +uimage2D KEYWORD(130, 300, 0, 0, UIMAGE2D); +uimage3D KEYWORD(130, 300, 0, 0, UIMAGE3D); +uimageCube KEYWORD(130, 300, 0, 0, UIMAGECUBE); +image1DArray KEYWORD(130, 300, 0, 0, IMAGE1DARRAY); +image2DArray KEYWORD(130, 300, 0, 0, IMAGE2DARRAY); +iimage1DArray KEYWORD(130, 300, 0, 0, IIMAGE1DARRAY); +iimage2DArray KEYWORD(130, 300, 0, 0, IIMAGE2DARRAY); +uimage1DArray KEYWORD(130, 300, 0, 0, UIMAGE1DARRAY); +uimage2DArray KEYWORD(130, 300, 0, 0, UIMAGE2DARRAY); +image1DShadow KEYWORD(130, 300, 0, 0, IMAGE1DSHADOW); +image2DShadow KEYWORD(130, 300, 0, 0, IMAGE2DSHADOW); +image1DArrayShadow KEYWORD(130, 300, 0, 0, IMAGE1DARRAYSHADOW); +image2DArrayShadow KEYWORD(130, 300, 0, 0, IMAGE2DARRAYSHADOW); +imageBuffer KEYWORD(130, 300, 0, 0, IMAGEBUFFER); +iimageBuffer KEYWORD(130, 300, 0, 0, IIMAGEBUFFER); +uimageBuffer KEYWORD(130, 300, 0, 0, UIMAGEBUFFER); +row_major KEYWORD_WITH_ALT(130, 0, 140, 0, yyextra->ARB_uniform_buffer_object_enable, ROW_MAJOR); /* Additional reserved words in GLSL 1.40 */ -isampler2DRect KEYWORD(140, 140, ISAMPLER2DRECT); -usampler2DRect KEYWORD(140, 140, USAMPLER2DRECT); -isamplerBuffer KEYWORD(140, 140, ISAMPLERBUFFER); -usamplerBuffer KEYWORD(140, 140, USAMPLERBUFFER); +isampler2DRect KEYWORD(140, 300, 140, 0, ISAMPLER2DRECT); +usampler2DRect KEYWORD(140, 300, 140, 0, USAMPLER2DRECT); +isamplerBuffer KEYWORD(140, 300, 140, 0, ISAMPLERBUFFER); +usamplerBuffer KEYWORD(140, 300, 140, 0, USAMPLERBUFFER); + + /* Additional reserved words in GLSL ES 3.00 */ +coherent KEYWORD(0, 300, 0, 0, COHERENT); +restrict KEYWORD(0, 300, 0, 0, RESTRICT); +readonly KEYWORD(0, 300, 0, 0, READONLY); +writeonly KEYWORD(0, 300, 0, 0, WRITEONLY); +resource KEYWORD(0, 300, 0, 0, RESOURCE); +atomic_uint KEYWORD(0, 300, 0, 0, ATOMIC_UINT); +patch KEYWORD(0, 300, 0, 0, PATCH); +sample KEYWORD(0, 300, 0, 0, SAMPLE); +subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE); +sampler2DMS KEYWORD(0, 300, 0, 0, SAMPLER2DMS); +isampler2DMS KEYWORD(0, 300, 0, 0, ISAMPLER2DMS); +usampler2DMS KEYWORD(0, 300, 0, 0, USAMPLER2DMS); +sampler2DMSArray KEYWORD(0, 300, 0, 0, SAMPLER2DMSARRAY); +isampler2DMSArray KEYWORD(0, 300, 0, 0, ISAMPLER2DMSARRAY); +usampler2DMSArray KEYWORD(0, 300, 0, 0, USAMPLER2DMSARRAY); + [_a-zA-Z][_a-zA-Z0-9]* { struct _mesa_glsl_parse_state *state = yyextra; diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 407dbbeeb..d8494667b 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -137,6 +137,9 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %token HVEC2 HVEC3 HVEC4 DVEC2 DVEC3 DVEC4 FVEC2 FVEC3 FVEC4 %token SAMPLER3DRECT %token SIZEOF CAST NAMESPACE USING +%token COHERENT RESTRICT READONLY WRITEONLY RESOURCE ATOMIC_UINT PATCH SAMPLE +%token SUBROUTINE SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS SAMPLER2DMSARRAY +%token ISAMPLER2DMSARRAY USAMPLER2DMSARRAY %token ERROR_TOK @@ -258,54 +261,12 @@ version_statement: /* blank - no #version specified: defaults are already set */ | VERSION_TOK INTCONSTANT EOL { - bool supported = false; - - switch ($2) { - case 100: - state->es_shader = true; - supported = state->ctx->API == API_OPENGLES2 || - state->ctx->Extensions.ARB_ES2_compatibility; - break; - case 110: - case 120: - /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or - * the OpenGL 3.2 Core context is supported, this logic will need - * change. Older versions of GLSL are no longer supported - * outside the compatibility contexts of 3.x. - */ - case 130: - case 140: - case 150: - case 330: - case 400: - case 410: - case 420: - supported = _mesa_is_desktop_gl(state->ctx) && - ((unsigned) $2) <= state->ctx->Const.GLSLVersion; - break; - default: - supported = false; - break; - } - - state->language_version = $2; - state->version_string = - ralloc_asprintf(state, "GLSL%s %d.%02d", - state->es_shader ? " ES" : "", - state->language_version / 100, - state->language_version % 100); - - if (!supported) { - _mesa_glsl_error(& @2, state, "%s is not supported. " - "Supported versions are: %s\n", - state->version_string, - state->supported_version_string); - } - - if (state->language_version >= 140) { - state->ARB_uniform_buffer_object_enable = true; - } + state->process_version_directive(&@2, $2, NULL); } + | VERSION_TOK INTCONSTANT any_identifier EOL + { + state->process_version_directive(&@2, $2, $3); + } ; pragma_statement: @@ -315,10 +276,11 @@ pragma_statement: | PRAGMA_OPTIMIZE_OFF EOL | PRAGMA_INVARIANT_ALL EOL { - if (state->language_version == 110) { + if (!state->is_version(120, 100)) { _mesa_glsl_warning(& @1, state, - "pragma `invariant(all)' not supported in %s", - state->version_string); + "pragma `invariant(all)' not supported in %s " + "(GLSL ES 1.00 or GLSL 1.20 required).", + state->get_version_string()); } else { state->all_invariant = true; } @@ -1126,6 +1088,7 @@ layout_qualifier_id_list: integer_constant: INTCONSTANT { $$ = $1; } | UINTCONSTANT { $$ = $1; } + ; layout_qualifier_id: any_identifier @@ -1181,6 +1144,8 @@ layout_qualifier_id: $$.flags.q.shared = 1; } else if (strcmp($1, "column_major") == 0) { $$.flags.q.column_major = 1; + } else if (strcmp($1, "row_major") == 0) { + $$.flags.q.row_major = 1; } if ($$.flags.i && state->ARB_uniform_buffer_object_warn) { @@ -1498,32 +1463,17 @@ basic_type_specifier_nonarray: precision_qualifier: HIGHP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); + state->check_precision_qualifiers_allowed(&@1); $$ = ast_precision_high; } | MEDIUMP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); + state->check_precision_qualifiers_allowed(&@1); $$ = ast_precision_medium; } | LOWP { - if (!state->es_shader && state->language_version < 130) - _mesa_glsl_error(& @1, state, - "precision qualifier forbidden " - "in %s (1.30 or later " - "required)\n", - state->version_string); + state->check_precision_qualifiers_allowed(&@1); $$ = ast_precision_low; } diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index f1fdd3a47..d36089226 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -37,6 +37,16 @@ extern "C" { #include "ir_optimization.h" #include "loop_analysis.h" +/** + * Format a short human-readable description of the given GLSL version. + */ +const char * +glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version) +{ + return ralloc_asprintf(mem_ctx, "GLSL%s %d.%02d", is_es ? " ES" : "", + version / 100, version % 100); +} + _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, void *mem_ctx) : ctx(_ctx) @@ -82,6 +92,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; this->Const.MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; this->Const.MaxFragmentUniformComponents = ctx->Const.FragmentProgram.MaxUniformComponents; + this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset; + this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset; this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; @@ -113,6 +125,166 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->default_uniform_qualifier->flags.q.column_major = 1; } +/** + * Determine whether the current GLSL version is sufficiently high to support + * a certain feature, and generate an error message if it isn't. + * + * \param required_glsl_version and \c required_glsl_es_version are + * interpreted as they are in _mesa_glsl_parse_state::is_version(). + * + * \param locp is the parser location where the error should be reported. + * + * \param fmt (and additional arguments) constitute a printf-style error + * message to report if the version check fails. Information about the + * current and required GLSL versions will be appended. So, for example, if + * the GLSL version being compiled is 1.20, and check_version(130, 300, locp, + * "foo unsupported") is called, the error message will be "foo unsupported in + * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)". + */ +bool +_mesa_glsl_parse_state::check_version(unsigned required_glsl_version, + unsigned required_glsl_es_version, + YYLTYPE *locp, const char *fmt, ...) +{ + if (this->is_version(required_glsl_version, required_glsl_es_version)) + return true; + + va_list args; + va_start(args, fmt); + char *problem = ralloc_vasprintf(ctx, fmt, args); + va_end(args); + const char *glsl_version_string + = glsl_compute_version_string(ctx, false, required_glsl_version); + const char *glsl_es_version_string + = glsl_compute_version_string(ctx, true, required_glsl_es_version); + const char *requirement_string = ""; + if (required_glsl_version && required_glsl_es_version) { + requirement_string = ralloc_asprintf(ctx, " (%s or %s required)", + glsl_version_string, + glsl_es_version_string); + } else if (required_glsl_version) { + requirement_string = ralloc_asprintf(ctx, " (%s required)", + glsl_version_string); + } else if (required_glsl_es_version) { + requirement_string = ralloc_asprintf(ctx, " (%s required)", + glsl_es_version_string); + } + _mesa_glsl_error(locp, this, "%s in %s%s.", + problem, this->get_version_string(), + requirement_string); + + return false; +} + +/** + * Process a GLSL #version directive. + * + * \param version is the integer that follows the #version token. + * + * \param ident is a string identifier that follows the integer, if any is + * present. Otherwise NULL. + */ +void +_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version, + const char *ident) +{ + bool es_token_present = false; + if (ident) { + if (strcmp(ident, "es") == 0) { + es_token_present = true; + } else { + _mesa_glsl_error(locp, this, + "Illegal text following version number\n"); + } + } + + bool supported = false; + + if (es_token_present) { + this->es_shader = true; + switch (version) { + case 100: + _mesa_glsl_error(locp, this, + "GLSL 1.00 ES should be selected using " + "`#version 100'\n"); + supported = this->ctx->API == API_OPENGLES2 || + this->ctx->Extensions.ARB_ES2_compatibility; + break; + case 300: + supported = _mesa_is_gles3(this->ctx) || + this->ctx->Extensions.ARB_ES3_compatibility; + break; + default: + supported = false; + break; + } + } else { + switch (version) { + case 100: + this->es_shader = true; + supported = this->ctx->API == API_OPENGLES2 || + this->ctx->Extensions.ARB_ES2_compatibility; + break; + case 110: + case 120: + /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or + * the OpenGL 3.2 Core context is supported, this logic will need + * change. Older versions of GLSL are no longer supported + * outside the compatibility contexts of 3.x. + */ + case 130: + case 140: + case 150: + case 330: + case 400: + case 410: + case 420: + supported = _mesa_is_desktop_gl(this->ctx) && + ((unsigned) version) <= this->ctx->Const.GLSLVersion; + break; + default: + supported = false; + break; + } + } + + this->language_version = version; + + if (!supported) { + _mesa_glsl_error(locp, this, "%s is not supported. " + "Supported versions are: %s\n", + this->get_version_string(), + this->supported_version_string); + + /* On exit, the language_version must be set to a valid value. + * Later calls to _mesa_glsl_initialize_types will misbehave if + * the version is invalid. + */ + switch (this->ctx->API) { + case API_OPENGL_COMPAT: + case API_OPENGL_CORE: + this->language_version = this->ctx->Const.GLSLVersion; + break; + + case API_OPENGLES: + assert(!"Should not get here."); + /* FALLTHROUGH */ + + case API_OPENGLES2: + this->language_version = 100; + break; + } + } + + if (this->language_version >= 140) { + this->ARB_uniform_buffer_object_enable = true; + } + + if (this->language_version == 300 && this->es_shader) { + this->ARB_explicit_attrib_location_enable = true; + } +} + const char * _mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target) { diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 0b208f6ca..46e0784ba 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -56,6 +56,19 @@ struct glsl_switch_state { bool is_switch_innermost; // if switch stmt is closest to break, ... }; +const char * +glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version); + +typedef struct YYLTYPE { + int first_line; + int first_column; + int last_line; + int last_column; + unsigned source; +} YYLTYPE; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 + struct _mesa_glsl_parse_state { _mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, void *mem_ctx); @@ -77,6 +90,55 @@ struct _mesa_glsl_parse_state { ralloc_free(mem); } + /** + * Generate a string representing the GLSL version currently being compiled + * (useful for error messages). + */ + const char *get_version_string() + { + return glsl_compute_version_string(this, this->es_shader, + this->language_version); + } + + /** + * Determine whether the current GLSL version is sufficiently high to + * support a certain feature. + * + * \param required_glsl_version is the desktop GLSL version that is + * required to support the feature, or 0 if no version of desktop GLSL + * supports the feature. + * + * \param required_glsl_es_version is the GLSL ES version that is required + * to support the feature, or 0 if no version of GLSL ES suports the + * feature. + */ + bool is_version(unsigned required_glsl_version, + unsigned required_glsl_es_version) + { + unsigned required_version = this->es_shader ? + required_glsl_es_version : required_glsl_version; + return required_version != 0 + && this->language_version >= required_version; + } + + bool check_version(unsigned required_glsl_version, + unsigned required_glsl_es_version, + YYLTYPE *locp, const char *fmt, ...) PRINTFLIKE(5, 6); + + bool check_precision_qualifiers_allowed(YYLTYPE *locp) + { + return check_version(130, 100, locp, + "precision qualifiers are forbidden"); + } + + bool check_bitwise_operations_allowed(YYLTYPE *locp) + { + return check_version(130, 300, locp, "bit-wise operations are forbidden"); + } + + void process_version_directive(YYLTYPE *locp, int version, + const char *ident); + struct gl_context *const ctx; void *scanner; exec_list translation_unit; @@ -88,7 +150,6 @@ struct _mesa_glsl_parse_state { bool es_shader; unsigned language_version; - const char *version_string; enum _mesa_glsl_parser_targets target; /** @@ -129,6 +190,10 @@ struct _mesa_glsl_parse_state { /* ARB_draw_buffers */ unsigned MaxDrawBuffers; + + /* 3.00 ES */ + int MinProgramTexelOffset; + int MaxProgramTexelOffset; } Const; /** @@ -217,16 +282,6 @@ struct _mesa_glsl_parse_state { unsigned num_builtins_to_link; }; -typedef struct YYLTYPE { - int first_line; - int first_column; - int last_line; - int last_column; - unsigned source; -} YYLTYPE; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 - # define YYLLOC_DEFAULT(Current, Rhs, N) \ do { \ if (N) \ diff --git a/mesalib/src/glsl/glsl_symbol_table.cpp b/mesalib/src/glsl/glsl_symbol_table.cpp index bcb65d301..f934ea865 100644 --- a/mesalib/src/glsl/glsl_symbol_table.cpp +++ b/mesalib/src/glsl/glsl_symbol_table.cpp @@ -52,7 +52,7 @@ public: glsl_symbol_table::glsl_symbol_table() { - this->language_version = 120; + this->separate_function_namespace = false; this->table = _mesa_symbol_table_ctor(); this->mem_ctx = ralloc_context(NULL); } @@ -80,7 +80,7 @@ bool glsl_symbol_table::name_declared_this_scope(const char *name) bool glsl_symbol_table::add_variable(ir_variable *v) { - if (this->language_version == 110) { + if (this->separate_function_namespace) { /* In 1.10, functions and variables have separate namespaces. */ symbol_table_entry *existing = get_entry(v->name); if (name_declared_this_scope(v->name)) { @@ -120,7 +120,7 @@ bool glsl_symbol_table::add_type(const char *name, const glsl_type *t) bool glsl_symbol_table::add_function(ir_function *f) { - if (this->language_version == 110 && name_declared_this_scope(f->name)) { + if (this->separate_function_namespace && name_declared_this_scope(f->name)) { /* In 1.10, functions and variables have separate namespaces. */ symbol_table_entry *existing = get_entry(f->name); if ((existing->f == NULL) && (existing->t == NULL)) { diff --git a/mesalib/src/glsl/glsl_symbol_table.h b/mesalib/src/glsl/glsl_symbol_table.h index 637bc033b..9f5602787 100644 --- a/mesalib/src/glsl/glsl_symbol_table.h +++ b/mesalib/src/glsl/glsl_symbol_table.h @@ -77,7 +77,8 @@ public: glsl_symbol_table(); ~glsl_symbol_table(); - unsigned int language_version; + /* In 1.10, functions and variables have separate namespaces. */ + bool separate_function_namespace; void push_scope(); void pop_scope(); diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 3940a12a5..71b185027 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -102,11 +102,16 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields, static void add_types_to_symbol_table(glsl_symbol_table *symtab, const struct glsl_type *types, - unsigned num_types, bool warn) + unsigned num_types, bool warn, + bool skip_1d) { (void) warn; for (unsigned i = 0; i < num_types; i++) { + if (skip_1d && types[i].base_type == GLSL_TYPE_SAMPLER + && types[i].sampler_dimensionality == GLSL_SAMPLER_DIM_1D) + continue; + symtab->add_type(types[i].name, & types[i]); } } @@ -158,49 +163,68 @@ glsl_type::sampler_index() const void glsl_type::generate_100ES_types(glsl_symbol_table *symtab) { + bool skip_1d = false; add_types_to_symbol_table(symtab, builtin_core_types, Elements(builtin_core_types), - false); + false, skip_1d); add_types_to_symbol_table(symtab, builtin_structure_types, Elements(builtin_structure_types), - false); - add_types_to_symbol_table(symtab, void_type, 1, false); + false, skip_1d); + add_types_to_symbol_table(symtab, void_type, 1, false, skip_1d); +} + +void +glsl_type::generate_300ES_types(glsl_symbol_table *symtab) +{ + /* GLSL 3.00 ES types are the same as GLSL 1.30 types, except that 1D + * samplers are skipped, and samplerCubeShadow is added. + */ + bool add_deprecated = false; + bool skip_1d = true; + + generate_130_types(symtab, add_deprecated, skip_1d); + + add_types_to_symbol_table(symtab, &_samplerCubeShadow_type, 1, false, + skip_1d); } void -glsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated) +glsl_type::generate_110_types(glsl_symbol_table *symtab, bool add_deprecated, + bool skip_1d) { generate_100ES_types(symtab); add_types_to_symbol_table(symtab, builtin_110_types, Elements(builtin_110_types), - false); - add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false); + false, skip_1d); + add_types_to_symbol_table(symtab, &_sampler3D_type, 1, false, skip_1d); if (add_deprecated) { add_types_to_symbol_table(symtab, builtin_110_deprecated_structure_types, Elements(builtin_110_deprecated_structure_types), - false); + false, skip_1d); } } void -glsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated) +glsl_type::generate_120_types(glsl_symbol_table *symtab, bool add_deprecated, + bool skip_1d) { - generate_110_types(symtab, add_deprecated); + generate_110_types(symtab, add_deprecated, skip_1d); add_types_to_symbol_table(symtab, builtin_120_types, - Elements(builtin_120_types), false); + Elements(builtin_120_types), false, skip_1d); } void -glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated) +glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated, + bool skip_1d) { - generate_120_types(symtab, add_deprecated); + generate_120_types(symtab, add_deprecated, skip_1d); add_types_to_symbol_table(symtab, builtin_130_types, - Elements(builtin_130_types), false); + Elements(builtin_130_types), false, skip_1d); generate_EXT_texture_array_types(symtab, false); } @@ -208,14 +232,16 @@ glsl_type::generate_130_types(glsl_symbol_table *symtab, bool add_deprecated) void glsl_type::generate_140_types(glsl_symbol_table *symtab) { - generate_130_types(symtab, false); + bool skip_1d = false; + + generate_130_types(symtab, false, skip_1d); add_types_to_symbol_table(symtab, builtin_140_types, - Elements(builtin_140_types), false); + Elements(builtin_140_types), false, skip_1d); add_types_to_symbol_table(symtab, builtin_EXT_texture_buffer_object_types, Elements(builtin_EXT_texture_buffer_object_types), - false); + false, skip_1d); } @@ -223,9 +249,11 @@ void glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab, bool warn) { + bool skip_1d = false; + add_types_to_symbol_table(symtab, builtin_ARB_texture_rectangle_types, Elements(builtin_ARB_texture_rectangle_types), - warn); + warn, skip_1d); } @@ -233,16 +261,20 @@ void glsl_type::generate_EXT_texture_array_types(glsl_symbol_table *symtab, bool warn) { + bool skip_1d = false; + add_types_to_symbol_table(symtab, builtin_EXT_texture_array_types, Elements(builtin_EXT_texture_array_types), - warn); + warn, skip_1d); } void glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn) { - add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn); + bool skip_1d = false; + + add_types_to_symbol_table(symtab, &_sampler3D_type, 1, warn, skip_1d); } @@ -250,56 +282,74 @@ void glsl_type::generate_OES_EGL_image_external_types(glsl_symbol_table *symtab, bool warn) { + bool skip_1d = false; + add_types_to_symbol_table(symtab, builtin_OES_EGL_image_external_types, Elements(builtin_OES_EGL_image_external_types), - warn); + warn, skip_1d); } void glsl_type::generate_ARB_texture_cube_map_array_types(glsl_symbol_table *symtab, bool warn) { + bool skip_1d = false; + add_types_to_symbol_table(symtab, builtin_ARB_texture_cube_map_array_types, Elements(builtin_ARB_texture_cube_map_array_types), - warn); + warn, skip_1d); } void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state) { - switch (state->language_version) { - case 100: - assert(state->es_shader); - glsl_type::generate_100ES_types(state->symbols); - break; - case 110: - glsl_type::generate_110_types(state->symbols, true); - break; - case 120: - glsl_type::generate_120_types(state->symbols, true); - break; - case 130: - glsl_type::generate_130_types(state->symbols, true); - break; - case 140: - glsl_type::generate_140_types(state->symbols); - break; - default: - /* error */ - break; + if (state->es_shader) { + switch (state->language_version) { + case 100: + assert(state->es_shader); + glsl_type::generate_100ES_types(state->symbols); + break; + case 300: + glsl_type::generate_300ES_types(state->symbols); + break; + default: + assert(!"Unexpected language version"); + break; + } + } else { + bool skip_1d = false; + switch (state->language_version) { + case 110: + glsl_type::generate_110_types(state->symbols, true, skip_1d); + break; + case 120: + glsl_type::generate_120_types(state->symbols, true, skip_1d); + break; + case 130: + glsl_type::generate_130_types(state->symbols, true, skip_1d); + break; + case 140: + glsl_type::generate_140_types(state->symbols); + break; + default: + assert(!"Unexpected language version"); + break; + } } if (state->ARB_texture_rectangle_enable || - state->language_version >= 140) { + state->is_version(140, 0)) { glsl_type::generate_ARB_texture_rectangle_types(state->symbols, state->ARB_texture_rectangle_warn); } - if (state->OES_texture_3D_enable && state->language_version == 100) { + if (state->OES_texture_3D_enable + && state->is_version(0, 100)) { glsl_type::generate_OES_texture_3D_types(state->symbols, state->OES_texture_3D_warn); } - if (state->EXT_texture_array_enable && state->language_version < 130) { + if (state->EXT_texture_array_enable + && !state->is_version(130, 0)) { // These are already included in 130; don't create twice. glsl_type::generate_EXT_texture_array_types(state->symbols, state->EXT_texture_array_warn); diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index cf954a256..d6f5c105e 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -510,6 +510,7 @@ private: static const glsl_type _error_type; static const glsl_type _void_type; static const glsl_type _sampler3D_type; + static const glsl_type _samplerCubeShadow_type; static const glsl_type builtin_core_types[]; static const glsl_type builtin_structure_types[]; static const glsl_type builtin_110_deprecated_structure_types[]; @@ -534,9 +535,13 @@ private: */ /*@{*/ static void generate_100ES_types(glsl_symbol_table *); - static void generate_110_types(glsl_symbol_table *, bool add_deprecated); - static void generate_120_types(glsl_symbol_table *, bool add_deprecated); - static void generate_130_types(glsl_symbol_table *, bool add_deprecated); + static void generate_300ES_types(glsl_symbol_table *); + static void generate_110_types(glsl_symbol_table *, bool add_deprecated, + bool skip_1d); + static void generate_120_types(glsl_symbol_table *, bool add_deprecated, + bool skip_1d); + static void generate_130_types(glsl_symbol_table *, bool add_deprecated, + bool skip_1d); static void generate_140_types(glsl_symbol_table *); static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool); static void generate_EXT_texture_array_types(glsl_symbol_table *, bool); diff --git a/mesalib/src/glsl/hir_field_selection.cpp b/mesalib/src/glsl/hir_field_selection.cpp index 260b415a8..ac416d5da 100644 --- a/mesalib/src/glsl/hir_field_selection.cpp +++ b/mesalib/src/glsl/hir_field_selection.cpp @@ -72,8 +72,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr, } } else if (expr->subexpressions[1] != NULL) { /* Handle "method calls" in GLSL 1.20 - namely, array.length() */ - if (state->language_version < 120) - _mesa_glsl_error(&loc, state, "Methods not supported in GLSL 1.10."); + state->check_version(120, 300, &loc, "Methods not supported"); ast_expression *call = expr->subexpressions[1]; assert(call->oper == ast_function_call); diff --git a/mesalib/src/glsl/ir_variable_refcount.cpp b/mesalib/src/glsl/ir_variable_refcount.cpp index 1633a7357..923eb1a82 100644 --- a/mesalib/src/glsl/ir_variable_refcount.cpp +++ b/mesalib/src/glsl/ir_variable_refcount.cpp @@ -33,7 +33,26 @@ #include "ir_visitor.h" #include "ir_variable_refcount.h" #include "glsl_types.h" +#include "main/hash_table.h" +ir_variable_refcount_visitor::ir_variable_refcount_visitor() +{ + this->mem_ctx = ralloc_context(NULL); + this->ht = _mesa_hash_table_create(NULL, _mesa_key_pointer_equal); +} + +static void +free_entry(struct hash_entry *entry) +{ + ir_variable_refcount_entry *ivre = (ir_variable_refcount_entry *) entry->data; + delete ivre; +} + +ir_variable_refcount_visitor::~ir_variable_refcount_visitor() +{ + ralloc_free(this->mem_ctx); + _mesa_hash_table_destroy(this->ht, free_entry); +} // constructor ir_variable_refcount_entry::ir_variable_refcount_entry(ir_variable *var) @@ -50,15 +69,17 @@ ir_variable_refcount_entry * ir_variable_refcount_visitor::get_variable_entry(ir_variable *var) { assert(var); - foreach_iter(exec_list_iterator, iter, this->variable_list) { - ir_variable_refcount_entry *entry = (ir_variable_refcount_entry *)iter.get(); - if (entry->var == var) - return entry; - } - ir_variable_refcount_entry *entry = new(mem_ctx) ir_variable_refcount_entry(var); + struct hash_entry *e = _mesa_hash_table_search(this->ht, + _mesa_hash_pointer(var), + var); + if (e) + return (ir_variable_refcount_entry *)e->data; + + ir_variable_refcount_entry *entry = new ir_variable_refcount_entry(var); assert(entry->referenced_count == 0); - this->variable_list.push_tail(entry); + _mesa_hash_table_insert(this->ht, _mesa_hash_pointer(var), var, entry); + return entry; } diff --git a/mesalib/src/glsl/ir_variable_refcount.h b/mesalib/src/glsl/ir_variable_refcount.h index 51a4945a1..c15e8110d 100644 --- a/mesalib/src/glsl/ir_variable_refcount.h +++ b/mesalib/src/glsl/ir_variable_refcount.h @@ -33,7 +33,7 @@ #include "ir_visitor.h" #include "glsl_types.h" -class ir_variable_refcount_entry : public exec_node +class ir_variable_refcount_entry { public: ir_variable_refcount_entry(ir_variable *var); @@ -52,16 +52,8 @@ public: class ir_variable_refcount_visitor : public ir_hierarchical_visitor { public: - ir_variable_refcount_visitor(void) - { - this->mem_ctx = ralloc_context(NULL); - this->variable_list.make_empty(); - } - - ~ir_variable_refcount_visitor(void) - { - ralloc_free(this->mem_ctx); - } + ir_variable_refcount_visitor(void); + ~ir_variable_refcount_visitor(void); virtual ir_visitor_status visit(ir_variable *); virtual ir_visitor_status visit(ir_dereference_variable *); @@ -71,8 +63,7 @@ public: ir_variable_refcount_entry *get_variable_entry(ir_variable *var); - /* List of ir_variable_refcount_entry */ - exec_list variable_list; + struct hash_table *ht; void *mem_ctx; }; diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 3b2ab962b..29fc5d841 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -289,8 +289,11 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, * operations, if present, that operate on primitives after * vertex processing has occurred. Its value is undefined if * the vertex shader executable does not write gl_Position." + * + * GLSL ES 3.00 is similar to GLSL 1.40--failing to write to gl_Position is + * not an error. */ - if (prog->Version < 140) { + if (prog->Version < (prog->IsES ? 300 : 140)) { find_assignment_visitor find("gl_Position"); find.run(shader->ir); if (!find.variable_found()) { @@ -301,12 +304,15 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, prog->Vert.ClipDistanceArraySize = 0; - if (prog->Version >= 130) { + if (!prog->IsES && prog->Version >= 130) { /* From section 7.1 (Vertex Shader Special Variables) of the * GLSL 1.30 spec: * * "It is an error for a shader to statically write both * gl_ClipVertex and gl_ClipDistance." + * + * This does not apply to GLSL ES shaders, since GLSL ES defines neither + * gl_ClipVertex nor gl_ClipDistance. */ find_assignment_visitor clip_vertex("gl_ClipVertex"); find_assignment_visitor clip_distance("gl_ClipDistance"); @@ -2144,7 +2150,7 @@ assign_varying_locations(struct gl_context *ctx, } } - if (ctx->API == API_OPENGLES2 || prog->Version == 100) { + if (ctx->API == API_OPENGLES2 || prog->IsES) { if (varying_vectors > ctx->Const.MaxVarying) { if (ctx->Const.GLSLSkipStrictMaxVaryingLimitCheck) { linker_warning(prog, "shader uses too many varying vectors " @@ -2421,10 +2427,18 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) unsigned min_version = UINT_MAX; unsigned max_version = 0; + const bool is_es_prog = + (prog->NumShaders > 0 && prog->Shaders[0]->IsES) ? true : false; for (unsigned i = 0; i < prog->NumShaders; i++) { min_version = MIN2(min_version, prog->Shaders[i]->Version); max_version = MAX2(max_version, prog->Shaders[i]->Version); + if (prog->Shaders[i]->IsES != is_es_prog) { + linker_error(prog, "all shaders must use same shading " + "language version\n"); + goto done; + } + switch (prog->Shaders[i]->Type) { case GL_VERTEX_SHADER: vert_shader_list[num_vert_shaders] = prog->Shaders[i]; @@ -2444,10 +2458,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) /* Previous to GLSL version 1.30, different compilation units could mix and * match shading language versions. With GLSL 1.30 and later, the versions * of all shaders must match. + * + * GLSL ES has never allowed mixing of shading language versions. */ - assert(min_version >= 100); - assert(max_version <= 140); - if ((max_version >= 130 || min_version == 100) + if ((is_es_prog || max_version >= 130) && min_version != max_version) { linker_error(prog, "all shaders must use same shading " "language version\n"); @@ -2455,6 +2469,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } prog->Version = max_version; + prog->IsES = is_es_prog; for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { if (prog->_LinkedShaders[i] != NULL) @@ -2528,8 +2543,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) /* Implement the GLSL 1.30+ rule for discard vs infinite loops Do * it before optimization because we want most of the checks to get * dropped thanks to constant propagation. + * + * This rule also applies to GLSL ES 3.00. */ - if (max_version >= 130) { + if (max_version >= (is_es_prog ? 300 : 130)) { struct gl_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; if (sh) { lower_discard_flow(sh->ir); @@ -2673,11 +2690,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) goto done; /* OpenGL ES requires that a vertex shader and a fragment shader both be - * present in a linked program. By checking for use of shading language - * version 1.00, we also catch the GL_ARB_ES2_compatibility case. + * present in a linked program. By checking prog->IsES, we also + * catch the GL_ARB_ES2_compatibility case. */ if (!prog->InternalSeparateShader && - (ctx->API == API_OPENGLES2 || prog->Version == 100)) { + (ctx->API == API_OPENGLES2 || prog->IsES)) { if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { linker_error(prog, "program lacks a vertex shader\n"); } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) { diff --git a/mesalib/src/glsl/lower_output_reads.cpp b/mesalib/src/glsl/lower_output_reads.cpp index 90d71b04a..a6192a517 100644 --- a/mesalib/src/glsl/lower_output_reads.cpp +++ b/mesalib/src/glsl/lower_output_reads.cpp @@ -97,6 +97,7 @@ output_read_remover::visit(ir_dereference_variable *ir) temp = new(var_ctx) ir_variable(ir->var->type, ir->var->name, ir_var_temporary); hash_table_insert(replacements, temp, ir->var); + ir->var->insert_after(temp); } /* Update the dereference to use the temporary */ diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index 33cd79c85..a84d010f4 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -48,6 +48,7 @@ initialize_context(struct gl_context *ctx, gl_api api) * everything in order to compile the built-in functions. */ ctx->Const.GLSLVersion = 140; + ctx->Extensions.ARB_ES3_compatibility = true; ctx->Const.MaxClipPlanes = 8; ctx->Const.MaxDrawBuffers = 2; @@ -190,6 +191,7 @@ compile_shader(struct gl_context *ctx, struct gl_shader *shader) shader->symbols = state->symbols; shader->CompileStatus = !state->error; shader->Version = state->language_version; + shader->IsES = state->es_shader; memcpy(shader->builtins_to_link, state->builtins_to_link, sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); shader->num_builtins_to_link = state->num_builtins_to_link; diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp index de8475f95..47247e20d 100644 --- a/mesalib/src/glsl/opt_dead_code.cpp +++ b/mesalib/src/glsl/opt_dead_code.cpp @@ -31,6 +31,7 @@ #include "ir_visitor.h" #include "ir_variable_refcount.h" #include "glsl_types.h" +#include "main/hash_table.h" static bool debug = false; @@ -49,8 +50,9 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned) v.run(instructions); - foreach_iter(exec_list_iterator, iter, v.variable_list) { - ir_variable_refcount_entry *entry = (ir_variable_refcount_entry *)iter.get(); + struct hash_entry *e; + hash_table_foreach(v.ht, e) { + ir_variable_refcount_entry *entry = (ir_variable_refcount_entry *)e->data; /* Since each assignment is a reference, the refereneced count must be * greater than or equal to the assignment count. If they are equal, diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp index 120ee9534..33d3804c6 100644 --- a/mesalib/src/glsl/standalone_scaffolding.cpp +++ b/mesalib/src/glsl/standalone_scaffolding.cpp @@ -73,6 +73,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) ctx->Extensions.dummy_false = false; ctx->Extensions.dummy_true = true; ctx->Extensions.ARB_ES2_compatibility = true; + ctx->Extensions.ARB_ES3_compatibility = false; ctx->Extensions.ARB_draw_instanced = true; ctx->Extensions.ARB_fragment_coord_conventions = true; ctx->Extensions.EXT_texture_array = true; |