aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/Android.mk95
-rw-r--r--mesalib/src/glsl/Makefile82
-rw-r--r--mesalib/src/glsl/Makefile.sources104
-rw-r--r--mesalib/src/glsl/SConscript82
-rw-r--r--mesalib/src/glsl/ast.h1
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp81
-rw-r--r--mesalib/src/glsl/ast_type.cpp1
-rw-r--r--mesalib/src/glsl/builtin_types.h10
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll962
-rw-r--r--mesalib/src/glsl/glsl_parser.yy2
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp1
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h2
-rw-r--r--mesalib/src/glsl/glsl_types.cpp41
-rw-r--r--mesalib/src/glsl/glsl_types.h16
-rw-r--r--mesalib/src/glsl/ir.cpp5
-rw-r--r--mesalib/src/glsl/ir.h34
-rw-r--r--mesalib/src/glsl/ir_clone.cpp5
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp4
-rw-r--r--mesalib/src/glsl/ir_reader.cpp6
-rw-r--r--mesalib/src/glsl/ir_validate.cpp7
-rw-r--r--mesalib/src/glsl/ir_variable.cpp13
-rw-r--r--mesalib/src/glsl/linker.cpp107
-rw-r--r--mesalib/src/glsl/ralloc.c8
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
26 files changed, 918 insertions, 757 deletions
diff --git a/mesalib/src/glsl/Android.mk b/mesalib/src/glsl/Android.mk
index 9bf4ff782..d7d17dd6d 100644
--- a/mesalib/src/glsl/Android.mk
+++ b/mesalib/src/glsl/Android.mk
@@ -25,81 +25,7 @@
LOCAL_PATH := $(call my-dir)
-# from Makefile
-LIBGLCPP_SOURCES = \
- glcpp/glcpp-lex.c \
- glcpp/glcpp-parse.c \
- glcpp/pp.c
-
-C_SOURCES = \
- strtod.c \
- ralloc.c \
- $(LIBGLCPP_SOURCES)
-
-CXX_SOURCES = \
- ast_expr.cpp \
- ast_function.cpp \
- ast_to_hir.cpp \
- ast_type.cpp \
- glsl_lexer.cpp \
- glsl_parser.cpp \
- glsl_parser_extras.cpp \
- glsl_types.cpp \
- glsl_symbol_table.cpp \
- hir_field_selection.cpp \
- ir_basic_block.cpp \
- ir_clone.cpp \
- ir_constant_expression.cpp \
- ir.cpp \
- ir_expression_flattening.cpp \
- ir_function_can_inline.cpp \
- ir_function_detect_recursion.cpp \
- ir_function.cpp \
- ir_hierarchical_visitor.cpp \
- ir_hv_accept.cpp \
- ir_import_prototypes.cpp \
- ir_print_visitor.cpp \
- ir_reader.cpp \
- ir_rvalue_visitor.cpp \
- ir_set_program_inouts.cpp \
- ir_validate.cpp \
- ir_variable.cpp \
- ir_variable_refcount.cpp \
- linker.cpp \
- link_functions.cpp \
- loop_analysis.cpp \
- loop_controls.cpp \
- loop_unroll.cpp \
- lower_clip_distance.cpp \
- lower_discard.cpp \
- lower_if_to_cond_assign.cpp \
- lower_instructions.cpp \
- lower_jumps.cpp \
- lower_mat_op_to_vec.cpp \
- lower_noise.cpp \
- lower_texture_projection.cpp \
- lower_variable_index_to_cond_assign.cpp \
- lower_vec_index_to_cond_assign.cpp \
- lower_vec_index_to_swizzle.cpp \
- lower_vector.cpp \
- opt_algebraic.cpp \
- opt_constant_folding.cpp \
- opt_constant_propagation.cpp \
- opt_constant_variable.cpp \
- opt_copy_propagation.cpp \
- opt_copy_propagation_elements.cpp \
- opt_dead_code.cpp \
- opt_dead_code_local.cpp \
- opt_dead_functions.cpp \
- opt_discard_simplification.cpp \
- opt_function_inlining.cpp \
- opt_if_simplification.cpp \
- opt_noop_swizzle.cpp \
- opt_redundant_jumps.cpp \
- opt_structure_splitting.cpp \
- opt_swizzle_swizzle.cpp \
- opt_tree_grafting.cpp \
- s_expression.cpp
+include $(LOCAL_PATH)/Makefile.sources
# ---------------------------------------
# Build libmesa_glsl
@@ -108,9 +34,9 @@ CXX_SOURCES = \
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- $(C_SOURCES) \
- $(CXX_SOURCES) \
- builtin_function.cpp
+ $(LIBGLCPP_SOURCES) \
+ $(LIBGLSL_SOURCES) \
+ $(LIBGLSL_CXX_SOURCES)
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/mapi \
@@ -129,11 +55,11 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- $(C_SOURCES) \
- $(CXX_SOURCES) \
- builtin_stubs.cpp \
- main.cpp \
- standalone_scaffolding.cpp
+ $(LIBGLCPP_SOURCES) \
+ $(LIBGLSL_SOURCES) \
+ $(LIBGLSL_CXX_SOURCES) \
+ $(BUILTIN_COMPILER_CXX_SOURCES) \
+ $(GLSL_COMPILER_CXX_SOURCES)
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/mapi \
@@ -156,8 +82,7 @@ include $(BUILD_HOST_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
- main.cpp \
- standalone_scaffolding.cpp
+ $(GLSL_COMPILER_CXX_SOURCES)
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/mapi \
diff --git a/mesalib/src/glsl/Makefile b/mesalib/src/glsl/Makefile
index 504f1fb43..d9ecbc8e3 100644
--- a/mesalib/src/glsl/Makefile
+++ b/mesalib/src/glsl/Makefile
@@ -7,86 +7,23 @@ include $(TOP)/configs/current
LIBNAME = glsl
-LIBGLCPP_SOURCES = \
- glcpp/glcpp-lex.c \
- glcpp/glcpp-parse.c \
- glcpp/pp.c
+include Makefile.sources
GLCPP_SOURCES = \
+ $(LIBGLCPP_GENERATED_SOURCES) \
$(LIBGLCPP_SOURCES) \
ralloc.c \
glcpp/glcpp.c
C_SOURCES = \
- strtod.c \
- ralloc.c \
- $(LIBGLCPP_SOURCES)
+ $(LIBGLCPP_GENERATED_SOURCES) \
+ $(LIBGLCPP_SOURCES) \
+ $(LIBGLSL_SOURCES)
+# common sources for builtin_compiler and libglsl
CXX_SOURCES = \
- ast_expr.cpp \
- ast_function.cpp \
- ast_to_hir.cpp \
- ast_type.cpp \
- glsl_lexer.cpp \
- glsl_parser.cpp \
- glsl_parser_extras.cpp \
- glsl_types.cpp \
- glsl_symbol_table.cpp \
- hir_field_selection.cpp \
- ir_basic_block.cpp \
- ir_clone.cpp \
- ir_constant_expression.cpp \
- ir.cpp \
- ir_expression_flattening.cpp \
- ir_function_can_inline.cpp \
- ir_function_detect_recursion.cpp \
- ir_function.cpp \
- ir_hierarchical_visitor.cpp \
- ir_hv_accept.cpp \
- ir_import_prototypes.cpp \
- ir_print_visitor.cpp \
- ir_reader.cpp \
- ir_rvalue_visitor.cpp \
- ir_set_program_inouts.cpp \
- ir_validate.cpp \
- ir_variable.cpp \
- ir_variable_refcount.cpp \
- linker.cpp \
- link_functions.cpp \
- link_uniforms.cpp \
- loop_analysis.cpp \
- loop_controls.cpp \
- loop_unroll.cpp \
- lower_clip_distance.cpp \
- lower_discard.cpp \
- lower_if_to_cond_assign.cpp \
- lower_instructions.cpp \
- lower_jumps.cpp \
- lower_mat_op_to_vec.cpp \
- lower_noise.cpp \
- lower_texture_projection.cpp \
- lower_variable_index_to_cond_assign.cpp \
- lower_vec_index_to_cond_assign.cpp \
- lower_vec_index_to_swizzle.cpp \
- lower_vector.cpp \
- opt_algebraic.cpp \
- opt_constant_folding.cpp \
- opt_constant_propagation.cpp \
- opt_constant_variable.cpp \
- opt_copy_propagation.cpp \
- opt_copy_propagation_elements.cpp \
- opt_dead_code.cpp \
- opt_dead_code_local.cpp \
- opt_dead_functions.cpp \
- opt_discard_simplification.cpp \
- opt_function_inlining.cpp \
- opt_if_simplification.cpp \
- opt_noop_swizzle.cpp \
- opt_redundant_jumps.cpp \
- opt_structure_splitting.cpp \
- opt_swizzle_swizzle.cpp \
- opt_tree_grafting.cpp \
- s_expression.cpp
+ $(BUILTIN_COMPILER_GENERATED_CXX_SOURCES) \
+ $(LIBGLSL_CXX_SOURCES)
LIBS = \
$(TOP)/src/glsl/libglsl.a
@@ -97,8 +34,7 @@ GLSL2_C_SOURCES = \
../mesa/program/hash_table.c \
../mesa/program/symbol_table.c
GLSL2_CXX_SOURCES = \
- main.cpp \
- standalone_scaffolding.cpp
+ $(GLSL_COMPILER_CXX_SOURCES)
GLSL2_OBJECTS = \
$(GLSL2_C_SOURCES:.c=.o) \
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
new file mode 100644
index 000000000..b4bfff09c
--- /dev/null
+++ b/mesalib/src/glsl/Makefile.sources
@@ -0,0 +1,104 @@
+# shared source lists for Makefile, SConscript, and Android.mk
+
+# libglcpp
+
+LIBGLCPP_SOURCES := \
+ glcpp/pp.c
+
+LIBGLCPP_GENERATED_SOURCES := \
+ glcpp/glcpp-lex.c \
+ glcpp/glcpp-parse.c
+
+# libglsl
+
+LIBGLSL_SOURCES := \
+ strtod.c \
+ ralloc.c
+
+LIBGLSL_CXX_SOURCES := \
+ ast_expr.cpp \
+ ast_function.cpp \
+ ast_to_hir.cpp \
+ ast_type.cpp \
+ glsl_parser_extras.cpp \
+ glsl_types.cpp \
+ glsl_symbol_table.cpp \
+ hir_field_selection.cpp \
+ ir_basic_block.cpp \
+ ir_clone.cpp \
+ ir_constant_expression.cpp \
+ ir.cpp \
+ ir_expression_flattening.cpp \
+ ir_function_can_inline.cpp \
+ ir_function_detect_recursion.cpp \
+ ir_function.cpp \
+ ir_hierarchical_visitor.cpp \
+ ir_hv_accept.cpp \
+ ir_import_prototypes.cpp \
+ ir_print_visitor.cpp \
+ ir_reader.cpp \
+ ir_rvalue_visitor.cpp \
+ ir_set_program_inouts.cpp \
+ ir_validate.cpp \
+ ir_variable.cpp \
+ ir_variable_refcount.cpp \
+ linker.cpp \
+ link_functions.cpp \
+ link_uniforms.cpp \
+ loop_analysis.cpp \
+ loop_controls.cpp \
+ loop_unroll.cpp \
+ lower_clip_distance.cpp \
+ lower_discard.cpp \
+ lower_if_to_cond_assign.cpp \
+ lower_instructions.cpp \
+ lower_jumps.cpp \
+ lower_mat_op_to_vec.cpp \
+ lower_noise.cpp \
+ lower_texture_projection.cpp \
+ lower_variable_index_to_cond_assign.cpp \
+ lower_vec_index_to_cond_assign.cpp \
+ lower_vec_index_to_swizzle.cpp \
+ lower_vector.cpp \
+ opt_algebraic.cpp \
+ opt_constant_folding.cpp \
+ opt_constant_propagation.cpp \
+ opt_constant_variable.cpp \
+ opt_copy_propagation.cpp \
+ opt_copy_propagation_elements.cpp \
+ opt_dead_code.cpp \
+ opt_dead_code_local.cpp \
+ opt_dead_functions.cpp \
+ opt_discard_simplification.cpp \
+ opt_function_inlining.cpp \
+ opt_if_simplification.cpp \
+ opt_noop_swizzle.cpp \
+ opt_redundant_jumps.cpp \
+ opt_structure_splitting.cpp \
+ opt_swizzle_swizzle.cpp \
+ opt_tree_grafting.cpp \
+ s_expression.cpp
+
+# glsl_compiler
+
+GLSL_COMPILER_CXX_SOURCES := \
+ standalone_scaffolding.cpp \
+ main.cpp
+
+# builtin_compiler
+#
+# This is built before libglsl to generate builtin_funciton.cpp for libglsl.
+# For this to work, a dummy version of builtin_function.cpp,
+# builtin_stubs.cpp, is used.
+
+BUILTIN_COMPILER_CXX_SOURCES := \
+ builtin_stubs.cpp
+
+BUILTIN_COMPILER_GENERATED_CXX_SOURCES := \
+ glsl_lexer.cpp \
+ glsl_parser.cpp
+
+# libglsl generated sources
+LIBGLSL_GENERATED_CXX_SOURCES := \
+ $(BUILTIN_COMPILER_GENERATED_CXX_SOURCES) \
+ builtin_function.cpp
diff --git a/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript
index 09c7edbc4..b8154d608 100644
--- a/mesalib/src/glsl/SConscript
+++ b/mesalib/src/glsl/SConscript
@@ -30,78 +30,21 @@ glcpp_parser = env.CFile('glcpp/glcpp-parse.c', 'glcpp/glcpp-parse.y')
glsl_lexer = parser_env.CXXFile('glsl_lexer.cpp', 'glsl_lexer.ll')
glsl_parser = parser_env.CXXFile('glsl_parser.cpp', 'glsl_parser.yy')
+# common generated sources
glsl_sources = [
glcpp_lexer,
glcpp_parser[0],
- 'glcpp/pp.c',
- 'ast_expr.cpp',
- 'ast_function.cpp',
- 'ast_to_hir.cpp',
- 'ast_type.cpp',
glsl_lexer,
glsl_parser[0],
- 'glsl_parser_extras.cpp',
- 'glsl_types.cpp',
- 'glsl_symbol_table.cpp',
- 'hir_field_selection.cpp',
- 'ir_basic_block.cpp',
- 'ir_clone.cpp',
- 'ir_constant_expression.cpp',
- 'ir.cpp',
- 'ir_expression_flattening.cpp',
- 'ir_function_can_inline.cpp',
- 'ir_function_detect_recursion.cpp',
- 'ir_function.cpp',
- 'ir_hierarchical_visitor.cpp',
- 'ir_hv_accept.cpp',
- 'ir_import_prototypes.cpp',
- 'ir_print_visitor.cpp',
- 'ir_reader.cpp',
- 'ir_rvalue_visitor.cpp',
- 'ir_set_program_inouts.cpp',
- 'ir_validate.cpp',
- 'ir_variable.cpp',
- 'ir_variable_refcount.cpp',
- 'linker.cpp',
- 'link_functions.cpp',
- 'link_uniforms.cpp',
- 'loop_analysis.cpp',
- 'loop_controls.cpp',
- 'loop_unroll.cpp',
- 'lower_clip_distance.cpp',
- 'lower_discard.cpp',
- 'lower_if_to_cond_assign.cpp',
- 'lower_instructions.cpp',
- 'lower_jumps.cpp',
- 'lower_mat_op_to_vec.cpp',
- 'lower_noise.cpp',
- 'lower_variable_index_to_cond_assign.cpp',
- 'lower_vec_index_to_cond_assign.cpp',
- 'lower_vec_index_to_swizzle.cpp',
- 'lower_vector.cpp',
- 'opt_algebraic.cpp',
- 'opt_constant_folding.cpp',
- 'opt_constant_propagation.cpp',
- 'opt_constant_variable.cpp',
- 'opt_copy_propagation.cpp',
- 'opt_copy_propagation_elements.cpp',
- 'opt_dead_code.cpp',
- 'opt_dead_code_local.cpp',
- 'opt_dead_functions.cpp',
- 'opt_discard_simplification.cpp',
- 'opt_function_inlining.cpp',
- 'opt_if_simplification.cpp',
- 'opt_noop_swizzle.cpp',
- 'opt_redundant_jumps.cpp',
- 'opt_structure_splitting.cpp',
- 'opt_swizzle_swizzle.cpp',
- 'opt_tree_grafting.cpp',
- 'ralloc.c',
- 's_expression.cpp',
- 'standalone_scaffolding.cpp',
- 'strtod.c',
]
+# parse Makefile.sources
+source_lists = env.ParseSourceList('Makefile.sources')
+
+# add non-generated sources
+for l in ('LIBGLCPP_SOURCES', 'LIBGLSL_SOURCES', 'LIBGLSL_CXX_SOURCES'):
+ glsl_sources += source_lists[l]
+
if env['msvc']:
env.Prepend(CPPPATH = ['#/src/getopt'])
env.PrependUnique(LIBS = [getopt])
@@ -114,16 +57,19 @@ else:
env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE'))
env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
- main_obj = env.StaticObject('main.cpp')
+ compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_SOURCES'])
mesa_objs = env.StaticObject([
'hash_table.c',
'symbol_table.c',
])
+ compiler_objs += mesa_objs
+
builtin_compiler = env.Program(
target = 'builtin_compiler',
- source = main_obj + glsl_sources + ['builtin_stubs.cpp'] + mesa_objs,
+ source = compiler_objs + glsl_sources + \
+ source_lists['BUILTIN_COMPILER_CXX_SOURCES'],
)
# SCons builtin dependency scanner doesn't detect that glsl_lexer.ll
@@ -174,7 +120,7 @@ env.Prepend(LIBS = [glsl])
glsl2 = env.Program(
target = 'glsl2',
- source = main_obj + mesa_objs,
+ source = compiler_objs,
)
env.Alias('glsl2', glsl2)
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index 532347df4..9fe6c4125 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -437,6 +437,7 @@ enum ast_types {
ast_sampler2drect,
ast_sampler3d,
ast_samplercube,
+ ast_samplerexternaloes,
ast_sampler1dshadow,
ast_sampler2dshadow,
ast_sampler2drectshadow,
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index fa6206e5e..ed6abdc70 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -935,6 +935,28 @@ check_builtin_array_max_size(const char *name, unsigned size,
return false;
}
+/**
+ * Create the constant 1, of a which is appropriate for incrementing and
+ * decrementing values of the given GLSL type. For example, if type is vec4,
+ * this creates a constant value of 1.0 having type float.
+ *
+ * If the given type is invalid for increment and decrement operators, return
+ * a floating point 1--the error will be detected later.
+ */
+static ir_rvalue *
+constant_one_for_inc_dec(void *ctx, const glsl_type *type)
+{
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ return new(ctx) ir_constant((unsigned) 1);
+ case GLSL_TYPE_INT:
+ return new(ctx) ir_constant(1);
+ default:
+ case GLSL_TYPE_FLOAT:
+ return new(ctx) ir_constant(1.0f);
+ }
+}
+
ir_rvalue *
ast_expression::hir(exec_list *instructions,
struct _mesa_glsl_parse_state *state)
@@ -1442,10 +1464,7 @@ ast_expression::hir(exec_list *instructions,
case ast_pre_inc:
case ast_pre_dec: {
op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
+ op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
type = arithmetic_result_type(op[0], op[1], false, state, & loc);
@@ -1463,10 +1482,7 @@ ast_expression::hir(exec_list *instructions,
case ast_post_inc:
case ast_post_dec: {
op[0] = this->subexpressions[0]->hir(instructions, state);
- if (op[0]->type->base_type == GLSL_TYPE_FLOAT)
- op[1] = new(ctx) ir_constant(1.0f);
- else
- op[1] = new(ctx) ir_constant(1);
+ op[1] = constant_one_for_inc_dec(ctx, op[0]->type);
error_emitted = op[0]->type->is_error() || op[1]->type->is_error();
@@ -1812,7 +1828,17 @@ process_array_type(YYLTYPE *loc, const glsl_type *base, ast_node *array_size,
{
unsigned length = 0;
- /* FINISHME: Reject delcarations of multidimensional arrays. */
+ /* From page 19 (page 25) of the GLSL 1.20 spec:
+ *
+ * "Only one-dimensional arrays may be declared."
+ */
+ if (base->is_array()) {
+ _mesa_glsl_error(loc, state,
+ "invalid array of `%s' (only one-dimensional arrays "
+ "may be declared)",
+ base->name);
+ return glsl_type::error_type;
+ }
if (array_size != NULL) {
exec_list dummy_instructions;
@@ -2341,6 +2367,9 @@ process_initializer(ir_variable *var, ast_declaration *decl,
} else
initializer_type = rhs->type;
+ var->constant_initializer = rhs->constant_expression_value();
+ var->has_initializer = true;
+
/* If the declared variable is an unsized array, it must inherrit
* its full type from the initializer. A declaration such as
*
@@ -2445,14 +2474,32 @@ ast_declarator_list::hir(exec_list *instructions,
decl_type = this->type->specifier->glsl_type(& type_name, state);
if (this->declarations.is_empty()) {
- if (decl_type != NULL) {
- /* Warn if this empty declaration is not for declaring a structure.
- */
- if (this->type->specifier->structure == NULL) {
+ /* If there is no structure involved in the program text, there are two
+ * possible scenarios:
+ *
+ * - The program text contained something like 'vec4;'. This is an
+ * empty declaration. It is valid but weird. Emit a warning.
+ *
+ * - The program text contained something like 'S;' and 'S' is not the
+ * name of a known structure type. This is both invalid and weird.
+ * Emit an error.
+ *
+ * Note that if decl_type is NULL and there is a structure involved,
+ * there must have been some sort of error with the structure. In this
+ * case we assume that an error was already generated on this line of
+ * code for the structure. There is no need to generate an additional,
+ * confusing error.
+ */
+ assert(this->type->specifier->structure == NULL || decl_type != NULL
+ || state->error);
+ if (this->type->specifier->structure == NULL) {
+ if (decl_type != NULL) {
_mesa_glsl_warning(&loc, state, "empty declaration");
+ } else {
+ _mesa_glsl_error(&loc, state,
+ "invalid type `%s' in empty declaration",
+ type_name);
}
- } else {
- _mesa_glsl_error(& loc, state, "incomplete declaration");
}
}
@@ -2480,6 +2527,8 @@ ast_declarator_list::hir(exec_list *instructions,
if (decl->is_array) {
var_type = process_array_type(&loc, decl_type, decl->array_size,
state);
+ if (var_type->is_error())
+ continue;
} else {
var_type = decl_type;
}
@@ -2921,7 +2970,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
type = process_array_type(&loc, type, this->array_size, state);
}
- if (type->array_size() == 0) {
+ if (!type->is_error() && type->array_size() == 0) {
_mesa_glsl_error(&loc, state, "arrays passed as parameters must have "
"a declared size.");
type = glsl_type::error_type;
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index c680ae5f6..79c43eefb 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -83,6 +83,7 @@ ast_type_specifier::ast_type_specifier(int specifier)
"sampler2DRect",
"sampler3D",
"samplerCube",
+ "samplerExternalOES",
"sampler1DShadow",
"sampler2DShadow",
"sampler2DRectShadow",
diff --git a/mesalib/src/glsl/builtin_types.h b/mesalib/src/glsl/builtin_types.h
index 58b9a8127..cc99b1bde 100644
--- a/mesalib/src/glsl/builtin_types.h
+++ b/mesalib/src/glsl/builtin_types.h
@@ -300,3 +300,13 @@ const glsl_type glsl_type::builtin_EXT_texture_buffer_object_types[] = {
GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT, "usamplerBuffer"),
};
/*@}*/
+
+/** \name Sampler types added by GL_OES_EGL_image_external
+ */
+/*@{*/
+
+const glsl_type glsl_type::builtin_OES_EGL_image_external_types[] = {
+ glsl_type(GL_SAMPLER_EXTERNAL_OES,
+ GLSL_SAMPLER_DIM_EXTERNAL, 0, 0, GLSL_TYPE_FLOAT, "samplerExternalOES"),
+};
+/*@}*/
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index 17941a9be..1b17ff43a 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -1136,6 +1136,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
add_builtin_define(parser, "GL_AMD_conservative_depth", 1);
add_builtin_define(parser, "GL_ARB_conservative_depth", 1);
}
+
+ if (extensions->OES_EGL_image_external)
+ add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
}
language_version = 110;
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index 267ca0f1c..49f3bc82e 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -1,457 +1,505 @@
-%{
-/*
- * Copyright © 2008, 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <ctype.h>
-#include "strtod.h"
-#include "ast.h"
-#include "glsl_parser_extras.h"
-#include "glsl_parser.h"
-
-static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
-
-#ifdef _MSC_VER
-#define YY_NO_UNISTD_H
-#endif
-
-#define YY_USER_ACTION \
- do { \
- yylloc->source = 0; \
- yylloc->first_column = yycolumn + 1; \
- yylloc->first_line = yylineno + 1; \
- yycolumn += yyleng; \
- } while(0);
-
-#define YY_USER_INIT yylineno = 0; yycolumn = 0;
-
-#define IS_UINT (yytext[yyleng - 1] == 'u' || yytext[yyleng - 1] == 'U')
-
-/* A macro for handling reserved words and keywords across language versions.
- *
- * Certain words start out as identifiers, become reserved words in
- * later language revisions, and finally become language keywords.
- *
- * For example, consider the following lexer rule:
- * samplerBuffer KEYWORD(130, 140, 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
- */
-#define KEYWORD(reserved_version, allowed_version, token) \
- do { \
- if (yyextra->language_version >= allowed_version) { \
- return token; \
- } else if (yyextra->language_version >= reserved_version) { \
- _mesa_glsl_error(yylloc, yyextra, \
- "Illegal use of reserved word `%s'", yytext); \
- return ERROR_TOK; \
- } else { \
- yylval->identifier = strdup(yytext); \
- return classify_identifier(yyextra, yytext); \
- } \
- } 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.
- */
-#define ES yyextra->es_shader
-%}
-
-%option bison-bridge bison-locations reentrant noyywrap
-%option nounput noyy_top_state
-%option never-interactive
-%option prefix="_mesa_glsl_"
-%option extra-type="struct _mesa_glsl_parse_state *"
-
-%x PP PRAGMA
-
-DEC_INT [1-9][0-9]*
-HEX_INT 0[xX][0-9a-fA-F]+
-OCT_INT 0[0-7]*
-INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
-SPC [ \t]*
-SPCP [ \t]+
-HASH ^{SPC}#{SPC}
-%%
-
-[ \r\t]+ ;
-
- /* Preprocessor tokens. */
-^[ \t]*#[ \t]*$ ;
-^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
-^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
-{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
- yylloc->source = strtol(ptr, NULL, 0);
- }
-{HASH}line{SPCP}{INT}{SPC}$ {
- /* Eat characters until the first digit is
- * encountered
- */
- char *ptr = yytext;
- while (!isdigit(*ptr))
- ptr++;
-
- /* Subtract one from the line number because
- * yylineno is zero-based instead of
- * one-based.
- */
- yylineno = strtol(ptr, &ptr, 0) - 1;
- }
-^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
- BEGIN PP;
- return PRAGMA_DEBUG_ON;
- }
-^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) {
- BEGIN PP;
- return PRAGMA_DEBUG_OFF;
- }
-^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) {
- BEGIN PP;
- return PRAGMA_OPTIMIZE_ON;
- }
-^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) {
- BEGIN PP;
- return PRAGMA_OPTIMIZE_OFF;
- }
-^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) {
- BEGIN PP;
- return PRAGMA_INVARIANT_ALL;
- }
-^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; }
-
-<PRAGMA>\n { BEGIN 0; yylineno++; yycolumn = 0; }
-<PRAGMA>. { }
-
-<PP>\/\/[^\n]* { }
-<PP>[ \t\r]* { }
-<PP>: return COLON;
-<PP>[_a-zA-Z][_a-zA-Z0-9]* {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
-<PP>[1-9][0-9]* {
- yylval->n = strtol(yytext, NULL, 10);
- return INTCONSTANT;
- }
-<PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
-
-\n { yylineno++; yycolumn = 0; }
-
-attribute return ATTRIBUTE;
-const return CONST_TOK;
-bool return BOOL_TOK;
-float return FLOAT_TOK;
-int return INT_TOK;
-uint KEYWORD(130, 130, UINT_TOK);
-
-break return BREAK;
-continue return CONTINUE;
-do return DO;
-while return WHILE;
-else return ELSE;
-for return FOR;
-if return IF;
-discard return DISCARD;
-return return RETURN;
-
-bvec2 return BVEC2;
-bvec3 return BVEC3;
-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);
-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);
-
-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;
-sampler2D return SAMPLER2D;
-sampler3D return SAMPLER3D;
-samplerCube return SAMPLERCUBE;
-sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY);
-sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY);
-sampler1DShadow return 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);
-
-
-struct return STRUCT;
-void return VOID_TOK;
-
-layout {
- if ((yyextra->language_version >= 140)
- || yyextra->AMD_conservative_depth_enable
- || yyextra->ARB_explicit_attrib_location_enable
- || yyextra->ARB_fragment_coord_conventions_enable) {
- return LAYOUT_TOK;
- } else {
- yylval->identifier = strdup(yytext);
- return IDENTIFIER;
- }
- }
-
-\+\+ return INC_OP;
--- return DEC_OP;
-\<= return LE_OP;
->= return GE_OP;
-== return EQ_OP;
-!= return NE_OP;
-&& return AND_OP;
-\|\| return OR_OP;
-"^^" return XOR_OP;
-"<<" return LEFT_OP;
-">>" return RIGHT_OP;
-
-\*= return MUL_ASSIGN;
-\/= return DIV_ASSIGN;
-\+= return ADD_ASSIGN;
-\%= return MOD_ASSIGN;
-\<\<= return LEFT_ASSIGN;
->>= return RIGHT_ASSIGN;
-&= return AND_ASSIGN;
-"^=" return XOR_ASSIGN;
-\|= return OR_ASSIGN;
--= return SUB_ASSIGN;
-
-[1-9][0-9]*[uU]? {
- yylval->n = strtol(yytext, NULL, 10);
- return IS_UINT ? UINTCONSTANT : INTCONSTANT;
- }
-0[xX][0-9a-fA-F]+[uU]? {
- yylval->n = strtol(yytext + 2, NULL, 16);
- return IS_UINT ? UINTCONSTANT : INTCONSTANT;
- }
-0[0-7]*[uU]? {
- yylval->n = strtol(yytext, NULL, 8);
- return IS_UINT ? UINTCONSTANT : INTCONSTANT;
- }
-
-[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = glsl_strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = glsl_strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = glsl_strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+[eE][+-]?[0-9]+[fF]? {
- yylval->real = glsl_strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+[fF] {
- yylval->real = glsl_strtod(yytext, NULL);
- return FLOATCONSTANT;
- }
-
-true {
- yylval->n = 1;
- return BOOLCONSTANT;
- }
-false {
- yylval->n = 0;
- return BOOLCONSTANT;
- }
-
-
- /* 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, 999, 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);
-
- /* 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);
-
- /* 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, 999, ROW_MAJOR);
-
-[_a-zA-Z][_a-zA-Z0-9]* {
- struct _mesa_glsl_parse_state *state = yyextra;
- void *ctx = state;
- yylval->identifier = ralloc_strdup(ctx, yytext);
- return classify_identifier(state, yytext);
- }
-
-. { return yytext[0]; }
-
-%%
-
-int
-classify_identifier(struct _mesa_glsl_parse_state *state, const char *name)
-{
- if (state->symbols->get_variable(name) || state->symbols->get_function(name))
- return IDENTIFIER;
- else if (state->symbols->get_type(name))
- return TYPE_IDENTIFIER;
- else
- return NEW_IDENTIFIER;
-}
-
-void
-_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
-{
- yylex_init_extra(state, & state->scanner);
- yy_scan_string(string, state->scanner);
-}
-
-void
-_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
-{
- yylex_destroy(state->scanner);
-}
+%{
+/*
+ * Copyright © 2008, 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <ctype.h>
+#include <limits.h>
+#include "strtod.h"
+#include "ast.h"
+#include "glsl_parser_extras.h"
+#include "glsl_parser.h"
+
+static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
+
+#ifdef _MSC_VER
+#define YY_NO_UNISTD_H
+#endif
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->source = 0; \
+ yylloc->first_column = yycolumn + 1; \
+ yylloc->first_line = yylineno + 1; \
+ yycolumn += yyleng; \
+ } while(0);
+
+#define YY_USER_INIT yylineno = 0; yycolumn = 0;
+
+/* A macro for handling reserved words and keywords across language versions.
+ *
+ * Certain words start out as identifiers, become reserved words in
+ * later language revisions, and finally become language keywords.
+ *
+ * For example, consider the following lexer rule:
+ * samplerBuffer KEYWORD(130, 140, 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
+ */
+#define KEYWORD(reserved_version, allowed_version, token) \
+ do { \
+ if (yyextra->language_version >= allowed_version) { \
+ return token; \
+ } else if (yyextra->language_version >= reserved_version) { \
+ _mesa_glsl_error(yylloc, yyextra, \
+ "Illegal use of reserved word `%s'", yytext); \
+ return ERROR_TOK; \
+ } else { \
+ yylval->identifier = strdup(yytext); \
+ return classify_identifier(yyextra, yytext); \
+ } \
+ } 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.
+ */
+#define ES yyextra->es_shader
+
+static int
+literal_integer(char *text, int len, struct _mesa_glsl_parse_state *state,
+ YYSTYPE *lval, YYLTYPE *lloc, int base)
+{
+ bool is_uint = (text[len - 1] == 'u' ||
+ text[len - 1] == 'U');
+ const char *digits = text;
+
+ /* Skip "0x" */
+ if (base == 16)
+ digits += 2;
+
+#ifdef _MSC_VER
+ unsigned __int64 value = _strtoui64(digits, NULL, base);
+#else
+ unsigned long long value = strtoull(digits, NULL, base);
+#endif
+
+ lval->n = (int)value;
+
+ if (value > UINT_MAX) {
+ /* Note that signed 0xffffffff is valid, not out of range! */
+ if (state->language_version >= 130) {
+ _mesa_glsl_error(lloc, state,
+ "Literal value `%s' out of range", text);
+ } else {
+ _mesa_glsl_warning(lloc, state,
+ "Literal value `%s' out of range", text);
+ }
+ } else if (base == 10 && !is_uint && (unsigned)value > (unsigned)INT_MAX + 1) {
+ /* Tries to catch unintentionally providing a negative value.
+ * Note that -2147483648 is parsed as -(2147483648), so we don't
+ * want to warn for INT_MAX.
+ */
+ _mesa_glsl_warning(lloc, state,
+ "Signed literal value `%s' is interpreted as %d",
+ text, lval->n);
+ }
+ return is_uint ? UINTCONSTANT : INTCONSTANT;
+}
+
+#define LITERAL_INTEGER(base) \
+ literal_integer(yytext, yyleng, yyextra, yylval, yylloc, base)
+
+%}
+
+%option bison-bridge bison-locations reentrant noyywrap
+%option nounput noyy_top_state
+%option never-interactive
+%option prefix="_mesa_glsl_"
+%option extra-type="struct _mesa_glsl_parse_state *"
+
+%x PP PRAGMA
+
+DEC_INT [1-9][0-9]*
+HEX_INT 0[xX][0-9a-fA-F]+
+OCT_INT 0[0-7]*
+INT ({DEC_INT}|{HEX_INT}|{OCT_INT})
+SPC [ \t]*
+SPCP [ \t]+
+HASH ^{SPC}#{SPC}
+%%
+
+[ \r\t]+ ;
+
+ /* Preprocessor tokens. */
+^[ \t]*#[ \t]*$ ;
+^[ \t]*#[ \t]*version { BEGIN PP; return VERSION; }
+^[ \t]*#[ \t]*extension { BEGIN PP; return EXTENSION; }
+{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
+ /* Eat characters until the first digit is
+ * encountered
+ */
+ char *ptr = yytext;
+ while (!isdigit(*ptr))
+ ptr++;
+
+ /* Subtract one from the line number because
+ * yylineno is zero-based instead of
+ * one-based.
+ */
+ yylineno = strtol(ptr, &ptr, 0) - 1;
+ yylloc->source = strtol(ptr, NULL, 0);
+ }
+{HASH}line{SPCP}{INT}{SPC}$ {
+ /* Eat characters until the first digit is
+ * encountered
+ */
+ char *ptr = yytext;
+ while (!isdigit(*ptr))
+ ptr++;
+
+ /* Subtract one from the line number because
+ * yylineno is zero-based instead of
+ * one-based.
+ */
+ yylineno = strtol(ptr, &ptr, 0) - 1;
+ }
+^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_DEBUG_ON;
+ }
+^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}off{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_DEBUG_OFF;
+ }
+^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}on{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_OPTIMIZE_ON;
+ }
+^{SPC}#{SPC}pragma{SPCP}optimize{SPC}\({SPC}off{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_OPTIMIZE_OFF;
+ }
+^{SPC}#{SPC}pragma{SPCP}STDGL{SPCP}invariant{SPC}\({SPC}all{SPC}\) {
+ BEGIN PP;
+ return PRAGMA_INVARIANT_ALL;
+ }
+^{SPC}#{SPC}pragma{SPCP} { BEGIN PRAGMA; }
+
+<PRAGMA>\n { BEGIN 0; yylineno++; yycolumn = 0; }
+<PRAGMA>. { }
+
+<PP>\/\/[^\n]* { }
+<PP>[ \t\r]* { }
+<PP>: return COLON;
+<PP>[_a-zA-Z][_a-zA-Z0-9]* {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+<PP>[1-9][0-9]* {
+ yylval->n = strtol(yytext, NULL, 10);
+ return INTCONSTANT;
+ }
+<PP>\n { BEGIN 0; yylineno++; yycolumn = 0; return EOL; }
+
+\n { yylineno++; yycolumn = 0; }
+
+attribute return ATTRIBUTE;
+const return CONST_TOK;
+bool return BOOL_TOK;
+float return FLOAT_TOK;
+int return INT_TOK;
+uint KEYWORD(130, 130, UINT_TOK);
+
+break return BREAK;
+continue return CONTINUE;
+do return DO;
+while return WHILE;
+else return ELSE;
+for return FOR;
+if return IF;
+discard return DISCARD;
+return return RETURN;
+
+bvec2 return BVEC2;
+bvec3 return BVEC3;
+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);
+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);
+
+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;
+sampler2D return SAMPLER2D;
+sampler3D return SAMPLER3D;
+samplerCube return SAMPLERCUBE;
+sampler1DArray KEYWORD(130, 130, SAMPLER1DARRAY);
+sampler2DArray KEYWORD(130, 130, SAMPLER2DARRAY);
+sampler1DShadow return 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);
+
+samplerExternalOES {
+ if (yyextra->OES_EGL_image_external_enable)
+ return SAMPLEREXTERNALOES;
+ else
+ return IDENTIFIER;
+ }
+
+
+struct return STRUCT;
+void return VOID_TOK;
+
+layout {
+ if ((yyextra->language_version >= 140)
+ || yyextra->AMD_conservative_depth_enable
+ || yyextra->ARB_explicit_attrib_location_enable
+ || yyextra->ARB_fragment_coord_conventions_enable) {
+ return LAYOUT_TOK;
+ } else {
+ yylval->identifier = strdup(yytext);
+ return IDENTIFIER;
+ }
+ }
+
+\+\+ return INC_OP;
+-- return DEC_OP;
+\<= return LE_OP;
+>= return GE_OP;
+== return EQ_OP;
+!= return NE_OP;
+&& return AND_OP;
+\|\| return OR_OP;
+"^^" return XOR_OP;
+"<<" return LEFT_OP;
+">>" return RIGHT_OP;
+
+\*= return MUL_ASSIGN;
+\/= return DIV_ASSIGN;
+\+= return ADD_ASSIGN;
+\%= return MOD_ASSIGN;
+\<\<= return LEFT_ASSIGN;
+>>= return RIGHT_ASSIGN;
+&= return AND_ASSIGN;
+"^=" return XOR_ASSIGN;
+\|= return OR_ASSIGN;
+-= return SUB_ASSIGN;
+
+[1-9][0-9]*[uU]? {
+ return LITERAL_INTEGER(10);
+ }
+0[xX][0-9a-fA-F]+[uU]? {
+ return LITERAL_INTEGER(16);
+ }
+0[0-7]*[uU]? {
+ return LITERAL_INTEGER(8);
+ }
+
+[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+[eE][+-]?[0-9]+[fF]? {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+[0-9]+[fF] {
+ yylval->real = glsl_strtod(yytext, NULL);
+ return FLOATCONSTANT;
+ }
+
+true {
+ yylval->n = 1;
+ return BOOLCONSTANT;
+ }
+false {
+ yylval->n = 0;
+ return BOOLCONSTANT;
+ }
+
+
+ /* 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, 999, 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);
+
+ /* 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);
+
+ /* 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, 999, ROW_MAJOR);
+
+[_a-zA-Z][_a-zA-Z0-9]* {
+ struct _mesa_glsl_parse_state *state = yyextra;
+ void *ctx = state;
+ yylval->identifier = ralloc_strdup(ctx, yytext);
+ return classify_identifier(state, yytext);
+ }
+
+. { return yytext[0]; }
+
+%%
+
+int
+classify_identifier(struct _mesa_glsl_parse_state *state, const char *name)
+{
+ if (state->symbols->get_variable(name) || state->symbols->get_function(name))
+ return IDENTIFIER;
+ else if (state->symbols->get_type(name))
+ return TYPE_IDENTIFIER;
+ else
+ return NEW_IDENTIFIER;
+}
+
+void
+_mesa_glsl_lexer_ctor(struct _mesa_glsl_parse_state *state, const char *string)
+{
+ yylex_init_extra(state, & state->scanner);
+ yy_scan_string(string, state->scanner);
+}
+
+void
+_mesa_glsl_lexer_dtor(struct _mesa_glsl_parse_state *state)
+{
+ yylex_destroy(state->scanner);
+}
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index 25d02fb1e..d32d6e4e1 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -92,6 +92,7 @@
%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE
%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D
%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY
+%token SAMPLEREXTERNALOES
%token STRUCT VOID_TOK WHILE
%token <identifier> IDENTIFIER TYPE_IDENTIFIER NEW_IDENTIFIER
%type <identifier> any_identifier
@@ -1368,6 +1369,7 @@ basic_type_specifier_nonarray:
| SAMPLER2DRECT { $$ = ast_sampler2drect; }
| SAMPLER3D { $$ = ast_sampler3d; }
| SAMPLERCUBE { $$ = ast_samplercube; }
+ | SAMPLEREXTERNALOES { $$ = ast_samplerexternaloes; }
| SAMPLER1DSHADOW { $$ = ast_sampler1dshadow; }
| SAMPLER2DSHADOW { $$ = ast_sampler2dshadow; }
| SAMPLER2DRECTSHADOW { $$ = ast_sampler2drectshadow; }
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index e2112fe6d..e627dabf7 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -267,6 +267,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth),
EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D),
+ EXT(OES_EGL_image_external, true, false, true, false, true, OES_EGL_image_external),
};
#undef EXT
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index dc6911d1c..1f3404c9d 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -186,6 +186,8 @@ struct _mesa_glsl_parse_state {
bool AMD_shader_stencil_export_warn;
bool OES_texture_3D_enable;
bool OES_texture_3D_warn;
+ bool OES_EGL_image_external_enable;
+ bool OES_EGL_image_external_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index c94aec0d2..8587da0a3 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -203,6 +203,15 @@ glsl_type::generate_OES_texture_3D_types(glsl_symbol_table *symtab, bool warn)
void
+glsl_type::generate_OES_EGL_image_external_types(glsl_symbol_table *symtab,
+ bool warn)
+{
+ add_types_to_symbol_table(symtab, builtin_OES_EGL_image_external_types,
+ Elements(builtin_OES_EGL_image_external_types),
+ warn);
+}
+
+void
_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
{
switch (state->language_version) {
@@ -238,6 +247,15 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
glsl_type::generate_EXT_texture_array_types(state->symbols,
state->EXT_texture_array_warn);
}
+
+ /* We cannot check for language_version == 100 here because we need the
+ * types to support fixed-function program generation. But this is fine
+ * since the extension is never enabled for OpenGL contexts.
+ */
+ if (state->OES_EGL_image_external_enable) {
+ glsl_type::generate_OES_EGL_image_external_types(state->symbols,
+ state->OES_EGL_image_external_warn);
+ }
}
@@ -258,6 +276,29 @@ const glsl_type *glsl_type::get_base_type() const
}
+const glsl_type *glsl_type::get_scalar_type() const
+{
+ const glsl_type *type = this;
+
+ /* Handle arrays */
+ while (type->base_type == GLSL_TYPE_ARRAY)
+ type = type->fields.array;
+
+ /* Handle vectors and matrices */
+ switch (type->base_type) {
+ case GLSL_TYPE_UINT:
+ return uint_type;
+ case GLSL_TYPE_INT:
+ return int_type;
+ case GLSL_TYPE_FLOAT:
+ return float_type;
+ default:
+ /* Handle everything else */
+ return type;
+ }
+}
+
+
void
_mesa_glsl_release_types(void)
{
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 048696693..56b8efe7b 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -62,7 +62,8 @@ enum glsl_sampler_dim {
GLSL_SAMPLER_DIM_3D,
GLSL_SAMPLER_DIM_CUBE,
GLSL_SAMPLER_DIM_RECT,
- GLSL_SAMPLER_DIM_BUF
+ GLSL_SAMPLER_DIM_BUF,
+ GLSL_SAMPLER_DIM_EXTERNAL
};
@@ -178,6 +179,17 @@ struct glsl_type {
const glsl_type *get_base_type() const;
/**
+ * Get the basic scalar type which this type aggregates.
+ *
+ * If the type is a numeric or boolean scalar, vector, or matrix, or an
+ * array of any of those, this function gets the scalar type of the
+ * individual components. For structs and arrays of structs, this function
+ * returns the struct type. For samplers and arrays of samplers, this
+ * function returns the sampler type.
+ */
+ const glsl_type *get_scalar_type() const;
+
+ /**
* Query the type of elements in an array
*
* \return
@@ -478,6 +490,7 @@ private:
static const glsl_type builtin_ARB_texture_rectangle_types[];
static const glsl_type builtin_EXT_texture_array_types[];
static const glsl_type builtin_EXT_texture_buffer_object_types[];
+ static const glsl_type builtin_OES_EGL_image_external_types[];
/*@}*/
/**
@@ -496,6 +509,7 @@ private:
static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool);
static void generate_EXT_texture_array_types(glsl_symbol_table *, bool);
static void generate_OES_texture_3D_types(glsl_symbol_table *, bool);
+ static void generate_OES_EGL_image_external_types(glsl_symbol_table *, bool);
/*@}*/
/**
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index ef7300e65..a5eca5a51 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1326,9 +1326,11 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
this->type = type;
this->name = ralloc_strdup(this, name);
this->explicit_location = false;
+ this->has_initializer = false;
this->location = -1;
this->warn_extension = NULL;
this->constant_value = NULL;
+ this->constant_initializer = NULL;
this->origin_upper_left = false;
this->pixel_center_integer = false;
this->depth_layout = ir_depth_layout_none;
@@ -1489,6 +1491,9 @@ steal_memory(ir_instruction *ir, void *new_ctx)
if (var != NULL && var->constant_value != NULL)
steal_memory(var->constant_value, ir);
+ if (var != NULL && var->constant_initializer != NULL)
+ steal_memory(var->constant_initializer, ir);
+
/* The components of aggregate constants are not visited by the normal
* visitor, so steal their values by hand.
*/
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index 404d4cffa..5878c051b 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -356,14 +356,6 @@ public:
/*@}*/
/**
- * \brief Layout qualifier for gl_FragDepth.
- *
- * This is not equal to \c ir_depth_layout_none if and only if this
- * variable is \c gl_FragDepth and a layout qualifier is specified.
- */
- ir_depth_layout depth_layout;
-
- /**
* Was the location explicitly set in the shader?
*
* If the location is explicitly set in the shader, it \b cannot be changed
@@ -373,6 +365,22 @@ public:
unsigned explicit_location:1;
/**
+ * Does this variable have an initializer?
+ *
+ * This is used by the linker to cross-validiate initializers of global
+ * variables.
+ */
+ unsigned has_initializer:1;
+
+ /**
+ * \brief Layout qualifier for gl_FragDepth.
+ *
+ * This is not equal to \c ir_depth_layout_none if and only if this
+ * variable is \c gl_FragDepth and a layout qualifier is specified.
+ */
+ ir_depth_layout depth_layout;
+
+ /**
* Storage location of the base of this variable
*
* The precise meaning of this field depends on the nature of the variable.
@@ -414,6 +422,16 @@ public:
* Value assigned in the initializer of a variable declared "const"
*/
ir_constant *constant_value;
+
+ /**
+ * Constant expression assigned in the initializer of the variable
+ *
+ * \warning
+ * This field and \c ::constant_value are distinct. Even if the two fields
+ * refer to constants with the same value, they must point to separate
+ * objects.
+ */
+ ir_constant *constant_initializer;
};
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index 9adf47050..e8ac9fbe4 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -50,6 +50,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
var->origin_upper_left = this->origin_upper_left;
var->pixel_center_integer = this->pixel_center_integer;
var->explicit_location = this->explicit_location;
+ var->has_initializer = this->has_initializer;
var->num_state_slots = this->num_state_slots;
if (this->state_slots) {
@@ -68,6 +69,10 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
if (this->constant_value)
var->constant_value = this->constant_value->clone(mem_ctx, ht);
+ if (this->constant_initializer)
+ var->constant_initializer =
+ this->constant_initializer->clone(mem_ctx, ht);
+
if (ht) {
hash_table_insert(ht, var, (void *)const_cast<ir_variable *>(this));
}
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index 83f084d88..492be325f 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -719,7 +719,7 @@ ir_expression::constant_expression_value()
}
break;
case ir_binop_nequal:
- assert(op[0]->type != op[1]->type);
+ assert(op[0]->type == op[1]->type);
for (unsigned c = 0; c < components; c++) {
switch (op[0]->type->base_type) {
case GLSL_TYPE_UINT:
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index b713bd03b..1471355f3 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -368,8 +368,6 @@ void ir_print_visitor::visit(ir_assignment *ir)
void ir_print_visitor::visit(ir_constant *ir)
{
- const glsl_type *const base_type = ir->type->get_base_type();
-
printf("(constant ");
print_type(ir->type);
printf(" (");
@@ -390,7 +388,7 @@ void ir_print_visitor::visit(ir_constant *ir)
for (unsigned i = 0; i < ir->type->components(); i++) {
if (i != 0)
printf(" ");
- switch (base_type->base_type) {
+ switch (ir->type->base_type) {
case GLSL_TYPE_UINT: printf("%u", ir->value.u[i]); break;
case GLSL_TYPE_INT: printf("%d", ir->value.i[i]); break;
case GLSL_TYPE_FLOAT: printf("%f", ir->value.f[i]); break;
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index e3a3ed97d..6f50cc439 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -773,8 +773,6 @@ ir_reader::read_constant(s_expression *expr)
return new(mem_ctx) ir_constant(type, &elements);
}
- const glsl_type *const base_type = type->get_base_type();
-
ir_constant_data data = { { 0 } };
// Read in list of values (at most 16).
@@ -787,7 +785,7 @@ ir_reader::read_constant(s_expression *expr)
s_expression *expr = (s_expression*) it.get();
- if (base_type->base_type == GLSL_TYPE_FLOAT) {
+ if (type->base_type == GLSL_TYPE_FLOAT) {
s_number *value = SX_AS_NUMBER(expr);
if (value == NULL) {
ir_read_error(values, "expected numbers");
@@ -801,7 +799,7 @@ ir_reader::read_constant(s_expression *expr)
return NULL;
}
- switch (base_type->base_type) {
+ switch (type->base_type) {
case GLSL_TYPE_UINT: {
data.u[k] = value->value();
break;
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index c387ecbca..a3520120f 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -496,6 +496,13 @@ ir_validate::visit(ir_variable *ir)
}
}
+ if (ir->constant_initializer != NULL && !ir->has_initializer) {
+ printf("ir_variable didn't have an initializer, but has a constant "
+ "initializer value.\n");
+ ir->print();
+ abort();
+ }
+
return visit_continue;
}
diff --git a/mesalib/src/glsl/ir_variable.cpp b/mesalib/src/glsl/ir_variable.cpp
index 1ee84d219..3092507bc 100644
--- a/mesalib/src/glsl/ir_variable.cpp
+++ b/mesalib/src/glsl/ir_variable.cpp
@@ -400,7 +400,7 @@ add_builtin_variable(exec_list *instructions, glsl_symbol_table *symtab,
}
}
-static void
+static ir_variable *
add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab,
const char *name, int value)
{
@@ -408,6 +408,9 @@ add_builtin_constant(exec_list *instructions, glsl_symbol_table *symtab,
name, glsl_type::int_type,
ir_var_auto, -1);
var->constant_value = new(var) ir_constant(value);
+ var->constant_initializer = new(var) ir_constant(value);
+ var->has_initializer = true;
+ return var;
}
/* Several constants in GLSL ES have different names than normal desktop GLSL.
@@ -749,16 +752,12 @@ generate_ARB_draw_buffers_variables(exec_list *instructions,
/* gl_MaxDrawBuffers is available in all shader stages.
*/
ir_variable *const mdb =
- add_variable(instructions, state->symbols,
- "gl_MaxDrawBuffers", glsl_type::int_type, ir_var_auto, -1);
+ add_builtin_constant(instructions, state->symbols, "gl_MaxDrawBuffers",
+ state->Const.MaxDrawBuffers);
if (warn)
mdb->warn_extension = "GL_ARB_draw_buffers";
- mdb->constant_value = new(mdb)
- ir_constant(int(state->Const.MaxDrawBuffers));
-
-
/* gl_FragData is only available in the fragment shader.
*/
if (target == fragment_shader) {
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index beadec6f6..915d5bbcf 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -415,43 +415,63 @@ cross_validate_globals(struct gl_shader_program *prog,
existing->explicit_location = true;
}
- /* Validate layout qualifiers for gl_FragDepth.
- *
- * From the AMD/ARB_conservative_depth specs:
- * "If gl_FragDepth is redeclared in any fragment shader in
- * a program, it must be redeclared in all fragment shaders in that
- * program that have static assignments to gl_FragDepth. All
- * redeclarations of gl_FragDepth in all fragment shaders in
- * a single program must have the same set of qualifiers."
- */
- if (strcmp(var->name, "gl_FragDepth") == 0) {
- bool layout_declared = var->depth_layout != ir_depth_layout_none;
- bool layout_differs = var->depth_layout != existing->depth_layout;
- if (layout_declared && layout_differs) {
- linker_error(prog,
- "All redeclarations of gl_FragDepth in all fragment shaders "
- "in a single program must have the same set of qualifiers.");
- }
- if (var->used && layout_differs) {
- linker_error(prog,
- "If gl_FragDepth is redeclared with a layout qualifier in"
- "any fragment shader, it must be redeclared with the same"
- "layout qualifier in all fragment shaders that have"
- "assignments to gl_FragDepth");
- }
- }
-
- /* FINISHME: Handle non-constant initializers.
+ /* Validate layout qualifiers for gl_FragDepth.
+ *
+ * From the AMD/ARB_conservative_depth specs:
+ *
+ * "If gl_FragDepth is redeclared in any fragment shader in a
+ * program, it must be redeclared in all fragment shaders in
+ * that program that have static assignments to
+ * gl_FragDepth. All redeclarations of gl_FragDepth in all
+ * fragment shaders in a single program must have the same set
+ * of qualifiers."
+ */
+ if (strcmp(var->name, "gl_FragDepth") == 0) {
+ bool layout_declared = var->depth_layout != ir_depth_layout_none;
+ bool layout_differs =
+ var->depth_layout != existing->depth_layout;
+
+ if (layout_declared && layout_differs) {
+ linker_error(prog,
+ "All redeclarations of gl_FragDepth in all "
+ "fragment shaders in a single program must have "
+ "the same set of qualifiers.");
+ }
+
+ if (var->used && layout_differs) {
+ linker_error(prog,
+ "If gl_FragDepth is redeclared with a layout "
+ "qualifier in any fragment shader, it must be "
+ "redeclared with the same layout qualifier in "
+ "all fragment shaders that have assignments to "
+ "gl_FragDepth");
+ }
+ }
+
+ /* Page 35 (page 41 of the PDF) of the GLSL 4.20 spec says:
+ *
+ * "If a shared global has multiple initializers, the
+ * initializers must all be constant expressions, and they
+ * must all have the same value. Otherwise, a link error will
+ * result. (A shared global having only one initializer does
+ * not require that initializer to be a constant expression.)"
+ *
+ * Previous to 4.20 the GLSL spec simply said that initializers
+ * must have the same value. In this case of non-constant
+ * initializers, this was impossible to determine. As a result,
+ * no vendor actually implemented that behavior. The 4.20
+ * behavior matches the implemented behavior of at least one other
+ * vendor, so we'll implement that for all GLSL versions.
*/
- if (var->constant_value != NULL) {
- if (existing->constant_value != NULL) {
- if (!var->constant_value->has_value(existing->constant_value)) {
+ if (var->constant_initializer != NULL) {
+ if (existing->constant_initializer != NULL) {
+ if (!var->constant_initializer->has_value(existing->constant_initializer)) {
linker_error(prog, "initializers for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
return false;
}
- } else
+ } else {
/* If the first-seen instance of a particular uniform did not
* have an initializer but a later instance does, copy the
* initializer to the version stored in the symbol table.
@@ -464,8 +484,29 @@ cross_validate_globals(struct gl_shader_program *prog,
* FINISHME: modify the shader, and linking with the second
* FINISHME: will fail.
*/
- existing->constant_value =
- var->constant_value->clone(ralloc_parent(existing), NULL);
+ existing->constant_initializer =
+ var->constant_initializer->clone(ralloc_parent(existing),
+ NULL);
+ }
+ }
+
+ if (var->has_initializer) {
+ if (existing->has_initializer
+ && (var->constant_initializer == NULL
+ || existing->constant_initializer == NULL)) {
+ linker_error(prog,
+ "shared global variable `%s' has multiple "
+ "non-constant initializers.\n",
+ var->name);
+ return false;
+ }
+
+ /* Some instance had an initializer, so keep track of that. In
+ * this location, all sorts of initializers (constant or
+ * otherwise) will propagate the existence to the variable
+ * stored in the symbol table.
+ */
+ existing->has_initializer = true;
}
if (existing->invariant != var->invariant) {
diff --git a/mesalib/src/glsl/ralloc.c b/mesalib/src/glsl/ralloc.c
index f5f3934ac..91e4bab2e 100644
--- a/mesalib/src/glsl/ralloc.c
+++ b/mesalib/src/glsl/ralloc.c
@@ -33,6 +33,12 @@
#include <limits.h>
#endif
+/* Some versions of MinGW are missing _vscprintf's declaration, although they
+ * still provide the symbol in the import library. */
+#ifdef __MINGW32__
+_CRTIMP int _vscprintf(const char *format, va_list argptr);
+#endif
+
#include "ralloc.h"
#ifdef __GNUC__
@@ -397,7 +403,7 @@ printf_length(const char *fmt, va_list untouched_args)
va_list args;
va_copy(args, untouched_args);
-#ifdef _MSC_VER
+#ifdef _WIN32
/* We need to use _vcsprintf to calculate the size as vsnprintf returns -1
* if the number of characters to write is greater than count.
*/
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index 5cc6c9879..24cc64ad9 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -72,6 +72,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Extensions.EXT_texture_array = true;
ctx->Extensions.NV_texture_rectangle = true;
ctx->Extensions.EXT_texture3D = true;
+ ctx->Extensions.OES_EGL_image_external = true;
ctx->Const.GLSLVersion = 120;