summaryrefslogtreecommitdiff
path: root/dist/Mesa/src/glsl
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2014-07-09 20:35:21 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2014-07-09 20:35:21 +0000
commit90414e9e8766ee4a4f0ba93d8206de27cf984ce6 (patch)
tree83dd43b1cace3aa9d449e272b195871441746ae8 /dist/Mesa/src/glsl
parent417af3adbc72ea5a850bad6c0490b7b0f2424a38 (diff)
Import Mesa 10.2.3
Diffstat (limited to 'dist/Mesa/src/glsl')
-rw-r--r--dist/Mesa/src/glsl/Android.gen.mk19
-rw-r--r--dist/Mesa/src/glsl/Android.mk26
-rw-r--r--dist/Mesa/src/glsl/Makefile.am76
-rw-r--r--dist/Mesa/src/glsl/Makefile.in864
-rw-r--r--dist/Mesa/src/glsl/Makefile.sources23
-rw-r--r--dist/Mesa/src/glsl/ast_array_index.cpp106
-rw-r--r--dist/Mesa/src/glsl/builtin_functions.cpp4405
-rw-r--r--dist/Mesa/src/glsl/builtin_type_macros.h126
-rw-r--r--dist/Mesa/src/glsl/builtin_types.cpp152
-rw-r--r--dist/Mesa/src/glsl/builtin_variables.cpp355
-rw-r--r--dist/Mesa/src/glsl/glcpp/glcpp.h10
-rw-r--r--dist/Mesa/src/glsl/glcpp/pp.c2
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c2
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c.expected2
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/100-macro-with-colon.c.expected4
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c.expected2
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c4
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c.expected5
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c6
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c.expected8
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c6
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c.expected8
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c2
-rw-r--r--dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected3
-rw-r--r--dist/Mesa/src/glsl/glsl_symbol_table.h10
-rw-r--r--dist/Mesa/src/glsl/hir_field_selection.cpp22
-rw-r--r--dist/Mesa/src/glsl/ir_basic_block.cpp10
-rw-r--r--dist/Mesa/src/glsl/ir_builder.cpp197
-rw-r--r--dist/Mesa/src/glsl/ir_builder.h41
-rw-r--r--dist/Mesa/src/glsl/ir_equals.cpp200
-rw-r--r--dist/Mesa/src/glsl/ir_expression_flattening.cpp4
-rw-r--r--dist/Mesa/src/glsl/ir_hierarchical_visitor.cpp18
-rw-r--r--dist/Mesa/src/glsl/ir_uniform.h54
-rw-r--r--dist/Mesa/src/glsl/ir_visitor.h4
-rw-r--r--dist/Mesa/src/glsl/link_atomics.cpp265
-rw-r--r--dist/Mesa/src/glsl/link_interface_blocks.cpp341
-rw-r--r--dist/Mesa/src/glsl/link_uniform_block_active_visitor.cpp20
-rw-r--r--dist/Mesa/src/glsl/link_uniform_block_active_visitor.h3
-rw-r--r--dist/Mesa/src/glsl/link_uniform_blocks.cpp20
-rw-r--r--dist/Mesa/src/glsl/link_uniform_initializers.cpp131
-rw-r--r--dist/Mesa/src/glsl/link_uniforms.cpp220
-rw-r--r--dist/Mesa/src/glsl/link_varyings.cpp755
-rw-r--r--dist/Mesa/src/glsl/link_varyings.h19
-rw-r--r--dist/Mesa/src/glsl/list.h118
-rw-r--r--dist/Mesa/src/glsl/loop_controls.cpp129
-rw-r--r--dist/Mesa/src/glsl/loop_unroll.cpp411
-rw-r--r--dist/Mesa/src/glsl/lower_clip_distance.cpp264
-rw-r--r--dist/Mesa/src/glsl/lower_discard.cpp3
-rw-r--r--dist/Mesa/src/glsl/lower_discard_flow.cpp4
-rw-r--r--dist/Mesa/src/glsl/lower_mat_op_to_vec.cpp4
-rw-r--r--dist/Mesa/src/glsl/lower_named_interface_blocks.cpp42
-rw-r--r--dist/Mesa/src/glsl/lower_offset_array.cpp90
-rw-r--r--dist/Mesa/src/glsl/lower_output_reads.cpp19
-rw-r--r--dist/Mesa/src/glsl/lower_packed_varyings.cpp352
-rw-r--r--dist/Mesa/src/glsl/lower_texture_projection.cpp4
-rw-r--r--dist/Mesa/src/glsl/lower_ubo_reference.cpp15
-rw-r--r--dist/Mesa/src/glsl/lower_vector.cpp6
-rw-r--r--dist/Mesa/src/glsl/lower_vector_insert.cpp3
-rw-r--r--dist/Mesa/src/glsl/opt_algebraic.cpp380
-rw-r--r--dist/Mesa/src/glsl/opt_array_splitting.cpp29
-rw-r--r--dist/Mesa/src/glsl/opt_cse.cpp423
-rw-r--r--dist/Mesa/src/glsl/opt_dead_builtin_varyings.cpp190
-rw-r--r--dist/Mesa/src/glsl/opt_dead_code.cpp17
-rw-r--r--dist/Mesa/src/glsl/opt_flip_matrices.cpp4
-rw-r--r--dist/Mesa/src/glsl/opt_vectorize.cpp395
-rw-r--r--dist/Mesa/src/glsl/ralloc.h38
-rw-r--r--dist/Mesa/src/glsl/standalone_scaffolding.cpp57
-rw-r--r--dist/Mesa/src/glsl/standalone_scaffolding.h10
-rw-r--r--dist/Mesa/src/glsl/test_optpass.cpp16
-rw-r--r--dist/Mesa/src/glsl/tests/builtin_variable_test.cpp394
-rw-r--r--dist/Mesa/src/glsl/tests/common.c30
-rw-r--r--dist/Mesa/src/glsl/tests/general_ir_test.cpp89
-rw-r--r--dist/Mesa/src/glsl/tests/invalidate_locations_test.cpp196
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/create_test_cases.py2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test.expected12
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test.expected8
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test.expected10
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_1.opt_test2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_2.opt_test2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test.expected4
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test2
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test.expected8
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test4
-rw-r--r--dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test.expected2
-rwxr-xr-xdist/Mesa/src/glsl/tests/optimization-test2
-rw-r--r--dist/Mesa/src/glsl/tests/sampler_types_test.cpp101
-rw-r--r--dist/Mesa/src/glsl/tests/set_uniform_initializer_tests.cpp4
-rw-r--r--dist/Mesa/src/glsl/tests/uniform_initializer_utils.cpp3
-rw-r--r--dist/Mesa/src/glsl/tests/varyings_test.cpp357
125 files changed, 11207 insertions, 1714 deletions
diff --git a/dist/Mesa/src/glsl/Android.gen.mk b/dist/Mesa/src/glsl/Android.gen.mk
index 2ed9fa64b..7ec56d4f2 100644
--- a/dist/Mesa/src/glsl/Android.gen.mk
+++ b/dist/Mesa/src/glsl/Android.gen.mk
@@ -35,10 +35,6 @@ sources := \
glcpp/glcpp-lex.c \
glcpp/glcpp-parse.c
-ifneq ($(LOCAL_IS_HOST_MODULE),true)
-sources += builtin_function.cpp
-endif
-
LOCAL_SRC_FILES := $(filter-out $(sources), $(LOCAL_SRC_FILES))
LOCAL_C_INCLUDES += $(intermediates) $(intermediates)/glcpp $(MESA_TOP)/src/glsl/glcpp
@@ -81,18 +77,3 @@ $(intermediates)/glcpp/glcpp-lex.c: $(LOCAL_PATH)/glcpp/glcpp-lex.l
$(intermediates)/glcpp/glcpp-parse.c: $(LOCAL_PATH)/glcpp/glcpp-parse.y
$(call glsl_local-y-to-c-and-h)
-
-BUILTIN_COMPILER := $(BUILD_OUT_EXECUTABLES)/mesa_builtin_compiler$(BUILD_EXECUTABLE_SUFFIX)
-
-builtin_function_deps := \
- $(LOCAL_PATH)/builtins/tools/generate_builtins.py \
- $(LOCAL_PATH)/builtins/tools/texture_builtins.py \
- $(BUILTIN_COMPILER) \
- $(wildcard $(LOCAL_PATH)/builtins/profiles/*) \
- $(wildcard $(LOCAL_PATH)/builtins/ir/*)
-
-$(intermediates)/builtin_function.cpp: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/builtins/tools/generate_builtins.py
-$(intermediates)/builtin_function.cpp: $(builtin_function_deps)
- @mkdir -p $(dir $@)
- @echo "Gen GLSL: $(PRIVATE_MODULE) <= $(notdir $@)"
- $(hide) $(PRIVATE_SCRIPT) $(BUILTIN_COMPILER) > $@ || rm -f $@
diff --git a/dist/Mesa/src/glsl/Android.mk b/dist/Mesa/src/glsl/Android.mk
index f088e67cb..8a3942652 100644
--- a/dist/Mesa/src/glsl/Android.mk
+++ b/dist/Mesa/src/glsl/Android.mk
@@ -50,32 +50,6 @@ include $(MESA_COMMON_MK)
include $(BUILD_STATIC_LIBRARY)
# ---------------------------------------
-# Build mesa_builtin_compiler for host
-# ---------------------------------------
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- $(LIBGLCPP_FILES) \
- $(LIBGLSL_FILES) \
- $(BUILTIN_COMPILER_CXX_FILES) \
- $(GLSL_COMPILER_CXX_FILES)
-
-LOCAL_C_INCLUDES := \
- $(MESA_TOP)/src/mapi \
- $(MESA_TOP)/src/mesa
-
-LOCAL_STATIC_LIBRARIES := libmesa_glsl_utils
-
-LOCAL_MODULE := mesa_builtin_compiler
-
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_IS_HOST_MODULE := true
-include $(LOCAL_PATH)/Android.gen.mk
-include $(MESA_COMMON_MK)
-include $(BUILD_HOST_EXECUTABLE)
-
-# ---------------------------------------
# Build glsl_compiler
# ---------------------------------------
diff --git a/dist/Mesa/src/glsl/Makefile.am b/dist/Mesa/src/glsl/Makefile.am
index 2bbad3d65..fd0e837d1 100644
--- a/dist/Mesa/src/glsl/Makefile.am
+++ b/dist/Mesa/src/glsl/Makefile.am
@@ -19,8 +19,6 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-SUBDIRS = builtin_compiler
-
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/mapi \
@@ -34,8 +32,10 @@ AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
include Makefile.sources
TESTS = glcpp/tests/glcpp-test \
+ tests/general-ir-test \
tests/optimization-test \
tests/ralloc-test \
+ tests/sampler-types-test \
tests/uniform-initializer-test
TESTS_ENVIRONMENT= \
@@ -46,9 +46,31 @@ noinst_LTLIBRARIES = libglsl.la libglcpp.la
check_PROGRAMS = \
glcpp/glcpp \
glsl_test \
+ tests/general-ir-test \
tests/ralloc-test \
+ tests/sampler-types-test \
tests/uniform-initializer-test
+noinst_PROGRAMS = glsl_compiler
+
+tests_general_ir_test_SOURCES = \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/main/imports.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c\
+ $(top_srcdir)/src/mesa/program/symbol_table.c \
+ $(GLSL_SRCDIR)/standalone_scaffolding.cpp \
+ tests/builtin_variable_test.cpp \
+ tests/invalidate_locations_test.cpp \
+ tests/general_ir_test.cpp \
+ tests/varyings_test.cpp \
+ tests/common.c
+tests_general_ir_test_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+tests_general_ir_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la \
+ $(PTHREAD_LIBS)
+
tests_uniform_initializer_test_SOURCES = \
$(top_srcdir)/src/mesa/main/hash_table.c \
$(top_srcdir)/src/mesa/main/imports.c \
@@ -56,7 +78,8 @@ tests_uniform_initializer_test_SOURCES = \
$(top_srcdir)/src/mesa/program/symbol_table.c \
tests/copy_constant_to_storage_tests.cpp \
tests/set_uniform_initializer_tests.cpp \
- tests/uniform_initializer_utils.cpp
+ tests/uniform_initializer_utils.cpp \
+ tests/common.c
tests_uniform_initializer_test_CFLAGS = \
$(PTHREAD_CFLAGS)
tests_uniform_initializer_test_LDADD = \
@@ -72,31 +95,46 @@ tests_ralloc_test_LDADD = \
$(top_builddir)/src/gtest/libgtest.la \
$(PTHREAD_LIBS)
-if CROSS_COMPILING
+tests_sampler_types_test_SOURCES = \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c\
+ $(top_srcdir)/src/mesa/program/symbol_table.c \
+ tests/sampler_types_test.cpp \
+ tests/common.c
+tests_sampler_types_test_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+tests_sampler_types_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la \
+ $(PTHREAD_LIBS)
+
libglcpp_la_SOURCES = \
glcpp/glcpp-lex.c \
glcpp/glcpp-parse.c \
$(LIBGLCPP_FILES)
-else
-libglcpp_la_LIBADD = builtin_compiler/libglcpp.la
-endif
glcpp_glcpp_SOURCES = \
glcpp/glcpp.c \
$(top_srcdir)/src/mesa/program/prog_hash_table.c
-glcpp_glcpp_LDADD = libglcpp.la
+glcpp_glcpp_LDADD = \
+ libglcpp.la \
+ -lm
-libglsl_la_SOURCES = builtin_function.cpp
libglsl_la_LIBADD = libglcpp.la
-if CROSS_COMPILING
-libglsl_la_SOURCES += \
+libglsl_la_SOURCES = \
glsl_lexer.cpp \
glsl_parser.cpp \
$(LIBGLSL_FILES)
-else
-libglsl_la_LIBADD += \
- builtin_compiler/libglslcore.la
-endif
+
+glsl_compiler_SOURCES = \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/main/imports.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 \
+ $(PTHREAD_LIBS)
glsl_test_SOURCES = \
$(top_srcdir)/src/mesa/main/hash_table.c \
@@ -104,6 +142,7 @@ glsl_test_SOURCES = \
$(top_srcdir)/src/mesa/program/prog_hash_table.c \
$(top_srcdir)/src/mesa/program/symbol_table.c \
$(GLSL_SRCDIR)/standalone_scaffolding.cpp \
+ tests/common.c \
test.cpp \
test_optpass.cpp
@@ -146,11 +185,11 @@ glsl_lexer.cpp: glsl_lexer.ll
$(AM_V_LEX) $(LEX) $(LFLAGS) -o $@ $<
glcpp/glcpp-parse.c glcpp/glcpp-parse.h: glcpp/glcpp-parse.y
- $(MKDIR_P) $(GLSL_BUILDDIR)/glcpp
+ $(AM_V_at)$(MKDIR_P) glcpp
$(AM_V_YACC) $(YACC) $(YFLAGS) -o $@ -p "glcpp_parser_" --defines=$(GLSL_BUILDDIR)/glcpp/glcpp-parse.h $<
glcpp/glcpp-lex.c: glcpp/glcpp-lex.l
- $(MKDIR_P) $(GLSL_BUILDDIR)/glcpp
+ $(AM_V_at)$(MKDIR_P) glcpp
$(AM_V_LEX) $(LEX) $(LFLAGS) -o $@ $<
# Only the parsers (specifically the header files generated at the same time)
@@ -168,6 +207,3 @@ CLEANFILES = \
glcpp/glcpp-parse.h \
glsl_parser.h \
$(BUILT_SOURCES)
-
-builtin_function.cpp: $(srcdir)/builtins/profiles/* $(srcdir)/builtins/ir/* $(srcdir)/builtins/glsl/* $(srcdir)/builtins/tools/generate_builtins.py $(srcdir)/builtins/tools/texture_builtins.py $(builddir)/builtin_compiler/builtin_compiler$(BUILD_EXEEXT)
- $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/builtins/tools/generate_builtins.py $(builddir)/builtin_compiler/builtin_compiler$(BUILD_EXEEXT) > builtin_function.cpp || rm -f builtin_function.cpp
diff --git a/dist/Mesa/src/glsl/Makefile.in b/dist/Mesa/src/glsl/Makefile.in
index 022aae477..d6c26d132 100644
--- a/dist/Mesa/src/glsl/Makefile.in
+++ b/dist/Mesa/src/glsl/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.14 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -37,6 +37,7 @@
# shared source lists for Makefile, SConscript, and Android.mk
+
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@@ -105,146 +106,60 @@ target_triplet = @target@
DIST_COMMON = $(srcdir)/Makefile.sources $(srcdir)/Makefile.in \
$(srcdir)/Makefile.am $(top_srcdir)/bin/depcomp \
$(top_srcdir)/bin/test-driver README TODO
-TESTS = glcpp/tests/glcpp-test tests/optimization-test \
- tests/ralloc-test$(EXEEXT) \
+TESTS = glcpp/tests/glcpp-test tests/general-ir-test$(EXEEXT) \
+ tests/optimization-test tests/ralloc-test$(EXEEXT) \
+ tests/sampler-types-test$(EXEEXT) \
tests/uniform-initializer-test$(EXEEXT)
check_PROGRAMS = glcpp/glcpp$(EXEEXT) glsl_test$(EXEEXT) \
- tests/ralloc-test$(EXEEXT) \
+ tests/general-ir-test$(EXEEXT) tests/ralloc-test$(EXEEXT) \
+ tests/sampler-types-test$(EXEEXT) \
tests/uniform-initializer-test$(EXEEXT)
-@CROSS_COMPILING_TRUE@am__append_1 = \
-@CROSS_COMPILING_TRUE@ glsl_lexer.cpp \
-@CROSS_COMPILING_TRUE@ glsl_parser.cpp \
-@CROSS_COMPILING_TRUE@ $(LIBGLSL_FILES)
-
-@CROSS_COMPILING_FALSE@am__append_2 = \
-@CROSS_COMPILING_FALSE@ builtin_compiler/libglslcore.la
-
+noinst_PROGRAMS = glsl_compiler$(EXEEXT)
subdir = src/glsl
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_prog_bison.m4 \
- $(top_srcdir)/m4/ax_prog_cc_for_build.m4 \
- $(top_srcdir)/m4/ax_prog_cxx_for_build.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_gcc_builtin.m4 \
+ $(top_srcdir)/m4/ax_prog_bison.m4 \
$(top_srcdir)/m4/ax_prog_flex.m4 \
- $(top_srcdir)/m4/ax_pthread.m4 \
- $(top_srcdir)/m4/ax_python_module.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/VERSION $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
-@CROSS_COMPILING_FALSE@libglcpp_la_DEPENDENCIES = \
-@CROSS_COMPILING_FALSE@ builtin_compiler/libglcpp.la
-am__libglcpp_la_SOURCES_DIST = glcpp/glcpp-lex.c glcpp/glcpp-parse.c \
- $(GLSL_SRCDIR)/ralloc.c $(GLSL_SRCDIR)/glcpp/pp.c
+libglcpp_la_LIBADD =
am__objects_1 = ralloc.lo pp.lo
-@CROSS_COMPILING_TRUE@am_libglcpp_la_OBJECTS = glcpp-lex.lo \
-@CROSS_COMPILING_TRUE@ glcpp-parse.lo $(am__objects_1)
+am_libglcpp_la_OBJECTS = glcpp-lex.lo glcpp-parse.lo $(am__objects_1)
libglcpp_la_OBJECTS = $(am_libglcpp_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
-libglsl_la_DEPENDENCIES = libglcpp.la $(am__append_2)
-am__libglsl_la_SOURCES_DIST = builtin_function.cpp glsl_lexer.cpp \
- glsl_parser.cpp $(GLSL_SRCDIR)/ast_array_index.cpp \
- $(GLSL_SRCDIR)/ast_expr.cpp $(GLSL_SRCDIR)/ast_function.cpp \
- $(GLSL_SRCDIR)/ast_to_hir.cpp $(GLSL_SRCDIR)/ast_type.cpp \
- $(GLSL_SRCDIR)/builtin_types.cpp \
- $(GLSL_SRCDIR)/builtin_variables.cpp \
- $(GLSL_SRCDIR)/glsl_parser_extras.cpp \
- $(GLSL_SRCDIR)/glsl_types.cpp \
- $(GLSL_SRCDIR)/glsl_symbol_table.cpp \
- $(GLSL_SRCDIR)/hir_field_selection.cpp \
- $(GLSL_SRCDIR)/ir_basic_block.cpp \
- $(GLSL_SRCDIR)/ir_builder.cpp $(GLSL_SRCDIR)/ir_clone.cpp \
- $(GLSL_SRCDIR)/ir_constant_expression.cpp \
- $(GLSL_SRCDIR)/ir.cpp \
- $(GLSL_SRCDIR)/ir_expression_flattening.cpp \
- $(GLSL_SRCDIR)/ir_function_can_inline.cpp \
- $(GLSL_SRCDIR)/ir_function_detect_recursion.cpp \
- $(GLSL_SRCDIR)/ir_function.cpp \
- $(GLSL_SRCDIR)/ir_hierarchical_visitor.cpp \
- $(GLSL_SRCDIR)/ir_hv_accept.cpp \
- $(GLSL_SRCDIR)/ir_import_prototypes.cpp \
- $(GLSL_SRCDIR)/ir_print_visitor.cpp \
- $(GLSL_SRCDIR)/ir_reader.cpp \
- $(GLSL_SRCDIR)/ir_rvalue_visitor.cpp \
- $(GLSL_SRCDIR)/ir_set_program_inouts.cpp \
- $(GLSL_SRCDIR)/ir_validate.cpp \
- $(GLSL_SRCDIR)/ir_variable_refcount.cpp \
- $(GLSL_SRCDIR)/linker.cpp $(GLSL_SRCDIR)/link_functions.cpp \
- $(GLSL_SRCDIR)/link_interface_blocks.cpp \
- $(GLSL_SRCDIR)/link_uniforms.cpp \
- $(GLSL_SRCDIR)/link_uniform_initializers.cpp \
- $(GLSL_SRCDIR)/link_uniform_block_active_visitor.cpp \
- $(GLSL_SRCDIR)/link_uniform_blocks.cpp \
- $(GLSL_SRCDIR)/link_varyings.cpp \
- $(GLSL_SRCDIR)/loop_analysis.cpp \
- $(GLSL_SRCDIR)/loop_controls.cpp \
- $(GLSL_SRCDIR)/loop_unroll.cpp \
- $(GLSL_SRCDIR)/lower_clip_distance.cpp \
- $(GLSL_SRCDIR)/lower_discard.cpp \
- $(GLSL_SRCDIR)/lower_discard_flow.cpp \
- $(GLSL_SRCDIR)/lower_if_to_cond_assign.cpp \
- $(GLSL_SRCDIR)/lower_instructions.cpp \
- $(GLSL_SRCDIR)/lower_jumps.cpp \
- $(GLSL_SRCDIR)/lower_mat_op_to_vec.cpp \
- $(GLSL_SRCDIR)/lower_noise.cpp \
- $(GLSL_SRCDIR)/lower_packed_varyings.cpp \
- $(GLSL_SRCDIR)/lower_named_interface_blocks.cpp \
- $(GLSL_SRCDIR)/lower_packing_builtins.cpp \
- $(GLSL_SRCDIR)/lower_texture_projection.cpp \
- $(GLSL_SRCDIR)/lower_variable_index_to_cond_assign.cpp \
- $(GLSL_SRCDIR)/lower_vec_index_to_cond_assign.cpp \
- $(GLSL_SRCDIR)/lower_vec_index_to_swizzle.cpp \
- $(GLSL_SRCDIR)/lower_vector.cpp \
- $(GLSL_SRCDIR)/lower_vector_insert.cpp \
- $(GLSL_SRCDIR)/lower_output_reads.cpp \
- $(GLSL_SRCDIR)/lower_ubo_reference.cpp \
- $(GLSL_SRCDIR)/opt_algebraic.cpp \
- $(GLSL_SRCDIR)/opt_array_splitting.cpp \
- $(GLSL_SRCDIR)/opt_constant_folding.cpp \
- $(GLSL_SRCDIR)/opt_constant_propagation.cpp \
- $(GLSL_SRCDIR)/opt_constant_variable.cpp \
- $(GLSL_SRCDIR)/opt_copy_propagation.cpp \
- $(GLSL_SRCDIR)/opt_copy_propagation_elements.cpp \
- $(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp \
- $(GLSL_SRCDIR)/opt_dead_code.cpp \
- $(GLSL_SRCDIR)/opt_dead_code_local.cpp \
- $(GLSL_SRCDIR)/opt_dead_functions.cpp \
- $(GLSL_SRCDIR)/opt_flatten_nested_if_blocks.cpp \
- $(GLSL_SRCDIR)/opt_flip_matrices.cpp \
- $(GLSL_SRCDIR)/opt_function_inlining.cpp \
- $(GLSL_SRCDIR)/opt_if_simplification.cpp \
- $(GLSL_SRCDIR)/opt_noop_swizzle.cpp \
- $(GLSL_SRCDIR)/opt_redundant_jumps.cpp \
- $(GLSL_SRCDIR)/opt_structure_splitting.cpp \
- $(GLSL_SRCDIR)/opt_swizzle_swizzle.cpp \
- $(GLSL_SRCDIR)/opt_tree_grafting.cpp \
- $(GLSL_SRCDIR)/s_expression.cpp $(GLSL_SRCDIR)/strtod.c
+libglsl_la_DEPENDENCIES = libglcpp.la
am__objects_2 = ast_array_index.lo ast_expr.lo ast_function.lo \
- ast_to_hir.lo ast_type.lo builtin_types.lo \
- builtin_variables.lo glsl_parser_extras.lo glsl_types.lo \
- glsl_symbol_table.lo hir_field_selection.lo ir_basic_block.lo \
- ir_builder.lo ir_clone.lo ir_constant_expression.lo ir.lo \
+ ast_to_hir.lo ast_type.lo builtin_functions.lo \
+ builtin_types.lo builtin_variables.lo glsl_parser_extras.lo \
+ glsl_types.lo glsl_symbol_table.lo hir_field_selection.lo \
+ ir_basic_block.lo ir_builder.lo ir_clone.lo \
+ ir_constant_expression.lo ir.lo ir_equals.lo \
ir_expression_flattening.lo ir_function_can_inline.lo \
ir_function_detect_recursion.lo ir_function.lo \
ir_hierarchical_visitor.lo ir_hv_accept.lo \
ir_import_prototypes.lo ir_print_visitor.lo ir_reader.lo \
ir_rvalue_visitor.lo ir_set_program_inouts.lo ir_validate.lo \
- ir_variable_refcount.lo linker.lo link_functions.lo \
- link_interface_blocks.lo link_uniforms.lo \
+ ir_variable_refcount.lo linker.lo link_atomics.lo \
+ link_functions.lo link_interface_blocks.lo link_uniforms.lo \
link_uniform_initializers.lo \
link_uniform_block_active_visitor.lo link_uniform_blocks.lo \
link_varyings.lo loop_analysis.lo loop_controls.lo \
loop_unroll.lo lower_clip_distance.lo lower_discard.lo \
lower_discard_flow.lo lower_if_to_cond_assign.lo \
lower_instructions.lo lower_jumps.lo lower_mat_op_to_vec.lo \
- lower_noise.lo lower_packed_varyings.lo \
+ lower_noise.lo lower_offset_array.lo lower_packed_varyings.lo \
lower_named_interface_blocks.lo lower_packing_builtins.lo \
lower_texture_projection.lo \
lower_variable_index_to_cond_assign.lo \
@@ -254,33 +169,63 @@ am__objects_2 = ast_array_index.lo ast_expr.lo ast_function.lo \
lower_ubo_reference.lo opt_algebraic.lo opt_array_splitting.lo \
opt_constant_folding.lo opt_constant_propagation.lo \
opt_constant_variable.lo opt_copy_propagation.lo \
- opt_copy_propagation_elements.lo opt_dead_builtin_varyings.lo \
- opt_dead_code.lo opt_dead_code_local.lo opt_dead_functions.lo \
+ opt_copy_propagation_elements.lo opt_cse.lo \
+ opt_dead_builtin_varyings.lo opt_dead_code.lo \
+ opt_dead_code_local.lo opt_dead_functions.lo \
opt_flatten_nested_if_blocks.lo opt_flip_matrices.lo \
opt_function_inlining.lo opt_if_simplification.lo \
opt_noop_swizzle.lo opt_redundant_jumps.lo \
opt_structure_splitting.lo opt_swizzle_swizzle.lo \
- opt_tree_grafting.lo s_expression.lo strtod.lo
-@CROSS_COMPILING_TRUE@am__objects_3 = glsl_lexer.lo glsl_parser.lo \
-@CROSS_COMPILING_TRUE@ $(am__objects_2)
-am_libglsl_la_OBJECTS = builtin_function.lo $(am__objects_3)
+ opt_tree_grafting.lo opt_vectorize.lo s_expression.lo \
+ strtod.lo
+am_libglsl_la_OBJECTS = glsl_lexer.lo glsl_parser.lo $(am__objects_2)
libglsl_la_OBJECTS = $(am_libglsl_la_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
am_glcpp_glcpp_OBJECTS = glcpp.$(OBJEXT) prog_hash_table.$(OBJEXT)
glcpp_glcpp_OBJECTS = $(am_glcpp_glcpp_OBJECTS)
glcpp_glcpp_DEPENDENCIES = libglcpp.la
am__dirstamp = $(am__leading_dot)dirstamp
+am__objects_3 = standalone_scaffolding.$(OBJEXT) main.$(OBJEXT)
+am_glsl_compiler_OBJECTS = hash_table.$(OBJEXT) imports.$(OBJEXT) \
+ prog_hash_table.$(OBJEXT) symbol_table.$(OBJEXT) \
+ $(am__objects_3)
+glsl_compiler_OBJECTS = $(am_glsl_compiler_OBJECTS)
+am__DEPENDENCIES_1 =
+glsl_compiler_DEPENDENCIES = libglsl.la $(am__DEPENDENCIES_1)
am_glsl_test_OBJECTS = hash_table.$(OBJEXT) imports.$(OBJEXT) \
prog_hash_table.$(OBJEXT) symbol_table.$(OBJEXT) \
- standalone_scaffolding.$(OBJEXT) test.$(OBJEXT) \
- test_optpass.$(OBJEXT)
+ standalone_scaffolding.$(OBJEXT) common.$(OBJEXT) \
+ test.$(OBJEXT) test_optpass.$(OBJEXT)
glsl_test_OBJECTS = $(am_glsl_test_OBJECTS)
glsl_test_DEPENDENCIES = libglsl.la
+am_tests_general_ir_test_OBJECTS = \
+ tests_general_ir_test-hash_table.$(OBJEXT) \
+ tests_general_ir_test-imports.$(OBJEXT) \
+ tests_general_ir_test-prog_hash_table.$(OBJEXT) \
+ tests_general_ir_test-symbol_table.$(OBJEXT) \
+ standalone_scaffolding.$(OBJEXT) \
+ builtin_variable_test.$(OBJEXT) \
+ invalidate_locations_test.$(OBJEXT) general_ir_test.$(OBJEXT) \
+ varyings_test.$(OBJEXT) tests_general_ir_test-common.$(OBJEXT)
+tests_general_ir_test_OBJECTS = $(am_tests_general_ir_test_OBJECTS)
+tests_general_ir_test_DEPENDENCIES = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la $(am__DEPENDENCIES_1)
am_tests_ralloc_test_OBJECTS = ralloc_test.$(OBJEXT) \
tests_ralloc_test-ralloc.$(OBJEXT)
tests_ralloc_test_OBJECTS = $(am_tests_ralloc_test_OBJECTS)
-am__DEPENDENCIES_1 =
tests_ralloc_test_DEPENDENCIES = \
$(top_builddir)/src/gtest/libgtest.la $(am__DEPENDENCIES_1)
+am_tests_sampler_types_test_OBJECTS = \
+ tests_sampler_types_test-prog_hash_table.$(OBJEXT) \
+ tests_sampler_types_test-symbol_table.$(OBJEXT) \
+ sampler_types_test.$(OBJEXT) \
+ tests_sampler_types_test-common.$(OBJEXT)
+tests_sampler_types_test_OBJECTS = \
+ $(am_tests_sampler_types_test_OBJECTS)
+tests_sampler_types_test_DEPENDENCIES = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la $(am__DEPENDENCIES_1)
am_tests_uniform_initializer_test_OBJECTS = \
tests_uniform_initializer_test-hash_table.$(OBJEXT) \
tests_uniform_initializer_test-imports.$(OBJEXT) \
@@ -288,7 +233,8 @@ am_tests_uniform_initializer_test_OBJECTS = \
tests_uniform_initializer_test-symbol_table.$(OBJEXT) \
copy_constant_to_storage_tests.$(OBJEXT) \
set_uniform_initializer_tests.$(OBJEXT) \
- uniform_initializer_utils.$(OBJEXT)
+ uniform_initializer_utils.$(OBJEXT) \
+ tests_uniform_initializer_test-common.$(OBJEXT)
tests_uniform_initializer_test_OBJECTS = \
$(am_tests_uniform_initializer_test_OBJECTS)
tests_uniform_initializer_test_DEPENDENCIES = \
@@ -347,34 +293,22 @@ am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libglcpp_la_SOURCES) $(libglsl_la_SOURCES) \
- $(glcpp_glcpp_SOURCES) $(glsl_test_SOURCES) \
+ $(glcpp_glcpp_SOURCES) $(glsl_compiler_SOURCES) \
+ $(glsl_test_SOURCES) $(tests_general_ir_test_SOURCES) \
$(tests_ralloc_test_SOURCES) \
+ $(tests_sampler_types_test_SOURCES) \
$(tests_uniform_initializer_test_SOURCES)
-DIST_SOURCES = $(am__libglcpp_la_SOURCES_DIST) \
- $(am__libglsl_la_SOURCES_DIST) $(glcpp_glcpp_SOURCES) \
- $(glsl_test_SOURCES) $(tests_ralloc_test_SOURCES) \
+DIST_SOURCES = $(libglcpp_la_SOURCES) $(libglsl_la_SOURCES) \
+ $(glcpp_glcpp_SOURCES) $(glsl_compiler_SOURCES) \
+ $(glsl_test_SOURCES) $(tests_general_ir_test_SOURCES) \
+ $(tests_ralloc_test_SOURCES) \
+ $(tests_sampler_types_test_SOURCES) \
$(tests_uniform_initializer_test_SOURCES)
-RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
- ctags-recursive dvi-recursive html-recursive info-recursive \
- install-data-recursive install-dvi-recursive \
- install-exec-recursive install-html-recursive \
- install-info-recursive install-pdf-recursive \
- install-ps-recursive install-recursive installcheck-recursive \
- installdirs-recursive pdf-recursive ps-recursive \
- tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
- distclean-recursive maintainer-clean-recursive
-am__recursive_targets = \
- $(RECURSIVE_TARGETS) \
- $(RECURSIVE_CLEAN_TARGETS) \
- $(am__extra_recursive_targets)
-AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
- check recheck distdir
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
@@ -577,6 +511,7 @@ am__set_TESTS_bases = \
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
bases=`echo $$bases`
RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
TEST_SUITE_LOG = test-suite.log
TEST_EXTENSIONS = @EXEEXT@ .test
LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver
@@ -597,33 +532,7 @@ TEST_LOGS = $(am__test_logs2:.test.log=.log)
TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/bin/test-driver
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
$(TEST_LOG_FLAGS)
-DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-am__relativize = \
- dir0=`pwd`; \
- sed_first='s,^\([^/]*\)/.*$$,\1,'; \
- sed_rest='s,^[^/]*/*,,'; \
- sed_last='s,^.*/\([^/]*\)$$,\1,'; \
- sed_butlast='s,/*[^/]*$$,,'; \
- while test -n "$$dir1"; do \
- first=`echo "$$dir1" | sed -e "$$sed_first"`; \
- if test "$$first" != "."; then \
- if test "$$first" = ".."; then \
- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
- else \
- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
- if test "$$first2" = "$$first"; then \
- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
- else \
- dir2="../$$dir2"; \
- fi; \
- dir0="$$dir0"/"$$first"; \
- fi; \
- fi; \
- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
- done; \
- reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -632,39 +541,30 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-BUILD_EXEEXT = @BUILD_EXEEXT@
-BUILD_OBJEXT = @BUILD_OBJEXT@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
-CC_FOR_BUILD = @CC_FOR_BUILD@
CFLAGS = @CFLAGS@
-CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@
CLOCK_LIB = @CLOCK_LIB@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
-CPP_FOR_BUILD = @CPP_FOR_BUILD@
CXX = @CXX@
CXXCPP = @CXXCPP@
-CXXCPPFLAGS_FOR_BUILD = @CXXCPPFLAGS_FOR_BUILD@
-CXXCPP_FOR_BUILD = @CXXCPP_FOR_BUILD@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
-CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
-CXX_FOR_BUILD = @CXX_FOR_BUILD@
CYGPATH_W = @CYGPATH_W@
DEFINES = @DEFINES@
-DEFINES_FOR_BUILD = @DEFINES_FOR_BUILD@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DLOPEN_LIBS = @DLOPEN_LIBS@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
+DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@
+DRI3PROTO_LIBS = @DRI3PROTO_LIBS@
DRIGL_CFLAGS = @DRIGL_CFLAGS@
DRIGL_LIBS = @DRIGL_LIBS@
DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@
@@ -680,41 +580,33 @@ EGL_CFLAGS = @EGL_CFLAGS@
EGL_CLIENT_APIS = @EGL_CLIENT_APIS@
EGL_DRIVER_INSTALL_DIR = @EGL_DRIVER_INSTALL_DIR@
EGL_LIB_DEPS = @EGL_LIB_DEPS@
-EGL_LIB_GLOB = @EGL_LIB_GLOB@
-EGL_LIB_NAME = @EGL_LIB_NAME@
EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@
-EGL_PLATFORMS = @EGL_PLATFORMS@
EGREP = @EGREP@
ELF_LIB = @ELF_LIB@
EXEEXT = @EXEEXT@
-EXPAT_INCLUDES = @EXPAT_INCLUDES@
+EXPAT_CFLAGS = @EXPAT_CFLAGS@
+EXPAT_LIBS = @EXPAT_LIBS@
FGREP = @FGREP@
FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@
FREEDRENO_LIBS = @FREEDRENO_LIBS@
-GALLIUM_DRI_LIB_DEPS = @GALLIUM_DRI_LIB_DEPS@
+GALLIUM_PIPE_LOADER_CLIENT_DEFINES = @GALLIUM_PIPE_LOADER_CLIENT_DEFINES@
+GALLIUM_PIPE_LOADER_CLIENT_LIBS = @GALLIUM_PIPE_LOADER_CLIENT_LIBS@
GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@
GALLIUM_PIPE_LOADER_LIBS = @GALLIUM_PIPE_LOADER_LIBS@
GALLIUM_PIPE_LOADER_XCB_CFLAGS = @GALLIUM_PIPE_LOADER_XCB_CFLAGS@
GALLIUM_PIPE_LOADER_XCB_LIBS = @GALLIUM_PIPE_LOADER_XCB_LIBS@
GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@
GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@
-GLAPI_LIB_GLOB = @GLAPI_LIB_GLOB@
-GLAPI_LIB_NAME = @GLAPI_LIB_NAME@
+GC_SECTIONS = @GC_SECTIONS@
GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@
-GLESv1_CM_LIB_GLOB = @GLESv1_CM_LIB_GLOB@
-GLESv1_CM_LIB_NAME = @GLESv1_CM_LIB_NAME@
GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@
GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@
-GLESv2_LIB_GLOB = @GLESv2_LIB_GLOB@
-GLESv2_LIB_NAME = @GLESv2_LIB_NAME@
GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@
GLPROTO_CFLAGS = @GLPROTO_CFLAGS@
GLPROTO_LIBS = @GLPROTO_LIBS@
GLX_TLS = @GLX_TLS@
GL_LIB = @GL_LIB@
GL_LIB_DEPS = @GL_LIB_DEPS@
-GL_LIB_GLOB = @GL_LIB_GLOB@
-GL_LIB_NAME = @GL_LIB_NAME@
GL_PC_CFLAGS = @GL_PC_CFLAGS@
GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
@@ -731,7 +623,7 @@ INTEL_CFLAGS = @INTEL_CFLAGS@
INTEL_LIBS = @INTEL_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
-LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LD_NO_UNDEFINED = @LD_NO_UNDEFINED@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
@@ -739,16 +631,13 @@ LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@
LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@
LIBDRM_CFLAGS = @LIBDRM_CFLAGS@
LIBDRM_LIBS = @LIBDRM_LIBS@
-LIBDRM_XORG_CFLAGS = @LIBDRM_XORG_CFLAGS@
-LIBDRM_XORG_LIBS = @LIBDRM_XORG_LIBS@
-LIBKMS_XORG_CFLAGS = @LIBKMS_XORG_CFLAGS@
-LIBKMS_XORG_LIBS = @LIBKMS_XORG_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@
LIBUDEV_LIBS = @LIBUDEV_LIBS@
LIB_DIR = @LIB_DIR@
+LIB_EXT = @LIB_EXT@
LIPO = @LIPO@
LLVM_BINDIR = @LLVM_BINDIR@
LLVM_CFLAGS = @LLVM_CFLAGS@
@@ -773,10 +662,13 @@ NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@
NOUVEAU_LIBS = @NOUVEAU_LIBS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
+OMX_CFLAGS = @OMX_CFLAGS@
+OMX_LIBS = @OMX_LIBS@
+OMX_LIB_INSTALL_DIR = @OMX_LIB_INSTALL_DIR@
+OPENCL_LIBNAME = @OPENCL_LIBNAME@
OPENCL_LIB_INSTALL_DIR = @OPENCL_LIB_INSTALL_DIR@
OSMESA_LIB = @OSMESA_LIB@
OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@
-OSMESA_LIB_NAME = @OSMESA_LIB_NAME@
OSMESA_MESA_DEPS = @OSMESA_MESA_DEPS@
OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@
OSMESA_PC_REQ = @OSMESA_PC_REQ@
@@ -796,6 +688,8 @@ PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSIX_SHELL = @POSIX_SHELL@
+PRESENTPROTO_CFLAGS = @PRESENTPROTO_CFLAGS@
+PRESENTPROTO_LIBS = @PRESENTPROTO_LIBS@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -804,6 +698,7 @@ RADEON_CFLAGS = @RADEON_CFLAGS@
RADEON_LIBS = @RADEON_LIBS@
RANLIB = @RANLIB@
SED = @SED@
+SELINUX_CFLAGS = @SELINUX_CFLAGS@
SELINUX_LIBS = @SELINUX_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -815,8 +710,6 @@ VDPAU_MAJOR = @VDPAU_MAJOR@
VDPAU_MINOR = @VDPAU_MINOR@
VERSION = @VERSION@
VG_LIB_DEPS = @VG_LIB_DEPS@
-VG_LIB_GLOB = @VG_LIB_GLOB@
-VG_LIB_NAME = @VG_LIB_NAME@
VG_PC_LIB_PRIV = @VG_PC_LIB_PRIV@
VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@
VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@
@@ -830,15 +723,10 @@ XA_TINY = @XA_TINY@
XA_VERSION = @XA_VERSION@
XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
-XEXT_CFLAGS = @XEXT_CFLAGS@
-XEXT_LIBS = @XEXT_LIBS@
XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@
XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@
XLIBGL_CFLAGS = @XLIBGL_CFLAGS@
XLIBGL_LIBS = @XLIBGL_LIBS@
-XORG_CFLAGS = @XORG_CFLAGS@
-XORG_DRIVER_INSTALL_DIR = @XORG_DRIVER_INSTALL_DIR@
-XORG_LIBS = @XORG_LIBS@
XVMC_CFLAGS = @XVMC_CFLAGS@
XVMC_LIBS = @XVMC_LIBS@
XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@
@@ -852,9 +740,7 @@ abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CC_FOR_BUILD = @ac_ct_CC_FOR_BUILD@
ac_ct_CXX = @ac_ct_CXX@
-ac_ct_CXX_FOR_BUILD = @ac_ct_CXX_FOR_BUILD@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
@@ -906,7 +792,6 @@ target_vendor = @target_vendor@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-SUBDIRS = builtin_compiler
AM_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/mapi \
@@ -937,6 +822,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ast_function.cpp \
$(GLSL_SRCDIR)/ast_to_hir.cpp \
$(GLSL_SRCDIR)/ast_type.cpp \
+ $(GLSL_SRCDIR)/builtin_functions.cpp \
$(GLSL_SRCDIR)/builtin_types.cpp \
$(GLSL_SRCDIR)/builtin_variables.cpp \
$(GLSL_SRCDIR)/glsl_parser_extras.cpp \
@@ -948,6 +834,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ir_clone.cpp \
$(GLSL_SRCDIR)/ir_constant_expression.cpp \
$(GLSL_SRCDIR)/ir.cpp \
+ $(GLSL_SRCDIR)/ir_equals.cpp \
$(GLSL_SRCDIR)/ir_expression_flattening.cpp \
$(GLSL_SRCDIR)/ir_function_can_inline.cpp \
$(GLSL_SRCDIR)/ir_function_detect_recursion.cpp \
@@ -962,6 +849,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ir_validate.cpp \
$(GLSL_SRCDIR)/ir_variable_refcount.cpp \
$(GLSL_SRCDIR)/linker.cpp \
+ $(GLSL_SRCDIR)/link_atomics.cpp \
$(GLSL_SRCDIR)/link_functions.cpp \
$(GLSL_SRCDIR)/link_interface_blocks.cpp \
$(GLSL_SRCDIR)/link_uniforms.cpp \
@@ -980,6 +868,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/lower_jumps.cpp \
$(GLSL_SRCDIR)/lower_mat_op_to_vec.cpp \
$(GLSL_SRCDIR)/lower_noise.cpp \
+ $(GLSL_SRCDIR)/lower_offset_array.cpp \
$(GLSL_SRCDIR)/lower_packed_varyings.cpp \
$(GLSL_SRCDIR)/lower_named_interface_blocks.cpp \
$(GLSL_SRCDIR)/lower_packing_builtins.cpp \
@@ -998,6 +887,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_constant_variable.cpp \
$(GLSL_SRCDIR)/opt_copy_propagation.cpp \
$(GLSL_SRCDIR)/opt_copy_propagation_elements.cpp \
+ $(GLSL_SRCDIR)/opt_cse.cpp \
$(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp \
$(GLSL_SRCDIR)/opt_dead_code.cpp \
$(GLSL_SRCDIR)/opt_dead_code_local.cpp \
@@ -1011,6 +901,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_structure_splitting.cpp \
$(GLSL_SRCDIR)/opt_swizzle_swizzle.cpp \
$(GLSL_SRCDIR)/opt_tree_grafting.cpp \
+ $(GLSL_SRCDIR)/opt_vectorize.cpp \
$(GLSL_SRCDIR)/s_expression.cpp \
$(GLSL_SRCDIR)/strtod.c
@@ -1021,29 +912,36 @@ GLSL_COMPILER_CXX_FILES = \
$(GLSL_SRCDIR)/main.cpp
-# builtin_compiler
-#
-# This is built before libglsl to generate builtin_function.cpp for libglsl.
-# For this to work, a dummy version of builtin_function.cpp,
-# builtin_stubs.cpp, is used.
-BUILTIN_COMPILER_CXX_FILES = \
- $(GLSL_SRCDIR)/builtin_compiler/builtin_stubs.cpp
-
-BUILTIN_COMPILER_GENERATED_CXX_FILES = \
- $(GLSL_BUILDDIR)/glsl_lexer.cpp \
- $(GLSL_BUILDDIR)/glsl_parser.cpp
-
-
# libglsl generated sources
LIBGLSL_GENERATED_CXX_FILES = \
- $(BUILTIN_COMPILER_GENERATED_CXX_FILES) \
- $(GLSL_BUILDDIR)/builtin_function.cpp
+ $(GLSL_BUILDDIR)/glsl_lexer.cpp \
+ $(GLSL_BUILDDIR)/glsl_parser.cpp
TESTS_ENVIRONMENT = \
export PYTHON2=$(PYTHON2); \
export PYTHON_FLAGS=$(PYTHON_FLAGS);
noinst_LTLIBRARIES = libglsl.la libglcpp.la
+tests_general_ir_test_SOURCES = \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/main/imports.c \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c\
+ $(top_srcdir)/src/mesa/program/symbol_table.c \
+ $(GLSL_SRCDIR)/standalone_scaffolding.cpp \
+ tests/builtin_variable_test.cpp \
+ tests/invalidate_locations_test.cpp \
+ tests/general_ir_test.cpp \
+ tests/varyings_test.cpp \
+ tests/common.c
+
+tests_general_ir_test_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+
+tests_general_ir_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la \
+ $(PTHREAD_LIBS)
+
tests_uniform_initializer_test_SOURCES = \
$(top_srcdir)/src/mesa/main/hash_table.c \
$(top_srcdir)/src/mesa/main/imports.c \
@@ -1051,7 +949,8 @@ tests_uniform_initializer_test_SOURCES = \
$(top_srcdir)/src/mesa/program/symbol_table.c \
tests/copy_constant_to_storage_tests.cpp \
tests/set_uniform_initializer_tests.cpp \
- tests/uniform_initializer_utils.cpp
+ tests/uniform_initializer_utils.cpp \
+ tests/common.c
tests_uniform_initializer_test_CFLAGS = \
$(PTHREAD_CFLAGS)
@@ -1070,25 +969,57 @@ tests_ralloc_test_LDADD = \
$(top_builddir)/src/gtest/libgtest.la \
$(PTHREAD_LIBS)
-@CROSS_COMPILING_TRUE@libglcpp_la_SOURCES = \
-@CROSS_COMPILING_TRUE@ glcpp/glcpp-lex.c \
-@CROSS_COMPILING_TRUE@ glcpp/glcpp-parse.c \
-@CROSS_COMPILING_TRUE@ $(LIBGLCPP_FILES)
+tests_sampler_types_test_SOURCES = \
+ $(top_srcdir)/src/mesa/program/prog_hash_table.c\
+ $(top_srcdir)/src/mesa/program/symbol_table.c \
+ tests/sampler_types_test.cpp \
+ tests/common.c
+
+tests_sampler_types_test_CFLAGS = \
+ $(PTHREAD_CFLAGS)
+
+tests_sampler_types_test_LDADD = \
+ $(top_builddir)/src/gtest/libgtest.la \
+ $(top_builddir)/src/glsl/libglsl.la \
+ $(PTHREAD_LIBS)
+
+libglcpp_la_SOURCES = \
+ glcpp/glcpp-lex.c \
+ glcpp/glcpp-parse.c \
+ $(LIBGLCPP_FILES)
-@CROSS_COMPILING_FALSE@libglcpp_la_LIBADD = builtin_compiler/libglcpp.la
glcpp_glcpp_SOURCES = \
glcpp/glcpp.c \
$(top_srcdir)/src/mesa/program/prog_hash_table.c
-glcpp_glcpp_LDADD = libglcpp.la
-libglsl_la_SOURCES = builtin_function.cpp $(am__append_1)
-libglsl_la_LIBADD = libglcpp.la $(am__append_2)
+glcpp_glcpp_LDADD = \
+ libglcpp.la \
+ -lm
+
+libglsl_la_LIBADD = libglcpp.la
+libglsl_la_SOURCES = \
+ glsl_lexer.cpp \
+ glsl_parser.cpp \
+ $(LIBGLSL_FILES)
+
+glsl_compiler_SOURCES = \
+ $(top_srcdir)/src/mesa/main/hash_table.c \
+ $(top_srcdir)/src/mesa/main/imports.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 \
+ $(PTHREAD_LIBS)
+
glsl_test_SOURCES = \
$(top_srcdir)/src/mesa/main/hash_table.c \
$(top_srcdir)/src/mesa/main/imports.c \
$(top_srcdir)/src/mesa/program/prog_hash_table.c \
$(top_srcdir)/src/mesa/program/symbol_table.c \
$(GLSL_SRCDIR)/standalone_scaffolding.cpp \
+ tests/common.c \
test.cpp \
test_optpass.cpp
@@ -1140,7 +1071,7 @@ CLEANFILES = \
$(BUILT_SOURCES)
all: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) all-recursive
+ $(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs
@@ -1201,6 +1132,15 @@ clean-checkPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
glcpp/$(am__dirstamp):
@$(MKDIR_P) glcpp
@: > glcpp/$(am__dirstamp)
@@ -1209,6 +1149,10 @@ glcpp/glcpp$(EXEEXT): $(glcpp_glcpp_OBJECTS) $(glcpp_glcpp_DEPENDENCIES) $(EXTRA
@rm -f glcpp/glcpp$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(glcpp_glcpp_OBJECTS) $(glcpp_glcpp_LDADD) $(LIBS)
+glsl_compiler$(EXEEXT): $(glsl_compiler_OBJECTS) $(glsl_compiler_DEPENDENCIES) $(EXTRA_glsl_compiler_DEPENDENCIES)
+ @rm -f glsl_compiler$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(glsl_compiler_OBJECTS) $(glsl_compiler_LDADD) $(LIBS)
+
glsl_test$(EXEEXT): $(glsl_test_OBJECTS) $(glsl_test_DEPENDENCIES) $(EXTRA_glsl_test_DEPENDENCIES)
@rm -f glsl_test$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(glsl_test_OBJECTS) $(glsl_test_LDADD) $(LIBS)
@@ -1216,10 +1160,18 @@ tests/$(am__dirstamp):
@$(MKDIR_P) tests
@: > tests/$(am__dirstamp)
+tests/general-ir-test$(EXEEXT): $(tests_general_ir_test_OBJECTS) $(tests_general_ir_test_DEPENDENCIES) $(EXTRA_tests_general_ir_test_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/general-ir-test$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(tests_general_ir_test_OBJECTS) $(tests_general_ir_test_LDADD) $(LIBS)
+
tests/ralloc-test$(EXEEXT): $(tests_ralloc_test_OBJECTS) $(tests_ralloc_test_DEPENDENCIES) $(EXTRA_tests_ralloc_test_DEPENDENCIES) tests/$(am__dirstamp)
@rm -f tests/ralloc-test$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(tests_ralloc_test_OBJECTS) $(tests_ralloc_test_LDADD) $(LIBS)
+tests/sampler-types-test$(EXEEXT): $(tests_sampler_types_test_OBJECTS) $(tests_sampler_types_test_DEPENDENCIES) $(EXTRA_tests_sampler_types_test_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/sampler-types-test$(EXEEXT)
+ $(AM_V_CXXLD)$(CXXLINK) $(tests_sampler_types_test_OBJECTS) $(tests_sampler_types_test_LDADD) $(LIBS)
+
tests/uniform-initializer-test$(EXEEXT): $(tests_uniform_initializer_test_OBJECTS) $(tests_uniform_initializer_test_DEPENDENCIES) $(EXTRA_tests_uniform_initializer_test_DEPENDENCIES) tests/$(am__dirstamp)
@rm -f tests/uniform-initializer-test$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(tests_uniform_initializer_test_OBJECTS) $(tests_uniform_initializer_test_LDADD) $(LIBS)
@@ -1235,10 +1187,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ast_function.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ast_to_hir.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ast_type.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin_function.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin_functions.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin_types.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin_variable_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtin_variables.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_constant_to_storage_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/general_ir_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glcpp-lex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glcpp-parse.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glcpp.Po@am__quote@
@@ -1250,11 +1205,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hir_field_selection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imports.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invalidate_locations_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_basic_block.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_builder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_clone.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_constant_expression.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_equals.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_expression_flattening.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_function.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_function_can_inline.Plo@am__quote@
@@ -1268,6 +1225,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_set_program_inouts.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_validate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ir_variable_refcount.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_atomics.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_functions.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_interface_blocks.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_uniform_block_active_visitor.Plo@am__quote@
@@ -1288,6 +1246,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_mat_op_to_vec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_named_interface_blocks.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_noise.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_offset_array.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_output_reads.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_packed_varyings.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_packing_builtins.Plo@am__quote@
@@ -1298,6 +1257,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_vec_index_to_swizzle.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_vector.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lower_vector_insert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_algebraic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_array_splitting.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_constant_folding.Plo@am__quote@
@@ -1305,6 +1265,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_constant_variable.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_copy_propagation.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_copy_propagation_elements.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_cse.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_dead_builtin_varyings.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_dead_code.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_dead_code_local.Plo@am__quote@
@@ -1318,23 +1279,35 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_structure_splitting.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_swizzle_swizzle.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_tree_grafting.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opt_vectorize.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prog_hash_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ralloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ralloc_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s_expression.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sampler_types_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/set_uniform_initializer_tests.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/standalone_scaffolding.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtod.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_optpass.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_general_ir_test-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_general_ir_test-hash_table.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_general_ir_test-imports.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_general_ir_test-prog_hash_table.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_general_ir_test-symbol_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_ralloc_test-ralloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_sampler_types_test-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_sampler_types_test-prog_hash_table.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_sampler_types_test-symbol_table.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_uniform_initializer_test-common.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_uniform_initializer_test-hash_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_uniform_initializer_test-imports.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_uniform_initializer_test-prog_hash_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests_uniform_initializer_test-symbol_table.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniform_initializer_utils.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/varyings_test.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -1462,6 +1435,90 @@ symbol_table.obj: $(top_srcdir)/src/mesa/program/symbol_table.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o symbol_table.obj `if test -f '$(top_srcdir)/src/mesa/program/symbol_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/symbol_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/symbol_table.c'; fi`
+common.o: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT common.o -MD -MP -MF $(DEPDIR)/common.Tpo -c -o common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/common.Tpo $(DEPDIR)/common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+
+common.obj: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT common.obj -MD -MP -MF $(DEPDIR)/common.Tpo -c -o common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/common.Tpo $(DEPDIR)/common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+
+tests_general_ir_test-hash_table.o: $(top_srcdir)/src/mesa/main/hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-hash_table.o -MD -MP -MF $(DEPDIR)/tests_general_ir_test-hash_table.Tpo -c -o tests_general_ir_test-hash_table.o `test -f '$(top_srcdir)/src/mesa/main/hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/main/hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-hash_table.Tpo $(DEPDIR)/tests_general_ir_test-hash_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/main/hash_table.c' object='tests_general_ir_test-hash_table.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-hash_table.o `test -f '$(top_srcdir)/src/mesa/main/hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/main/hash_table.c
+
+tests_general_ir_test-hash_table.obj: $(top_srcdir)/src/mesa/main/hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-hash_table.obj -MD -MP -MF $(DEPDIR)/tests_general_ir_test-hash_table.Tpo -c -o tests_general_ir_test-hash_table.obj `if test -f '$(top_srcdir)/src/mesa/main/hash_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/main/hash_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/main/hash_table.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-hash_table.Tpo $(DEPDIR)/tests_general_ir_test-hash_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/main/hash_table.c' object='tests_general_ir_test-hash_table.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-hash_table.obj `if test -f '$(top_srcdir)/src/mesa/main/hash_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/main/hash_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/main/hash_table.c'; fi`
+
+tests_general_ir_test-imports.o: $(top_srcdir)/src/mesa/main/imports.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-imports.o -MD -MP -MF $(DEPDIR)/tests_general_ir_test-imports.Tpo -c -o tests_general_ir_test-imports.o `test -f '$(top_srcdir)/src/mesa/main/imports.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/main/imports.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-imports.Tpo $(DEPDIR)/tests_general_ir_test-imports.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/main/imports.c' object='tests_general_ir_test-imports.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-imports.o `test -f '$(top_srcdir)/src/mesa/main/imports.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/main/imports.c
+
+tests_general_ir_test-imports.obj: $(top_srcdir)/src/mesa/main/imports.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-imports.obj -MD -MP -MF $(DEPDIR)/tests_general_ir_test-imports.Tpo -c -o tests_general_ir_test-imports.obj `if test -f '$(top_srcdir)/src/mesa/main/imports.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/main/imports.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/main/imports.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-imports.Tpo $(DEPDIR)/tests_general_ir_test-imports.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/main/imports.c' object='tests_general_ir_test-imports.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-imports.obj `if test -f '$(top_srcdir)/src/mesa/main/imports.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/main/imports.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/main/imports.c'; fi`
+
+tests_general_ir_test-prog_hash_table.o: $(top_srcdir)/src/mesa/program/prog_hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-prog_hash_table.o -MD -MP -MF $(DEPDIR)/tests_general_ir_test-prog_hash_table.Tpo -c -o tests_general_ir_test-prog_hash_table.o `test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/prog_hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-prog_hash_table.Tpo $(DEPDIR)/tests_general_ir_test-prog_hash_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/prog_hash_table.c' object='tests_general_ir_test-prog_hash_table.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-prog_hash_table.o `test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/prog_hash_table.c
+
+tests_general_ir_test-prog_hash_table.obj: $(top_srcdir)/src/mesa/program/prog_hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-prog_hash_table.obj -MD -MP -MF $(DEPDIR)/tests_general_ir_test-prog_hash_table.Tpo -c -o tests_general_ir_test-prog_hash_table.obj `if test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/prog_hash_table.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-prog_hash_table.Tpo $(DEPDIR)/tests_general_ir_test-prog_hash_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/prog_hash_table.c' object='tests_general_ir_test-prog_hash_table.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-prog_hash_table.obj `if test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/prog_hash_table.c'; fi`
+
+tests_general_ir_test-symbol_table.o: $(top_srcdir)/src/mesa/program/symbol_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-symbol_table.o -MD -MP -MF $(DEPDIR)/tests_general_ir_test-symbol_table.Tpo -c -o tests_general_ir_test-symbol_table.o `test -f '$(top_srcdir)/src/mesa/program/symbol_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/symbol_table.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-symbol_table.Tpo $(DEPDIR)/tests_general_ir_test-symbol_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/symbol_table.c' object='tests_general_ir_test-symbol_table.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-symbol_table.o `test -f '$(top_srcdir)/src/mesa/program/symbol_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/symbol_table.c
+
+tests_general_ir_test-symbol_table.obj: $(top_srcdir)/src/mesa/program/symbol_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-symbol_table.obj -MD -MP -MF $(DEPDIR)/tests_general_ir_test-symbol_table.Tpo -c -o tests_general_ir_test-symbol_table.obj `if test -f '$(top_srcdir)/src/mesa/program/symbol_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/symbol_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/symbol_table.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-symbol_table.Tpo $(DEPDIR)/tests_general_ir_test-symbol_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/symbol_table.c' object='tests_general_ir_test-symbol_table.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-symbol_table.obj `if test -f '$(top_srcdir)/src/mesa/program/symbol_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/symbol_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/symbol_table.c'; fi`
+
+tests_general_ir_test-common.o: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-common.o -MD -MP -MF $(DEPDIR)/tests_general_ir_test-common.Tpo -c -o tests_general_ir_test-common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-common.Tpo $(DEPDIR)/tests_general_ir_test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='tests_general_ir_test-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+
+tests_general_ir_test-common.obj: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -MT tests_general_ir_test-common.obj -MD -MP -MF $(DEPDIR)/tests_general_ir_test-common.Tpo -c -o tests_general_ir_test-common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_general_ir_test-common.Tpo $(DEPDIR)/tests_general_ir_test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='tests_general_ir_test-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_general_ir_test_CFLAGS) $(CFLAGS) -c -o tests_general_ir_test-common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+
tests_ralloc_test-ralloc.o: $(top_builddir)/src/glsl/ralloc.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_ralloc_test_CFLAGS) $(CFLAGS) -MT tests_ralloc_test-ralloc.o -MD -MP -MF $(DEPDIR)/tests_ralloc_test-ralloc.Tpo -c -o tests_ralloc_test-ralloc.o `test -f '$(top_builddir)/src/glsl/ralloc.c' || echo '$(srcdir)/'`$(top_builddir)/src/glsl/ralloc.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_ralloc_test-ralloc.Tpo $(DEPDIR)/tests_ralloc_test-ralloc.Po
@@ -1476,6 +1533,48 @@ tests_ralloc_test-ralloc.obj: $(top_builddir)/src/glsl/ralloc.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_ralloc_test_CFLAGS) $(CFLAGS) -c -o tests_ralloc_test-ralloc.obj `if test -f '$(top_builddir)/src/glsl/ralloc.c'; then $(CYGPATH_W) '$(top_builddir)/src/glsl/ralloc.c'; else $(CYGPATH_W) '$(srcdir)/$(top_builddir)/src/glsl/ralloc.c'; fi`
+tests_sampler_types_test-prog_hash_table.o: $(top_srcdir)/src/mesa/program/prog_hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -MT tests_sampler_types_test-prog_hash_table.o -MD -MP -MF $(DEPDIR)/tests_sampler_types_test-prog_hash_table.Tpo -c -o tests_sampler_types_test-prog_hash_table.o `test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/prog_hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_sampler_types_test-prog_hash_table.Tpo $(DEPDIR)/tests_sampler_types_test-prog_hash_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/prog_hash_table.c' object='tests_sampler_types_test-prog_hash_table.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -c -o tests_sampler_types_test-prog_hash_table.o `test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/prog_hash_table.c
+
+tests_sampler_types_test-prog_hash_table.obj: $(top_srcdir)/src/mesa/program/prog_hash_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -MT tests_sampler_types_test-prog_hash_table.obj -MD -MP -MF $(DEPDIR)/tests_sampler_types_test-prog_hash_table.Tpo -c -o tests_sampler_types_test-prog_hash_table.obj `if test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/prog_hash_table.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_sampler_types_test-prog_hash_table.Tpo $(DEPDIR)/tests_sampler_types_test-prog_hash_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/prog_hash_table.c' object='tests_sampler_types_test-prog_hash_table.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -c -o tests_sampler_types_test-prog_hash_table.obj `if test -f '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/prog_hash_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/prog_hash_table.c'; fi`
+
+tests_sampler_types_test-symbol_table.o: $(top_srcdir)/src/mesa/program/symbol_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -MT tests_sampler_types_test-symbol_table.o -MD -MP -MF $(DEPDIR)/tests_sampler_types_test-symbol_table.Tpo -c -o tests_sampler_types_test-symbol_table.o `test -f '$(top_srcdir)/src/mesa/program/symbol_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/symbol_table.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_sampler_types_test-symbol_table.Tpo $(DEPDIR)/tests_sampler_types_test-symbol_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/symbol_table.c' object='tests_sampler_types_test-symbol_table.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -c -o tests_sampler_types_test-symbol_table.o `test -f '$(top_srcdir)/src/mesa/program/symbol_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/program/symbol_table.c
+
+tests_sampler_types_test-symbol_table.obj: $(top_srcdir)/src/mesa/program/symbol_table.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -MT tests_sampler_types_test-symbol_table.obj -MD -MP -MF $(DEPDIR)/tests_sampler_types_test-symbol_table.Tpo -c -o tests_sampler_types_test-symbol_table.obj `if test -f '$(top_srcdir)/src/mesa/program/symbol_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/symbol_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/symbol_table.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_sampler_types_test-symbol_table.Tpo $(DEPDIR)/tests_sampler_types_test-symbol_table.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/mesa/program/symbol_table.c' object='tests_sampler_types_test-symbol_table.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -c -o tests_sampler_types_test-symbol_table.obj `if test -f '$(top_srcdir)/src/mesa/program/symbol_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/symbol_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/symbol_table.c'; fi`
+
+tests_sampler_types_test-common.o: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -MT tests_sampler_types_test-common.o -MD -MP -MF $(DEPDIR)/tests_sampler_types_test-common.Tpo -c -o tests_sampler_types_test-common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_sampler_types_test-common.Tpo $(DEPDIR)/tests_sampler_types_test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='tests_sampler_types_test-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -c -o tests_sampler_types_test-common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+
+tests_sampler_types_test-common.obj: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -MT tests_sampler_types_test-common.obj -MD -MP -MF $(DEPDIR)/tests_sampler_types_test-common.Tpo -c -o tests_sampler_types_test-common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_sampler_types_test-common.Tpo $(DEPDIR)/tests_sampler_types_test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='tests_sampler_types_test-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_sampler_types_test_CFLAGS) $(CFLAGS) -c -o tests_sampler_types_test-common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+
tests_uniform_initializer_test-hash_table.o: $(top_srcdir)/src/mesa/main/hash_table.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_uniform_initializer_test_CFLAGS) $(CFLAGS) -MT tests_uniform_initializer_test-hash_table.o -MD -MP -MF $(DEPDIR)/tests_uniform_initializer_test-hash_table.Tpo -c -o tests_uniform_initializer_test-hash_table.o `test -f '$(top_srcdir)/src/mesa/main/hash_table.c' || echo '$(srcdir)/'`$(top_srcdir)/src/mesa/main/hash_table.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_uniform_initializer_test-hash_table.Tpo $(DEPDIR)/tests_uniform_initializer_test-hash_table.Po
@@ -1532,6 +1631,20 @@ tests_uniform_initializer_test-symbol_table.obj: $(top_srcdir)/src/mesa/program/
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_uniform_initializer_test_CFLAGS) $(CFLAGS) -c -o tests_uniform_initializer_test-symbol_table.obj `if test -f '$(top_srcdir)/src/mesa/program/symbol_table.c'; then $(CYGPATH_W) '$(top_srcdir)/src/mesa/program/symbol_table.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mesa/program/symbol_table.c'; fi`
+tests_uniform_initializer_test-common.o: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_uniform_initializer_test_CFLAGS) $(CFLAGS) -MT tests_uniform_initializer_test-common.o -MD -MP -MF $(DEPDIR)/tests_uniform_initializer_test-common.Tpo -c -o tests_uniform_initializer_test-common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_uniform_initializer_test-common.Tpo $(DEPDIR)/tests_uniform_initializer_test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='tests_uniform_initializer_test-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_uniform_initializer_test_CFLAGS) $(CFLAGS) -c -o tests_uniform_initializer_test-common.o `test -f 'tests/common.c' || echo '$(srcdir)/'`tests/common.c
+
+tests_uniform_initializer_test-common.obj: tests/common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_uniform_initializer_test_CFLAGS) $(CFLAGS) -MT tests_uniform_initializer_test-common.obj -MD -MP -MF $(DEPDIR)/tests_uniform_initializer_test-common.Tpo -c -o tests_uniform_initializer_test-common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests_uniform_initializer_test-common.Tpo $(DEPDIR)/tests_uniform_initializer_test-common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests/common.c' object='tests_uniform_initializer_test-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_uniform_initializer_test_CFLAGS) $(CFLAGS) -c -o tests_uniform_initializer_test-common.obj `if test -f 'tests/common.c'; then $(CYGPATH_W) 'tests/common.c'; else $(CYGPATH_W) '$(srcdir)/tests/common.c'; fi`
+
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@@ -1588,6 +1701,13 @@ ast_type.lo: $(GLSL_SRCDIR)/ast_type.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ast_type.lo `test -f '$(GLSL_SRCDIR)/ast_type.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/ast_type.cpp
+builtin_functions.lo: $(GLSL_SRCDIR)/builtin_functions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT builtin_functions.lo -MD -MP -MF $(DEPDIR)/builtin_functions.Tpo -c -o builtin_functions.lo `test -f '$(GLSL_SRCDIR)/builtin_functions.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/builtin_functions.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/builtin_functions.Tpo $(DEPDIR)/builtin_functions.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/builtin_functions.cpp' object='builtin_functions.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o builtin_functions.lo `test -f '$(GLSL_SRCDIR)/builtin_functions.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/builtin_functions.cpp
+
builtin_types.lo: $(GLSL_SRCDIR)/builtin_types.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT builtin_types.lo -MD -MP -MF $(DEPDIR)/builtin_types.Tpo -c -o builtin_types.lo `test -f '$(GLSL_SRCDIR)/builtin_types.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/builtin_types.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/builtin_types.Tpo $(DEPDIR)/builtin_types.Plo
@@ -1665,6 +1785,13 @@ ir.lo: $(GLSL_SRCDIR)/ir.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ir.lo `test -f '$(GLSL_SRCDIR)/ir.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/ir.cpp
+ir_equals.lo: $(GLSL_SRCDIR)/ir_equals.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ir_equals.lo -MD -MP -MF $(DEPDIR)/ir_equals.Tpo -c -o ir_equals.lo `test -f '$(GLSL_SRCDIR)/ir_equals.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/ir_equals.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ir_equals.Tpo $(DEPDIR)/ir_equals.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/ir_equals.cpp' object='ir_equals.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ir_equals.lo `test -f '$(GLSL_SRCDIR)/ir_equals.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/ir_equals.cpp
+
ir_expression_flattening.lo: $(GLSL_SRCDIR)/ir_expression_flattening.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ir_expression_flattening.lo -MD -MP -MF $(DEPDIR)/ir_expression_flattening.Tpo -c -o ir_expression_flattening.lo `test -f '$(GLSL_SRCDIR)/ir_expression_flattening.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/ir_expression_flattening.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ir_expression_flattening.Tpo $(DEPDIR)/ir_expression_flattening.Plo
@@ -1763,6 +1890,13 @@ linker.lo: $(GLSL_SRCDIR)/linker.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o linker.lo `test -f '$(GLSL_SRCDIR)/linker.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/linker.cpp
+link_atomics.lo: $(GLSL_SRCDIR)/link_atomics.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT link_atomics.lo -MD -MP -MF $(DEPDIR)/link_atomics.Tpo -c -o link_atomics.lo `test -f '$(GLSL_SRCDIR)/link_atomics.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/link_atomics.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/link_atomics.Tpo $(DEPDIR)/link_atomics.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/link_atomics.cpp' object='link_atomics.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o link_atomics.lo `test -f '$(GLSL_SRCDIR)/link_atomics.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/link_atomics.cpp
+
link_functions.lo: $(GLSL_SRCDIR)/link_functions.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT link_functions.lo -MD -MP -MF $(DEPDIR)/link_functions.Tpo -c -o link_functions.lo `test -f '$(GLSL_SRCDIR)/link_functions.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/link_functions.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/link_functions.Tpo $(DEPDIR)/link_functions.Plo
@@ -1889,6 +2023,13 @@ lower_noise.lo: $(GLSL_SRCDIR)/lower_noise.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lower_noise.lo `test -f '$(GLSL_SRCDIR)/lower_noise.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/lower_noise.cpp
+lower_offset_array.lo: $(GLSL_SRCDIR)/lower_offset_array.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lower_offset_array.lo -MD -MP -MF $(DEPDIR)/lower_offset_array.Tpo -c -o lower_offset_array.lo `test -f '$(GLSL_SRCDIR)/lower_offset_array.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/lower_offset_array.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lower_offset_array.Tpo $(DEPDIR)/lower_offset_array.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/lower_offset_array.cpp' object='lower_offset_array.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o lower_offset_array.lo `test -f '$(GLSL_SRCDIR)/lower_offset_array.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/lower_offset_array.cpp
+
lower_packed_varyings.lo: $(GLSL_SRCDIR)/lower_packed_varyings.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT lower_packed_varyings.lo -MD -MP -MF $(DEPDIR)/lower_packed_varyings.Tpo -c -o lower_packed_varyings.lo `test -f '$(GLSL_SRCDIR)/lower_packed_varyings.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/lower_packed_varyings.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lower_packed_varyings.Tpo $(DEPDIR)/lower_packed_varyings.Plo
@@ -2015,6 +2156,13 @@ opt_copy_propagation_elements.lo: $(GLSL_SRCDIR)/opt_copy_propagation_elements.c
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o opt_copy_propagation_elements.lo `test -f '$(GLSL_SRCDIR)/opt_copy_propagation_elements.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_copy_propagation_elements.cpp
+opt_cse.lo: $(GLSL_SRCDIR)/opt_cse.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT opt_cse.lo -MD -MP -MF $(DEPDIR)/opt_cse.Tpo -c -o opt_cse.lo `test -f '$(GLSL_SRCDIR)/opt_cse.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_cse.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/opt_cse.Tpo $(DEPDIR)/opt_cse.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/opt_cse.cpp' object='opt_cse.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o opt_cse.lo `test -f '$(GLSL_SRCDIR)/opt_cse.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_cse.cpp
+
opt_dead_builtin_varyings.lo: $(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT opt_dead_builtin_varyings.lo -MD -MP -MF $(DEPDIR)/opt_dead_builtin_varyings.Tpo -c -o opt_dead_builtin_varyings.lo `test -f '$(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/opt_dead_builtin_varyings.Tpo $(DEPDIR)/opt_dead_builtin_varyings.Plo
@@ -2106,6 +2254,13 @@ opt_tree_grafting.lo: $(GLSL_SRCDIR)/opt_tree_grafting.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o opt_tree_grafting.lo `test -f '$(GLSL_SRCDIR)/opt_tree_grafting.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_tree_grafting.cpp
+opt_vectorize.lo: $(GLSL_SRCDIR)/opt_vectorize.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT opt_vectorize.lo -MD -MP -MF $(DEPDIR)/opt_vectorize.Tpo -c -o opt_vectorize.lo `test -f '$(GLSL_SRCDIR)/opt_vectorize.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_vectorize.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/opt_vectorize.Tpo $(DEPDIR)/opt_vectorize.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/opt_vectorize.cpp' object='opt_vectorize.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o opt_vectorize.lo `test -f '$(GLSL_SRCDIR)/opt_vectorize.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/opt_vectorize.cpp
+
s_expression.lo: $(GLSL_SRCDIR)/s_expression.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT s_expression.lo -MD -MP -MF $(DEPDIR)/s_expression.Tpo -c -o s_expression.lo `test -f '$(GLSL_SRCDIR)/s_expression.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/s_expression.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/s_expression.Tpo $(DEPDIR)/s_expression.Plo
@@ -2127,6 +2282,76 @@ standalone_scaffolding.obj: $(GLSL_SRCDIR)/standalone_scaffolding.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o standalone_scaffolding.obj `if test -f '$(GLSL_SRCDIR)/standalone_scaffolding.cpp'; then $(CYGPATH_W) '$(GLSL_SRCDIR)/standalone_scaffolding.cpp'; else $(CYGPATH_W) '$(srcdir)/$(GLSL_SRCDIR)/standalone_scaffolding.cpp'; fi`
+main.o: $(GLSL_SRCDIR)/main.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main.o -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.o `test -f '$(GLSL_SRCDIR)/main.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/main.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/main.cpp' object='main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.o `test -f '$(GLSL_SRCDIR)/main.cpp' || echo '$(srcdir)/'`$(GLSL_SRCDIR)/main.cpp
+
+main.obj: $(GLSL_SRCDIR)/main.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT main.obj -MD -MP -MF $(DEPDIR)/main.Tpo -c -o main.obj `if test -f '$(GLSL_SRCDIR)/main.cpp'; then $(CYGPATH_W) '$(GLSL_SRCDIR)/main.cpp'; else $(CYGPATH_W) '$(srcdir)/$(GLSL_SRCDIR)/main.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/main.Tpo $(DEPDIR)/main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GLSL_SRCDIR)/main.cpp' object='main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o main.obj `if test -f '$(GLSL_SRCDIR)/main.cpp'; then $(CYGPATH_W) '$(GLSL_SRCDIR)/main.cpp'; else $(CYGPATH_W) '$(srcdir)/$(GLSL_SRCDIR)/main.cpp'; fi`
+
+builtin_variable_test.o: tests/builtin_variable_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT builtin_variable_test.o -MD -MP -MF $(DEPDIR)/builtin_variable_test.Tpo -c -o builtin_variable_test.o `test -f 'tests/builtin_variable_test.cpp' || echo '$(srcdir)/'`tests/builtin_variable_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/builtin_variable_test.Tpo $(DEPDIR)/builtin_variable_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/builtin_variable_test.cpp' object='builtin_variable_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o builtin_variable_test.o `test -f 'tests/builtin_variable_test.cpp' || echo '$(srcdir)/'`tests/builtin_variable_test.cpp
+
+builtin_variable_test.obj: tests/builtin_variable_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT builtin_variable_test.obj -MD -MP -MF $(DEPDIR)/builtin_variable_test.Tpo -c -o builtin_variable_test.obj `if test -f 'tests/builtin_variable_test.cpp'; then $(CYGPATH_W) 'tests/builtin_variable_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/builtin_variable_test.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/builtin_variable_test.Tpo $(DEPDIR)/builtin_variable_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/builtin_variable_test.cpp' object='builtin_variable_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o builtin_variable_test.obj `if test -f 'tests/builtin_variable_test.cpp'; then $(CYGPATH_W) 'tests/builtin_variable_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/builtin_variable_test.cpp'; fi`
+
+invalidate_locations_test.o: tests/invalidate_locations_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT invalidate_locations_test.o -MD -MP -MF $(DEPDIR)/invalidate_locations_test.Tpo -c -o invalidate_locations_test.o `test -f 'tests/invalidate_locations_test.cpp' || echo '$(srcdir)/'`tests/invalidate_locations_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/invalidate_locations_test.Tpo $(DEPDIR)/invalidate_locations_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/invalidate_locations_test.cpp' object='invalidate_locations_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o invalidate_locations_test.o `test -f 'tests/invalidate_locations_test.cpp' || echo '$(srcdir)/'`tests/invalidate_locations_test.cpp
+
+invalidate_locations_test.obj: tests/invalidate_locations_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT invalidate_locations_test.obj -MD -MP -MF $(DEPDIR)/invalidate_locations_test.Tpo -c -o invalidate_locations_test.obj `if test -f 'tests/invalidate_locations_test.cpp'; then $(CYGPATH_W) 'tests/invalidate_locations_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/invalidate_locations_test.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/invalidate_locations_test.Tpo $(DEPDIR)/invalidate_locations_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/invalidate_locations_test.cpp' object='invalidate_locations_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o invalidate_locations_test.obj `if test -f 'tests/invalidate_locations_test.cpp'; then $(CYGPATH_W) 'tests/invalidate_locations_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/invalidate_locations_test.cpp'; fi`
+
+general_ir_test.o: tests/general_ir_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT general_ir_test.o -MD -MP -MF $(DEPDIR)/general_ir_test.Tpo -c -o general_ir_test.o `test -f 'tests/general_ir_test.cpp' || echo '$(srcdir)/'`tests/general_ir_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/general_ir_test.Tpo $(DEPDIR)/general_ir_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/general_ir_test.cpp' object='general_ir_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o general_ir_test.o `test -f 'tests/general_ir_test.cpp' || echo '$(srcdir)/'`tests/general_ir_test.cpp
+
+general_ir_test.obj: tests/general_ir_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT general_ir_test.obj -MD -MP -MF $(DEPDIR)/general_ir_test.Tpo -c -o general_ir_test.obj `if test -f 'tests/general_ir_test.cpp'; then $(CYGPATH_W) 'tests/general_ir_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/general_ir_test.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/general_ir_test.Tpo $(DEPDIR)/general_ir_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/general_ir_test.cpp' object='general_ir_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o general_ir_test.obj `if test -f 'tests/general_ir_test.cpp'; then $(CYGPATH_W) 'tests/general_ir_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/general_ir_test.cpp'; fi`
+
+varyings_test.o: tests/varyings_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT varyings_test.o -MD -MP -MF $(DEPDIR)/varyings_test.Tpo -c -o varyings_test.o `test -f 'tests/varyings_test.cpp' || echo '$(srcdir)/'`tests/varyings_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/varyings_test.Tpo $(DEPDIR)/varyings_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/varyings_test.cpp' object='varyings_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o varyings_test.o `test -f 'tests/varyings_test.cpp' || echo '$(srcdir)/'`tests/varyings_test.cpp
+
+varyings_test.obj: tests/varyings_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT varyings_test.obj -MD -MP -MF $(DEPDIR)/varyings_test.Tpo -c -o varyings_test.obj `if test -f 'tests/varyings_test.cpp'; then $(CYGPATH_W) 'tests/varyings_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/varyings_test.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/varyings_test.Tpo $(DEPDIR)/varyings_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/varyings_test.cpp' object='varyings_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o varyings_test.obj `if test -f 'tests/varyings_test.cpp'; then $(CYGPATH_W) 'tests/varyings_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/varyings_test.cpp'; fi`
+
ralloc_test.o: tests/ralloc_test.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ralloc_test.o -MD -MP -MF $(DEPDIR)/ralloc_test.Tpo -c -o ralloc_test.o `test -f 'tests/ralloc_test.cpp' || echo '$(srcdir)/'`tests/ralloc_test.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ralloc_test.Tpo $(DEPDIR)/ralloc_test.Po
@@ -2141,6 +2366,20 @@ ralloc_test.obj: tests/ralloc_test.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ralloc_test.obj `if test -f 'tests/ralloc_test.cpp'; then $(CYGPATH_W) 'tests/ralloc_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/ralloc_test.cpp'; fi`
+sampler_types_test.o: tests/sampler_types_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sampler_types_test.o -MD -MP -MF $(DEPDIR)/sampler_types_test.Tpo -c -o sampler_types_test.o `test -f 'tests/sampler_types_test.cpp' || echo '$(srcdir)/'`tests/sampler_types_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sampler_types_test.Tpo $(DEPDIR)/sampler_types_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/sampler_types_test.cpp' object='sampler_types_test.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sampler_types_test.o `test -f 'tests/sampler_types_test.cpp' || echo '$(srcdir)/'`tests/sampler_types_test.cpp
+
+sampler_types_test.obj: tests/sampler_types_test.cpp
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sampler_types_test.obj -MD -MP -MF $(DEPDIR)/sampler_types_test.Tpo -c -o sampler_types_test.obj `if test -f 'tests/sampler_types_test.cpp'; then $(CYGPATH_W) 'tests/sampler_types_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/sampler_types_test.cpp'; fi`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/sampler_types_test.Tpo $(DEPDIR)/sampler_types_test.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tests/sampler_types_test.cpp' object='sampler_types_test.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sampler_types_test.obj `if test -f 'tests/sampler_types_test.cpp'; then $(CYGPATH_W) 'tests/sampler_types_test.cpp'; else $(CYGPATH_W) '$(srcdir)/tests/sampler_types_test.cpp'; fi`
+
copy_constant_to_storage_tests.o: tests/copy_constant_to_storage_tests.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT copy_constant_to_storage_tests.o -MD -MP -MF $(DEPDIR)/copy_constant_to_storage_tests.Tpo -c -o copy_constant_to_storage_tests.o `test -f 'tests/copy_constant_to_storage_tests.cpp' || echo '$(srcdir)/'`tests/copy_constant_to_storage_tests.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/copy_constant_to_storage_tests.Tpo $(DEPDIR)/copy_constant_to_storage_tests.Po
@@ -2191,61 +2430,14 @@ clean-libtool:
-rm -rf glcpp/.libs glcpp/_libs
-rm -rf tests/.libs tests/_libs
-# This directory's subdirectories are mostly independent; you can cd
-# into them and run 'make' without going through this Makefile.
-# To change the values of 'make' variables: instead of editing Makefiles,
-# (1) if the variable is set in 'config.status', edit 'config.status'
-# (which will cause the Makefiles to be regenerated when you run 'make');
-# (2) otherwise, pass the desired values on the 'make' command line.
-$(am__recursive_targets):
- @fail=; \
- if $(am__make_keepgoing); then \
- failcom='fail=yes'; \
- else \
- failcom='exit 1'; \
- fi; \
- dot_seen=no; \
- target=`echo $@ | sed s/-recursive//`; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- for subdir in $$list; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
- fi; test -z "$$fail"
-
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-recursive
+tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
- include_option=--etags-include; \
- empty_fix=.; \
- else \
- include_option=--include; \
- empty_fix=; \
- fi; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test ! -f $$subdir/TAGS || \
- set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
- fi; \
- done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
@@ -2258,7 +2450,7 @@ tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$$unique; \
fi; \
fi
-ctags: ctags-recursive
+ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
@@ -2271,7 +2463,7 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-recursive
+cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
@@ -2438,6 +2630,13 @@ glcpp/tests/glcpp-test.log: glcpp/tests/glcpp-test
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/general-ir-test.log: tests/general-ir-test$(EXEEXT)
+ @p='tests/general-ir-test$(EXEEXT)'; \
+ b='tests/general-ir-test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
tests/optimization-test.log: tests/optimization-test
@p='tests/optimization-test'; \
b='tests/optimization-test'; \
@@ -2452,6 +2651,13 @@ tests/ralloc-test.log: tests/ralloc-test$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/sampler-types-test.log: tests/sampler-types-test$(EXEEXT)
+ @p='tests/sampler-types-test$(EXEEXT)'; \
+ b='tests/sampler-types-test'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
tests/uniform-initializer-test.log: tests/uniform-initializer-test$(EXEEXT)
@p='tests/uniform-initializer-test$(EXEEXT)'; \
b='tests/uniform-initializer-test'; \
@@ -2504,49 +2710,23 @@ distdir: $(DISTFILES)
|| exit 1; \
fi; \
done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- $(am__make_dryrun) \
- || test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
- $(am__relativize); \
- new_distdir=$$reldir; \
- dir1=$$subdir; dir2="$(top_distdir)"; \
- $(am__relativize); \
- new_top_distdir=$$reldir; \
- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
- ($(am__cd) $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$new_top_distdir" \
- distdir="$$new_distdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- am__skip_mode_fix=: \
- distdir) \
- || exit 1; \
- fi; \
- done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) check-recursive
-all-am: Makefile $(LTLIBRARIES)
-installdirs: installdirs-recursive
-installdirs-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
+installdirs:
install: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) install-recursive
-install-exec: install-exec-recursive
-install-data: install-data-recursive
-uninstall: uninstall-recursive
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-installcheck: installcheck-recursive
+installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
@@ -2575,91 +2755,90 @@ maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-clean: clean-recursive
+clean: clean-am
clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
- clean-noinstLTLIBRARIES mostlyclean-am
+ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am
-distclean: distclean-recursive
+distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
-dvi: dvi-recursive
+dvi: dvi-am
dvi-am:
-html: html-recursive
+html: html-am
html-am:
-info: info-recursive
+info: info-am
info-am:
install-data-am:
-install-dvi: install-dvi-recursive
+install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
-install-html: install-html-recursive
+install-html: install-html-am
install-html-am:
-install-info: install-info-recursive
+install-info: install-info-am
install-info-am:
install-man:
-install-pdf: install-pdf-recursive
+install-pdf: install-pdf-am
install-pdf-am:
-install-ps: install-ps-recursive
+install-ps: install-ps-am
install-ps-am:
installcheck-am:
-maintainer-clean: maintainer-clean-recursive
+maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
-mostlyclean: mostlyclean-recursive
+mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
-pdf: pdf-recursive
+pdf: pdf-am
pdf-am:
-ps: ps-recursive
+ps: ps-am
ps-am:
uninstall-am:
-.MAKE: $(am__recursive_targets) all check check-am install install-am \
- install-strip
+.MAKE: all check check-am install install-am install-strip
-.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
- check-TESTS check-am clean clean-checkPROGRAMS clean-generic \
- clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
- ctags-am distclean distclean-compile distclean-generic \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs installdirs-am maintainer-clean \
+ installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
recheck tags tags-am uninstall uninstall-am
@@ -2672,16 +2851,13 @@ glsl_lexer.cpp: glsl_lexer.ll
$(AM_V_LEX) $(LEX) $(LFLAGS) -o $@ $<
glcpp/glcpp-parse.c glcpp/glcpp-parse.h: glcpp/glcpp-parse.y
- $(MKDIR_P) $(GLSL_BUILDDIR)/glcpp
+ $(AM_V_at)$(MKDIR_P) glcpp
$(AM_V_YACC) $(YACC) $(YFLAGS) -o $@ -p "glcpp_parser_" --defines=$(GLSL_BUILDDIR)/glcpp/glcpp-parse.h $<
glcpp/glcpp-lex.c: glcpp/glcpp-lex.l
- $(MKDIR_P) $(GLSL_BUILDDIR)/glcpp
+ $(AM_V_at)$(MKDIR_P) glcpp
$(AM_V_LEX) $(LEX) $(LFLAGS) -o $@ $<
-builtin_function.cpp: $(srcdir)/builtins/profiles/* $(srcdir)/builtins/ir/* $(srcdir)/builtins/glsl/* $(srcdir)/builtins/tools/generate_builtins.py $(srcdir)/builtins/tools/texture_builtins.py $(builddir)/builtin_compiler/builtin_compiler$(BUILD_EXEEXT)
- $(AM_V_GEN) $(PYTHON2) $(PYTHON_FLAGS) $(srcdir)/builtins/tools/generate_builtins.py $(builddir)/builtin_compiler/builtin_compiler$(BUILD_EXEEXT) > builtin_function.cpp || rm -f builtin_function.cpp
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/dist/Mesa/src/glsl/Makefile.sources b/dist/Mesa/src/glsl/Makefile.sources
index 979c4165f..5945590a5 100644
--- a/dist/Mesa/src/glsl/Makefile.sources
+++ b/dist/Mesa/src/glsl/Makefile.sources
@@ -21,6 +21,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ast_function.cpp \
$(GLSL_SRCDIR)/ast_to_hir.cpp \
$(GLSL_SRCDIR)/ast_type.cpp \
+ $(GLSL_SRCDIR)/builtin_functions.cpp \
$(GLSL_SRCDIR)/builtin_types.cpp \
$(GLSL_SRCDIR)/builtin_variables.cpp \
$(GLSL_SRCDIR)/glsl_parser_extras.cpp \
@@ -32,6 +33,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ir_clone.cpp \
$(GLSL_SRCDIR)/ir_constant_expression.cpp \
$(GLSL_SRCDIR)/ir.cpp \
+ $(GLSL_SRCDIR)/ir_equals.cpp \
$(GLSL_SRCDIR)/ir_expression_flattening.cpp \
$(GLSL_SRCDIR)/ir_function_can_inline.cpp \
$(GLSL_SRCDIR)/ir_function_detect_recursion.cpp \
@@ -46,6 +48,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/ir_validate.cpp \
$(GLSL_SRCDIR)/ir_variable_refcount.cpp \
$(GLSL_SRCDIR)/linker.cpp \
+ $(GLSL_SRCDIR)/link_atomics.cpp \
$(GLSL_SRCDIR)/link_functions.cpp \
$(GLSL_SRCDIR)/link_interface_blocks.cpp \
$(GLSL_SRCDIR)/link_uniforms.cpp \
@@ -64,6 +67,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/lower_jumps.cpp \
$(GLSL_SRCDIR)/lower_mat_op_to_vec.cpp \
$(GLSL_SRCDIR)/lower_noise.cpp \
+ $(GLSL_SRCDIR)/lower_offset_array.cpp \
$(GLSL_SRCDIR)/lower_packed_varyings.cpp \
$(GLSL_SRCDIR)/lower_named_interface_blocks.cpp \
$(GLSL_SRCDIR)/lower_packing_builtins.cpp \
@@ -82,6 +86,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_constant_variable.cpp \
$(GLSL_SRCDIR)/opt_copy_propagation.cpp \
$(GLSL_SRCDIR)/opt_copy_propagation_elements.cpp \
+ $(GLSL_SRCDIR)/opt_cse.cpp \
$(GLSL_SRCDIR)/opt_dead_builtin_varyings.cpp \
$(GLSL_SRCDIR)/opt_dead_code.cpp \
$(GLSL_SRCDIR)/opt_dead_code_local.cpp \
@@ -95,6 +100,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_structure_splitting.cpp \
$(GLSL_SRCDIR)/opt_swizzle_swizzle.cpp \
$(GLSL_SRCDIR)/opt_tree_grafting.cpp \
+ $(GLSL_SRCDIR)/opt_vectorize.cpp \
$(GLSL_SRCDIR)/s_expression.cpp \
$(GLSL_SRCDIR)/strtod.c
@@ -104,20 +110,7 @@ GLSL_COMPILER_CXX_FILES = \
$(GLSL_SRCDIR)/standalone_scaffolding.cpp \
$(GLSL_SRCDIR)/main.cpp
-# builtin_compiler
-#
-# This is built before libglsl to generate builtin_function.cpp for libglsl.
-# For this to work, a dummy version of builtin_function.cpp,
-# builtin_stubs.cpp, is used.
-
-BUILTIN_COMPILER_CXX_FILES = \
- $(GLSL_SRCDIR)/builtin_compiler/builtin_stubs.cpp
-
-BUILTIN_COMPILER_GENERATED_CXX_FILES = \
- $(GLSL_BUILDDIR)/glsl_lexer.cpp \
- $(GLSL_BUILDDIR)/glsl_parser.cpp
-
# libglsl generated sources
LIBGLSL_GENERATED_CXX_FILES = \
- $(BUILTIN_COMPILER_GENERATED_CXX_FILES) \
- $(GLSL_BUILDDIR)/builtin_function.cpp
+ $(GLSL_BUILDDIR)/glsl_lexer.cpp \
+ $(GLSL_BUILDDIR)/glsl_parser.cpp
diff --git a/dist/Mesa/src/glsl/ast_array_index.cpp b/dist/Mesa/src/glsl/ast_array_index.cpp
index 4baeb6f9d..f3b060ea6 100644
--- a/dist/Mesa/src/glsl/ast_array_index.cpp
+++ b/dist/Mesa/src/glsl/ast_array_index.cpp
@@ -25,6 +25,84 @@
#include "glsl_types.h"
#include "ir.h"
+void
+ast_array_specifier::print(void) const
+{
+ if (this->is_unsized_array) {
+ printf("[ ] ");
+ }
+
+ foreach_list_typed (ast_node, array_dimension, link, &this->array_dimensions) {
+ printf("[ ");
+ array_dimension->print();
+ printf("] ");
+ }
+}
+
+/**
+ * If \c ir is a reference to an array for which we are tracking the max array
+ * element accessed, track that the given element has been accessed.
+ * Otherwise do nothing.
+ *
+ * This function also checks whether the array is a built-in array whose
+ * maximum size is too small to accommodate the given index, and if so uses
+ * loc and state to report the error.
+ */
+static void
+update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc,
+ struct _mesa_glsl_parse_state *state)
+{
+ if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) {
+ ir_variable *var = deref_var->var;
+ if (idx > var->data.max_array_access) {
+ var->data.max_array_access = idx;
+
+ /* Check whether this access will, as a side effect, implicitly cause
+ * the size of a built-in array to be too large.
+ */
+ check_builtin_array_max_size(var->name, idx+1, *loc, state);
+ }
+ } else if (ir_dereference_record *deref_record =
+ ir->as_dereference_record()) {
+ /* There are two possibilities we need to consider:
+ *
+ * - Accessing an element of an array that is a member of a named
+ * interface block (e.g. ifc.foo[i])
+ *
+ * - Accessing an element of an array that is a member of a named
+ * interface block array (e.g. ifc[j].foo[i]).
+ */
+ ir_dereference_variable *deref_var =
+ deref_record->record->as_dereference_variable();
+ if (deref_var == NULL) {
+ if (ir_dereference_array *deref_array =
+ deref_record->record->as_dereference_array()) {
+ deref_var = deref_array->array->as_dereference_variable();
+ }
+ }
+
+ if (deref_var != NULL) {
+ if (deref_var->var->is_interface_instance()) {
+ const glsl_type *interface_type =
+ deref_var->var->get_interface_type();
+ unsigned field_index =
+ deref_record->record->type->field_index(deref_record->field);
+ assert(field_index < interface_type->length);
+ if (idx > deref_var->var->max_ifc_array_access[field_index]) {
+ deref_var->var->max_ifc_array_access[field_index] = idx;
+
+ /* Check whether this access will, as a side effect, implicitly
+ * cause the size of a built-in array to be too large.
+ */
+ check_builtin_array_max_size(deref_record->field, idx+1, *loc,
+ state);
+ }
+ }
+ }
+ }
+}
+
+
ir_rvalue *
_mesa_ast_array_index_to_hir(void *mem_ctx,
struct _mesa_glsl_parse_state *state,
@@ -78,7 +156,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
bound = array->type->vector_elements;
}
} else {
- /* glsl_type::array_size() returns 0 for non-array types. This means
+ /* glsl_type::array_size() returns -1 for non-array types. This means
* that we don't need to verify that the type is an array before
* doing the bounds checking.
*/
@@ -97,27 +175,13 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
type_name);
}
- if (array->type->is_array()) {
- /* If the array is a variable dereference, it dereferences the
- * whole array, by definition. Use this to get the variable.
- *
- * FINISHME: Should some methods for getting / setting / testing
- * FINISHME: array access limits be added to ir_dereference?
- */
- ir_variable *const v = array->whole_variable_referenced();
- if ((v != NULL) && (unsigned(idx) > v->max_array_access)) {
- v->max_array_access = idx;
-
- /* Check whether this access will, as a side effect, implicitly
- * cause the size of a built-in array to be too large.
- */
- check_builtin_array_max_size(v->name, idx+1, loc, state);
- }
- }
+ if (array->type->is_array())
+ update_max_array_access(array, idx, &loc, state);
} else if (const_index == NULL && array->type->is_array()) {
- if (array->type->array_size() == 0) {
+ if (array->type->is_unsized_array()) {
_mesa_glsl_error(&loc, state, "unsized array index must be constant");
- } else if (array->type->fields.array->is_interface()) {
+ } else if (array->type->fields.array->is_interface()
+ && array->variable_referenced()->data.mode == ir_var_uniform) {
/* Page 46 in section 4.3.7 of the OpenGL ES 3.00 spec says:
*
* "All indexes used to index a uniform block array must be
@@ -133,7 +197,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
*/
ir_variable *v = array->whole_variable_referenced();
if (v != NULL)
- v->max_array_access = array->type->array_size() - 1;
+ v->data.max_array_access = array->type->array_size() - 1;
}
/* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
diff --git a/dist/Mesa/src/glsl/builtin_functions.cpp b/dist/Mesa/src/glsl/builtin_functions.cpp
new file mode 100644
index 000000000..f9f06862e
--- /dev/null
+++ b/dist/Mesa/src/glsl/builtin_functions.cpp
@@ -0,0 +1,4405 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+/**
+ * \file builtin_functions.cpp
+ *
+ * Support for GLSL built-in functions.
+ *
+ * This file is split into several main components:
+ *
+ * 1. Availability predicates
+ *
+ * A series of small functions that check whether the current shader
+ * supports the version/extensions required to expose a built-in.
+ *
+ * 2. Core builtin_builder class functionality
+ *
+ * 3. Lists of built-in functions
+ *
+ * The builtin_builder::create_builtins() function contains lists of all
+ * built-in function signatures, where they're available, what types they
+ * take, and so on.
+ *
+ * 4. Implementations of built-in function signatures
+ *
+ * A series of functions which create ir_function_signatures and emit IR
+ * via ir_builder to implement them.
+ *
+ * 5. External API
+ *
+ * A few functions the rest of the compiler can use to interact with the
+ * built-in function module. For example, searching for a built-in by
+ * name and parameters.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "main/core.h" /* for struct gl_shader */
+#include "main/shaderobj.h"
+#include "ir_builder.h"
+#include "glsl_parser_extras.h"
+#include "program/prog_instruction.h"
+#include <limits>
+
+#define M_PIf ((float) M_PI)
+#define M_PI_2f ((float) M_PI_2)
+#define M_PI_4f ((float) M_PI_4)
+
+using namespace ir_builder;
+
+/**
+ * Availability predicates:
+ * @{
+ */
+static bool
+always_available(const _mesa_glsl_parse_state *)
+{
+ return true;
+}
+
+static bool
+compatibility_vs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_VERTEX &&
+ state->language_version <= 130 &&
+ !state->es_shader;
+}
+
+static bool
+fs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT;
+}
+
+static bool
+gs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_GEOMETRY;
+}
+
+static bool
+v110(const _mesa_glsl_parse_state *state)
+{
+ return !state->es_shader;
+}
+
+static bool
+v110_fs_only(const _mesa_glsl_parse_state *state)
+{
+ return !state->es_shader && state->stage == MESA_SHADER_FRAGMENT;
+}
+
+static bool
+v120(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(120, 300);
+}
+
+static bool
+v130(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(130, 300);
+}
+
+static bool
+v130_fs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(130, 300) &&
+ state->stage == MESA_SHADER_FRAGMENT;
+}
+
+static bool
+v140(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(140, 0);
+}
+
+static bool
+texture_rectangle(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_texture_rectangle_enable;
+}
+
+static bool
+texture_external(const _mesa_glsl_parse_state *state)
+{
+ return state->OES_EGL_image_external_enable;
+}
+
+/** True if texturing functions with explicit LOD are allowed. */
+static bool
+lod_exists_in_stage(const _mesa_glsl_parse_state *state)
+{
+ /* Texturing functions with "Lod" in their name exist:
+ * - In the vertex shader stage (for all languages)
+ * - In any stage for GLSL 1.30+ or GLSL ES 3.00
+ * - In any stage for desktop GLSL with ARB_shader_texture_lod enabled.
+ *
+ * Since ARB_shader_texture_lod can only be enabled on desktop GLSL, we
+ * don't need to explicitly check state->es_shader.
+ */
+ return state->stage == MESA_SHADER_VERTEX ||
+ state->is_version(130, 300) ||
+ state->ARB_shader_texture_lod_enable;
+}
+
+static bool
+v110_lod(const _mesa_glsl_parse_state *state)
+{
+ return !state->es_shader && lod_exists_in_stage(state);
+}
+
+static bool
+shader_texture_lod(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shader_texture_lod_enable;
+}
+
+static bool
+shader_texture_lod_and_rect(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shader_texture_lod_enable &&
+ state->ARB_texture_rectangle_enable;
+}
+
+static bool
+shader_bit_encoding(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(330, 300) ||
+ state->ARB_shader_bit_encoding_enable ||
+ state->ARB_gpu_shader5_enable;
+}
+
+static bool
+shader_integer_mix(const _mesa_glsl_parse_state *state)
+{
+ return v130(state) && state->EXT_shader_integer_mix_enable;
+}
+
+static bool
+shader_packing_or_es3(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shading_language_packing_enable ||
+ state->is_version(400, 300);
+}
+
+static bool
+shader_packing_or_es3_or_gpu_shader5(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shading_language_packing_enable ||
+ state->ARB_gpu_shader5_enable ||
+ state->is_version(400, 300);
+}
+
+static bool
+gpu_shader5(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(400, 0) || state->ARB_gpu_shader5_enable;
+}
+
+static bool
+shader_packing_or_gpu_shader5(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shading_language_packing_enable ||
+ gpu_shader5(state);
+}
+
+static bool
+texture_array_lod(const _mesa_glsl_parse_state *state)
+{
+ return lod_exists_in_stage(state) &&
+ state->EXT_texture_array_enable;
+}
+
+static bool
+fs_texture_array(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ state->EXT_texture_array_enable;
+}
+
+static bool
+texture_array(const _mesa_glsl_parse_state *state)
+{
+ return state->EXT_texture_array_enable;
+}
+
+static bool
+texture_multisample(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(150, 0) ||
+ state->ARB_texture_multisample_enable;
+}
+
+static bool
+fs_texture_cube_map_array(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ (state->is_version(400, 0) ||
+ state->ARB_texture_cube_map_array_enable);
+}
+
+static bool
+texture_cube_map_array(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(400, 0) ||
+ state->ARB_texture_cube_map_array_enable;
+}
+
+static bool
+texture_query_levels(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(430, 0) ||
+ state->ARB_texture_query_levels_enable;
+}
+
+static bool
+texture_query_lod(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ state->ARB_texture_query_lod_enable;
+}
+
+static bool
+texture_gather(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(400, 0) ||
+ state->ARB_texture_gather_enable ||
+ state->ARB_gpu_shader5_enable;
+}
+
+/* Only ARB_texture_gather but not GLSL 4.0 or ARB_gpu_shader5.
+ * used for relaxation of const offset requirements.
+ */
+static bool
+texture_gather_only(const _mesa_glsl_parse_state *state)
+{
+ return !state->is_version(400, 0) &&
+ !state->ARB_gpu_shader5_enable &&
+ state->ARB_texture_gather_enable;
+}
+
+/* Desktop GL or OES_standard_derivatives + fragment shader only */
+static bool
+fs_oes_derivatives(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ (state->is_version(110, 300) ||
+ state->OES_standard_derivatives_enable);
+}
+
+static bool
+tex1d_lod(const _mesa_glsl_parse_state *state)
+{
+ return !state->es_shader && lod_exists_in_stage(state);
+}
+
+/** True if sampler3D exists */
+static bool
+tex3d(const _mesa_glsl_parse_state *state)
+{
+ /* sampler3D exists in all desktop GLSL versions, GLSL ES 1.00 with the
+ * OES_texture_3D extension, and in GLSL ES 3.00.
+ */
+ return !state->es_shader ||
+ state->OES_texture_3D_enable ||
+ state->language_version >= 300;
+}
+
+static bool
+fs_tex3d(const _mesa_glsl_parse_state *state)
+{
+ return state->stage == MESA_SHADER_FRAGMENT &&
+ (!state->es_shader || state->OES_texture_3D_enable);
+}
+
+static bool
+tex3d_lod(const _mesa_glsl_parse_state *state)
+{
+ return tex3d(state) && lod_exists_in_stage(state);
+}
+
+static bool
+shader_atomic_counters(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shader_atomic_counters_enable;
+}
+
+static bool
+shader_trinary_minmax(const _mesa_glsl_parse_state *state)
+{
+ return state->AMD_shader_trinary_minmax_enable;
+}
+
+static bool
+shader_image_load_store(const _mesa_glsl_parse_state *state)
+{
+ return (state->is_version(420, 0) ||
+ state->ARB_shader_image_load_store_enable);
+}
+
+/** @} */
+
+/******************************************************************************/
+
+namespace {
+
+/**
+ * builtin_builder: A singleton object representing the core of the built-in
+ * function module.
+ *
+ * It generates IR for every built-in function signature, and organizes them
+ * into functions.
+ */
+class builtin_builder {
+public:
+ builtin_builder();
+ ~builtin_builder();
+
+ void initialize();
+ void release();
+ ir_function_signature *find(_mesa_glsl_parse_state *state,
+ const char *name, exec_list *actual_parameters);
+
+ /**
+ * A shader to hold all the built-in signatures; created by this module.
+ *
+ * This includes signatures for every built-in, regardless of version or
+ * enabled extensions. The availability predicate associated with each
+ * signature allows matching_signature() to filter out the irrelevant ones.
+ */
+ gl_shader *shader;
+
+private:
+ void *mem_ctx;
+
+ /** Global variables used by built-in functions. */
+ ir_variable *gl_ModelViewProjectionMatrix;
+ ir_variable *gl_Vertex;
+
+ void create_shader();
+ void create_intrinsics();
+ void create_builtins();
+
+ /**
+ * IR builder helpers:
+ *
+ * These convenience functions assist in emitting IR, but don't necessarily
+ * fit in ir_builder itself. Many of them rely on having a mem_ctx class
+ * member available.
+ */
+ ir_variable *in_var(const glsl_type *type, const char *name);
+ ir_variable *out_var(const glsl_type *type, const char *name);
+ ir_constant *imm(float f, unsigned vector_elements=1);
+ ir_constant *imm(int i, unsigned vector_elements=1);
+ ir_constant *imm(unsigned u, unsigned vector_elements=1);
+ ir_constant *imm(const glsl_type *type, const ir_constant_data &);
+ ir_dereference_variable *var_ref(ir_variable *var);
+ ir_dereference_array *array_ref(ir_variable *var, int i);
+ ir_swizzle *matrix_elt(ir_variable *var, int col, int row);
+
+ ir_expression *asin_expr(ir_variable *x);
+
+ /**
+ * Call function \param f with parameters specified as the linked
+ * list \param params of \c ir_variable objects. \param ret should
+ * point to the ir_variable that will hold the function return
+ * value, or be \c NULL if the function has void return type.
+ */
+ ir_call *call(ir_function *f, ir_variable *ret, exec_list params);
+
+ /** Create a new function and add the given signatures. */
+ void add_function(const char *name, ...);
+
+ enum image_function_flags {
+ IMAGE_FUNCTION_EMIT_STUB = (1 << 0),
+ IMAGE_FUNCTION_RETURNS_VOID = (1 << 1),
+ IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE = (1 << 2),
+ IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE = (1 << 3),
+ IMAGE_FUNCTION_READ_ONLY = (1 << 4),
+ IMAGE_FUNCTION_WRITE_ONLY = (1 << 5)
+ };
+
+ /**
+ * Create a new image built-in function for all known image types.
+ * \p flags is a bitfield of \c image_function_flags flags.
+ */
+ void add_image_function(const char *name,
+ const char *intrinsic_name,
+ unsigned num_arguments,
+ unsigned flags);
+
+ /**
+ * Create new functions for all known image built-ins and types.
+ * If \p glsl is \c true, use the GLSL built-in names and emit code
+ * to call into the actual compiler intrinsic. If \p glsl is
+ * false, emit a function prototype with no body for each image
+ * intrinsic name.
+ */
+ void add_image_functions(bool glsl);
+
+ ir_function_signature *new_sig(const glsl_type *return_type,
+ builtin_available_predicate avail,
+ int num_params, ...);
+
+ /**
+ * Function signature generators:
+ * @{
+ */
+ ir_function_signature *unop(builtin_available_predicate avail,
+ ir_expression_operation opcode,
+ const glsl_type *return_type,
+ const glsl_type *param_type);
+ ir_function_signature *binop(ir_expression_operation opcode,
+ builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *param0_type,
+ const glsl_type *param1_type);
+
+#define B0(X) ir_function_signature *_##X();
+#define B1(X) ir_function_signature *_##X(const glsl_type *);
+#define B2(X) ir_function_signature *_##X(const glsl_type *, const glsl_type *);
+#define B3(X) ir_function_signature *_##X(const glsl_type *, const glsl_type *, const glsl_type *);
+#define BA1(X) ir_function_signature *_##X(builtin_available_predicate, const glsl_type *);
+#define BA2(X) ir_function_signature *_##X(builtin_available_predicate, const glsl_type *, const glsl_type *);
+ B1(radians)
+ B1(degrees)
+ B1(sin)
+ B1(cos)
+ B1(tan)
+ B1(asin)
+ B1(acos)
+ B1(atan2)
+ B1(atan)
+ B1(sinh)
+ B1(cosh)
+ B1(tanh)
+ B1(asinh)
+ B1(acosh)
+ B1(atanh)
+ B1(pow)
+ B1(exp)
+ B1(log)
+ B1(exp2)
+ B1(log2)
+ B1(sqrt)
+ B1(inversesqrt)
+ B1(abs)
+ B1(sign)
+ B1(floor)
+ B1(trunc)
+ B1(round)
+ B1(roundEven)
+ B1(ceil)
+ B1(fract)
+ B2(mod)
+ B1(modf)
+ BA2(min)
+ BA2(max)
+ BA2(clamp)
+ B2(mix_lrp)
+ ir_function_signature *_mix_sel(builtin_available_predicate avail,
+ const glsl_type *val_type,
+ const glsl_type *blend_type);
+ B2(step)
+ B2(smoothstep)
+ B1(isnan)
+ B1(isinf)
+ B1(floatBitsToInt)
+ B1(floatBitsToUint)
+ B1(intBitsToFloat)
+ B1(uintBitsToFloat)
+ ir_function_signature *_packUnorm2x16(builtin_available_predicate avail);
+ ir_function_signature *_packSnorm2x16(builtin_available_predicate avail);
+ ir_function_signature *_packUnorm4x8(builtin_available_predicate avail);
+ ir_function_signature *_packSnorm4x8(builtin_available_predicate avail);
+ ir_function_signature *_unpackUnorm2x16(builtin_available_predicate avail);
+ ir_function_signature *_unpackSnorm2x16(builtin_available_predicate avail);
+ ir_function_signature *_unpackUnorm4x8(builtin_available_predicate avail);
+ ir_function_signature *_unpackSnorm4x8(builtin_available_predicate avail);
+ ir_function_signature *_packHalf2x16(builtin_available_predicate avail);
+ ir_function_signature *_unpackHalf2x16(builtin_available_predicate avail);
+ B1(length)
+ B1(distance);
+ B1(dot);
+ B1(cross);
+ B1(normalize);
+ B0(ftransform);
+ B1(faceforward);
+ B1(reflect);
+ B1(refract);
+ B1(matrixCompMult);
+ B1(outerProduct);
+ B0(determinant_mat2);
+ B0(determinant_mat3);
+ B0(determinant_mat4);
+ B0(inverse_mat2);
+ B0(inverse_mat3);
+ B0(inverse_mat4);
+ B1(transpose);
+ BA1(lessThan);
+ BA1(lessThanEqual);
+ BA1(greaterThan);
+ BA1(greaterThanEqual);
+ BA1(equal);
+ BA1(notEqual);
+ B1(any);
+ B1(all);
+ B1(not);
+ B2(textureSize);
+ ir_function_signature *_textureSize(builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type);
+
+/** Flags to _texture() */
+#define TEX_PROJECT 1
+#define TEX_OFFSET 2
+#define TEX_COMPONENT 4
+#define TEX_OFFSET_NONCONST 8
+#define TEX_OFFSET_ARRAY 16
+
+ ir_function_signature *_texture(ir_texture_opcode opcode,
+ builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type,
+ const glsl_type *coord_type,
+ int flags = 0);
+ B0(textureCubeArrayShadow);
+ ir_function_signature *_texelFetch(builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type,
+ const glsl_type *coord_type,
+ const glsl_type *offset_type = NULL);
+
+ B0(EmitVertex)
+ B0(EndPrimitive)
+
+ B2(textureQueryLod);
+ B1(textureQueryLevels);
+ B1(dFdx);
+ B1(dFdy);
+ B1(fwidth);
+ B1(noise1);
+ B1(noise2);
+ B1(noise3);
+ B1(noise4);
+
+ B1(bitfieldExtract)
+ B1(bitfieldInsert)
+ B1(bitfieldReverse)
+ B1(bitCount)
+ B1(findLSB)
+ B1(findMSB)
+ B1(fma)
+ B2(ldexp)
+ B2(frexp)
+ B1(uaddCarry)
+ B1(usubBorrow)
+ B1(mulExtended)
+
+ ir_function_signature *_atomic_intrinsic(builtin_available_predicate avail);
+ ir_function_signature *_atomic_op(const char *intrinsic,
+ builtin_available_predicate avail);
+
+ B1(min3)
+ B1(max3)
+ B1(mid3)
+
+ ir_function_signature *_image_prototype(const glsl_type *image_type,
+ const char *intrinsic_name,
+ unsigned num_arguments,
+ unsigned flags);
+ ir_function_signature *_image(const glsl_type *image_type,
+ const char *intrinsic_name,
+ unsigned num_arguments,
+ unsigned flags);
+
+ ir_function_signature *_memory_barrier_intrinsic(
+ builtin_available_predicate avail);
+ ir_function_signature *_memory_barrier(
+ builtin_available_predicate avail);
+
+#undef B0
+#undef B1
+#undef B2
+#undef B3
+#undef BA1
+#undef BA2
+ /** @} */
+};
+
+} /* anonymous namespace */
+
+/**
+ * Core builtin_builder functionality:
+ * @{
+ */
+builtin_builder::builtin_builder()
+ : shader(NULL),
+ gl_ModelViewProjectionMatrix(NULL),
+ gl_Vertex(NULL)
+{
+ mem_ctx = NULL;
+}
+
+builtin_builder::~builtin_builder()
+{
+ ralloc_free(mem_ctx);
+}
+
+ir_function_signature *
+builtin_builder::find(_mesa_glsl_parse_state *state,
+ const char *name, exec_list *actual_parameters)
+{
+ /* The shader currently being compiled requested a built-in function;
+ * it needs to link against builtin_builder::shader in order to get them.
+ *
+ * Even if we don't find a matching signature, we still need to do this so
+ * that the "no matching signature" error will list potential candidates
+ * from the available built-ins.
+ */
+ state->uses_builtin_functions = true;
+
+ ir_function *f = shader->symbols->get_function(name);
+ if (f == NULL)
+ return NULL;
+
+ ir_function_signature *sig = f->matching_signature(state, actual_parameters);
+ if (sig == NULL)
+ return NULL;
+
+ return sig;
+}
+
+void
+builtin_builder::initialize()
+{
+ /* If already initialized, don't do it again. */
+ if (mem_ctx != NULL)
+ return;
+
+ mem_ctx = ralloc_context(NULL);
+ create_shader();
+ create_intrinsics();
+ create_builtins();
+}
+
+void
+builtin_builder::release()
+{
+ ralloc_free(mem_ctx);
+ mem_ctx = NULL;
+
+ ralloc_free(shader);
+ shader = NULL;
+}
+
+void
+builtin_builder::create_shader()
+{
+ /* The target doesn't actually matter. There's no target for generic
+ * GLSL utility code that could be linked against any stage, so just
+ * arbitrarily pick GL_VERTEX_SHADER.
+ */
+ shader = _mesa_new_shader(NULL, 0, GL_VERTEX_SHADER);
+ shader->symbols = new(mem_ctx) glsl_symbol_table;
+
+ gl_ModelViewProjectionMatrix =
+ new(mem_ctx) ir_variable(glsl_type::mat4_type,
+ "gl_ModelViewProjectionMatrix",
+ ir_var_uniform);
+
+ shader->symbols->add_variable(gl_ModelViewProjectionMatrix);
+
+ gl_Vertex = in_var(glsl_type::vec4_type, "gl_Vertex");
+ shader->symbols->add_variable(gl_Vertex);
+}
+
+/** @} */
+
+/**
+ * Create ir_function and ir_function_signature objects for each
+ * intrinsic.
+ */
+void
+builtin_builder::create_intrinsics()
+{
+ add_function("__intrinsic_atomic_read",
+ _atomic_intrinsic(shader_atomic_counters),
+ NULL);
+ add_function("__intrinsic_atomic_increment",
+ _atomic_intrinsic(shader_atomic_counters),
+ NULL);
+ add_function("__intrinsic_atomic_predecrement",
+ _atomic_intrinsic(shader_atomic_counters),
+ NULL);
+
+ add_image_functions(false);
+
+ add_function("__intrinsic_memory_barrier",
+ _memory_barrier_intrinsic(shader_image_load_store),
+ NULL);
+}
+
+/**
+ * Create ir_function and ir_function_signature objects for each built-in.
+ *
+ * Contains a list of every available built-in.
+ */
+void
+builtin_builder::create_builtins()
+{
+#define F(NAME) \
+ add_function(#NAME, \
+ _##NAME(glsl_type::float_type), \
+ _##NAME(glsl_type::vec2_type), \
+ _##NAME(glsl_type::vec3_type), \
+ _##NAME(glsl_type::vec4_type), \
+ NULL);
+
+#define FI(NAME) \
+ add_function(#NAME, \
+ _##NAME(glsl_type::float_type), \
+ _##NAME(glsl_type::vec2_type), \
+ _##NAME(glsl_type::vec3_type), \
+ _##NAME(glsl_type::vec4_type), \
+ _##NAME(glsl_type::int_type), \
+ _##NAME(glsl_type::ivec2_type), \
+ _##NAME(glsl_type::ivec3_type), \
+ _##NAME(glsl_type::ivec4_type), \
+ NULL);
+
+#define FIU(NAME) \
+ add_function(#NAME, \
+ _##NAME(always_available, glsl_type::float_type), \
+ _##NAME(always_available, glsl_type::vec2_type), \
+ _##NAME(always_available, glsl_type::vec3_type), \
+ _##NAME(always_available, glsl_type::vec4_type), \
+ \
+ _##NAME(always_available, glsl_type::int_type), \
+ _##NAME(always_available, glsl_type::ivec2_type), \
+ _##NAME(always_available, glsl_type::ivec3_type), \
+ _##NAME(always_available, glsl_type::ivec4_type), \
+ \
+ _##NAME(v130, glsl_type::uint_type), \
+ _##NAME(v130, glsl_type::uvec2_type), \
+ _##NAME(v130, glsl_type::uvec3_type), \
+ _##NAME(v130, glsl_type::uvec4_type), \
+ NULL);
+
+#define IU(NAME) \
+ add_function(#NAME, \
+ _##NAME(glsl_type::int_type), \
+ _##NAME(glsl_type::ivec2_type), \
+ _##NAME(glsl_type::ivec3_type), \
+ _##NAME(glsl_type::ivec4_type), \
+ \
+ _##NAME(glsl_type::uint_type), \
+ _##NAME(glsl_type::uvec2_type), \
+ _##NAME(glsl_type::uvec3_type), \
+ _##NAME(glsl_type::uvec4_type), \
+ NULL);
+
+#define FIUB(NAME) \
+ add_function(#NAME, \
+ _##NAME(always_available, glsl_type::float_type), \
+ _##NAME(always_available, glsl_type::vec2_type), \
+ _##NAME(always_available, glsl_type::vec3_type), \
+ _##NAME(always_available, glsl_type::vec4_type), \
+ \
+ _##NAME(always_available, glsl_type::int_type), \
+ _##NAME(always_available, glsl_type::ivec2_type), \
+ _##NAME(always_available, glsl_type::ivec3_type), \
+ _##NAME(always_available, glsl_type::ivec4_type), \
+ \
+ _##NAME(v130, glsl_type::uint_type), \
+ _##NAME(v130, glsl_type::uvec2_type), \
+ _##NAME(v130, glsl_type::uvec3_type), \
+ _##NAME(v130, glsl_type::uvec4_type), \
+ \
+ _##NAME(always_available, glsl_type::bool_type), \
+ _##NAME(always_available, glsl_type::bvec2_type), \
+ _##NAME(always_available, glsl_type::bvec3_type), \
+ _##NAME(always_available, glsl_type::bvec4_type), \
+ NULL);
+
+#define FIU2_MIXED(NAME) \
+ add_function(#NAME, \
+ _##NAME(always_available, glsl_type::float_type, glsl_type::float_type), \
+ _##NAME(always_available, glsl_type::vec2_type, glsl_type::float_type), \
+ _##NAME(always_available, glsl_type::vec3_type, glsl_type::float_type), \
+ _##NAME(always_available, glsl_type::vec4_type, glsl_type::float_type), \
+ \
+ _##NAME(always_available, glsl_type::vec2_type, glsl_type::vec2_type), \
+ _##NAME(always_available, glsl_type::vec3_type, glsl_type::vec3_type), \
+ _##NAME(always_available, glsl_type::vec4_type, glsl_type::vec4_type), \
+ \
+ _##NAME(always_available, glsl_type::int_type, glsl_type::int_type), \
+ _##NAME(always_available, glsl_type::ivec2_type, glsl_type::int_type), \
+ _##NAME(always_available, glsl_type::ivec3_type, glsl_type::int_type), \
+ _##NAME(always_available, glsl_type::ivec4_type, glsl_type::int_type), \
+ \
+ _##NAME(always_available, glsl_type::ivec2_type, glsl_type::ivec2_type), \
+ _##NAME(always_available, glsl_type::ivec3_type, glsl_type::ivec3_type), \
+ _##NAME(always_available, glsl_type::ivec4_type, glsl_type::ivec4_type), \
+ \
+ _##NAME(v130, glsl_type::uint_type, glsl_type::uint_type), \
+ _##NAME(v130, glsl_type::uvec2_type, glsl_type::uint_type), \
+ _##NAME(v130, glsl_type::uvec3_type, glsl_type::uint_type), \
+ _##NAME(v130, glsl_type::uvec4_type, glsl_type::uint_type), \
+ \
+ _##NAME(v130, glsl_type::uvec2_type, glsl_type::uvec2_type), \
+ _##NAME(v130, glsl_type::uvec3_type, glsl_type::uvec3_type), \
+ _##NAME(v130, glsl_type::uvec4_type, glsl_type::uvec4_type), \
+ NULL);
+
+ F(radians)
+ F(degrees)
+ F(sin)
+ F(cos)
+ F(tan)
+ F(asin)
+ F(acos)
+
+ add_function("atan",
+ _atan(glsl_type::float_type),
+ _atan(glsl_type::vec2_type),
+ _atan(glsl_type::vec3_type),
+ _atan(glsl_type::vec4_type),
+ _atan2(glsl_type::float_type),
+ _atan2(glsl_type::vec2_type),
+ _atan2(glsl_type::vec3_type),
+ _atan2(glsl_type::vec4_type),
+ NULL);
+
+ F(sinh)
+ F(cosh)
+ F(tanh)
+ F(asinh)
+ F(acosh)
+ F(atanh)
+ F(pow)
+ F(exp)
+ F(log)
+ F(exp2)
+ F(log2)
+ F(sqrt)
+ F(inversesqrt)
+ FI(abs)
+ FI(sign)
+ F(floor)
+ F(trunc)
+ F(round)
+ F(roundEven)
+ F(ceil)
+ F(fract)
+
+ add_function("mod",
+ _mod(glsl_type::float_type, glsl_type::float_type),
+ _mod(glsl_type::vec2_type, glsl_type::float_type),
+ _mod(glsl_type::vec3_type, glsl_type::float_type),
+ _mod(glsl_type::vec4_type, glsl_type::float_type),
+
+ _mod(glsl_type::vec2_type, glsl_type::vec2_type),
+ _mod(glsl_type::vec3_type, glsl_type::vec3_type),
+ _mod(glsl_type::vec4_type, glsl_type::vec4_type),
+ NULL);
+
+ F(modf)
+
+ FIU2_MIXED(min)
+ FIU2_MIXED(max)
+ FIU2_MIXED(clamp)
+
+ add_function("mix",
+ _mix_lrp(glsl_type::float_type, glsl_type::float_type),
+ _mix_lrp(glsl_type::vec2_type, glsl_type::float_type),
+ _mix_lrp(glsl_type::vec3_type, glsl_type::float_type),
+ _mix_lrp(glsl_type::vec4_type, glsl_type::float_type),
+
+ _mix_lrp(glsl_type::vec2_type, glsl_type::vec2_type),
+ _mix_lrp(glsl_type::vec3_type, glsl_type::vec3_type),
+ _mix_lrp(glsl_type::vec4_type, glsl_type::vec4_type),
+
+ _mix_sel(v130, glsl_type::float_type, glsl_type::bool_type),
+ _mix_sel(v130, glsl_type::vec2_type, glsl_type::bvec2_type),
+ _mix_sel(v130, glsl_type::vec3_type, glsl_type::bvec3_type),
+ _mix_sel(v130, glsl_type::vec4_type, glsl_type::bvec4_type),
+
+ _mix_sel(shader_integer_mix, glsl_type::int_type, glsl_type::bool_type),
+ _mix_sel(shader_integer_mix, glsl_type::ivec2_type, glsl_type::bvec2_type),
+ _mix_sel(shader_integer_mix, glsl_type::ivec3_type, glsl_type::bvec3_type),
+ _mix_sel(shader_integer_mix, glsl_type::ivec4_type, glsl_type::bvec4_type),
+
+ _mix_sel(shader_integer_mix, glsl_type::uint_type, glsl_type::bool_type),
+ _mix_sel(shader_integer_mix, glsl_type::uvec2_type, glsl_type::bvec2_type),
+ _mix_sel(shader_integer_mix, glsl_type::uvec3_type, glsl_type::bvec3_type),
+ _mix_sel(shader_integer_mix, glsl_type::uvec4_type, glsl_type::bvec4_type),
+
+ _mix_sel(shader_integer_mix, glsl_type::bool_type, glsl_type::bool_type),
+ _mix_sel(shader_integer_mix, glsl_type::bvec2_type, glsl_type::bvec2_type),
+ _mix_sel(shader_integer_mix, glsl_type::bvec3_type, glsl_type::bvec3_type),
+ _mix_sel(shader_integer_mix, glsl_type::bvec4_type, glsl_type::bvec4_type),
+ NULL);
+
+ add_function("step",
+ _step(glsl_type::float_type, glsl_type::float_type),
+ _step(glsl_type::float_type, glsl_type::vec2_type),
+ _step(glsl_type::float_type, glsl_type::vec3_type),
+ _step(glsl_type::float_type, glsl_type::vec4_type),
+
+ _step(glsl_type::vec2_type, glsl_type::vec2_type),
+ _step(glsl_type::vec3_type, glsl_type::vec3_type),
+ _step(glsl_type::vec4_type, glsl_type::vec4_type),
+ NULL);
+
+ add_function("smoothstep",
+ _smoothstep(glsl_type::float_type, glsl_type::float_type),
+ _smoothstep(glsl_type::float_type, glsl_type::vec2_type),
+ _smoothstep(glsl_type::float_type, glsl_type::vec3_type),
+ _smoothstep(glsl_type::float_type, glsl_type::vec4_type),
+
+ _smoothstep(glsl_type::vec2_type, glsl_type::vec2_type),
+ _smoothstep(glsl_type::vec3_type, glsl_type::vec3_type),
+ _smoothstep(glsl_type::vec4_type, glsl_type::vec4_type),
+ NULL);
+
+ F(isnan)
+ F(isinf)
+
+ F(floatBitsToInt)
+ F(floatBitsToUint)
+ add_function("intBitsToFloat",
+ _intBitsToFloat(glsl_type::int_type),
+ _intBitsToFloat(glsl_type::ivec2_type),
+ _intBitsToFloat(glsl_type::ivec3_type),
+ _intBitsToFloat(glsl_type::ivec4_type),
+ NULL);
+ add_function("uintBitsToFloat",
+ _uintBitsToFloat(glsl_type::uint_type),
+ _uintBitsToFloat(glsl_type::uvec2_type),
+ _uintBitsToFloat(glsl_type::uvec3_type),
+ _uintBitsToFloat(glsl_type::uvec4_type),
+ NULL);
+
+ add_function("packUnorm2x16", _packUnorm2x16(shader_packing_or_es3_or_gpu_shader5), NULL);
+ add_function("packSnorm2x16", _packSnorm2x16(shader_packing_or_es3), NULL);
+ add_function("packUnorm4x8", _packUnorm4x8(shader_packing_or_gpu_shader5), NULL);
+ add_function("packSnorm4x8", _packSnorm4x8(shader_packing_or_gpu_shader5), NULL);
+ add_function("unpackUnorm2x16", _unpackUnorm2x16(shader_packing_or_es3_or_gpu_shader5), NULL);
+ add_function("unpackSnorm2x16", _unpackSnorm2x16(shader_packing_or_es3), NULL);
+ add_function("unpackUnorm4x8", _unpackUnorm4x8(shader_packing_or_gpu_shader5), NULL);
+ add_function("unpackSnorm4x8", _unpackSnorm4x8(shader_packing_or_gpu_shader5), NULL);
+ add_function("packHalf2x16", _packHalf2x16(shader_packing_or_es3), NULL);
+ add_function("unpackHalf2x16", _unpackHalf2x16(shader_packing_or_es3), NULL);
+
+ F(length)
+ F(distance)
+ F(dot)
+
+ add_function("cross", _cross(glsl_type::vec3_type), NULL);
+
+ F(normalize)
+ add_function("ftransform", _ftransform(), NULL);
+ F(faceforward)
+ F(reflect)
+ F(refract)
+ // ...
+ add_function("matrixCompMult",
+ _matrixCompMult(glsl_type::mat2_type),
+ _matrixCompMult(glsl_type::mat3_type),
+ _matrixCompMult(glsl_type::mat4_type),
+ _matrixCompMult(glsl_type::mat2x3_type),
+ _matrixCompMult(glsl_type::mat2x4_type),
+ _matrixCompMult(glsl_type::mat3x2_type),
+ _matrixCompMult(glsl_type::mat3x4_type),
+ _matrixCompMult(glsl_type::mat4x2_type),
+ _matrixCompMult(glsl_type::mat4x3_type),
+ NULL);
+ add_function("outerProduct",
+ _outerProduct(glsl_type::mat2_type),
+ _outerProduct(glsl_type::mat3_type),
+ _outerProduct(glsl_type::mat4_type),
+ _outerProduct(glsl_type::mat2x3_type),
+ _outerProduct(glsl_type::mat2x4_type),
+ _outerProduct(glsl_type::mat3x2_type),
+ _outerProduct(glsl_type::mat3x4_type),
+ _outerProduct(glsl_type::mat4x2_type),
+ _outerProduct(glsl_type::mat4x3_type),
+ NULL);
+ add_function("determinant",
+ _determinant_mat2(),
+ _determinant_mat3(),
+ _determinant_mat4(),
+ NULL);
+ add_function("inverse",
+ _inverse_mat2(),
+ _inverse_mat3(),
+ _inverse_mat4(),
+ NULL);
+ add_function("transpose",
+ _transpose(glsl_type::mat2_type),
+ _transpose(glsl_type::mat3_type),
+ _transpose(glsl_type::mat4_type),
+ _transpose(glsl_type::mat2x3_type),
+ _transpose(glsl_type::mat2x4_type),
+ _transpose(glsl_type::mat3x2_type),
+ _transpose(glsl_type::mat3x4_type),
+ _transpose(glsl_type::mat4x2_type),
+ _transpose(glsl_type::mat4x3_type),
+ NULL);
+ FIU(lessThan)
+ FIU(lessThanEqual)
+ FIU(greaterThan)
+ FIU(greaterThanEqual)
+ FIUB(notEqual)
+ FIUB(equal)
+
+ add_function("any",
+ _any(glsl_type::bvec2_type),
+ _any(glsl_type::bvec3_type),
+ _any(glsl_type::bvec4_type),
+ NULL);
+
+ add_function("all",
+ _all(glsl_type::bvec2_type),
+ _all(glsl_type::bvec3_type),
+ _all(glsl_type::bvec4_type),
+ NULL);
+
+ add_function("not",
+ _not(glsl_type::bvec2_type),
+ _not(glsl_type::bvec3_type),
+ _not(glsl_type::bvec4_type),
+ NULL);
+
+ add_function("textureSize",
+ _textureSize(v130, glsl_type::int_type, glsl_type::sampler1D_type),
+ _textureSize(v130, glsl_type::int_type, glsl_type::isampler1D_type),
+ _textureSize(v130, glsl_type::int_type, glsl_type::usampler1D_type),
+
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::sampler2D_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::isampler2D_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::usampler2D_type),
+
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::sampler3D_type),
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::isampler3D_type),
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::usampler3D_type),
+
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::samplerCube_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::isamplerCube_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::usamplerCube_type),
+
+ _textureSize(v130, glsl_type::int_type, glsl_type::sampler1DShadow_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::sampler2DShadow_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::samplerCubeShadow_type),
+
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::sampler1DArray_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::isampler1DArray_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::usampler1DArray_type),
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::sampler2DArray_type),
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::isampler2DArray_type),
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::usampler2DArray_type),
+
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::sampler1DArrayShadow_type),
+ _textureSize(v130, glsl_type::ivec3_type, glsl_type::sampler2DArrayShadow_type),
+
+ _textureSize(texture_cube_map_array, glsl_type::ivec3_type, glsl_type::samplerCubeArray_type),
+ _textureSize(texture_cube_map_array, glsl_type::ivec3_type, glsl_type::isamplerCubeArray_type),
+ _textureSize(texture_cube_map_array, glsl_type::ivec3_type, glsl_type::usamplerCubeArray_type),
+ _textureSize(texture_cube_map_array, glsl_type::ivec3_type, glsl_type::samplerCubeArrayShadow_type),
+
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::sampler2DRect_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::isampler2DRect_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::usampler2DRect_type),
+ _textureSize(v130, glsl_type::ivec2_type, glsl_type::sampler2DRectShadow_type),
+
+ _textureSize(v140, glsl_type::int_type, glsl_type::samplerBuffer_type),
+ _textureSize(v140, glsl_type::int_type, glsl_type::isamplerBuffer_type),
+ _textureSize(v140, glsl_type::int_type, glsl_type::usamplerBuffer_type),
+ _textureSize(texture_multisample, glsl_type::ivec2_type, glsl_type::sampler2DMS_type),
+ _textureSize(texture_multisample, glsl_type::ivec2_type, glsl_type::isampler2DMS_type),
+ _textureSize(texture_multisample, glsl_type::ivec2_type, glsl_type::usampler2DMS_type),
+
+ _textureSize(texture_multisample, glsl_type::ivec3_type, glsl_type::sampler2DMSArray_type),
+ _textureSize(texture_multisample, glsl_type::ivec3_type, glsl_type::isampler2DMSArray_type),
+ _textureSize(texture_multisample, glsl_type::ivec3_type, glsl_type::usampler2DMSArray_type),
+ NULL);
+
+ add_function("texture",
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::samplerCubeShadow_type, glsl_type::vec4_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type),
+
+ _texture(ir_tex, texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_tex, texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_tex, texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, glsl_type::vec4_type),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec4_type),
+ /* samplerCubeArrayShadow is special; it has an extra parameter
+ * for the shadow comparitor since there is no vec5 type.
+ */
+ _textureCubeArrayShadow(),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::samplerCubeShadow_type, glsl_type::vec4_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type),
+
+ _texture(ir_txb, fs_texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_txb, fs_texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_txb, fs_texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, glsl_type::vec4_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureLod",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type),
+
+ _texture(ir_txl, texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_txl, texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_txl, texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, glsl_type::vec4_type),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureOffset",
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ NULL);
+
+ add_function("textureProj",
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texelFetch",
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::int_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::int_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::int_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::ivec2_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::ivec3_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::ivec3_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::ivec3_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::ivec2_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::ivec2_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::ivec3_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::ivec3_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::ivec3_type),
+
+ _texelFetch(v140, glsl_type::vec4_type, glsl_type::samplerBuffer_type, glsl_type::int_type),
+ _texelFetch(v140, glsl_type::ivec4_type, glsl_type::isamplerBuffer_type, glsl_type::int_type),
+ _texelFetch(v140, glsl_type::uvec4_type, glsl_type::usamplerBuffer_type, glsl_type::int_type),
+
+ _texelFetch(texture_multisample, glsl_type::vec4_type, glsl_type::sampler2DMS_type, glsl_type::ivec2_type),
+ _texelFetch(texture_multisample, glsl_type::ivec4_type, glsl_type::isampler2DMS_type, glsl_type::ivec2_type),
+ _texelFetch(texture_multisample, glsl_type::uvec4_type, glsl_type::usampler2DMS_type, glsl_type::ivec2_type),
+
+ _texelFetch(texture_multisample, glsl_type::vec4_type, glsl_type::sampler2DMSArray_type, glsl_type::ivec3_type),
+ _texelFetch(texture_multisample, glsl_type::ivec4_type, glsl_type::isampler2DMSArray_type, glsl_type::ivec3_type),
+ _texelFetch(texture_multisample, glsl_type::uvec4_type, glsl_type::usampler2DMSArray_type, glsl_type::ivec3_type),
+ NULL);
+
+ add_function("texelFetchOffset",
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::int_type, glsl_type::int_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::int_type, glsl_type::int_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::int_type, glsl_type::int_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::ivec2_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::ivec2_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::ivec2_type, glsl_type::ivec2_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::ivec3_type, glsl_type::ivec3_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::ivec3_type, glsl_type::ivec3_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::ivec3_type, glsl_type::ivec3_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::ivec2_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::ivec2_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::ivec2_type, glsl_type::ivec2_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::ivec2_type, glsl_type::int_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::ivec2_type, glsl_type::int_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::ivec2_type, glsl_type::int_type),
+
+ _texelFetch(v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::ivec3_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::ivec3_type, glsl_type::ivec2_type),
+ _texelFetch(v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::ivec3_type, glsl_type::ivec2_type),
+
+ NULL);
+
+ add_function("textureProjOffset",
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ NULL);
+
+ add_function("textureLodOffset",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ NULL);
+
+ add_function("textureProjLod",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureProjLodOffset",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ NULL);
+
+ add_function("textureGrad",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::samplerCubeShadow_type, glsl_type::vec4_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type),
+
+ _texture(ir_txd, texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_txd, texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_txd, texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, glsl_type::vec4_type),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec4_type),
+ NULL);
+
+ add_function("textureGradOffset",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec4_type, TEX_OFFSET),
+ NULL);
+
+ add_function("textureProjGrad",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureProjGradOffset",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ NULL);
+
+ add_function("EmitVertex", _EmitVertex(), NULL);
+ add_function("EndPrimitive", _EndPrimitive(), NULL);
+
+ add_function("textureQueryLOD",
+ _textureQueryLod(glsl_type::sampler1D_type, glsl_type::float_type),
+ _textureQueryLod(glsl_type::isampler1D_type, glsl_type::float_type),
+ _textureQueryLod(glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _textureQueryLod(glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _textureQueryLod(glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _textureQueryLod(glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _textureQueryLod(glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _textureQueryLod(glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _textureQueryLod(glsl_type::sampler1DArray_type, glsl_type::float_type),
+ _textureQueryLod(glsl_type::isampler1DArray_type, glsl_type::float_type),
+ _textureQueryLod(glsl_type::usampler1DArray_type, glsl_type::float_type),
+
+ _textureQueryLod(glsl_type::sampler2DArray_type, glsl_type::vec2_type),
+ _textureQueryLod(glsl_type::isampler2DArray_type, glsl_type::vec2_type),
+ _textureQueryLod(glsl_type::usampler2DArray_type, glsl_type::vec2_type),
+
+ _textureQueryLod(glsl_type::samplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::isamplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::usamplerCubeArray_type, glsl_type::vec3_type),
+
+ _textureQueryLod(glsl_type::sampler1DShadow_type, glsl_type::float_type),
+ _textureQueryLod(glsl_type::sampler2DShadow_type, glsl_type::vec2_type),
+ _textureQueryLod(glsl_type::samplerCubeShadow_type, glsl_type::vec3_type),
+ _textureQueryLod(glsl_type::sampler1DArrayShadow_type, glsl_type::float_type),
+ _textureQueryLod(glsl_type::sampler2DArrayShadow_type, glsl_type::vec2_type),
+ _textureQueryLod(glsl_type::samplerCubeArrayShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureQueryLevels",
+ _textureQueryLevels(glsl_type::sampler1D_type),
+ _textureQueryLevels(glsl_type::sampler2D_type),
+ _textureQueryLevels(glsl_type::sampler3D_type),
+ _textureQueryLevels(glsl_type::samplerCube_type),
+ _textureQueryLevels(glsl_type::sampler1DArray_type),
+ _textureQueryLevels(glsl_type::sampler2DArray_type),
+ _textureQueryLevels(glsl_type::samplerCubeArray_type),
+ _textureQueryLevels(glsl_type::sampler1DShadow_type),
+ _textureQueryLevels(glsl_type::sampler2DShadow_type),
+ _textureQueryLevels(glsl_type::samplerCubeShadow_type),
+ _textureQueryLevels(glsl_type::sampler1DArrayShadow_type),
+ _textureQueryLevels(glsl_type::sampler2DArrayShadow_type),
+ _textureQueryLevels(glsl_type::samplerCubeArrayShadow_type),
+
+ _textureQueryLevels(glsl_type::isampler1D_type),
+ _textureQueryLevels(glsl_type::isampler2D_type),
+ _textureQueryLevels(glsl_type::isampler3D_type),
+ _textureQueryLevels(glsl_type::isamplerCube_type),
+ _textureQueryLevels(glsl_type::isampler1DArray_type),
+ _textureQueryLevels(glsl_type::isampler2DArray_type),
+ _textureQueryLevels(glsl_type::isamplerCubeArray_type),
+
+ _textureQueryLevels(glsl_type::usampler1D_type),
+ _textureQueryLevels(glsl_type::usampler2D_type),
+ _textureQueryLevels(glsl_type::usampler3D_type),
+ _textureQueryLevels(glsl_type::usamplerCube_type),
+ _textureQueryLevels(glsl_type::usampler1DArray_type),
+ _textureQueryLevels(glsl_type::usampler2DArray_type),
+ _textureQueryLevels(glsl_type::usamplerCubeArray_type),
+
+ NULL);
+
+ add_function("texture1D",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ NULL);
+
+ add_function("texture1DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture1DProj",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture1DLod",
+ _texture(ir_txl, tex1d_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ NULL);
+
+ add_function("texture1DArrayLod",
+ _texture(ir_txl, texture_array_lod, glsl_type::vec4_type, glsl_type::sampler1DArray_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture1DProjLod",
+ _texture(ir_txl, tex1d_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, tex1d_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture2D",
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_tex, texture_external, glsl_type::vec4_type, glsl_type::samplerExternalOES_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture2DProj",
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, texture_external, glsl_type::vec4_type, glsl_type::samplerExternalOES_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, texture_external, glsl_type::vec4_type, glsl_type::samplerExternalOES_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture2DLod",
+ _texture(ir_txl, lod_exists_in_stage, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DArrayLod",
+ _texture(ir_txl, texture_array_lod, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture2DProjLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture3D",
+ _texture(ir_tex, tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _texture(ir_txb, fs_tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture3DProj",
+ _texture(ir_tex, tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, fs_tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture3DLod",
+ _texture(ir_txl, tex3d_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture3DProjLod",
+ _texture(ir_txl, tex3d_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureCube",
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureCubeLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture2DRect",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DRectProj",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow1D",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2D",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec4_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec4_type),
+ NULL);
+
+ add_function("shadow1DProj",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DProj",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow1DLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DArrayLod",
+ _texture(ir_txl, texture_array_lod, glsl_type::vec4_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DProjLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DProjLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DRect",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DRectProj",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture1DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
+ NULL);
+
+ add_function("texture1DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture2DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture3DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture3DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureCubeGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture2DRectGradARB",
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DRectProjGradARB",
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DRectGradARB",
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DRectProjGradARB",
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureGather",
+ _texture(ir_tg4, texture_gather, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _texture(ir_tg4, texture_gather, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _texture(ir_tg4, texture_gather, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type),
+
+ _texture(ir_tg4, texture_gather, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_tg4, texture_gather, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type),
+ _texture(ir_tg4, texture_gather, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type),
+
+ _texture(ir_tg4, texture_gather, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _texture(ir_tg4, texture_gather, glsl_type::ivec4_type, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _texture(ir_tg4, texture_gather, glsl_type::uvec4_type, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _texture(ir_tg4, texture_gather, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_tg4, texture_gather, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, glsl_type::vec4_type),
+ _texture(ir_tg4, texture_gather, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, glsl_type::vec4_type),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::samplerCube_type, glsl_type::vec3_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isamplerCube_type, glsl_type::vec3_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usamplerCube_type, glsl_type::vec3_type, TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, glsl_type::vec4_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, glsl_type::vec4_type, TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, glsl_type::vec4_type, TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec2_type),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec3_type),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::samplerCubeShadow_type, glsl_type::vec3_type),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::samplerCubeArrayShadow_type, glsl_type::vec4_type),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec2_type),
+ NULL);
+
+ add_function("textureGatherOffset",
+ _texture(ir_tg4, texture_gather_only, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tg4, texture_gather_only, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tg4, texture_gather_only, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tg4, texture_gather_only, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tg4, texture_gather_only, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tg4, texture_gather_only, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST | TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec3_type, TEX_OFFSET_NONCONST),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec2_type, TEX_OFFSET_NONCONST),
+ NULL);
+
+ add_function("textureGatherOffsets",
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2D_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2D_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2D_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+ _texture(ir_tg4, gpu_shader5, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY | TEX_COMPONENT),
+
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec3_type, TEX_OFFSET_ARRAY),
+ _texture(ir_tg4, gpu_shader5, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, glsl_type::vec2_type, TEX_OFFSET_ARRAY),
+ NULL);
+
+ F(dFdx)
+ F(dFdy)
+ F(fwidth)
+ F(noise1)
+ F(noise2)
+ F(noise3)
+ F(noise4)
+
+ IU(bitfieldExtract)
+ IU(bitfieldInsert)
+ IU(bitfieldReverse)
+ IU(bitCount)
+ IU(findLSB)
+ IU(findMSB)
+ F(fma)
+
+ add_function("ldexp",
+ _ldexp(glsl_type::float_type, glsl_type::int_type),
+ _ldexp(glsl_type::vec2_type, glsl_type::ivec2_type),
+ _ldexp(glsl_type::vec3_type, glsl_type::ivec3_type),
+ _ldexp(glsl_type::vec4_type, glsl_type::ivec4_type),
+ NULL);
+
+ add_function("frexp",
+ _frexp(glsl_type::float_type, glsl_type::int_type),
+ _frexp(glsl_type::vec2_type, glsl_type::ivec2_type),
+ _frexp(glsl_type::vec3_type, glsl_type::ivec3_type),
+ _frexp(glsl_type::vec4_type, glsl_type::ivec4_type),
+ NULL);
+ add_function("uaddCarry",
+ _uaddCarry(glsl_type::uint_type),
+ _uaddCarry(glsl_type::uvec2_type),
+ _uaddCarry(glsl_type::uvec3_type),
+ _uaddCarry(glsl_type::uvec4_type),
+ NULL);
+ add_function("usubBorrow",
+ _usubBorrow(glsl_type::uint_type),
+ _usubBorrow(glsl_type::uvec2_type),
+ _usubBorrow(glsl_type::uvec3_type),
+ _usubBorrow(glsl_type::uvec4_type),
+ NULL);
+ add_function("imulExtended",
+ _mulExtended(glsl_type::int_type),
+ _mulExtended(glsl_type::ivec2_type),
+ _mulExtended(glsl_type::ivec3_type),
+ _mulExtended(glsl_type::ivec4_type),
+ NULL);
+ add_function("umulExtended",
+ _mulExtended(glsl_type::uint_type),
+ _mulExtended(glsl_type::uvec2_type),
+ _mulExtended(glsl_type::uvec3_type),
+ _mulExtended(glsl_type::uvec4_type),
+ NULL);
+
+ add_function("atomicCounter",
+ _atomic_op("__intrinsic_atomic_read",
+ shader_atomic_counters),
+ NULL);
+ add_function("atomicCounterIncrement",
+ _atomic_op("__intrinsic_atomic_increment",
+ shader_atomic_counters),
+ NULL);
+ add_function("atomicCounterDecrement",
+ _atomic_op("__intrinsic_atomic_predecrement",
+ shader_atomic_counters),
+ NULL);
+
+ add_function("min3",
+ _min3(glsl_type::float_type),
+ _min3(glsl_type::vec2_type),
+ _min3(glsl_type::vec3_type),
+ _min3(glsl_type::vec4_type),
+
+ _min3(glsl_type::int_type),
+ _min3(glsl_type::ivec2_type),
+ _min3(glsl_type::ivec3_type),
+ _min3(glsl_type::ivec4_type),
+
+ _min3(glsl_type::uint_type),
+ _min3(glsl_type::uvec2_type),
+ _min3(glsl_type::uvec3_type),
+ _min3(glsl_type::uvec4_type),
+ NULL);
+
+ add_function("max3",
+ _max3(glsl_type::float_type),
+ _max3(glsl_type::vec2_type),
+ _max3(glsl_type::vec3_type),
+ _max3(glsl_type::vec4_type),
+
+ _max3(glsl_type::int_type),
+ _max3(glsl_type::ivec2_type),
+ _max3(glsl_type::ivec3_type),
+ _max3(glsl_type::ivec4_type),
+
+ _max3(glsl_type::uint_type),
+ _max3(glsl_type::uvec2_type),
+ _max3(glsl_type::uvec3_type),
+ _max3(glsl_type::uvec4_type),
+ NULL);
+
+ add_function("mid3",
+ _mid3(glsl_type::float_type),
+ _mid3(glsl_type::vec2_type),
+ _mid3(glsl_type::vec3_type),
+ _mid3(glsl_type::vec4_type),
+
+ _mid3(glsl_type::int_type),
+ _mid3(glsl_type::ivec2_type),
+ _mid3(glsl_type::ivec3_type),
+ _mid3(glsl_type::ivec4_type),
+
+ _mid3(glsl_type::uint_type),
+ _mid3(glsl_type::uvec2_type),
+ _mid3(glsl_type::uvec3_type),
+ _mid3(glsl_type::uvec4_type),
+ NULL);
+
+ add_image_functions(true);
+
+ add_function("memoryBarrier",
+ _memory_barrier(shader_image_load_store),
+ NULL);
+
+#undef F
+#undef FI
+#undef FIU
+#undef FIUB
+#undef FIU2_MIXED
+}
+
+void
+builtin_builder::add_function(const char *name, ...)
+{
+ va_list ap;
+
+ ir_function *f = new(mem_ctx) ir_function(name);
+
+ va_start(ap, name);
+ while (true) {
+ ir_function_signature *sig = va_arg(ap, ir_function_signature *);
+ if (sig == NULL)
+ break;
+
+ if (false) {
+ exec_list stuff;
+ stuff.push_tail(sig);
+ validate_ir_tree(&stuff);
+ }
+
+ f->add_signature(sig);
+ }
+ va_end(ap);
+
+ shader->symbols->add_function(f);
+}
+
+void
+builtin_builder::add_image_function(const char *name,
+ const char *intrinsic_name,
+ unsigned num_arguments,
+ unsigned flags)
+{
+ static const glsl_type *const types[] = {
+ glsl_type::image1D_type,
+ glsl_type::image2D_type,
+ glsl_type::image3D_type,
+ glsl_type::image2DRect_type,
+ glsl_type::imageCube_type,
+ glsl_type::imageBuffer_type,
+ glsl_type::image1DArray_type,
+ glsl_type::image2DArray_type,
+ glsl_type::imageCubeArray_type,
+ glsl_type::image2DMS_type,
+ glsl_type::image2DMSArray_type,
+ glsl_type::iimage1D_type,
+ glsl_type::iimage2D_type,
+ glsl_type::iimage3D_type,
+ glsl_type::iimage2DRect_type,
+ glsl_type::iimageCube_type,
+ glsl_type::iimageBuffer_type,
+ glsl_type::iimage1DArray_type,
+ glsl_type::iimage2DArray_type,
+ glsl_type::iimageCubeArray_type,
+ glsl_type::iimage2DMS_type,
+ glsl_type::iimage2DMSArray_type,
+ glsl_type::uimage1D_type,
+ glsl_type::uimage2D_type,
+ glsl_type::uimage3D_type,
+ glsl_type::uimage2DRect_type,
+ glsl_type::uimageCube_type,
+ glsl_type::uimageBuffer_type,
+ glsl_type::uimage1DArray_type,
+ glsl_type::uimage2DArray_type,
+ glsl_type::uimageCubeArray_type,
+ glsl_type::uimage2DMS_type,
+ glsl_type::uimage2DMSArray_type
+ };
+ ir_function *f = new(mem_ctx) ir_function(name);
+
+ for (unsigned i = 0; i < Elements(types); ++i) {
+ if (types[i]->sampler_type != GLSL_TYPE_FLOAT ||
+ (flags & IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE))
+ f->add_signature(_image(types[i], intrinsic_name,
+ num_arguments, flags));
+ }
+
+ shader->symbols->add_function(f);
+}
+
+void
+builtin_builder::add_image_functions(bool glsl)
+{
+ const unsigned flags = (glsl ? IMAGE_FUNCTION_EMIT_STUB : 0);
+
+ add_image_function(glsl ? "imageLoad" : "__intrinsic_image_load",
+ "__intrinsic_image_load", 0,
+ (flags | IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE |
+ IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE |
+ IMAGE_FUNCTION_READ_ONLY));
+
+ add_image_function(glsl ? "imageStore" : "__intrinsic_image_store",
+ "__intrinsic_image_store", 1,
+ (flags | IMAGE_FUNCTION_RETURNS_VOID |
+ IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE |
+ IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE |
+ IMAGE_FUNCTION_WRITE_ONLY));
+
+ add_image_function(glsl ? "imageAtomicAdd" : "__intrinsic_image_atomic_add",
+ "__intrinsic_image_atomic_add", 1, flags);
+
+ add_image_function(glsl ? "imageAtomicMin" : "__intrinsic_image_atomic_min",
+ "__intrinsic_image_atomic_min", 1, flags);
+
+ add_image_function(glsl ? "imageAtomicMax" : "__intrinsic_image_atomic_max",
+ "__intrinsic_image_atomic_max", 1, flags);
+
+ add_image_function(glsl ? "imageAtomicAnd" : "__intrinsic_image_atomic_and",
+ "__intrinsic_image_atomic_and", 1, flags);
+
+ add_image_function(glsl ? "imageAtomicOr" : "__intrinsic_image_atomic_or",
+ "__intrinsic_image_atomic_or", 1, flags);
+
+ add_image_function(glsl ? "imageAtomicXor" : "__intrinsic_image_atomic_xor",
+ "__intrinsic_image_atomic_xor", 1, flags);
+
+ add_image_function((glsl ? "imageAtomicExchange" :
+ "__intrinsic_image_atomic_exchange"),
+ "__intrinsic_image_atomic_exchange", 1, flags);
+
+ add_image_function((glsl ? "imageAtomicCompSwap" :
+ "__intrinsic_image_atomic_comp_swap"),
+ "__intrinsic_image_atomic_comp_swap", 2, flags);
+}
+
+ir_variable *
+builtin_builder::in_var(const glsl_type *type, const char *name)
+{
+ return new(mem_ctx) ir_variable(type, name, ir_var_function_in);
+}
+
+ir_variable *
+builtin_builder::out_var(const glsl_type *type, const char *name)
+{
+ return new(mem_ctx) ir_variable(type, name, ir_var_function_out);
+}
+
+ir_constant *
+builtin_builder::imm(float f, unsigned vector_elements)
+{
+ return new(mem_ctx) ir_constant(f, vector_elements);
+}
+
+ir_constant *
+builtin_builder::imm(int i, unsigned vector_elements)
+{
+ return new(mem_ctx) ir_constant(i, vector_elements);
+}
+
+ir_constant *
+builtin_builder::imm(unsigned u, unsigned vector_elements)
+{
+ return new(mem_ctx) ir_constant(u, vector_elements);
+}
+
+ir_constant *
+builtin_builder::imm(const glsl_type *type, const ir_constant_data &data)
+{
+ return new(mem_ctx) ir_constant(type, &data);
+}
+
+ir_dereference_variable *
+builtin_builder::var_ref(ir_variable *var)
+{
+ return new(mem_ctx) ir_dereference_variable(var);
+}
+
+ir_dereference_array *
+builtin_builder::array_ref(ir_variable *var, int idx)
+{
+ return new(mem_ctx) ir_dereference_array(var, imm(idx));
+}
+
+/** Return an element of a matrix */
+ir_swizzle *
+builtin_builder::matrix_elt(ir_variable *var, int column, int row)
+{
+ return swizzle(array_ref(var, column), row, 1);
+}
+
+/**
+ * Implementations of built-in functions:
+ * @{
+ */
+ir_function_signature *
+builtin_builder::new_sig(const glsl_type *return_type,
+ builtin_available_predicate avail,
+ int num_params,
+ ...)
+{
+ va_list ap;
+
+ ir_function_signature *sig =
+ new(mem_ctx) ir_function_signature(return_type, avail);
+
+ exec_list plist;
+ va_start(ap, num_params);
+ for (int i = 0; i < num_params; i++) {
+ plist.push_tail(va_arg(ap, ir_variable *));
+ }
+ va_end(ap);
+
+ sig->replace_parameters(&plist);
+ return sig;
+}
+
+#define MAKE_SIG(return_type, avail, ...) \
+ ir_function_signature *sig = \
+ new_sig(return_type, avail, __VA_ARGS__); \
+ ir_factory body(&sig->body, mem_ctx); \
+ sig->is_defined = true;
+
+#define MAKE_INTRINSIC(return_type, avail, ...) \
+ ir_function_signature *sig = \
+ new_sig(return_type, avail, __VA_ARGS__); \
+ sig->is_intrinsic = true;
+
+ir_function_signature *
+builtin_builder::unop(builtin_available_predicate avail,
+ ir_expression_operation opcode,
+ const glsl_type *return_type,
+ const glsl_type *param_type)
+{
+ ir_variable *x = in_var(param_type, "x");
+ MAKE_SIG(return_type, avail, 1, x);
+ body.emit(ret(expr(opcode, x)));
+ return sig;
+}
+
+#define UNOP(NAME, OPCODE, AVAIL) \
+ir_function_signature * \
+builtin_builder::_##NAME(const glsl_type *type) \
+{ \
+ return unop(&AVAIL, OPCODE, type, type); \
+}
+
+ir_function_signature *
+builtin_builder::binop(ir_expression_operation opcode,
+ builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *param0_type,
+ const glsl_type *param1_type)
+{
+ ir_variable *x = in_var(param0_type, "x");
+ ir_variable *y = in_var(param1_type, "y");
+ MAKE_SIG(return_type, avail, 2, x, y);
+ body.emit(ret(expr(opcode, x, y)));
+ return sig;
+}
+
+#define BINOP(NAME, OPCODE, AVAIL) \
+ir_function_signature * \
+builtin_builder::_##NAME(const glsl_type *return_type, \
+ const glsl_type *param0_type, \
+ const glsl_type *param1_type) \
+{ \
+ return binop(&AVAIL, OPCODE, return_type, param0_type, param1_type); \
+}
+
+/**
+ * Angle and Trigonometry Functions @{
+ */
+
+ir_function_signature *
+builtin_builder::_radians(const glsl_type *type)
+{
+ ir_variable *degrees = in_var(type, "degrees");
+ MAKE_SIG(type, always_available, 1, degrees);
+ body.emit(ret(mul(degrees, imm(0.0174532925f))));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_degrees(const glsl_type *type)
+{
+ ir_variable *radians = in_var(type, "radians");
+ MAKE_SIG(type, always_available, 1, radians);
+ body.emit(ret(mul(radians, imm(57.29578f))));
+ return sig;
+}
+
+UNOP(sin, ir_unop_sin, always_available)
+UNOP(cos, ir_unop_cos, always_available)
+
+ir_function_signature *
+builtin_builder::_tan(const glsl_type *type)
+{
+ ir_variable *theta = in_var(type, "theta");
+ MAKE_SIG(type, always_available, 1, theta);
+ body.emit(ret(div(sin(theta), cos(theta))));
+ return sig;
+}
+
+ir_expression *
+builtin_builder::asin_expr(ir_variable *x)
+{
+ return mul(sign(x),
+ sub(imm(M_PI_2f),
+ mul(sqrt(sub(imm(1.0f), abs(x))),
+ add(imm(M_PI_2f),
+ mul(abs(x),
+ add(imm(M_PI_4f - 1.0f),
+ mul(abs(x),
+ add(imm(0.086566724f),
+ mul(abs(x), imm(-0.03102955f))))))))));
+}
+
+ir_call *
+builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
+{
+ exec_list actual_params;
+
+ foreach_list(node, &params) {
+ ir_variable *var = (ir_variable *) node;
+ actual_params.push_tail(var_ref(var));
+ }
+
+ ir_function_signature *sig =
+ f->exact_matching_signature(NULL, &actual_params);
+ if (!sig)
+ return NULL;
+
+ ir_dereference_variable *deref =
+ (sig->return_type->is_void() ? NULL : var_ref(ret));
+
+ return new(mem_ctx) ir_call(sig, deref, &actual_params);
+}
+
+ir_function_signature *
+builtin_builder::_asin(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, always_available, 1, x);
+
+ body.emit(ret(asin_expr(x)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_acos(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, always_available, 1, x);
+
+ body.emit(ret(sub(imm(M_PI_2f), asin_expr(x))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atan2(const glsl_type *type)
+{
+ ir_variable *vec_y = in_var(type, "vec_y");
+ ir_variable *vec_x = in_var(type, "vec_x");
+ MAKE_SIG(type, always_available, 2, vec_y, vec_x);
+
+ ir_variable *vec_result = body.make_temp(type, "vec_result");
+ ir_variable *r = body.make_temp(glsl_type::float_type, "r");
+ for (int i = 0; i < type->vector_elements; i++) {
+ ir_variable *y = body.make_temp(glsl_type::float_type, "y");
+ ir_variable *x = body.make_temp(glsl_type::float_type, "x");
+ body.emit(assign(y, swizzle(vec_y, i, 1)));
+ body.emit(assign(x, swizzle(vec_x, i, 1)));
+
+ /* If |x| >= 1.0e-8 * |y|: */
+ ir_if *outer_if =
+ new(mem_ctx) ir_if(greater(abs(x), mul(imm(1.0e-8f), abs(y))));
+
+ ir_factory outer_then(&outer_if->then_instructions, mem_ctx);
+
+ /* Then...call atan(y/x) */
+ ir_variable *y_over_x = outer_then.make_temp(glsl_type::float_type, "y_over_x");
+ outer_then.emit(assign(y_over_x, div(y, x)));
+ outer_then.emit(assign(r, mul(y_over_x, rsq(add(mul(y_over_x, y_over_x),
+ imm(1.0f))))));
+ outer_then.emit(assign(r, asin_expr(r)));
+
+ /* ...and fix it up: */
+ ir_if *inner_if = new(mem_ctx) ir_if(less(x, imm(0.0f)));
+ inner_if->then_instructions.push_tail(
+ if_tree(gequal(y, imm(0.0f)),
+ assign(r, add(r, imm(M_PIf))),
+ assign(r, sub(r, imm(M_PIf)))));
+ outer_then.emit(inner_if);
+
+ /* Else... */
+ outer_if->else_instructions.push_tail(
+ assign(r, mul(sign(y), imm(M_PI_2f))));
+
+ body.emit(outer_if);
+
+ body.emit(assign(vec_result, r, 1 << i));
+ }
+ body.emit(ret(vec_result));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atan(const glsl_type *type)
+{
+ ir_variable *y_over_x = in_var(type, "y_over_x");
+ MAKE_SIG(type, always_available, 1, y_over_x);
+
+ ir_variable *t = body.make_temp(type, "t");
+ body.emit(assign(t, mul(y_over_x, rsq(add(mul(y_over_x, y_over_x),
+ imm(1.0f))))));
+
+ body.emit(ret(asin_expr(t)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_sinh(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, v130, 1, x);
+
+ /* 0.5 * (e^x - e^(-x)) */
+ body.emit(ret(mul(imm(0.5f), sub(exp(x), exp(neg(x))))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_cosh(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, v130, 1, x);
+
+ /* 0.5 * (e^x + e^(-x)) */
+ body.emit(ret(mul(imm(0.5f), add(exp(x), exp(neg(x))))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_tanh(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, v130, 1, x);
+
+ /* (e^x - e^(-x)) / (e^x + e^(-x)) */
+ body.emit(ret(div(sub(exp(x), exp(neg(x))),
+ add(exp(x), exp(neg(x))))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_asinh(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, v130, 1, x);
+
+ body.emit(ret(mul(sign(x), log(add(abs(x), sqrt(add(mul(x, x),
+ imm(1.0f))))))));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_acosh(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, v130, 1, x);
+
+ body.emit(ret(log(add(x, sqrt(sub(mul(x, x), imm(1.0f)))))));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atanh(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, v130, 1, x);
+
+ body.emit(ret(mul(imm(0.5f), log(div(add(imm(1.0f), x),
+ sub(imm(1.0f), x))))));
+ return sig;
+}
+/** @} */
+
+/**
+ * Exponential Functions @{
+ */
+
+ir_function_signature *
+builtin_builder::_pow(const glsl_type *type)
+{
+ return binop(ir_binop_pow, always_available, type, type, type);
+}
+
+UNOP(exp, ir_unop_exp, always_available)
+UNOP(log, ir_unop_log, always_available)
+UNOP(exp2, ir_unop_exp2, always_available)
+UNOP(log2, ir_unop_log2, always_available)
+UNOP(sqrt, ir_unop_sqrt, always_available)
+UNOP(inversesqrt, ir_unop_rsq, always_available)
+
+/** @} */
+
+UNOP(abs, ir_unop_abs, always_available)
+UNOP(sign, ir_unop_sign, always_available)
+UNOP(floor, ir_unop_floor, always_available)
+UNOP(trunc, ir_unop_trunc, v130)
+UNOP(round, ir_unop_round_even, always_available)
+UNOP(roundEven, ir_unop_round_even, always_available)
+UNOP(ceil, ir_unop_ceil, always_available)
+UNOP(fract, ir_unop_fract, always_available)
+
+ir_function_signature *
+builtin_builder::_mod(const glsl_type *x_type, const glsl_type *y_type)
+{
+ return binop(ir_binop_mod, always_available, x_type, x_type, y_type);
+}
+
+ir_function_signature *
+builtin_builder::_modf(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *i = out_var(type, "i");
+ MAKE_SIG(type, v130, 2, x, i);
+
+ ir_variable *t = body.make_temp(type, "t");
+ body.emit(assign(t, expr(ir_unop_trunc, x)));
+ body.emit(assign(i, t));
+ body.emit(ret(sub(x, t)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_min(builtin_available_predicate avail,
+ const glsl_type *x_type, const glsl_type *y_type)
+{
+ return binop(ir_binop_min, avail, x_type, x_type, y_type);
+}
+
+ir_function_signature *
+builtin_builder::_max(builtin_available_predicate avail,
+ const glsl_type *x_type, const glsl_type *y_type)
+{
+ return binop(ir_binop_max, avail, x_type, x_type, y_type);
+}
+
+ir_function_signature *
+builtin_builder::_clamp(builtin_available_predicate avail,
+ const glsl_type *val_type, const glsl_type *bound_type)
+{
+ ir_variable *x = in_var(val_type, "x");
+ ir_variable *minVal = in_var(bound_type, "minVal");
+ ir_variable *maxVal = in_var(bound_type, "maxVal");
+ MAKE_SIG(val_type, avail, 3, x, minVal, maxVal);
+
+ body.emit(ret(clamp(x, minVal, maxVal)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_mix_lrp(const glsl_type *val_type, const glsl_type *blend_type)
+{
+ ir_variable *x = in_var(val_type, "x");
+ ir_variable *y = in_var(val_type, "y");
+ ir_variable *a = in_var(blend_type, "a");
+ MAKE_SIG(val_type, always_available, 3, x, y, a);
+
+ body.emit(ret(lrp(x, y, a)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_mix_sel(builtin_available_predicate avail,
+ const glsl_type *val_type,
+ const glsl_type *blend_type)
+{
+ ir_variable *x = in_var(val_type, "x");
+ ir_variable *y = in_var(val_type, "y");
+ ir_variable *a = in_var(blend_type, "a");
+ MAKE_SIG(val_type, avail, 3, x, y, a);
+
+ /* csel matches the ternary operator in that a selector of true choses the
+ * first argument. This differs from mix(x, y, false) which choses the
+ * second argument (to remain consistent with the interpolating version of
+ * mix() which takes a blend factor from 0.0 to 1.0 where 0.0 is only x.
+ *
+ * To handle the behavior mismatch, reverse the x and y arguments.
+ */
+ body.emit(ret(csel(a, y, x)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_step(const glsl_type *edge_type, const glsl_type *x_type)
+{
+ ir_variable *edge = in_var(edge_type, "edge");
+ ir_variable *x = in_var(x_type, "x");
+ MAKE_SIG(x_type, always_available, 2, edge, x);
+
+ ir_variable *t = body.make_temp(x_type, "t");
+ if (x_type->vector_elements == 1) {
+ /* Both are floats */
+ body.emit(assign(t, b2f(gequal(x, edge))));
+ } else if (edge_type->vector_elements == 1) {
+ /* x is a vector but edge is a float */
+ for (int i = 0; i < x_type->vector_elements; i++) {
+ body.emit(assign(t, b2f(gequal(swizzle(x, i, 1), edge)), 1 << i));
+ }
+ } else {
+ /* Both are vectors */
+ for (int i = 0; i < x_type->vector_elements; i++) {
+ body.emit(assign(t, b2f(gequal(swizzle(x, i, 1), swizzle(edge, i, 1))),
+ 1 << i));
+ }
+ }
+ body.emit(ret(t));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_smoothstep(const glsl_type *edge_type, const glsl_type *x_type)
+{
+ ir_variable *edge0 = in_var(edge_type, "edge0");
+ ir_variable *edge1 = in_var(edge_type, "edge1");
+ ir_variable *x = in_var(x_type, "x");
+ MAKE_SIG(x_type, always_available, 3, edge0, edge1, x);
+
+ /* From the GLSL 1.10 specification:
+ *
+ * genType t;
+ * t = clamp((x - edge0) / (edge1 - edge0), 0, 1);
+ * return t * t * (3 - 2 * t);
+ */
+
+ ir_variable *t = body.make_temp(x_type, "t");
+ body.emit(assign(t, clamp(div(sub(x, edge0), sub(edge1, edge0)),
+ imm(0.0f), imm(1.0f))));
+
+ body.emit(ret(mul(t, mul(t, sub(imm(3.0f), mul(imm(2.0f), t))))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_isnan(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::bvec(type->vector_elements), v130, 1, x);
+
+ body.emit(ret(nequal(x, x)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_isinf(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::bvec(type->vector_elements), v130, 1, x);
+
+ ir_constant_data infinities;
+ for (int i = 0; i < type->vector_elements; i++) {
+ infinities.f[i] = std::numeric_limits<float>::infinity();
+ }
+
+ body.emit(ret(equal(abs(x), imm(type, infinities))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_floatBitsToInt(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::ivec(type->vector_elements), shader_bit_encoding, 1, x);
+ body.emit(ret(bitcast_f2i(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_floatBitsToUint(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::uvec(type->vector_elements), shader_bit_encoding, 1, x);
+ body.emit(ret(bitcast_f2u(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_intBitsToFloat(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::vec(type->vector_elements), shader_bit_encoding, 1, x);
+ body.emit(ret(bitcast_i2f(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_uintBitsToFloat(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::vec(type->vector_elements), shader_bit_encoding, 1, x);
+ body.emit(ret(bitcast_u2f(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_packUnorm2x16(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::vec2_type, "v");
+ MAKE_SIG(glsl_type::uint_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_unorm_2x16, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_packSnorm2x16(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::vec2_type, "v");
+ MAKE_SIG(glsl_type::uint_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_snorm_2x16, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_packUnorm4x8(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::vec4_type, "v");
+ MAKE_SIG(glsl_type::uint_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_unorm_4x8, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_packSnorm4x8(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::vec4_type, "v");
+ MAKE_SIG(glsl_type::uint_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_snorm_4x8, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_unpackUnorm2x16(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::uint_type, "p");
+ MAKE_SIG(glsl_type::vec2_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_unorm_2x16, p)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_unpackSnorm2x16(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::uint_type, "p");
+ MAKE_SIG(glsl_type::vec2_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_snorm_2x16, p)));
+ return sig;
+}
+
+
+ir_function_signature *
+builtin_builder::_unpackUnorm4x8(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::uint_type, "p");
+ MAKE_SIG(glsl_type::vec4_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_unorm_4x8, p)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_unpackSnorm4x8(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::uint_type, "p");
+ MAKE_SIG(glsl_type::vec4_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_snorm_4x8, p)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_packHalf2x16(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::vec2_type, "v");
+ MAKE_SIG(glsl_type::uint_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_half_2x16, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_unpackHalf2x16(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::uint_type, "p");
+ MAKE_SIG(glsl_type::vec2_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_half_2x16, p)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_length(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::float_type, always_available, 1, x);
+
+ body.emit(ret(sqrt(dot(x, x))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_distance(const glsl_type *type)
+{
+ ir_variable *p0 = in_var(type, "p0");
+ ir_variable *p1 = in_var(type, "p1");
+ MAKE_SIG(glsl_type::float_type, always_available, 2, p0, p1);
+
+ if (type->vector_elements == 1) {
+ body.emit(ret(abs(sub(p0, p1))));
+ } else {
+ ir_variable *p = body.make_temp(type, "p");
+ body.emit(assign(p, sub(p0, p1)));
+ body.emit(ret(sqrt(dot(p, p))));
+ }
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_dot(const glsl_type *type)
+{
+ if (type->vector_elements == 1)
+ return binop(ir_binop_mul, always_available, type, type, type);
+
+ return binop(ir_binop_dot, always_available,
+ glsl_type::float_type, type, type);
+}
+
+ir_function_signature *
+builtin_builder::_cross(const glsl_type *type)
+{
+ ir_variable *a = in_var(type, "a");
+ ir_variable *b = in_var(type, "b");
+ MAKE_SIG(type, always_available, 2, a, b);
+
+ int yzx = MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, 0);
+ int zxy = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, 0);
+
+ body.emit(ret(sub(mul(swizzle(a, yzx, 3), swizzle(b, zxy, 3)),
+ mul(swizzle(a, zxy, 3), swizzle(b, yzx, 3)))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_normalize(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, always_available, 1, x);
+
+ if (type->vector_elements == 1) {
+ body.emit(ret(sign(x)));
+ } else {
+ body.emit(ret(mul(x, rsq(dot(x, x)))));
+ }
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_ftransform()
+{
+ MAKE_SIG(glsl_type::vec4_type, compatibility_vs_only, 0);
+
+ body.emit(ret(new(mem_ctx) ir_expression(ir_binop_mul,
+ glsl_type::vec4_type,
+ var_ref(gl_ModelViewProjectionMatrix),
+ var_ref(gl_Vertex))));
+
+ /* FINISHME: Once the ir_expression() constructor handles type inference
+ * for matrix operations, we can simplify this to:
+ *
+ * body.emit(ret(mul(gl_ModelViewProjectionMatrix, gl_Vertex)));
+ */
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_faceforward(const glsl_type *type)
+{
+ ir_variable *N = in_var(type, "N");
+ ir_variable *I = in_var(type, "I");
+ ir_variable *Nref = in_var(type, "Nref");
+ MAKE_SIG(type, always_available, 3, N, I, Nref);
+
+ body.emit(if_tree(less(dot(Nref, I), imm(0.0f)),
+ ret(N), ret(neg(N))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_reflect(const glsl_type *type)
+{
+ ir_variable *I = in_var(type, "I");
+ ir_variable *N = in_var(type, "N");
+ MAKE_SIG(type, always_available, 2, I, N);
+
+ /* I - 2 * dot(N, I) * N */
+ body.emit(ret(sub(I, mul(imm(2.0f), mul(dot(N, I), N)))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_refract(const glsl_type *type)
+{
+ ir_variable *I = in_var(type, "I");
+ ir_variable *N = in_var(type, "N");
+ ir_variable *eta = in_var(glsl_type::float_type, "eta");
+ MAKE_SIG(type, always_available, 3, I, N, eta);
+
+ ir_variable *n_dot_i = body.make_temp(glsl_type::float_type, "n_dot_i");
+ body.emit(assign(n_dot_i, dot(N, I)));
+
+ /* From the GLSL 1.10 specification:
+ * k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
+ * if (k < 0.0)
+ * return genType(0.0)
+ * else
+ * return eta * I - (eta * dot(N, I) + sqrt(k)) * N
+ */
+ ir_variable *k = body.make_temp(glsl_type::float_type, "k");
+ body.emit(assign(k, sub(imm(1.0f),
+ mul(eta, mul(eta, sub(imm(1.0f),
+ mul(n_dot_i, n_dot_i)))))));
+ body.emit(if_tree(less(k, imm(0.0f)),
+ ret(ir_constant::zero(mem_ctx, type)),
+ ret(sub(mul(eta, I),
+ mul(add(mul(eta, n_dot_i), sqrt(k)), N)))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_matrixCompMult(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ MAKE_SIG(type, always_available, 2, x, y);
+
+ ir_variable *z = body.make_temp(type, "z");
+ for (int i = 0; i < type->matrix_columns; i++) {
+ body.emit(assign(array_ref(z, i), mul(array_ref(x, i), array_ref(y, i))));
+ }
+ body.emit(ret(z));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_outerProduct(const glsl_type *type)
+{
+ ir_variable *c = in_var(glsl_type::vec(type->vector_elements), "c");
+ ir_variable *r = in_var(glsl_type::vec(type->matrix_columns), "r");
+ MAKE_SIG(type, v120, 2, c, r);
+
+ ir_variable *m = body.make_temp(type, "m");
+ for (int i = 0; i < type->matrix_columns; i++) {
+ body.emit(assign(array_ref(m, i), mul(c, swizzle(r, i, 1))));
+ }
+ body.emit(ret(m));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_transpose(const glsl_type *orig_type)
+{
+ const glsl_type *transpose_type =
+ glsl_type::get_instance(GLSL_TYPE_FLOAT,
+ orig_type->matrix_columns,
+ orig_type->vector_elements);
+
+ ir_variable *m = in_var(orig_type, "m");
+ MAKE_SIG(transpose_type, v120, 1, m);
+
+ ir_variable *t = body.make_temp(transpose_type, "t");
+ for (int i = 0; i < orig_type->matrix_columns; i++) {
+ for (int j = 0; j < orig_type->vector_elements; j++) {
+ body.emit(assign(array_ref(t, j),
+ matrix_elt(m, i, j),
+ 1 << i));
+ }
+ }
+ body.emit(ret(t));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_determinant_mat2()
+{
+ ir_variable *m = in_var(glsl_type::mat2_type, "m");
+ MAKE_SIG(glsl_type::float_type, v120, 1, m);
+
+ body.emit(ret(sub(mul(matrix_elt(m, 0, 0), matrix_elt(m, 1, 1)),
+ mul(matrix_elt(m, 1, 0), matrix_elt(m, 0, 1)))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_determinant_mat3()
+{
+ ir_variable *m = in_var(glsl_type::mat3_type, "m");
+ MAKE_SIG(glsl_type::float_type, v120, 1, m);
+
+ ir_expression *f1 =
+ sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 2)),
+ mul(matrix_elt(m, 1, 2), matrix_elt(m, 2, 1)));
+
+ ir_expression *f2 =
+ sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 2)),
+ mul(matrix_elt(m, 1, 2), matrix_elt(m, 2, 0)));
+
+ ir_expression *f3 =
+ sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 1)),
+ mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 0)));
+
+ body.emit(ret(add(sub(mul(matrix_elt(m, 0, 0), f1),
+ mul(matrix_elt(m, 0, 1), f2)),
+ mul(matrix_elt(m, 0, 2), f3))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_determinant_mat4()
+{
+ ir_variable *m = in_var(glsl_type::mat4_type, "m");
+ MAKE_SIG(glsl_type::float_type, v120, 1, m);
+
+ ir_variable *SubFactor00 = body.make_temp(glsl_type::float_type, "SubFactor00");
+ ir_variable *SubFactor01 = body.make_temp(glsl_type::float_type, "SubFactor01");
+ ir_variable *SubFactor02 = body.make_temp(glsl_type::float_type, "SubFactor02");
+ ir_variable *SubFactor03 = body.make_temp(glsl_type::float_type, "SubFactor03");
+ ir_variable *SubFactor04 = body.make_temp(glsl_type::float_type, "SubFactor04");
+ ir_variable *SubFactor05 = body.make_temp(glsl_type::float_type, "SubFactor05");
+ ir_variable *SubFactor06 = body.make_temp(glsl_type::float_type, "SubFactor06");
+ ir_variable *SubFactor07 = body.make_temp(glsl_type::float_type, "SubFactor07");
+ ir_variable *SubFactor08 = body.make_temp(glsl_type::float_type, "SubFactor08");
+ ir_variable *SubFactor09 = body.make_temp(glsl_type::float_type, "SubFactor09");
+ ir_variable *SubFactor10 = body.make_temp(glsl_type::float_type, "SubFactor10");
+ ir_variable *SubFactor11 = body.make_temp(glsl_type::float_type, "SubFactor11");
+ ir_variable *SubFactor12 = body.make_temp(glsl_type::float_type, "SubFactor12");
+ ir_variable *SubFactor13 = body.make_temp(glsl_type::float_type, "SubFactor13");
+ ir_variable *SubFactor14 = body.make_temp(glsl_type::float_type, "SubFactor14");
+ ir_variable *SubFactor15 = body.make_temp(glsl_type::float_type, "SubFactor15");
+ ir_variable *SubFactor16 = body.make_temp(glsl_type::float_type, "SubFactor16");
+ ir_variable *SubFactor17 = body.make_temp(glsl_type::float_type, "SubFactor17");
+ ir_variable *SubFactor18 = body.make_temp(glsl_type::float_type, "SubFactor18");
+
+ body.emit(assign(SubFactor00, sub(mul(matrix_elt(m, 2, 2), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 2), matrix_elt(m, 2, 3)))));
+ body.emit(assign(SubFactor01, sub(mul(matrix_elt(m, 2, 1), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 2, 3)))));
+ body.emit(assign(SubFactor02, sub(mul(matrix_elt(m, 2, 1), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 2, 2)))));
+ body.emit(assign(SubFactor03, sub(mul(matrix_elt(m, 2, 0), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 2, 3)))));
+ body.emit(assign(SubFactor04, sub(mul(matrix_elt(m, 2, 0), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 2, 2)))));
+ body.emit(assign(SubFactor05, sub(mul(matrix_elt(m, 2, 0), matrix_elt(m, 3, 1)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 2, 1)))));
+ body.emit(assign(SubFactor06, sub(mul(matrix_elt(m, 1, 2), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 2), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor07, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor08, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor09, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor10, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor11, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor12, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 3, 1)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 1, 1)))));
+ body.emit(assign(SubFactor13, sub(mul(matrix_elt(m, 1, 2), matrix_elt(m, 2, 3)), mul(matrix_elt(m, 2, 2), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor14, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 3)), mul(matrix_elt(m, 2, 1), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor15, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 2)), mul(matrix_elt(m, 2, 1), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor16, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 3)), mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor17, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 2)), mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor18, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 1)), mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 1)))));
+
+ ir_variable *adj_0 = body.make_temp(glsl_type::vec4_type, "adj_0");
+
+ body.emit(assign(adj_0,
+ add(sub(mul(matrix_elt(m, 1, 1), SubFactor00),
+ mul(matrix_elt(m, 1, 2), SubFactor01)),
+ mul(matrix_elt(m, 1, 3), SubFactor02)),
+ WRITEMASK_X));
+ body.emit(assign(adj_0, neg(
+ add(sub(mul(matrix_elt(m, 1, 0), SubFactor00),
+ mul(matrix_elt(m, 1, 2), SubFactor03)),
+ mul(matrix_elt(m, 1, 3), SubFactor04))),
+ WRITEMASK_Y));
+ body.emit(assign(adj_0,
+ add(sub(mul(matrix_elt(m, 1, 0), SubFactor01),
+ mul(matrix_elt(m, 1, 1), SubFactor03)),
+ mul(matrix_elt(m, 1, 3), SubFactor05)),
+ WRITEMASK_Z));
+ body.emit(assign(adj_0, neg(
+ add(sub(mul(matrix_elt(m, 1, 0), SubFactor02),
+ mul(matrix_elt(m, 1, 1), SubFactor04)),
+ mul(matrix_elt(m, 1, 2), SubFactor05))),
+ WRITEMASK_W));
+
+ body.emit(ret(dot(array_ref(m, 0), adj_0)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_inverse_mat2()
+{
+ ir_variable *m = in_var(glsl_type::mat2_type, "m");
+ MAKE_SIG(glsl_type::mat2_type, v120, 1, m);
+
+ ir_variable *adj = body.make_temp(glsl_type::mat2_type, "adj");
+ body.emit(assign(array_ref(adj, 0), matrix_elt(m, 1, 1), 1 << 0));
+ body.emit(assign(array_ref(adj, 0), neg(matrix_elt(m, 0, 1)), 1 << 1));
+ body.emit(assign(array_ref(adj, 1), neg(matrix_elt(m, 1, 0)), 1 << 0));
+ body.emit(assign(array_ref(adj, 1), matrix_elt(m, 0, 0), 1 << 1));
+
+ ir_expression *det =
+ sub(mul(matrix_elt(m, 0, 0), matrix_elt(m, 1, 1)),
+ mul(matrix_elt(m, 1, 0), matrix_elt(m, 0, 1)));
+
+ body.emit(ret(div(adj, det)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_inverse_mat3()
+{
+ ir_variable *m = in_var(glsl_type::mat3_type, "m");
+ MAKE_SIG(glsl_type::mat3_type, v120, 1, m);
+
+ ir_variable *f11_22_21_12 = body.make_temp(glsl_type::float_type, "f11_22_21_12");
+ ir_variable *f10_22_20_12 = body.make_temp(glsl_type::float_type, "f10_22_20_12");
+ ir_variable *f10_21_20_11 = body.make_temp(glsl_type::float_type, "f10_21_20_11");
+
+ body.emit(assign(f11_22_21_12,
+ sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 2)),
+ mul(matrix_elt(m, 2, 1), matrix_elt(m, 1, 2)))));
+ body.emit(assign(f10_22_20_12,
+ sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 2)),
+ mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 2)))));
+ body.emit(assign(f10_21_20_11,
+ sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 1)),
+ mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 1)))));
+
+ ir_variable *adj = body.make_temp(glsl_type::mat3_type, "adj");
+ body.emit(assign(array_ref(adj, 0), f11_22_21_12, WRITEMASK_X));
+ body.emit(assign(array_ref(adj, 1), neg(f10_22_20_12), WRITEMASK_X));
+ body.emit(assign(array_ref(adj, 2), f10_21_20_11, WRITEMASK_X));
+
+ body.emit(assign(array_ref(adj, 0), neg(
+ sub(mul(matrix_elt(m, 0, 1), matrix_elt(m, 2, 2)),
+ mul(matrix_elt(m, 2, 1), matrix_elt(m, 0, 2)))),
+ WRITEMASK_Y));
+ body.emit(assign(array_ref(adj, 1),
+ sub(mul(matrix_elt(m, 0, 0), matrix_elt(m, 2, 2)),
+ mul(matrix_elt(m, 2, 0), matrix_elt(m, 0, 2))),
+ WRITEMASK_Y));
+ body.emit(assign(array_ref(adj, 2), neg(
+ sub(mul(matrix_elt(m, 0, 0), matrix_elt(m, 2, 1)),
+ mul(matrix_elt(m, 2, 0), matrix_elt(m, 0, 1)))),
+ WRITEMASK_Y));
+
+ body.emit(assign(array_ref(adj, 0),
+ sub(mul(matrix_elt(m, 0, 1), matrix_elt(m, 1, 2)),
+ mul(matrix_elt(m, 1, 1), matrix_elt(m, 0, 2))),
+ WRITEMASK_Z));
+ body.emit(assign(array_ref(adj, 1), neg(
+ sub(mul(matrix_elt(m, 0, 0), matrix_elt(m, 1, 2)),
+ mul(matrix_elt(m, 1, 0), matrix_elt(m, 0, 2)))),
+ WRITEMASK_Z));
+ body.emit(assign(array_ref(adj, 2),
+ sub(mul(matrix_elt(m, 0, 0), matrix_elt(m, 1, 1)),
+ mul(matrix_elt(m, 1, 0), matrix_elt(m, 0, 1))),
+ WRITEMASK_Z));
+
+ ir_expression *det =
+ add(sub(mul(matrix_elt(m, 0, 0), f11_22_21_12),
+ mul(matrix_elt(m, 0, 1), f10_22_20_12)),
+ mul(matrix_elt(m, 0, 2), f10_21_20_11));
+
+ body.emit(ret(div(adj, det)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_inverse_mat4()
+{
+ ir_variable *m = in_var(glsl_type::mat4_type, "m");
+ MAKE_SIG(glsl_type::mat4_type, v120, 1, m);
+
+ ir_variable *SubFactor00 = body.make_temp(glsl_type::float_type, "SubFactor00");
+ ir_variable *SubFactor01 = body.make_temp(glsl_type::float_type, "SubFactor01");
+ ir_variable *SubFactor02 = body.make_temp(glsl_type::float_type, "SubFactor02");
+ ir_variable *SubFactor03 = body.make_temp(glsl_type::float_type, "SubFactor03");
+ ir_variable *SubFactor04 = body.make_temp(glsl_type::float_type, "SubFactor04");
+ ir_variable *SubFactor05 = body.make_temp(glsl_type::float_type, "SubFactor05");
+ ir_variable *SubFactor06 = body.make_temp(glsl_type::float_type, "SubFactor06");
+ ir_variable *SubFactor07 = body.make_temp(glsl_type::float_type, "SubFactor07");
+ ir_variable *SubFactor08 = body.make_temp(glsl_type::float_type, "SubFactor08");
+ ir_variable *SubFactor09 = body.make_temp(glsl_type::float_type, "SubFactor09");
+ ir_variable *SubFactor10 = body.make_temp(glsl_type::float_type, "SubFactor10");
+ ir_variable *SubFactor11 = body.make_temp(glsl_type::float_type, "SubFactor11");
+ ir_variable *SubFactor12 = body.make_temp(glsl_type::float_type, "SubFactor12");
+ ir_variable *SubFactor13 = body.make_temp(glsl_type::float_type, "SubFactor13");
+ ir_variable *SubFactor14 = body.make_temp(glsl_type::float_type, "SubFactor14");
+ ir_variable *SubFactor15 = body.make_temp(glsl_type::float_type, "SubFactor15");
+ ir_variable *SubFactor16 = body.make_temp(glsl_type::float_type, "SubFactor16");
+ ir_variable *SubFactor17 = body.make_temp(glsl_type::float_type, "SubFactor17");
+ ir_variable *SubFactor18 = body.make_temp(glsl_type::float_type, "SubFactor18");
+
+ body.emit(assign(SubFactor00, sub(mul(matrix_elt(m, 2, 2), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 2), matrix_elt(m, 2, 3)))));
+ body.emit(assign(SubFactor01, sub(mul(matrix_elt(m, 2, 1), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 2, 3)))));
+ body.emit(assign(SubFactor02, sub(mul(matrix_elt(m, 2, 1), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 2, 2)))));
+ body.emit(assign(SubFactor03, sub(mul(matrix_elt(m, 2, 0), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 2, 3)))));
+ body.emit(assign(SubFactor04, sub(mul(matrix_elt(m, 2, 0), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 2, 2)))));
+ body.emit(assign(SubFactor05, sub(mul(matrix_elt(m, 2, 0), matrix_elt(m, 3, 1)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 2, 1)))));
+ body.emit(assign(SubFactor06, sub(mul(matrix_elt(m, 1, 2), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 2), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor07, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor08, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor09, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor10, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 3, 2)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor11, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 3, 3)), mul(matrix_elt(m, 3, 1), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor12, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 3, 1)), mul(matrix_elt(m, 3, 0), matrix_elt(m, 1, 1)))));
+ body.emit(assign(SubFactor13, sub(mul(matrix_elt(m, 1, 2), matrix_elt(m, 2, 3)), mul(matrix_elt(m, 2, 2), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor14, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 3)), mul(matrix_elt(m, 2, 1), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor15, sub(mul(matrix_elt(m, 1, 1), matrix_elt(m, 2, 2)), mul(matrix_elt(m, 2, 1), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor16, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 3)), mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 3)))));
+ body.emit(assign(SubFactor17, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 2)), mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 2)))));
+ body.emit(assign(SubFactor18, sub(mul(matrix_elt(m, 1, 0), matrix_elt(m, 2, 1)), mul(matrix_elt(m, 2, 0), matrix_elt(m, 1, 1)))));
+
+ ir_variable *adj = body.make_temp(glsl_type::mat4_type, "adj");
+ body.emit(assign(array_ref(adj, 0),
+ add(sub(mul(matrix_elt(m, 1, 1), SubFactor00),
+ mul(matrix_elt(m, 1, 2), SubFactor01)),
+ mul(matrix_elt(m, 1, 3), SubFactor02)),
+ WRITEMASK_X));
+ body.emit(assign(array_ref(adj, 1), neg(
+ add(sub(mul(matrix_elt(m, 1, 0), SubFactor00),
+ mul(matrix_elt(m, 1, 2), SubFactor03)),
+ mul(matrix_elt(m, 1, 3), SubFactor04))),
+ WRITEMASK_X));
+ body.emit(assign(array_ref(adj, 2),
+ add(sub(mul(matrix_elt(m, 1, 0), SubFactor01),
+ mul(matrix_elt(m, 1, 1), SubFactor03)),
+ mul(matrix_elt(m, 1, 3), SubFactor05)),
+ WRITEMASK_X));
+ body.emit(assign(array_ref(adj, 3), neg(
+ add(sub(mul(matrix_elt(m, 1, 0), SubFactor02),
+ mul(matrix_elt(m, 1, 1), SubFactor04)),
+ mul(matrix_elt(m, 1, 2), SubFactor05))),
+ WRITEMASK_X));
+
+ body.emit(assign(array_ref(adj, 0), neg(
+ add(sub(mul(matrix_elt(m, 0, 1), SubFactor00),
+ mul(matrix_elt(m, 0, 2), SubFactor01)),
+ mul(matrix_elt(m, 0, 3), SubFactor02))),
+ WRITEMASK_Y));
+ body.emit(assign(array_ref(adj, 1),
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor00),
+ mul(matrix_elt(m, 0, 2), SubFactor03)),
+ mul(matrix_elt(m, 0, 3), SubFactor04)),
+ WRITEMASK_Y));
+ body.emit(assign(array_ref(adj, 2), neg(
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor01),
+ mul(matrix_elt(m, 0, 1), SubFactor03)),
+ mul(matrix_elt(m, 0, 3), SubFactor05))),
+ WRITEMASK_Y));
+ body.emit(assign(array_ref(adj, 3),
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor02),
+ mul(matrix_elt(m, 0, 1), SubFactor04)),
+ mul(matrix_elt(m, 0, 2), SubFactor05)),
+ WRITEMASK_Y));
+
+ body.emit(assign(array_ref(adj, 0),
+ add(sub(mul(matrix_elt(m, 0, 1), SubFactor06),
+ mul(matrix_elt(m, 0, 2), SubFactor07)),
+ mul(matrix_elt(m, 0, 3), SubFactor08)),
+ WRITEMASK_Z));
+ body.emit(assign(array_ref(adj, 1), neg(
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor06),
+ mul(matrix_elt(m, 0, 2), SubFactor09)),
+ mul(matrix_elt(m, 0, 3), SubFactor10))),
+ WRITEMASK_Z));
+ body.emit(assign(array_ref(adj, 2),
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor11),
+ mul(matrix_elt(m, 0, 1), SubFactor09)),
+ mul(matrix_elt(m, 0, 3), SubFactor12)),
+ WRITEMASK_Z));
+ body.emit(assign(array_ref(adj, 3), neg(
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor08),
+ mul(matrix_elt(m, 0, 1), SubFactor10)),
+ mul(matrix_elt(m, 0, 2), SubFactor12))),
+ WRITEMASK_Z));
+
+ body.emit(assign(array_ref(adj, 0), neg(
+ add(sub(mul(matrix_elt(m, 0, 1), SubFactor13),
+ mul(matrix_elt(m, 0, 2), SubFactor14)),
+ mul(matrix_elt(m, 0, 3), SubFactor15))),
+ WRITEMASK_W));
+ body.emit(assign(array_ref(adj, 1),
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor13),
+ mul(matrix_elt(m, 0, 2), SubFactor16)),
+ mul(matrix_elt(m, 0, 3), SubFactor17)),
+ WRITEMASK_W));
+ body.emit(assign(array_ref(adj, 2), neg(
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor14),
+ mul(matrix_elt(m, 0, 1), SubFactor16)),
+ mul(matrix_elt(m, 0, 3), SubFactor18))),
+ WRITEMASK_W));
+ body.emit(assign(array_ref(adj, 3),
+ add(sub(mul(matrix_elt(m, 0, 0), SubFactor15),
+ mul(matrix_elt(m, 0, 1), SubFactor17)),
+ mul(matrix_elt(m, 0, 2), SubFactor18)),
+ WRITEMASK_W));
+
+ ir_expression *det =
+ add(mul(matrix_elt(m, 0, 0), matrix_elt(adj, 0, 0)),
+ add(mul(matrix_elt(m, 0, 1), matrix_elt(adj, 1, 0)),
+ add(mul(matrix_elt(m, 0, 2), matrix_elt(adj, 2, 0)),
+ mul(matrix_elt(m, 0, 3), matrix_elt(adj, 3, 0)))));
+
+ body.emit(ret(div(adj, det)));
+
+ return sig;
+}
+
+
+ir_function_signature *
+builtin_builder::_lessThan(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ return binop(ir_binop_less, avail,
+ glsl_type::bvec(type->vector_elements), type, type);
+}
+
+ir_function_signature *
+builtin_builder::_lessThanEqual(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ return binop(ir_binop_lequal, avail,
+ glsl_type::bvec(type->vector_elements), type, type);
+}
+
+ir_function_signature *
+builtin_builder::_greaterThan(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ return binop(ir_binop_greater, avail,
+ glsl_type::bvec(type->vector_elements), type, type);
+}
+
+ir_function_signature *
+builtin_builder::_greaterThanEqual(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ return binop(ir_binop_gequal, avail,
+ glsl_type::bvec(type->vector_elements), type, type);
+}
+
+ir_function_signature *
+builtin_builder::_equal(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ return binop(ir_binop_equal, avail,
+ glsl_type::bvec(type->vector_elements), type, type);
+}
+
+ir_function_signature *
+builtin_builder::_notEqual(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ return binop(ir_binop_nequal, avail,
+ glsl_type::bvec(type->vector_elements), type, type);
+}
+
+ir_function_signature *
+builtin_builder::_any(const glsl_type *type)
+{
+ return unop(always_available, ir_unop_any, glsl_type::bool_type, type);
+}
+
+ir_function_signature *
+builtin_builder::_all(const glsl_type *type)
+{
+ ir_variable *v = in_var(type, "v");
+ MAKE_SIG(glsl_type::bool_type, always_available, 1, v);
+
+ switch (type->vector_elements) {
+ case 2:
+ body.emit(ret(logic_and(swizzle_x(v), swizzle_y(v))));
+ break;
+ case 3:
+ body.emit(ret(logic_and(logic_and(swizzle_x(v), swizzle_y(v)),
+ swizzle_z(v))));
+ break;
+ case 4:
+ body.emit(ret(logic_and(logic_and(logic_and(swizzle_x(v), swizzle_y(v)),
+ swizzle_z(v)),
+ swizzle_w(v))));
+ break;
+ }
+
+ return sig;
+}
+
+UNOP(not, ir_unop_logic_not, always_available)
+
+static bool
+has_lod(const glsl_type *sampler_type)
+{
+ assert(sampler_type->is_sampler());
+
+ switch (sampler_type->sampler_dimensionality) {
+ case GLSL_SAMPLER_DIM_RECT:
+ case GLSL_SAMPLER_DIM_BUF:
+ case GLSL_SAMPLER_DIM_MS:
+ return false;
+ default:
+ return true;
+ }
+}
+
+ir_function_signature *
+builtin_builder::_textureSize(builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ /* The sampler always exists; add optional lod later. */
+ MAKE_SIG(return_type, avail, 1, s);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_txs);
+ tex->set_sampler(new(mem_ctx) ir_dereference_variable(s), return_type);
+
+ if (has_lod(sampler_type)) {
+ ir_variable *lod = in_var(glsl_type::int_type, "lod");
+ sig->parameters.push_tail(lod);
+ tex->lod_info.lod = var_ref(lod);
+ } else {
+ tex->lod_info.lod = imm(0u);
+ }
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_texture(ir_texture_opcode opcode,
+ builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type,
+ const glsl_type *coord_type,
+ int flags)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ ir_variable *P = in_var(coord_type, "P");
+ /* The sampler and coordinate always exist; add optional parameters later. */
+ MAKE_SIG(return_type, avail, 2, s, P);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(opcode);
+ tex->set_sampler(var_ref(s), return_type);
+
+ const int coord_size = sampler_type->coordinate_components();
+
+ if (coord_size == coord_type->vector_elements) {
+ tex->coordinate = var_ref(P);
+ } else {
+ /* The incoming coordinate also has the projector or shadow comparitor,
+ * so we need to swizzle those away.
+ */
+ tex->coordinate = swizzle_for_size(P, coord_size);
+ }
+
+ /* The projector is always in the last component. */
+ if (flags & TEX_PROJECT)
+ tex->projector = swizzle(P, coord_type->vector_elements - 1, 1);
+
+ if (sampler_type->sampler_shadow) {
+ if (opcode == ir_tg4) {
+ /* gather has refz as a separate parameter, immediately after the
+ * coordinate
+ */
+ ir_variable *refz = in_var(glsl_type::float_type, "refz");
+ sig->parameters.push_tail(refz);
+ tex->shadow_comparitor = var_ref(refz);
+ } else {
+ /* The shadow comparitor is normally in the Z component, but a few types
+ * have sufficiently large coordinates that it's in W.
+ */
+ tex->shadow_comparitor = swizzle(P, MAX2(coord_size, SWIZZLE_Z), 1);
+ }
+ }
+
+ if (opcode == ir_txl) {
+ ir_variable *lod = in_var(glsl_type::float_type, "lod");
+ sig->parameters.push_tail(lod);
+ tex->lod_info.lod = var_ref(lod);
+ } else if (opcode == ir_txd) {
+ int grad_size = coord_size - (sampler_type->sampler_array ? 1 : 0);
+ ir_variable *dPdx = in_var(glsl_type::vec(grad_size), "dPdx");
+ ir_variable *dPdy = in_var(glsl_type::vec(grad_size), "dPdy");
+ sig->parameters.push_tail(dPdx);
+ sig->parameters.push_tail(dPdy);
+ tex->lod_info.grad.dPdx = var_ref(dPdx);
+ tex->lod_info.grad.dPdy = var_ref(dPdy);
+ }
+
+ if (flags & (TEX_OFFSET | TEX_OFFSET_NONCONST)) {
+ int offset_size = coord_size - (sampler_type->sampler_array ? 1 : 0);
+ ir_variable *offset =
+ new(mem_ctx) ir_variable(glsl_type::ivec(offset_size), "offset",
+ (flags & TEX_OFFSET) ? ir_var_const_in : ir_var_function_in);
+ sig->parameters.push_tail(offset);
+ tex->offset = var_ref(offset);
+ }
+
+ if (flags & TEX_OFFSET_ARRAY) {
+ ir_variable *offsets =
+ new(mem_ctx) ir_variable(glsl_type::get_array_instance(glsl_type::ivec2_type, 4),
+ "offsets", ir_var_const_in);
+ sig->parameters.push_tail(offsets);
+ tex->offset = var_ref(offsets);
+ }
+
+ if (opcode == ir_tg4) {
+ if (flags & TEX_COMPONENT) {
+ ir_variable *component =
+ new(mem_ctx) ir_variable(glsl_type::int_type, "comp", ir_var_const_in);
+ sig->parameters.push_tail(component);
+ tex->lod_info.component = var_ref(component);
+ }
+ else {
+ tex->lod_info.component = imm(0);
+ }
+ }
+
+ /* The "bias" parameter comes /after/ the "offset" parameter, which is
+ * inconsistent with both textureLodOffset and textureGradOffset.
+ */
+ if (opcode == ir_txb) {
+ ir_variable *bias = in_var(glsl_type::float_type, "bias");
+ sig->parameters.push_tail(bias);
+ tex->lod_info.bias = var_ref(bias);
+ }
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_textureCubeArrayShadow()
+{
+ ir_variable *s = in_var(glsl_type::samplerCubeArrayShadow_type, "sampler");
+ ir_variable *P = in_var(glsl_type::vec4_type, "P");
+ ir_variable *compare = in_var(glsl_type::float_type, "compare");
+ MAKE_SIG(glsl_type::float_type, texture_cube_map_array, 3, s, P, compare);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_tex);
+ tex->set_sampler(var_ref(s), glsl_type::float_type);
+
+ tex->coordinate = var_ref(P);
+ tex->shadow_comparitor = var_ref(compare);
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_texelFetch(builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type,
+ const glsl_type *coord_type,
+ const glsl_type *offset_type)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ ir_variable *P = in_var(coord_type, "P");
+ /* The sampler and coordinate always exist; add optional parameters later. */
+ MAKE_SIG(return_type, avail, 2, s, P);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_txf);
+ tex->coordinate = var_ref(P);
+ tex->set_sampler(var_ref(s), return_type);
+
+ if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) {
+ ir_variable *sample = in_var(glsl_type::int_type, "sample");
+ sig->parameters.push_tail(sample);
+ tex->lod_info.sample_index = var_ref(sample);
+ tex->op = ir_txf_ms;
+ } else if (has_lod(sampler_type)) {
+ ir_variable *lod = in_var(glsl_type::int_type, "lod");
+ sig->parameters.push_tail(lod);
+ tex->lod_info.lod = var_ref(lod);
+ } else {
+ tex->lod_info.lod = imm(0u);
+ }
+
+ if (offset_type != NULL) {
+ ir_variable *offset =
+ new(mem_ctx) ir_variable(offset_type, "offset", ir_var_const_in);
+ sig->parameters.push_tail(offset);
+ tex->offset = var_ref(offset);
+ }
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_EmitVertex()
+{
+ MAKE_SIG(glsl_type::void_type, gs_only, 0);
+
+ body.emit(new(mem_ctx) ir_emit_vertex());
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_EndPrimitive()
+{
+ MAKE_SIG(glsl_type::void_type, gs_only, 0);
+
+ body.emit(new(mem_ctx) ir_end_primitive());
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_textureQueryLod(const glsl_type *sampler_type,
+ const glsl_type *coord_type)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ ir_variable *coord = in_var(coord_type, "coord");
+ /* The sampler and coordinate always exist; add optional parameters later. */
+ MAKE_SIG(glsl_type::vec2_type, texture_query_lod, 2, s, coord);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_lod);
+ tex->coordinate = var_ref(coord);
+ tex->set_sampler(var_ref(s), glsl_type::vec2_type);
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_textureQueryLevels(const glsl_type *sampler_type)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ const glsl_type *return_type = glsl_type::int_type;
+ MAKE_SIG(return_type, texture_query_levels, 1, s);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_query_levels);
+ tex->set_sampler(var_ref(s), return_type);
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
+UNOP(dFdx, ir_unop_dFdx, fs_oes_derivatives)
+UNOP(dFdy, ir_unop_dFdy, fs_oes_derivatives)
+
+ir_function_signature *
+builtin_builder::_fwidth(const glsl_type *type)
+{
+ ir_variable *p = in_var(type, "p");
+ MAKE_SIG(type, fs_oes_derivatives, 1, p);
+
+ body.emit(ret(add(abs(expr(ir_unop_dFdx, p)), abs(expr(ir_unop_dFdy, p)))));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_noise1(const glsl_type *type)
+{
+ return unop(v110, ir_unop_noise, glsl_type::float_type, type);
+}
+
+ir_function_signature *
+builtin_builder::_noise2(const glsl_type *type)
+{
+ ir_variable *p = in_var(type, "p");
+ MAKE_SIG(glsl_type::vec2_type, v110, 1, p);
+
+ ir_constant_data b_offset;
+ b_offset.f[0] = 601.0f;
+ b_offset.f[1] = 313.0f;
+ b_offset.f[2] = 29.0f;
+ b_offset.f[3] = 277.0f;
+
+ ir_variable *a = body.make_temp(glsl_type::float_type, "a");
+ ir_variable *b = body.make_temp(glsl_type::float_type, "b");
+ ir_variable *t = body.make_temp(glsl_type::vec2_type, "t");
+ body.emit(assign(a, expr(ir_unop_noise, p)));
+ body.emit(assign(b, expr(ir_unop_noise, add(p, imm(type, b_offset)))));
+ body.emit(assign(t, a, WRITEMASK_X));
+ body.emit(assign(t, b, WRITEMASK_Y));
+ body.emit(ret(t));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_noise3(const glsl_type *type)
+{
+ ir_variable *p = in_var(type, "p");
+ MAKE_SIG(glsl_type::vec3_type, v110, 1, p);
+
+ ir_constant_data b_offset;
+ b_offset.f[0] = 601.0f;
+ b_offset.f[1] = 313.0f;
+ b_offset.f[2] = 29.0f;
+ b_offset.f[3] = 277.0f;
+
+ ir_constant_data c_offset;
+ c_offset.f[0] = 1559.0f;
+ c_offset.f[1] = 113.0f;
+ c_offset.f[2] = 1861.0f;
+ c_offset.f[3] = 797.0f;
+
+ ir_variable *a = body.make_temp(glsl_type::float_type, "a");
+ ir_variable *b = body.make_temp(glsl_type::float_type, "b");
+ ir_variable *c = body.make_temp(glsl_type::float_type, "c");
+ ir_variable *t = body.make_temp(glsl_type::vec3_type, "t");
+ body.emit(assign(a, expr(ir_unop_noise, p)));
+ body.emit(assign(b, expr(ir_unop_noise, add(p, imm(type, b_offset)))));
+ body.emit(assign(c, expr(ir_unop_noise, add(p, imm(type, c_offset)))));
+ body.emit(assign(t, a, WRITEMASK_X));
+ body.emit(assign(t, b, WRITEMASK_Y));
+ body.emit(assign(t, c, WRITEMASK_Z));
+ body.emit(ret(t));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_noise4(const glsl_type *type)
+{
+ ir_variable *p = in_var(type, "p");
+ MAKE_SIG(glsl_type::vec4_type, v110, 1, p);
+
+ ir_variable *_p = body.make_temp(type, "_p");
+
+ ir_constant_data p_offset;
+ p_offset.f[0] = 1559.0f;
+ p_offset.f[1] = 113.0f;
+ p_offset.f[2] = 1861.0f;
+ p_offset.f[3] = 797.0f;
+
+ body.emit(assign(_p, add(p, imm(type, p_offset))));
+
+ ir_constant_data offset;
+ offset.f[0] = 601.0f;
+ offset.f[1] = 313.0f;
+ offset.f[2] = 29.0f;
+ offset.f[3] = 277.0f;
+
+ ir_variable *a = body.make_temp(glsl_type::float_type, "a");
+ ir_variable *b = body.make_temp(glsl_type::float_type, "b");
+ ir_variable *c = body.make_temp(glsl_type::float_type, "c");
+ ir_variable *d = body.make_temp(glsl_type::float_type, "d");
+ ir_variable *t = body.make_temp(glsl_type::vec4_type, "t");
+ body.emit(assign(a, expr(ir_unop_noise, p)));
+ body.emit(assign(b, expr(ir_unop_noise, add(p, imm(type, offset)))));
+ body.emit(assign(c, expr(ir_unop_noise, _p)));
+ body.emit(assign(d, expr(ir_unop_noise, add(_p, imm(type, offset)))));
+ body.emit(assign(t, a, WRITEMASK_X));
+ body.emit(assign(t, b, WRITEMASK_Y));
+ body.emit(assign(t, c, WRITEMASK_Z));
+ body.emit(assign(t, d, WRITEMASK_W));
+ body.emit(ret(t));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_bitfieldExtract(const glsl_type *type)
+{
+ ir_variable *value = in_var(type, "value");
+ ir_variable *offset = in_var(glsl_type::int_type, "offset");
+ ir_variable *bits = in_var(glsl_type::int_type, "bits");
+ MAKE_SIG(type, gpu_shader5, 3, value, offset, bits);
+
+ body.emit(ret(expr(ir_triop_bitfield_extract, value, offset, bits)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_bitfieldInsert(const glsl_type *type)
+{
+ ir_variable *base = in_var(type, "base");
+ ir_variable *insert = in_var(type, "insert");
+ ir_variable *offset = in_var(glsl_type::int_type, "offset");
+ ir_variable *bits = in_var(glsl_type::int_type, "bits");
+ MAKE_SIG(type, gpu_shader5, 4, base, insert, offset, bits);
+
+ body.emit(ret(bitfield_insert(base, insert, offset, bits)));
+
+ return sig;
+}
+
+UNOP(bitfieldReverse, ir_unop_bitfield_reverse, gpu_shader5)
+
+ir_function_signature *
+builtin_builder::_bitCount(const glsl_type *type)
+{
+ return unop(gpu_shader5, ir_unop_bit_count,
+ glsl_type::ivec(type->vector_elements), type);
+}
+
+ir_function_signature *
+builtin_builder::_findLSB(const glsl_type *type)
+{
+ return unop(gpu_shader5, ir_unop_find_lsb,
+ glsl_type::ivec(type->vector_elements), type);
+}
+
+ir_function_signature *
+builtin_builder::_findMSB(const glsl_type *type)
+{
+ return unop(gpu_shader5, ir_unop_find_msb,
+ glsl_type::ivec(type->vector_elements), type);
+}
+
+ir_function_signature *
+builtin_builder::_fma(const glsl_type *type)
+{
+ ir_variable *a = in_var(type, "a");
+ ir_variable *b = in_var(type, "b");
+ ir_variable *c = in_var(type, "c");
+ MAKE_SIG(type, gpu_shader5, 3, a, b, c);
+
+ body.emit(ret(ir_builder::fma(a, b, c)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_ldexp(const glsl_type *x_type, const glsl_type *exp_type)
+{
+ return binop(ir_binop_ldexp, gpu_shader5, x_type, x_type, exp_type);
+}
+
+ir_function_signature *
+builtin_builder::_frexp(const glsl_type *x_type, const glsl_type *exp_type)
+{
+ ir_variable *x = in_var(x_type, "x");
+ ir_variable *exponent = out_var(exp_type, "exp");
+ MAKE_SIG(x_type, gpu_shader5, 2, x, exponent);
+
+ const unsigned vec_elem = x_type->vector_elements;
+ const glsl_type *bvec = glsl_type::get_instance(GLSL_TYPE_BOOL, vec_elem, 1);
+ const glsl_type *uvec = glsl_type::get_instance(GLSL_TYPE_UINT, vec_elem, 1);
+
+ /* Single-precision floating-point values are stored as
+ * 1 sign bit;
+ * 8 exponent bits;
+ * 23 mantissa bits.
+ *
+ * An exponent shift of 23 will shift the mantissa out, leaving only the
+ * exponent and sign bit (which itself may be zero, if the absolute value
+ * was taken before the bitcast and shift.
+ */
+ ir_constant *exponent_shift = imm(23);
+ ir_constant *exponent_bias = imm(-126, vec_elem);
+
+ ir_constant *sign_mantissa_mask = imm(0x807fffffu, vec_elem);
+
+ /* Exponent of floating-point values in the range [0.5, 1.0). */
+ ir_constant *exponent_value = imm(0x3f000000u, vec_elem);
+
+ ir_variable *is_not_zero = body.make_temp(bvec, "is_not_zero");
+ body.emit(assign(is_not_zero, nequal(abs(x), imm(0.0f, vec_elem))));
+
+ /* Since abs(x) ensures that the sign bit is zero, we don't need to bitcast
+ * to unsigned integers to ensure that 1 bits aren't shifted in.
+ */
+ body.emit(assign(exponent, rshift(bitcast_f2i(abs(x)), exponent_shift)));
+ body.emit(assign(exponent, add(exponent, csel(is_not_zero, exponent_bias,
+ imm(0, vec_elem)))));
+
+ ir_variable *bits = body.make_temp(uvec, "bits");
+ body.emit(assign(bits, bitcast_f2u(x)));
+ body.emit(assign(bits, bit_and(bits, sign_mantissa_mask)));
+ body.emit(assign(bits, bit_or(bits, csel(is_not_zero, exponent_value,
+ imm(0u, vec_elem)))));
+ body.emit(ret(bitcast_u2f(bits)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_uaddCarry(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ ir_variable *carry = out_var(type, "carry");
+ MAKE_SIG(type, gpu_shader5, 3, x, y, carry);
+
+ body.emit(assign(carry, ir_builder::carry(x, y)));
+ body.emit(ret(add(x, y)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_usubBorrow(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ ir_variable *borrow = out_var(type, "borrow");
+ MAKE_SIG(type, gpu_shader5, 3, x, y, borrow);
+
+ body.emit(assign(borrow, ir_builder::borrow(x, y)));
+ body.emit(ret(sub(x, y)));
+
+ return sig;
+}
+
+/**
+ * For both imulExtended() and umulExtended() built-ins.
+ */
+ir_function_signature *
+builtin_builder::_mulExtended(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ ir_variable *msb = out_var(type, "msb");
+ ir_variable *lsb = out_var(type, "lsb");
+ MAKE_SIG(glsl_type::void_type, gpu_shader5, 4, x, y, msb, lsb);
+
+ body.emit(assign(msb, imul_high(x, y)));
+ body.emit(assign(lsb, mul(x, y)));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atomic_intrinsic(builtin_available_predicate avail)
+{
+ ir_variable *counter = in_var(glsl_type::atomic_uint_type, "counter");
+ MAKE_INTRINSIC(glsl_type::uint_type, avail, 1, counter);
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atomic_op(const char *intrinsic,
+ builtin_available_predicate avail)
+{
+ ir_variable *counter = in_var(glsl_type::atomic_uint_type, "atomic_counter");
+ MAKE_SIG(glsl_type::uint_type, avail, 1, counter);
+
+ ir_variable *retval = body.make_temp(glsl_type::uint_type, "atomic_retval");
+ body.emit(call(shader->symbols->get_function(intrinsic), retval,
+ sig->parameters));
+ body.emit(ret(retval));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_min3(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ ir_variable *z = in_var(type, "z");
+ MAKE_SIG(type, shader_trinary_minmax, 3, x, y, z);
+
+ ir_expression *min3 = min2(x, min2(y,z));
+ body.emit(ret(min3));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_max3(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ ir_variable *z = in_var(type, "z");
+ MAKE_SIG(type, shader_trinary_minmax, 3, x, y, z);
+
+ ir_expression *max3 = max2(x, max2(y,z));
+ body.emit(ret(max3));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_mid3(const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ ir_variable *y = in_var(type, "y");
+ ir_variable *z = in_var(type, "z");
+ MAKE_SIG(type, shader_trinary_minmax, 3, x, y, z);
+
+ ir_expression *mid3 = max2(min2(x, y), max2(min2(x, z), min2(y, z)));
+ body.emit(ret(mid3));
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_image_prototype(const glsl_type *image_type,
+ const char *intrinsic_name,
+ unsigned num_arguments,
+ unsigned flags)
+{
+ const glsl_type *data_type = glsl_type::get_instance(
+ image_type->sampler_type,
+ (flags & IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE ? 4 : 1),
+ 1);
+ const glsl_type *ret_type = (flags & IMAGE_FUNCTION_RETURNS_VOID ?
+ glsl_type::void_type : data_type);
+
+ /* Addressing arguments that are always present. */
+ ir_variable *image = in_var(image_type, "image");
+ ir_variable *coord = in_var(
+ glsl_type::ivec(image_type->coordinate_components()), "coord");
+
+ ir_function_signature *sig = new_sig(
+ ret_type, shader_image_load_store, 2, image, coord);
+
+ /* Sample index for multisample images. */
+ if (image_type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS)
+ sig->parameters.push_tail(in_var(glsl_type::int_type, "sample"));
+
+ /* Data arguments. */
+ for (unsigned i = 0; i < num_arguments; ++i)
+ sig->parameters.push_tail(in_var(data_type,
+ ralloc_asprintf(NULL, "arg%d", i)));
+
+ /* Set the maximal set of qualifiers allowed for this image
+ * built-in. Function calls with arguments having fewer
+ * qualifiers than present in the prototype are allowed by the
+ * spec, but not with more, i.e. this will make the compiler
+ * accept everything that needs to be accepted, and reject cases
+ * like loads from write-only or stores to read-only images.
+ */
+ image->data.image.read_only = flags & IMAGE_FUNCTION_READ_ONLY;
+ image->data.image.write_only = flags & IMAGE_FUNCTION_WRITE_ONLY;
+ image->data.image.coherent = true;
+ image->data.image._volatile = true;
+ image->data.image.restrict_flag = true;
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_image(const glsl_type *image_type,
+ const char *intrinsic_name,
+ unsigned num_arguments,
+ unsigned flags)
+{
+ ir_function_signature *sig = _image_prototype(image_type, intrinsic_name,
+ num_arguments, flags);
+
+ if (flags & IMAGE_FUNCTION_EMIT_STUB) {
+ ir_factory body(&sig->body, mem_ctx);
+ ir_function *f = shader->symbols->get_function(intrinsic_name);
+
+ if (flags & IMAGE_FUNCTION_RETURNS_VOID) {
+ body.emit(call(f, NULL, sig->parameters));
+ } else {
+ ir_variable *ret_val =
+ body.make_temp(sig->return_type, "_ret_val");
+ body.emit(call(f, ret_val, sig->parameters));
+ body.emit(ret(ret_val));
+ }
+
+ sig->is_defined = true;
+
+ } else {
+ sig->is_intrinsic = true;
+ }
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_memory_barrier_intrinsic(builtin_available_predicate avail)
+{
+ MAKE_INTRINSIC(glsl_type::void_type, avail, 0);
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_memory_barrier(builtin_available_predicate avail)
+{
+ MAKE_SIG(glsl_type::void_type, avail, 0);
+ body.emit(call(shader->symbols->get_function("__intrinsic_memory_barrier"),
+ NULL, sig->parameters));
+ return sig;
+}
+
+/** @} */
+
+/******************************************************************************/
+
+/* The singleton instance of builtin_builder. */
+static builtin_builder builtins;
+static mtx_t builtins_lock = _MTX_INITIALIZER_NP;
+
+/**
+ * External API (exposing the built-in module to the rest of the compiler):
+ * @{
+ */
+void
+_mesa_glsl_initialize_builtin_functions()
+{
+ mtx_lock(&builtins_lock);
+ builtins.initialize();
+ mtx_unlock(&builtins_lock);
+}
+
+void
+_mesa_glsl_release_builtin_functions()
+{
+ mtx_lock(&builtins_lock);
+ builtins.release();
+ mtx_unlock(&builtins_lock);
+}
+
+ir_function_signature *
+_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
+ const char *name, exec_list *actual_parameters)
+{
+ ir_function_signature * s;
+ mtx_lock(&builtins_lock);
+ s = builtins.find(state, name, actual_parameters);
+ mtx_unlock(&builtins_lock);
+ return s;
+}
+
+gl_shader *
+_mesa_glsl_get_builtin_function_shader()
+{
+ return builtins.shader;
+}
+
+/** @} */
diff --git a/dist/Mesa/src/glsl/builtin_type_macros.h b/dist/Mesa/src/glsl/builtin_type_macros.h
index fec38da12..236e1ce8c 100644
--- a/dist/Mesa/src/glsl/builtin_type_macros.h
+++ b/dist/Mesa/src/glsl/builtin_type_macros.h
@@ -64,51 +64,87 @@ DECL_TYPE(mat3x4, GL_FLOAT_MAT3x4, GLSL_TYPE_FLOAT, 4, 3)
DECL_TYPE(mat4x2, GL_FLOAT_MAT4x2, GLSL_TYPE_FLOAT, 2, 4)
DECL_TYPE(mat4x3, GL_FLOAT_MAT4x3, GLSL_TYPE_FLOAT, 3, 4)
-DECL_TYPE(sampler1D, GL_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2D, GL_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler3D, GL_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(samplerCube, GL_SAMPLER_CUBE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler1DArray, GL_SAMPLER_1D_ARRAY, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DArray, GL_SAMPLER_2D_ARRAY, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT)
-DECL_TYPE(samplerCubeArray, GL_SAMPLER_CUBE_MAP_ARRAY, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DRect, GL_SAMPLER_2D_RECT, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(samplerBuffer, GL_SAMPLER_BUFFER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DMS, GL_SAMPLER_2D_MULTISAMPLE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DMSArray, GL_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT)
-
-DECL_TYPE(isampler1D, GL_INT_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isampler2D, GL_INT_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isampler3D, GL_INT_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isamplerCube, GL_INT_SAMPLER_CUBE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isampler1DArray, GL_INT_SAMPLER_1D_ARRAY, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT)
-DECL_TYPE(isampler2DArray, GL_INT_SAMPLER_2D_ARRAY, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT)
-DECL_TYPE(isamplerCubeArray, GL_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_INT)
-DECL_TYPE(isampler2DRect, GL_INT_SAMPLER_2D_RECT, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isamplerBuffer, GL_INT_SAMPLER_BUFFER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isampler2DMS, GL_INT_SAMPLER_2D_MULTISAMPLE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT)
-DECL_TYPE(isampler2DMSArray, GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT)
-
-DECL_TYPE(usampler1D, GL_UNSIGNED_INT_SAMPLER_1D, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usampler2D, GL_UNSIGNED_INT_SAMPLER_2D, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usampler3D, GL_UNSIGNED_INT_SAMPLER_3D, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usamplerCube, GL_INT_SAMPLER_CUBE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usampler1DArray, GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT)
-DECL_TYPE(usampler2DArray, GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT)
-DECL_TYPE(usamplerCubeArray, GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT)
-DECL_TYPE(usampler2DRect, GL_UNSIGNED_INT_SAMPLER_2D_RECT, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usamplerBuffer, GL_UNSIGNED_INT_SAMPLER_BUFFER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usampler2DMS, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT)
-DECL_TYPE(usampler2DMSArray, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT)
-
-DECL_TYPE(sampler1DShadow, GL_SAMPLER_1D_SHADOW, GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DShadow, GL_SAMPLER_2D_SHADOW, GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(samplerCubeShadow, GL_SAMPLER_CUBE_SHADOW, GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler1DArrayShadow, GL_SAMPLER_1D_ARRAY_SHADOW, GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DArrayShadow, GL_SAMPLER_2D_ARRAY_SHADOW, GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT)
-DECL_TYPE(samplerCubeArrayShadow, GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, GLSL_SAMPLER_DIM_CUBE, 1, 1, GLSL_TYPE_FLOAT)
-DECL_TYPE(sampler2DRectShadow, GL_SAMPLER_2D_RECT_SHADOW, GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT)
-
-DECL_TYPE(samplerExternalOES, GL_SAMPLER_EXTERNAL_OES, GLSL_SAMPLER_DIM_EXTERNAL, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler1D, GL_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2D, GL_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler3D, GL_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCube, GL_SAMPLER_CUBE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler1DArray, GL_SAMPLER_1D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DArray, GL_SAMPLER_2D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCubeArray, GL_SAMPLER_CUBE_MAP_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DRect, GL_SAMPLER_2D_RECT, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerBuffer, GL_SAMPLER_BUFFER, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DMS, GL_SAMPLER_2D_MULTISAMPLE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DMSArray, GL_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT)
+
+DECL_TYPE(isampler1D, GL_INT_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler2D, GL_INT_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler3D, GL_INT_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isamplerCube, GL_INT_SAMPLER_CUBE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler1DArray, GL_INT_SAMPLER_1D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DArray, GL_INT_SAMPLER_2D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT)
+DECL_TYPE(isamplerCubeArray, GL_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DRect, GL_INT_SAMPLER_2D_RECT, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isamplerBuffer, GL_INT_SAMPLER_BUFFER, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DMS, GL_INT_SAMPLER_2D_MULTISAMPLE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT)
+DECL_TYPE(isampler2DMSArray, GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT)
+
+DECL_TYPE(usampler1D, GL_UNSIGNED_INT_SAMPLER_1D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2D, GL_UNSIGNED_INT_SAMPLER_2D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler3D, GL_UNSIGNED_INT_SAMPLER_3D, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usamplerCube, GL_UNSIGNED_INT_SAMPLER_CUBE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler1DArray, GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DArray, GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT)
+DECL_TYPE(usamplerCubeArray, GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DRect, GL_UNSIGNED_INT_SAMPLER_2D_RECT, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usamplerBuffer, GL_UNSIGNED_INT_SAMPLER_BUFFER, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DMS, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT)
+DECL_TYPE(usampler2DMSArray, GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT)
+
+DECL_TYPE(sampler1DShadow, GL_SAMPLER_1D_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 1, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DShadow, GL_SAMPLER_2D_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 1, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCubeShadow, GL_SAMPLER_CUBE_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 1, 0, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler1DArrayShadow, GL_SAMPLER_1D_ARRAY_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_1D, 1, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DArrayShadow, GL_SAMPLER_2D_ARRAY_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_2D, 1, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(samplerCubeArrayShadow, GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_CUBE, 1, 1, GLSL_TYPE_FLOAT)
+DECL_TYPE(sampler2DRectShadow, GL_SAMPLER_2D_RECT_SHADOW, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_RECT, 1, 0, GLSL_TYPE_FLOAT)
+
+DECL_TYPE(samplerExternalOES, GL_SAMPLER_EXTERNAL_OES, GLSL_TYPE_SAMPLER, GLSL_SAMPLER_DIM_EXTERNAL, 0, 0, GLSL_TYPE_FLOAT)
+
+DECL_TYPE(image1D, GL_IMAGE_1D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2D, GL_IMAGE_2D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image3D, GL_IMAGE_3D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DRect, GL_IMAGE_2D_RECT, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(imageCube, GL_IMAGE_CUBE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(imageBuffer, GL_IMAGE_BUFFER, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image1DArray, GL_IMAGE_1D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DArray, GL_IMAGE_2D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(imageCubeArray, GL_IMAGE_CUBE_MAP_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DMS, GL_IMAGE_2D_MULTISAMPLE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_FLOAT);
+DECL_TYPE(image2DMSArray, GL_IMAGE_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_FLOAT);
+DECL_TYPE(iimage1D, GL_INT_IMAGE_1D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage2D, GL_INT_IMAGE_2D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage3D, GL_INT_IMAGE_3D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DRect, GL_INT_IMAGE_2D_RECT, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimageCube, GL_INT_IMAGE_CUBE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimageBuffer, GL_INT_IMAGE_BUFFER, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage1DArray, GL_INT_IMAGE_1D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DArray, GL_INT_IMAGE_2D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(iimageCubeArray, GL_INT_IMAGE_CUBE_MAP_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DMS, GL_INT_IMAGE_2D_MULTISAMPLE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_INT);
+DECL_TYPE(iimage2DMSArray, GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_INT);
+DECL_TYPE(uimage1D, GL_UNSIGNED_INT_IMAGE_1D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2D, GL_UNSIGNED_INT_IMAGE_2D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage3D, GL_UNSIGNED_INT_IMAGE_3D, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_3D, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DRect, GL_UNSIGNED_INT_IMAGE_2D_RECT, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_RECT, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimageCube, GL_UNSIGNED_INT_IMAGE_CUBE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimageBuffer, GL_UNSIGNED_INT_IMAGE_BUFFER, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_BUF, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage1DArray, GL_UNSIGNED_INT_IMAGE_1D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_1D, 0, 1, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DArray, GL_UNSIGNED_INT_IMAGE_2D_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_2D, 0, 1, GLSL_TYPE_UINT);
+DECL_TYPE(uimageCubeArray, GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_CUBE, 0, 1, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DMS, GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 0, GLSL_TYPE_UINT);
+DECL_TYPE(uimage2DMSArray, GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY, GLSL_TYPE_IMAGE, GLSL_SAMPLER_DIM_MS, 0, 1, GLSL_TYPE_UINT);
+
+DECL_TYPE(atomic_uint, GL_UNSIGNED_INT_ATOMIC_COUNTER, GLSL_TYPE_ATOMIC_UINT, 1, 1)
STRUCT_TYPE(gl_DepthRangeParameters)
STRUCT_TYPE(gl_PointParameters)
diff --git a/dist/Mesa/src/glsl/builtin_types.cpp b/dist/Mesa/src/glsl/builtin_types.cpp
index 722eda2da..0a0fa8cd3 100644
--- a/dist/Mesa/src/glsl/builtin_types.cpp
+++ b/dist/Mesa/src/glsl/builtin_types.cpp
@@ -53,64 +53,64 @@
&glsl_type::_struct_##NAME##_type;
static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = {
- { glsl_type::float_type, "near", false },
- { glsl_type::float_type, "far", false },
- { glsl_type::float_type, "diff", false },
+ { glsl_type::float_type, "near", false, -1 },
+ { glsl_type::float_type, "far", false, -1 },
+ { glsl_type::float_type, "diff", false, -1 },
};
static const struct glsl_struct_field gl_PointParameters_fields[] = {
- { glsl_type::float_type, "size", false },
- { glsl_type::float_type, "sizeMin", false },
- { glsl_type::float_type, "sizeMax", false },
- { glsl_type::float_type, "fadeThresholdSize", false },
- { glsl_type::float_type, "distanceConstantAttenuation", false },
- { glsl_type::float_type, "distanceLinearAttenuation", false },
- { glsl_type::float_type, "distanceQuadraticAttenuation", false },
+ { glsl_type::float_type, "size", false, -1 },
+ { glsl_type::float_type, "sizeMin", false, -1 },
+ { glsl_type::float_type, "sizeMax", false, -1 },
+ { glsl_type::float_type, "fadeThresholdSize", false, -1 },
+ { glsl_type::float_type, "distanceConstantAttenuation", false, -1 },
+ { glsl_type::float_type, "distanceLinearAttenuation", false, -1 },
+ { glsl_type::float_type, "distanceQuadraticAttenuation", false, -1 },
};
static const struct glsl_struct_field gl_MaterialParameters_fields[] = {
- { glsl_type::vec4_type, "emission", false },
- { glsl_type::vec4_type, "ambient", false },
- { glsl_type::vec4_type, "diffuse", false },
- { glsl_type::vec4_type, "specular", false },
- { glsl_type::float_type, "shininess", false },
+ { glsl_type::vec4_type, "emission", false, -1 },
+ { glsl_type::vec4_type, "ambient", false, -1 },
+ { glsl_type::vec4_type, "diffuse", false, -1 },
+ { glsl_type::vec4_type, "specular", false, -1 },
+ { glsl_type::float_type, "shininess", false, -1 },
};
static const struct glsl_struct_field gl_LightSourceParameters_fields[] = {
- { glsl_type::vec4_type, "ambient", false },
- { glsl_type::vec4_type, "diffuse", false },
- { glsl_type::vec4_type, "specular", false },
- { glsl_type::vec4_type, "position", false },
- { glsl_type::vec4_type, "halfVector", false },
- { glsl_type::vec3_type, "spotDirection", false },
- { glsl_type::float_type, "spotExponent", false },
- { glsl_type::float_type, "spotCutoff", false },
- { glsl_type::float_type, "spotCosCutoff", false },
- { glsl_type::float_type, "constantAttenuation", false },
- { glsl_type::float_type, "linearAttenuation", false },
- { glsl_type::float_type, "quadraticAttenuation", false },
+ { glsl_type::vec4_type, "ambient", false, -1 },
+ { glsl_type::vec4_type, "diffuse", false, -1 },
+ { glsl_type::vec4_type, "specular", false, -1 },
+ { glsl_type::vec4_type, "position", false, -1 },
+ { glsl_type::vec4_type, "halfVector", false, -1 },
+ { glsl_type::vec3_type, "spotDirection", false, -1 },
+ { glsl_type::float_type, "spotExponent", false, -1 },
+ { glsl_type::float_type, "spotCutoff", false, -1 },
+ { glsl_type::float_type, "spotCosCutoff", false, -1 },
+ { glsl_type::float_type, "constantAttenuation", false, -1 },
+ { glsl_type::float_type, "linearAttenuation", false, -1 },
+ { glsl_type::float_type, "quadraticAttenuation", false, -1 },
};
static const struct glsl_struct_field gl_LightModelParameters_fields[] = {
- { glsl_type::vec4_type, "ambient", false },
+ { glsl_type::vec4_type, "ambient", false, -1 },
};
static const struct glsl_struct_field gl_LightModelProducts_fields[] = {
- { glsl_type::vec4_type, "sceneColor", false },
+ { glsl_type::vec4_type, "sceneColor", false, -1 },
};
static const struct glsl_struct_field gl_LightProducts_fields[] = {
- { glsl_type::vec4_type, "ambient", false },
- { glsl_type::vec4_type, "diffuse", false },
- { glsl_type::vec4_type, "specular", false },
+ { glsl_type::vec4_type, "ambient", false, -1 },
+ { glsl_type::vec4_type, "diffuse", false, -1 },
+ { glsl_type::vec4_type, "specular", false, -1 },
};
static const struct glsl_struct_field gl_FogParameters_fields[] = {
- { glsl_type::vec4_type, "color", false },
- { glsl_type::float_type, "density", false },
- { glsl_type::float_type, "start", false },
- { glsl_type::float_type, "end", false },
- { glsl_type::float_type, "scale", false },
+ { glsl_type::vec4_type, "color", false, -1 },
+ { glsl_type::float_type, "density", false, -1 },
+ { glsl_type::float_type, "start", false, -1 },
+ { glsl_type::float_type, "end", false, -1 },
+ { glsl_type::float_type, "scale", false, -1 },
};
#include "builtin_type_macros.h"
@@ -203,9 +203,45 @@ const static struct builtin_type_versions {
T(sampler2DRectShadow, 140, 999)
T(struct_gl_DepthRangeParameters, 110, 100)
+
+ T(image1D, 420, 999)
+ T(image2D, 420, 999)
+ T(image3D, 420, 999)
+ T(image2DRect, 420, 999)
+ T(imageCube, 420, 999)
+ T(imageBuffer, 420, 999)
+ T(image1DArray, 420, 999)
+ T(image2DArray, 420, 999)
+ T(imageCubeArray, 420, 999)
+ T(image2DMS, 420, 999)
+ T(image2DMSArray, 420, 999)
+ T(iimage1D, 420, 999)
+ T(iimage2D, 420, 999)
+ T(iimage3D, 420, 999)
+ T(iimage2DRect, 420, 999)
+ T(iimageCube, 420, 999)
+ T(iimageBuffer, 420, 999)
+ T(iimage1DArray, 420, 999)
+ T(iimage2DArray, 420, 999)
+ T(iimageCubeArray, 420, 999)
+ T(iimage2DMS, 420, 999)
+ T(iimage2DMSArray, 420, 999)
+ T(uimage1D, 420, 999)
+ T(uimage2D, 420, 999)
+ T(uimage3D, 420, 999)
+ T(uimage2DRect, 420, 999)
+ T(uimageCube, 420, 999)
+ T(uimageBuffer, 420, 999)
+ T(uimage1DArray, 420, 999)
+ T(uimage2DArray, 420, 999)
+ T(uimageCubeArray, 420, 999)
+ T(uimage2DMS, 420, 999)
+ T(uimage2DMSArray, 420, 999)
+
+ T(atomic_uint, 420, 999)
};
-const glsl_type *const deprecated_types[] = {
+static const glsl_type *const deprecated_types[] = {
glsl_type::struct_gl_PointParameters_type,
glsl_type::struct_gl_MaterialParameters_type,
glsl_type::struct_gl_LightSourceParameters_type,
@@ -284,5 +320,45 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
if (state->OES_texture_3D_enable) {
add_type(symbols, glsl_type::sampler3D_type);
}
+
+ if (state->ARB_shader_image_load_store_enable) {
+ add_type(symbols, glsl_type::image1D_type);
+ add_type(symbols, glsl_type::image2D_type);
+ add_type(symbols, glsl_type::image3D_type);
+ add_type(symbols, glsl_type::image2DRect_type);
+ add_type(symbols, glsl_type::imageCube_type);
+ add_type(symbols, glsl_type::imageBuffer_type);
+ add_type(symbols, glsl_type::image1DArray_type);
+ add_type(symbols, glsl_type::image2DArray_type);
+ add_type(symbols, glsl_type::imageCubeArray_type);
+ add_type(symbols, glsl_type::image2DMS_type);
+ add_type(symbols, glsl_type::image2DMSArray_type);
+ add_type(symbols, glsl_type::iimage1D_type);
+ add_type(symbols, glsl_type::iimage2D_type);
+ add_type(symbols, glsl_type::iimage3D_type);
+ add_type(symbols, glsl_type::iimage2DRect_type);
+ add_type(symbols, glsl_type::iimageCube_type);
+ add_type(symbols, glsl_type::iimageBuffer_type);
+ add_type(symbols, glsl_type::iimage1DArray_type);
+ add_type(symbols, glsl_type::iimage2DArray_type);
+ add_type(symbols, glsl_type::iimageCubeArray_type);
+ add_type(symbols, glsl_type::iimage2DMS_type);
+ add_type(symbols, glsl_type::iimage2DMSArray_type);
+ add_type(symbols, glsl_type::uimage1D_type);
+ add_type(symbols, glsl_type::uimage2D_type);
+ add_type(symbols, glsl_type::uimage3D_type);
+ add_type(symbols, glsl_type::uimage2DRect_type);
+ add_type(symbols, glsl_type::uimageCube_type);
+ add_type(symbols, glsl_type::uimageBuffer_type);
+ add_type(symbols, glsl_type::uimage1DArray_type);
+ add_type(symbols, glsl_type::uimage2DArray_type);
+ add_type(symbols, glsl_type::uimageCubeArray_type);
+ add_type(symbols, glsl_type::uimage2DMS_type);
+ add_type(symbols, glsl_type::uimage2DMSArray_type);
+ }
+
+ if (state->ARB_shader_atomic_counters_enable) {
+ add_type(symbols, glsl_type::atomic_uint_type);
+ }
}
/** @} */
diff --git a/dist/Mesa/src/glsl/builtin_variables.cpp b/dist/Mesa/src/glsl/builtin_variables.cpp
index 1e88b6a73..9b35850ee 100644
--- a/dist/Mesa/src/glsl/builtin_variables.cpp
+++ b/dist/Mesa/src/glsl/builtin_variables.cpp
@@ -30,18 +30,21 @@
#include "program/prog_statevars.h"
#include "program/prog_instruction.h"
+static const struct gl_builtin_uniform_element gl_NumSamples_elements[] = {
+ {NULL, {STATE_NUM_SAMPLES, 0, 0}, SWIZZLE_XXXX}
+};
-static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
+static const struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
{"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
{"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
{"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
};
-static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = {
+static const struct gl_builtin_uniform_element gl_ClipPlane_elements[] = {
{NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
};
-static struct gl_builtin_uniform_element gl_Point_elements[] = {
+static const struct gl_builtin_uniform_element gl_Point_elements[] = {
{"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
{"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
{"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
@@ -51,7 +54,7 @@ static struct gl_builtin_uniform_element gl_Point_elements[] = {
{"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
};
-static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
+static const struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
{"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
{"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
{"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
@@ -59,7 +62,7 @@ static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
{"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
};
-static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
+static const struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
{"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
{"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
{"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
@@ -67,7 +70,7 @@ static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
{"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
};
-static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
+static const struct gl_builtin_uniform_element gl_LightSource_elements[] = {
{"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
{"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
{"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
@@ -86,67 +89,67 @@ static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
{"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
};
-static struct gl_builtin_uniform_element gl_LightModel_elements[] = {
+static const struct gl_builtin_uniform_element gl_LightModel_elements[] = {
{"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
+static const struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
{"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = {
+static const struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = {
{"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
+static const struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
{"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
{"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
{"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
+static const struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
{"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
{"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
{"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
+static const struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
{NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = {
+static const struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = {
+static const struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = {
+static const struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = {
+static const struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = {
+static const struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = {
+static const struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = {
+static const struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = {
+static const struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = {
{NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_Fog_elements[] = {
+static const struct gl_builtin_uniform_element gl_Fog_elements[] = {
{"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
{"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
{"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
@@ -154,32 +157,32 @@ static struct gl_builtin_uniform_element gl_Fog_elements[] = {
{"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
};
-static struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
+static const struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
{NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX},
};
-static struct gl_builtin_uniform_element gl_BumpRotMatrix0MESA_elements[] = {
+static const struct gl_builtin_uniform_element gl_BumpRotMatrix0MESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_0}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_BumpRotMatrix1MESA_elements[] = {
+static const struct gl_builtin_uniform_element gl_BumpRotMatrix1MESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_ROT_MATRIX_1}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = {
+static const struct gl_builtin_uniform_element gl_FogParamsOptimizedMESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = {
+static const struct gl_builtin_uniform_element gl_CurrentAttribVertMESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB, 0}, SWIZZLE_XYZW},
};
-static struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = {
+static const struct gl_builtin_uniform_element gl_CurrentAttribFragMESA_elements[] = {
{NULL, {STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, 0}, SWIZZLE_XYZW},
};
#define MATRIX(name, statevar, modifier) \
- static struct gl_builtin_uniform_element name ## _elements[] = { \
+ static const struct gl_builtin_uniform_element name ## _elements[] = { \
{ NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \
{ NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \
{ NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \
@@ -222,7 +225,7 @@ MATRIX(gl_TextureMatrixTranspose,
MATRIX(gl_TextureMatrixInverseTranspose,
STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
-static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
+static const struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z) },
{ NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
@@ -236,6 +239,7 @@ static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
+ STATEVAR(gl_NumSamples),
STATEVAR(gl_DepthRange),
STATEVAR(gl_ClipPlane),
STATEVAR(gl_Point),
@@ -293,6 +297,55 @@ static const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
namespace {
+/**
+ * Data structure that accumulates fields for the gl_PerVertex interface
+ * block.
+ */
+class per_vertex_accumulator
+{
+public:
+ per_vertex_accumulator();
+ void add_field(int slot, const glsl_type *type, const char *name);
+ const glsl_type *construct_interface_instance() const;
+
+private:
+ glsl_struct_field fields[10];
+ unsigned num_fields;
+};
+
+
+per_vertex_accumulator::per_vertex_accumulator()
+ : fields(),
+ num_fields(0)
+{
+}
+
+
+void
+per_vertex_accumulator::add_field(int slot, const glsl_type *type,
+ const char *name)
+{
+ assert(this->num_fields < ARRAY_SIZE(this->fields));
+ this->fields[this->num_fields].type = type;
+ this->fields[this->num_fields].name = name;
+ this->fields[this->num_fields].row_major = false;
+ this->fields[this->num_fields].location = slot;
+ this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE;
+ this->fields[this->num_fields].centroid = 0;
+ this->fields[this->num_fields].sample = 0;
+ this->num_fields++;
+}
+
+
+const glsl_type *
+per_vertex_accumulator::construct_interface_instance() const
+{
+ return glsl_type::get_interface_instance(this->fields, this->num_fields,
+ GLSL_INTERFACE_PACKING_STD140,
+ "gl_PerVertex");
+}
+
+
class builtin_variable_generator
{
public:
@@ -303,6 +356,7 @@ public:
void generate_vs_special_vars();
void generate_gs_special_vars();
void generate_fs_special_vars();
+ void generate_cs_special_vars();
void generate_varyings();
private:
@@ -336,6 +390,7 @@ private:
enum ir_variable_mode mode, int slot);
ir_variable *add_uniform(const glsl_type *type, const char *name);
ir_variable *add_const(const char *name, int value);
+ ir_variable *add_const_ivec3(const char *name, int x, int y, int z);
void add_varying(int slot, const glsl_type *type, const char *name,
const char *name_as_gs_input);
@@ -358,6 +413,9 @@ private:
const glsl_type * const vec4_t;
const glsl_type * const mat3_t;
const glsl_type * const mat4_t;
+
+ per_vertex_accumulator per_vertex_in;
+ per_vertex_accumulator per_vertex_out;
};
@@ -379,13 +437,14 @@ builtin_variable_generator::add_variable(const char *name,
enum ir_variable_mode mode, int slot)
{
ir_variable *var = new(symtab) ir_variable(type, name, mode);
+ var->data.how_declared = ir_var_declared_implicitly;
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_auto:
case ir_var_shader_in:
case ir_var_uniform:
case ir_var_system_value:
- var->read_only = true;
+ var->data.read_only = true;
break;
case ir_var_shader_out:
break;
@@ -398,9 +457,9 @@ builtin_variable_generator::add_variable(const char *name,
break;
}
- var->location = slot;
- var->explicit_location = (slot >= 0);
- var->explicit_index = 0;
+ var->data.location = slot;
+ var->data.explicit_location = (slot >= 0);
+ var->data.explicit_index = 0;
/* Once the variable is created an initialized, add it to the symbol table
* and add the declaration to the IR stream.
@@ -439,7 +498,8 @@ builtin_variable_generator::add_uniform(const glsl_type *type,
for (unsigned a = 0; a < array_count; a++) {
for (unsigned j = 0; j < statevar->num_elements; j++) {
- struct gl_builtin_uniform_element *element = &statevar->elements[j];
+ const struct gl_builtin_uniform_element *element =
+ &statevar->elements[j];
memcpy(slots->tokens, element->tokens, sizeof(element->tokens));
if (type->is_array()) {
@@ -467,7 +527,26 @@ builtin_variable_generator::add_const(const char *name, int value)
ir_var_auto, -1);
var->constant_value = new(var) ir_constant(value);
var->constant_initializer = new(var) ir_constant(value);
- var->has_initializer = true;
+ var->data.has_initializer = true;
+ return var;
+}
+
+
+ir_variable *
+builtin_variable_generator::add_const_ivec3(const char *name, int x, int y,
+ int z)
+{
+ ir_variable *const var = add_variable(name, glsl_type::ivec3_type,
+ ir_var_auto, -1);
+ ir_constant_data data;
+ memset(&data, 0, sizeof(data));
+ data.i[0] = x;
+ data.i[1] = y;
+ data.i[2] = z;
+ var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
+ var->constant_initializer =
+ new(var) ir_constant(glsl_type::ivec3_type, &data);
+ var->data.has_initializer = true;
return var;
}
@@ -497,11 +576,12 @@ builtin_variable_generator::generate_constants()
*/
if (state->is_version(0, 300)) {
add_const("gl_MaxVertexOutputVectors",
- state->Const.MaxVaryingFloats / 4);
+ state->ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4);
add_const("gl_MaxFragmentInputVectors",
- state->Const.MaxVaryingFloats / 4);
+ state->ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4);
} else {
- add_const("gl_MaxVaryingVectors", state->Const.MaxVaryingFloats / 4);
+ add_const("gl_MaxVaryingVectors",
+ state->ctx->Const.MaxVarying);
}
} else {
add_const("gl_MaxVertexUniformComponents",
@@ -510,7 +590,7 @@ builtin_variable_generator::generate_constants()
/* Note: gl_MaxVaryingFloats was deprecated in GLSL 1.30+, but not
* removed
*/
- add_const("gl_MaxVaryingFloats", state->Const.MaxVaryingFloats);
+ add_const("gl_MaxVaryingFloats", state->ctx->Const.MaxVarying * 4);
add_const("gl_MaxFragmentUniformComponents",
state->Const.MaxFragmentUniformComponents);
@@ -531,7 +611,38 @@ builtin_variable_generator::generate_constants()
if (state->is_version(130, 0)) {
add_const("gl_MaxClipDistances", state->Const.MaxClipPlanes);
- add_const("gl_MaxVaryingComponents", state->Const.MaxVaryingFloats);
+ add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4);
+ }
+
+ if (state->is_version(150, 0)) {
+ add_const("gl_MaxVertexOutputComponents",
+ state->Const.MaxVertexOutputComponents);
+ add_const("gl_MaxGeometryInputComponents",
+ state->Const.MaxGeometryInputComponents);
+ add_const("gl_MaxGeometryOutputComponents",
+ state->Const.MaxGeometryOutputComponents);
+ add_const("gl_MaxFragmentInputComponents",
+ state->Const.MaxFragmentInputComponents);
+ add_const("gl_MaxGeometryTextureImageUnits",
+ state->Const.MaxGeometryTextureImageUnits);
+ add_const("gl_MaxGeometryOutputVertices",
+ state->Const.MaxGeometryOutputVertices);
+ add_const("gl_MaxGeometryTotalOutputComponents",
+ state->Const.MaxGeometryTotalOutputComponents);
+ add_const("gl_MaxGeometryUniformComponents",
+ state->Const.MaxGeometryUniformComponents);
+
+ /* Note: the GLSL 1.50-4.40 specs require
+ * gl_MaxGeometryVaryingComponents to be present, and to be at least 64.
+ * But they do not define what it means (and there does not appear to be
+ * any corresponding constant in the GL specs). However,
+ * ARB_geometry_shader4 defines MAX_GEOMETRY_VARYING_COMPONENTS_ARB to
+ * be the maximum number of components available for use as geometry
+ * outputs. So we assume this is a synonym for
+ * gl_MaxGeometryOutputComponents.
+ */
+ add_const("gl_MaxGeometryVaryingComponents",
+ state->Const.MaxGeometryOutputComponents);
}
if (compatibility) {
@@ -555,6 +666,72 @@ builtin_variable_generator::generate_constants()
*/
add_const("gl_MaxTextureCoords", state->Const.MaxTextureCoords);
}
+
+ if (state->ARB_shader_atomic_counters_enable) {
+ add_const("gl_MaxVertexAtomicCounters",
+ state->Const.MaxVertexAtomicCounters);
+ add_const("gl_MaxGeometryAtomicCounters",
+ state->Const.MaxGeometryAtomicCounters);
+ add_const("gl_MaxFragmentAtomicCounters",
+ state->Const.MaxFragmentAtomicCounters);
+ add_const("gl_MaxCombinedAtomicCounters",
+ state->Const.MaxCombinedAtomicCounters);
+ add_const("gl_MaxAtomicCounterBindings",
+ state->Const.MaxAtomicBufferBindings);
+ add_const("gl_MaxTessControlAtomicCounters", 0);
+ add_const("gl_MaxTessEvaluationAtomicCounters", 0);
+ }
+
+ if (state->is_version(430, 0) || state->ARB_compute_shader_enable) {
+ add_const_ivec3("gl_MaxComputeWorkGroupCount",
+ state->Const.MaxComputeWorkGroupCount[0],
+ state->Const.MaxComputeWorkGroupCount[1],
+ state->Const.MaxComputeWorkGroupCount[2]);
+ add_const_ivec3("gl_MaxComputeWorkGroupSize",
+ state->Const.MaxComputeWorkGroupSize[0],
+ state->Const.MaxComputeWorkGroupSize[1],
+ state->Const.MaxComputeWorkGroupSize[2]);
+
+ /* From the GLSL 4.40 spec, section 7.1 (Built-In Language Variables):
+ *
+ * The built-in constant gl_WorkGroupSize is a compute-shader
+ * constant containing the local work-group size of the shader. The
+ * size of the work group in the X, Y, and Z dimensions is stored in
+ * the x, y, and z components. The constants values in
+ * gl_WorkGroupSize will match those specified in the required
+ * local_size_x, local_size_y, and local_size_z layout qualifiers
+ * for the current shader. This is a constant so that it can be
+ * used to size arrays of memory that can be shared within the local
+ * work group. It is a compile-time error to use gl_WorkGroupSize
+ * in a shader that does not declare a fixed local group size, or
+ * before that shader has declared a fixed local group size, using
+ * local_size_x, local_size_y, and local_size_z.
+ *
+ * To prevent the shader from trying to refer to gl_WorkGroupSize before
+ * the layout declaration, we don't define it here. Intead we define it
+ * in ast_cs_input_layout::hir().
+ */
+ }
+
+ if (state->is_version(420, 0) ||
+ state->ARB_shader_image_load_store_enable) {
+ add_const("gl_MaxImageUnits",
+ state->Const.MaxImageUnits);
+ add_const("gl_MaxCombinedImageUnitsAndFragmentOutputs",
+ state->Const.MaxCombinedImageUnitsAndFragmentOutputs);
+ add_const("gl_MaxImageSamples",
+ state->Const.MaxImageSamples);
+ add_const("gl_MaxVertexImageUniforms",
+ state->Const.MaxVertexImageUniforms);
+ add_const("gl_MaxTessControlImageUniforms", 0);
+ add_const("gl_MaxTessEvaluationImageUniforms", 0);
+ add_const("gl_MaxGeometryImageUniforms",
+ state->Const.MaxGeometryImageUniforms);
+ add_const("gl_MaxFragmentImageUniforms",
+ state->Const.MaxFragmentImageUniforms);
+ add_const("gl_MaxCombinedImageUniforms",
+ state->Const.MaxCombinedImageUniforms);
+ }
}
@@ -564,6 +741,7 @@ builtin_variable_generator::generate_constants()
void
builtin_variable_generator::generate_uniforms()
{
+ add_uniform(int_t, "gl_NumSamples");
add_uniform(type("gl_DepthRangeParameters"), "gl_DepthRange");
add_uniform(array(vec4_t, VERT_ATTRIB_MAX), "gl_CurrentAttribVertMESA");
add_uniform(array(vec4_t, VARYING_SLOT_MAX), "gl_CurrentAttribFragMESA");
@@ -675,6 +853,10 @@ void
builtin_variable_generator::generate_gs_special_vars()
{
add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer");
+ if (state->ARB_viewport_array_enable)
+ add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex");
+ if (state->ARB_gpu_shader5_enable)
+ add_system_value(SYSTEM_VALUE_INVOCATION_ID, int_t, "gl_InvocationID");
/* Although gl_PrimitiveID appears in tessellation control and tessellation
* evaluation shaders, it has a different function there than it has in
@@ -686,8 +868,11 @@ builtin_variable_generator::generate_gs_special_vars()
* the specific case of gl_PrimitiveIDIn. So we don't need to treat
* gl_PrimitiveIDIn as an {ARB,EXT}_geometry_shader4-only variable.
*/
- add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn");
- add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
+ ir_variable *var;
+ var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn");
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
+ var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
@@ -702,6 +887,12 @@ builtin_variable_generator::generate_fs_special_vars()
if (state->is_version(120, 100))
add_input(VARYING_SLOT_PNTC, vec2_t, "gl_PointCoord");
+ if (state->is_version(150, 0)) {
+ ir_variable *var =
+ add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
+ }
+
/* gl_FragColor and gl_FragData were deprecated starting in desktop GLSL
* 1.30, and were relegated to the compatibility profile in GLSL 4.20.
* They were removed from GLSL ES 3.00.
@@ -731,6 +922,33 @@ builtin_variable_generator::generate_fs_special_vars()
if (state->AMD_shader_stencil_export_warn)
var->warn_extension = "GL_AMD_shader_stencil_export";
}
+
+ if (state->ARB_sample_shading_enable) {
+ add_system_value(SYSTEM_VALUE_SAMPLE_ID, int_t, "gl_SampleID");
+ add_system_value(SYSTEM_VALUE_SAMPLE_POS, vec2_t, "gl_SamplePosition");
+ /* From the ARB_sample_shading specification:
+ * "The number of elements in the array is ceil(<s>/32), where
+ * <s> is the maximum number of color samples supported by the
+ * implementation."
+ * Since no drivers expose more than 32x MSAA, we can simply set
+ * the array size to 1 rather than computing it.
+ */
+ add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask");
+ }
+
+ if (state->ARB_gpu_shader5_enable) {
+ add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), "gl_SampleMaskIn");
+ }
+}
+
+
+/**
+ * Generate variables which only exist in compute shaders.
+ */
+void
+builtin_variable_generator::generate_cs_special_vars()
+{
+ /* TODO: finish this. */
}
@@ -745,16 +963,19 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type,
const char *name,
const char *name_as_gs_input)
{
- switch (state->target) {
- case geometry_shader:
- add_input(slot, array(type, 0), name_as_gs_input);
+ switch (state->stage) {
+ case MESA_SHADER_GEOMETRY:
+ this->per_vertex_in.add_field(slot, type, name);
/* FALLTHROUGH */
- case vertex_shader:
- add_output(slot, type, name);
+ case MESA_SHADER_VERTEX:
+ this->per_vertex_out.add_field(slot, type, name);
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
add_input(slot, type, name);
break;
+ case MESA_SHADER_COMPUTE:
+ /* Compute shaders don't have varyings. */
+ break;
}
}
@@ -770,7 +991,7 @@ builtin_variable_generator::generate_varyings()
add_varying(loc, type, name, name "In")
/* gl_Position and gl_PointSize are not visible from fragment shaders. */
- if (state->target != fragment_shader) {
+ if (state->stage != MESA_SHADER_FRAGMENT) {
ADD_VARYING(VARYING_SLOT_POS, vec4_t, "gl_Position");
ADD_VARYING(VARYING_SLOT_PSIZ, float_t, "gl_PointSize");
}
@@ -783,7 +1004,7 @@ builtin_variable_generator::generate_varyings()
if (compatibility) {
ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord");
ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord");
- if (state->target == fragment_shader) {
+ if (state->stage == MESA_SHADER_FRAGMENT) {
ADD_VARYING(VARYING_SLOT_COL0, vec4_t, "gl_Color");
ADD_VARYING(VARYING_SLOT_COL1, vec4_t, "gl_SecondaryColor");
} else {
@@ -794,6 +1015,27 @@ builtin_variable_generator::generate_varyings()
ADD_VARYING(VARYING_SLOT_BFC1, vec4_t, "gl_BackSecondaryColor");
}
}
+
+ if (state->stage == MESA_SHADER_GEOMETRY) {
+ const glsl_type *per_vertex_in_type =
+ this->per_vertex_in.construct_interface_instance();
+ add_variable("gl_in", array(per_vertex_in_type, 0),
+ ir_var_shader_in, -1);
+ }
+ if (state->stage == MESA_SHADER_VERTEX || state->stage == MESA_SHADER_GEOMETRY) {
+ const glsl_type *per_vertex_out_type =
+ this->per_vertex_out.construct_interface_instance();
+ const glsl_struct_field *fields = per_vertex_out_type->fields.structure;
+ for (unsigned i = 0; i < per_vertex_out_type->length; i++) {
+ ir_variable *var =
+ add_variable(fields[i].name, fields[i].type, ir_var_shader_out,
+ fields[i].location);
+ var->data.interpolation = fields[i].interpolation;
+ var->data.centroid = fields[i].centroid;
+ var->data.sample = fields[i].sample;
+ var->init_interface_type(per_vertex_out_type);
+ }
+ }
}
@@ -811,15 +1053,18 @@ _mesa_glsl_initialize_variables(exec_list *instructions,
gen.generate_varyings();
- switch (state->target) {
- case vertex_shader:
+ switch (state->stage) {
+ case MESA_SHADER_VERTEX:
gen.generate_vs_special_vars();
break;
- case geometry_shader:
+ case MESA_SHADER_GEOMETRY:
gen.generate_gs_special_vars();
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
gen.generate_fs_special_vars();
break;
+ case MESA_SHADER_COMPUTE:
+ gen.generate_cs_special_vars();
+ break;
}
}
diff --git a/dist/Mesa/src/glsl/glcpp/glcpp.h b/dist/Mesa/src/glsl/glcpp/glcpp.h
index 8aaa551d1..79ccb234f 100644
--- a/dist/Mesa/src/glsl/glcpp/glcpp.h
+++ b/dist/Mesa/src/glsl/glcpp/glcpp.h
@@ -153,6 +153,7 @@ typedef enum skip_type {
typedef struct skip_node {
skip_type_t type;
+ bool has_else;
YYLTYPE loc; /* location of the initial #if/#elif/... */
struct skip_node *next;
} skip_node_t;
@@ -172,6 +173,7 @@ struct glcpp_parser {
int newline_as_space;
int in_control_line;
int paren_count;
+ int commented_newlines;
skip_node_t *skip_stack;
token_list_t *lex_from_list;
token_node_t *lex_from_node;
@@ -180,6 +182,9 @@ struct glcpp_parser {
size_t output_length;
size_t info_log_length;
int error;
+ const struct gl_extensions *extensions;
+ gl_api api;
+ bool version_resolved;
bool has_new_line_number;
int new_line_number;
bool has_new_source_number;
@@ -190,7 +195,7 @@ struct glcpp_parser {
struct gl_extensions;
glcpp_parser_t *
-glcpp_parser_create (const struct gl_extensions *extensions, int api);
+glcpp_parser_create (const struct gl_extensions *extensions, gl_api api);
int
glcpp_parser_parse (glcpp_parser_t *parser);
@@ -198,6 +203,9 @@ glcpp_parser_parse (glcpp_parser_t *parser);
void
glcpp_parser_destroy (glcpp_parser_t *parser);
+void
+glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser);
+
int
glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
const struct gl_extensions *extensions, struct gl_context *g_ctx);
diff --git a/dist/Mesa/src/glsl/glcpp/pp.c b/dist/Mesa/src/glsl/glcpp/pp.c
index 7e1b6c689..4a623f81e 100644
--- a/dist/Mesa/src/glsl/glcpp/pp.c
+++ b/dist/Mesa/src/glsl/glcpp/pp.c
@@ -151,6 +151,8 @@ glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log,
if (parser->skip_stack)
glcpp_error (&parser->skip_stack->loc, parser, "Unterminated #if\n");
+ glcpp_parser_resolve_implicit_version(parser);
+
ralloc_strcat(info_log, parser->info_log);
ralloc_steal(ralloc_ctx, parser->output);
diff --git a/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c b/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c
index 696cb3a74..1f2320e6f 100644
--- a/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c
+++ b/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c
@@ -1 +1 @@
-this is four tokens
+ this is four tokens with spaces
diff --git a/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c.expected b/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c.expected
index 83f7834d5..5e17ec910 100644
--- a/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c.expected
+++ b/dist/Mesa/src/glsl/glcpp/tests/000-content-with-spaces.c.expected
@@ -1,2 +1,2 @@
-this is four tokens
+ this is four tokens with spaces
diff --git a/dist/Mesa/src/glsl/glcpp/tests/100-macro-with-colon.c.expected b/dist/Mesa/src/glsl/glcpp/tests/100-macro-with-colon.c.expected
index 6cfac257b..36f98aa3e 100644
--- a/dist/Mesa/src/glsl/glcpp/tests/100-macro-with-colon.c.expected
+++ b/dist/Mesa/src/glsl/glcpp/tests/100-macro-with-colon.c.expected
@@ -2,7 +2,7 @@
switch (1) {
- case 1 + 2:
- break;
+ case 1 + 2:
+ break;
}
diff --git a/dist/Mesa/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c.expected b/dist/Mesa/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c.expected
index 9b3eb676f..292d6516f 100644
--- a/dist/Mesa/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c.expected
+++ b/dist/Mesa/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c.expected
@@ -1,3 +1,4 @@
+
@@ -6,7 +7,6 @@
-
diff --git a/dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c b/dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c
new file mode 100644
index 000000000..53e80394a
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c
@@ -0,0 +1,4 @@
+#define FOO first/*
+*/second
+
+FOO
diff --git a/dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c.expected b/dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c.expected
new file mode 100644
index 000000000..2adf5d1ba
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/118-comment-becomes-space.c.expected
@@ -0,0 +1,5 @@
+
+
+
+first second
+
diff --git a/dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c b/dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c
new file mode 100644
index 000000000..62ad49cf7
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c
@@ -0,0 +1,6 @@
+#if 0
+#else
+int foo;
+#else
+int bar;
+#endif
diff --git a/dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c.expected b/dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c.expected
new file mode 100644
index 000000000..eaec48150
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/118-multiple-else.c.expected
@@ -0,0 +1,8 @@
+0:4(1): preprocessor error: multiple #else
+
+
+int foo;
+
+int bar;
+
+
diff --git a/dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c b/dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c
new file mode 100644
index 000000000..9b9e9233b
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c
@@ -0,0 +1,6 @@
+#if 0
+#else
+int foo;
+#elif 0
+int bar;
+#endif
diff --git a/dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c.expected b/dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c.expected
new file mode 100644
index 000000000..33f051361
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/119-elif-after-else.c.expected
@@ -0,0 +1,8 @@
+0:4(1): preprocessor error: #elif after #else
+
+
+int foo;
+
+int bar;
+
+
diff --git a/dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c b/dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c
new file mode 100644
index 000000000..67ebe73e5
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c
@@ -0,0 +1,2 @@
+/*
+ */ //
diff --git a/dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected b/dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected
new file mode 100644
index 000000000..402a76381
--- /dev/null
+++ b/dist/Mesa/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected
@@ -0,0 +1,3 @@
+
+
+
diff --git a/dist/Mesa/src/glsl/glsl_symbol_table.h b/dist/Mesa/src/glsl/glsl_symbol_table.h
index 62d26b89a..f323fc305 100644
--- a/dist/Mesa/src/glsl/glsl_symbol_table.h
+++ b/dist/Mesa/src/glsl/glsl_symbol_table.h
@@ -98,7 +98,6 @@ public:
/*@{*/
bool add_variable(ir_variable *v);
bool add_type(const char *name, const glsl_type *t);
- bool add_type_ast(const char *name, const class ast_type_specifier *t);
bool add_function(ir_function *f);
bool add_interface(const char *name, const glsl_type *i,
enum ir_variable_mode mode);
@@ -115,12 +114,19 @@ public:
/*@{*/
ir_variable *get_variable(const char *name);
const glsl_type *get_type(const char *name);
- const class ast_type_specifier *get_type_ast(const char *name);
ir_function *get_function(const char *name);
const glsl_type *get_interface(const char *name,
enum ir_variable_mode mode);
/*@}*/
+ /**
+ * Disable a previously-added variable so that it no longer appears to be
+ * in the symbol table. This is necessary when gl_PerVertex is redeclared,
+ * to ensure that previously-available built-in variables are no longer
+ * available.
+ */
+ void disable_variable(const char *name);
+
private:
symbol_table_entry *get_entry(const char *name);
diff --git a/dist/Mesa/src/glsl/hir_field_selection.cpp b/dist/Mesa/src/glsl/hir_field_selection.cpp
index ceb0a4cdb..1e92c89ae 100644
--- a/dist/Mesa/src/glsl/hir_field_selection.cpp
+++ b/dist/Mesa/src/glsl/hir_field_selection.cpp
@@ -53,13 +53,13 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
expr->primary_expression.identifier);
if (result->type->is_error()) {
- _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
+ _mesa_glsl_error(& loc, state, "cannot access field `%s' of "
"structure",
expr->primary_expression.identifier);
}
} else if (expr->subexpressions[1] != NULL) {
/* Handle "method calls" in GLSL 1.20 - namely, array.length() */
- state->check_version(120, 300, &loc, "Methods not supported");
+ state->check_version(120, 300, &loc, "methods not supported");
ast_expression *call = expr->subexpressions[1];
assert(call->oper == ast_function_call);
@@ -69,11 +69,11 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
if (strcmp(method, "length") == 0) {
if (!call->expressions.is_empty())
- _mesa_glsl_error(&loc, state, "length method takes no arguments.");
+ _mesa_glsl_error(&loc, state, "length method takes no arguments");
if (op->type->is_array()) {
- if (op->type->array_size() == 0)
- _mesa_glsl_error(&loc, state, "length called on unsized array.");
+ if (op->type->is_unsized_array())
+ _mesa_glsl_error(&loc, state, "length called on unsized array");
result = new(ctx) ir_constant(op->type->array_size());
} else if (op->type->is_vector()) {
@@ -82,7 +82,7 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
result = new(ctx) ir_constant((int) op->type->vector_elements);
} else {
_mesa_glsl_error(&loc, state, "length method on matrix only available"
- "with ARB_shading_language_420pack.");
+ "with ARB_shading_language_420pack");
}
} else if (op->type->is_matrix()) {
if (state->ARB_shading_language_420pack_enable) {
@@ -90,11 +90,11 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
result = new(ctx) ir_constant((int) op->type->matrix_columns);
} else {
_mesa_glsl_error(&loc, state, "length method on matrix only available"
- "with ARB_shading_language_420pack.");
+ "with ARB_shading_language_420pack");
}
}
} else {
- _mesa_glsl_error(&loc, state, "Unknown method: `%s'.", method);
+ _mesa_glsl_error(&loc, state, "unknown method: `%s'", method);
}
} else if (op->type->is_vector() ||
(state->ARB_shading_language_420pack_enable &&
@@ -109,12 +109,12 @@ _mesa_ast_field_selection_to_hir(const ast_expression *expr,
* FINISHME: ir_swizzle::create. This allows the generation of more
* FINISHME: specific error messages.
*/
- _mesa_glsl_error(& loc, state, "Invalid swizzle / mask `%s'",
+ _mesa_glsl_error(& loc, state, "invalid swizzle / mask `%s'",
expr->primary_expression.identifier);
}
} else {
- _mesa_glsl_error(& loc, state, "Cannot access field `%s' of "
- "non-structure / non-vector.",
+ _mesa_glsl_error(& loc, state, "cannot access field `%s' of "
+ "non-structure / non-vector",
expr->primary_expression.identifier);
}
diff --git a/dist/Mesa/src/glsl/ir_basic_block.cpp b/dist/Mesa/src/glsl/ir_basic_block.cpp
index 2cbc682d4..426fda2f2 100644
--- a/dist/Mesa/src/glsl/ir_basic_block.cpp
+++ b/dist/Mesa/src/glsl/ir_basic_block.cpp
@@ -58,8 +58,8 @@ void call_for_basic_blocks(exec_list *instructions,
ir_instruction *leader = NULL;
ir_instruction *last = NULL;
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_if *ir_if;
ir_loop *ir_loop;
ir_function *ir_function;
@@ -90,10 +90,8 @@ void call_for_basic_blocks(exec_list *instructions,
* and the body of main(). Perhaps those instructions ought
* to live inside of main().
*/
- foreach_iter(exec_list_iterator, fun_iter, *ir_function) {
- ir_function_signature *ir_sig;
-
- ir_sig = (ir_function_signature *)fun_iter.get();
+ foreach_list(func_node, &ir_function->signatures) {
+ ir_function_signature *ir_sig = (ir_function_signature *) func_node;
call_for_basic_blocks(&ir_sig->body, callback, data);
}
diff --git a/dist/Mesa/src/glsl/ir_builder.cpp b/dist/Mesa/src/glsl/ir_builder.cpp
index 8fb30a02a..f4a1c6efa 100644
--- a/dist/Mesa/src/glsl/ir_builder.cpp
+++ b/dist/Mesa/src/glsl/ir_builder.cpp
@@ -46,13 +46,14 @@ ir_factory::make_temp(const glsl_type *type, const char *name)
}
ir_assignment *
-assign(deref lhs, operand rhs, int writemask)
+assign(deref lhs, operand rhs, operand condition, int writemask)
{
void *mem_ctx = ralloc_parent(lhs.val);
ir_assignment *assign = new(mem_ctx) ir_assignment(lhs.val,
rhs.val,
- NULL, writemask);
+ condition.val,
+ writemask);
return assign;
}
@@ -63,6 +64,25 @@ assign(deref lhs, operand rhs)
return assign(lhs, rhs, (1 << lhs.val->type->vector_elements) - 1);
}
+ir_assignment *
+assign(deref lhs, operand rhs, int writemask)
+{
+ return assign(lhs, rhs, (ir_rvalue *) NULL, writemask);
+}
+
+ir_assignment *
+assign(deref lhs, operand rhs, operand condition)
+{
+ return assign(lhs, rhs, condition, (1 << lhs.val->type->vector_elements) - 1);
+}
+
+ir_return *
+ret(operand retval)
+{
+ void *mem_ctx = ralloc_parent(retval.val);
+ return new(mem_ctx) ir_return(retval.val);
+}
+
ir_swizzle *
swizzle(operand a, int swizzle, int components)
{
@@ -173,6 +193,14 @@ expr(ir_expression_operation op, operand a, operand b)
return new(mem_ctx) ir_expression(op, a.val, b.val);
}
+ir_expression *
+expr(ir_expression_operation op, operand a, operand b, operand c)
+{
+ void *mem_ctx = ralloc_parent(a.val);
+
+ return new(mem_ctx) ir_expression(op, a.val, b.val, c.val);
+}
+
ir_expression *add(operand a, operand b)
{
return expr(ir_binop_add, a, b);
@@ -183,23 +211,54 @@ ir_expression *sub(operand a, operand b)
return expr(ir_binop_sub, a, b);
}
+ir_expression *min2(operand a, operand b)
+{
+ return expr(ir_binop_min, a, b);
+}
+
+ir_expression *max2(operand a, operand b)
+{
+ return expr(ir_binop_max, a, b);
+}
+
ir_expression *mul(operand a, operand b)
{
return expr(ir_binop_mul, a, b);
}
+ir_expression *imul_high(operand a, operand b)
+{
+ return expr(ir_binop_imul_high, a, b);
+}
+
ir_expression *div(operand a, operand b)
{
return expr(ir_binop_div, a, b);
}
+ir_expression *carry(operand a, operand b)
+{
+ return expr(ir_binop_carry, a, b);
+}
+
+ir_expression *borrow(operand a, operand b)
+{
+ return expr(ir_binop_borrow, a, b);
+}
+
ir_expression *round_even(operand a)
{
return expr(ir_unop_round_even, a);
}
+/* dot for vectors, mul for scalars */
ir_expression *dot(operand a, operand b)
{
+ assert(a.val->type == b.val->type);
+
+ if (a.val->type->vector_elements == 1)
+ return expr(ir_binop_mul, a, b);
+
return expr(ir_binop_dot, a, b);
}
@@ -219,6 +278,60 @@ saturate(operand a)
new(mem_ctx) ir_constant(0.0f));
}
+ir_expression *
+abs(operand a)
+{
+ return expr(ir_unop_abs, a);
+}
+
+ir_expression *
+neg(operand a)
+{
+ return expr(ir_unop_neg, a);
+}
+
+ir_expression *
+sin(operand a)
+{
+ return expr(ir_unop_sin, a);
+}
+
+ir_expression *
+cos(operand a)
+{
+ return expr(ir_unop_cos, a);
+}
+
+ir_expression *
+exp(operand a)
+{
+ return expr(ir_unop_exp, a);
+}
+
+ir_expression *
+rsq(operand a)
+{
+ return expr(ir_unop_rsq, a);
+}
+
+ir_expression *
+sqrt(operand a)
+{
+ return expr(ir_unop_sqrt, a);
+}
+
+ir_expression *
+log(operand a)
+{
+ return expr(ir_unop_log, a);
+}
+
+ir_expression *
+sign(operand a)
+{
+ return expr(ir_unop_sign, a);
+}
+
ir_expression*
equal(operand a, operand b)
{
@@ -226,6 +339,12 @@ equal(operand a, operand b)
}
ir_expression*
+nequal(operand a, operand b)
+{
+ return expr(ir_binop_nequal, a, b);
+}
+
+ir_expression*
less(operand a, operand b)
{
return expr(ir_binop_less, a, b);
@@ -304,12 +423,24 @@ f2i(operand a)
}
ir_expression*
+bitcast_f2i(operand a)
+{
+ return expr(ir_unop_bitcast_f2i, a);
+}
+
+ir_expression*
i2f(operand a)
{
return expr(ir_unop_i2f, a);
}
ir_expression*
+bitcast_i2f(operand a)
+{
+ return expr(ir_unop_bitcast_i2f, a);
+}
+
+ir_expression*
i2u(operand a)
{
return expr(ir_unop_i2u, a);
@@ -328,11 +459,73 @@ f2u(operand a)
}
ir_expression*
+bitcast_f2u(operand a)
+{
+ return expr(ir_unop_bitcast_f2u, a);
+}
+
+ir_expression*
u2f(operand a)
{
return expr(ir_unop_u2f, a);
}
+ir_expression*
+bitcast_u2f(operand a)
+{
+ return expr(ir_unop_bitcast_u2f, a);
+}
+
+ir_expression*
+i2b(operand a)
+{
+ return expr(ir_unop_i2b, a);
+}
+
+ir_expression*
+b2i(operand a)
+{
+ return expr(ir_unop_b2i, a);
+}
+
+ir_expression *
+f2b(operand a)
+{
+ return expr(ir_unop_f2b, a);
+}
+
+ir_expression *
+b2f(operand a)
+{
+ return expr(ir_unop_b2f, a);
+}
+
+ir_expression *
+fma(operand a, operand b, operand c)
+{
+ return expr(ir_triop_fma, a, b, c);
+}
+
+ir_expression *
+lrp(operand x, operand y, operand a)
+{
+ return expr(ir_triop_lrp, x, y, a);
+}
+
+ir_expression *
+csel(operand a, operand b, operand c)
+{
+ return expr(ir_triop_csel, a, b, c);
+}
+
+ir_expression *
+bitfield_insert(operand a, operand b, operand c, operand d)
+{
+ void *mem_ctx = ralloc_parent(a.val);
+ return new(mem_ctx) ir_expression(ir_quadop_bitfield_insert,
+ a.val->type, a.val, b.val, c.val, d.val);
+}
+
ir_if*
if_tree(operand condition,
ir_instruction *then_branch)
diff --git a/dist/Mesa/src/glsl/ir_builder.h b/dist/Mesa/src/glsl/ir_builder.h
index 690ac74eb..108b53a5e 100644
--- a/dist/Mesa/src/glsl/ir_builder.h
+++ b/dist/Mesa/src/glsl/ir_builder.h
@@ -82,9 +82,9 @@ public:
class ir_factory {
public:
- ir_factory()
- : instructions(NULL),
- mem_ctx(NULL)
+ ir_factory(exec_list *instructions = NULL, void *mem_ctx = NULL)
+ : instructions(instructions),
+ mem_ctx(mem_ctx)
{
return;
}
@@ -122,19 +122,37 @@ public:
ir_assignment *assign(deref lhs, operand rhs);
ir_assignment *assign(deref lhs, operand rhs, int writemask);
+ir_assignment *assign(deref lhs, operand rhs, operand condition);
+ir_assignment *assign(deref lhs, operand rhs, operand condition, int writemask);
+
+ir_return *ret(operand retval);
ir_expression *expr(ir_expression_operation op, operand a);
ir_expression *expr(ir_expression_operation op, operand a, operand b);
+ir_expression *expr(ir_expression_operation op, operand a, operand b, operand c);
ir_expression *add(operand a, operand b);
ir_expression *sub(operand a, operand b);
ir_expression *mul(operand a, operand b);
+ir_expression *imul_high(operand a, operand b);
ir_expression *div(operand a, operand b);
+ir_expression *carry(operand a, operand b);
+ir_expression *borrow(operand a, operand b);
ir_expression *round_even(operand a);
ir_expression *dot(operand a, operand b);
ir_expression *clamp(operand a, operand b, operand c);
ir_expression *saturate(operand a);
+ir_expression *abs(operand a);
+ir_expression *neg(operand a);
+ir_expression *sin(operand a);
+ir_expression *cos(operand a);
+ir_expression *exp(operand a);
+ir_expression *rsq(operand a);
+ir_expression *sqrt(operand a);
+ir_expression *log(operand a);
+ir_expression *sign(operand a);
ir_expression *equal(operand a, operand b);
+ir_expression *nequal(operand a, operand b);
ir_expression *less(operand a, operand b);
ir_expression *greater(operand a, operand b);
ir_expression *lequal(operand a, operand b);
@@ -151,12 +169,29 @@ ir_expression *lshift(operand a, operand b);
ir_expression *rshift(operand a, operand b);
ir_expression *f2i(operand a);
+ir_expression *bitcast_f2i(operand a);
ir_expression *i2f(operand a);
+ir_expression *bitcast_i2f(operand a);
ir_expression *f2u(operand a);
+ir_expression *bitcast_f2u(operand a);
ir_expression *u2f(operand a);
+ir_expression *bitcast_u2f(operand a);
ir_expression *i2u(operand a);
ir_expression *u2i(operand a);
+ir_expression *b2i(operand a);
+ir_expression *i2b(operand a);
+ir_expression *f2b(operand a);
+ir_expression *b2f(operand a);
+
+ir_expression *min2(operand a, operand b);
+ir_expression *max2(operand a, operand b);
+
+ir_expression *fma(operand a, operand b, operand c);
+ir_expression *lrp(operand x, operand y, operand a);
+ir_expression *csel(operand a, operand b, operand c);
+ir_expression *bitfield_insert(operand a, operand b, operand c, operand d);
+ir_swizzle *swizzle(operand a, int swizzle, int components);
/**
* Swizzle away later components, but preserve the ordering.
*/
diff --git a/dist/Mesa/src/glsl/ir_equals.cpp b/dist/Mesa/src/glsl/ir_equals.cpp
new file mode 100644
index 000000000..65376cd94
--- /dev/null
+++ b/dist/Mesa/src/glsl/ir_equals.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright © 2013 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 "ir.h"
+
+/**
+ * Helper for checking equality when one instruction might be NULL, since you
+ * can't access a's vtable in that case.
+ */
+static bool
+possibly_null_equals(ir_instruction *a, ir_instruction *b, enum ir_node_type ignore)
+{
+ if (!a || !b)
+ return !a && !b;
+
+ return a->equals(b, ignore);
+}
+
+/**
+ * The base equality function: Return not equal for anything we don't know
+ * about.
+ */
+bool
+ir_instruction::equals(ir_instruction *, enum ir_node_type)
+{
+ return false;
+}
+
+bool
+ir_constant::equals(ir_instruction *ir, enum ir_node_type)
+{
+ const ir_constant *other = ir->as_constant();
+ if (!other)
+ return false;
+
+ if (type != other->type)
+ return false;
+
+ for (unsigned i = 0; i < type->components(); i++) {
+ if (value.u[i] != other->value.u[i])
+ return false;
+ }
+
+ return true;
+}
+
+bool
+ir_dereference_variable::equals(ir_instruction *ir, enum ir_node_type)
+{
+ const ir_dereference_variable *other = ir->as_dereference_variable();
+ if (!other)
+ return false;
+
+ return var == other->var;
+}
+
+bool
+ir_dereference_array::equals(ir_instruction *ir, enum ir_node_type ignore)
+{
+ const ir_dereference_array *other = ir->as_dereference_array();
+ if (!other)
+ return false;
+
+ if (type != other->type)
+ return false;
+
+ if (!array->equals(other->array, ignore))
+ return false;
+
+ if (!array_index->equals(other->array_index, ignore))
+ return false;
+
+ return true;
+}
+
+bool
+ir_swizzle::equals(ir_instruction *ir, enum ir_node_type ignore)
+{
+ const ir_swizzle *other = ir->as_swizzle();
+ if (!other)
+ return false;
+
+ if (type != other->type)
+ return false;
+
+ if (ignore != ir_type_swizzle) {
+ if (mask.x != other->mask.x ||
+ mask.y != other->mask.y ||
+ mask.z != other->mask.z ||
+ mask.w != other->mask.w) {
+ return false;
+ }
+ }
+
+ return val->equals(other->val, ignore);
+}
+
+bool
+ir_texture::equals(ir_instruction *ir, enum ir_node_type ignore)
+{
+ const ir_texture *other = ir->as_texture();
+ if (!other)
+ return false;
+
+ if (type != other->type)
+ return false;
+
+ if (op != other->op)
+ return false;
+
+ if (!possibly_null_equals(coordinate, other->coordinate, ignore))
+ return false;
+
+ if (!possibly_null_equals(projector, other->projector, ignore))
+ return false;
+
+ if (!possibly_null_equals(shadow_comparitor, other->shadow_comparitor, ignore))
+ return false;
+
+ if (!possibly_null_equals(offset, other->offset, ignore))
+ return false;
+
+ if (!sampler->equals(other->sampler, ignore))
+ return false;
+
+ switch (op) {
+ case ir_tex:
+ case ir_lod:
+ case ir_query_levels:
+ break;
+ case ir_txb:
+ if (!lod_info.bias->equals(other->lod_info.bias, ignore))
+ return false;
+ break;
+ case ir_txl:
+ case ir_txf:
+ case ir_txs:
+ if (!lod_info.lod->equals(other->lod_info.lod, ignore))
+ return false;
+ break;
+ case ir_txd:
+ if (!lod_info.grad.dPdx->equals(other->lod_info.grad.dPdx, ignore) ||
+ !lod_info.grad.dPdy->equals(other->lod_info.grad.dPdy, ignore))
+ return false;
+ break;
+ case ir_txf_ms:
+ if (!lod_info.sample_index->equals(other->lod_info.sample_index, ignore))
+ return false;
+ break;
+ case ir_tg4:
+ if (!lod_info.component->equals(other->lod_info.component, ignore))
+ return false;
+ break;
+ default:
+ assert(!"Unrecognized texture op");
+ }
+
+ return true;
+}
+
+bool
+ir_expression::equals(ir_instruction *ir, enum ir_node_type ignore)
+{
+ const ir_expression *other = ir->as_expression();
+ if (!other)
+ return false;
+
+ if (type != other->type)
+ return false;
+
+ if (operation != other->operation)
+ return false;
+
+ for (unsigned i = 0; i < get_num_operands(); i++) {
+ if (!operands[i]->equals(other->operands[i], ignore))
+ return false;
+ }
+
+ return true;
+}
diff --git a/dist/Mesa/src/glsl/ir_expression_flattening.cpp b/dist/Mesa/src/glsl/ir_expression_flattening.cpp
index b44e68ca3..c1cadb122 100644
--- a/dist/Mesa/src/glsl/ir_expression_flattening.cpp
+++ b/dist/Mesa/src/glsl/ir_expression_flattening.cpp
@@ -59,8 +59,8 @@ do_expression_flattening(exec_list *instructions,
{
ir_expression_flattening_visitor v(predicate);
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir->accept(&v);
}
diff --git a/dist/Mesa/src/glsl/ir_hierarchical_visitor.cpp b/dist/Mesa/src/glsl/ir_hierarchical_visitor.cpp
index f24414046..2e606dda4 100644
--- a/dist/Mesa/src/glsl/ir_hierarchical_visitor.cpp
+++ b/dist/Mesa/src/glsl/ir_hierarchical_visitor.cpp
@@ -69,6 +69,24 @@ ir_hierarchical_visitor::visit(ir_loop_jump *ir)
}
ir_visitor_status
+ir_hierarchical_visitor::visit(ir_emit_vertex *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
+ir_hierarchical_visitor::visit(ir_end_primitive *ir)
+{
+ if (this->callback != NULL)
+ this->callback(ir, this->data);
+
+ return visit_continue;
+}
+
+ir_visitor_status
ir_hierarchical_visitor::visit(ir_dereference_variable *ir)
{
if (this->callback != NULL)
diff --git a/dist/Mesa/src/glsl/ir_uniform.h b/dist/Mesa/src/glsl/ir_uniform.h
index 8198c4819..3508509d4 100644
--- a/dist/Mesa/src/glsl/ir_uniform.h
+++ b/dist/Mesa/src/glsl/ir_uniform.h
@@ -78,6 +78,26 @@ struct gl_uniform_driver_storage {
void *data;
};
+struct gl_opaque_uniform_index {
+ /**
+ * Base opaque uniform index
+ *
+ * If \c gl_uniform_storage::base_type is an opaque type, this
+ * represents its uniform index. If \c
+ * gl_uniform_storage::array_elements is not zero, the array will
+ * use opaque uniform indices \c index through \c index + \c
+ * gl_uniform_storage::array_elements - 1, inclusive.
+ *
+ * Note that the index may be different in each shader stage.
+ */
+ uint8_t index;
+
+ /**
+ * Whether this opaque uniform is used in this shader stage.
+ */
+ bool active;
+};
+
struct gl_uniform_storage {
char *name;
/** Type of this uniform data stored.
@@ -99,24 +119,9 @@ struct gl_uniform_storage {
*/
bool initialized;
- struct {
- /**
- * Base sampler index
- *
- * If \c ::base_type is \c GLSL_TYPE_SAMPLER, this represents the index
- * of this sampler. If \c ::array_elements is not zero, the array will
- * use sampler indices \c ::sampler through \c ::sampler +
- * \c ::array_elements - 1, inclusive.
- *
- * Note that the index may be different in each shader stage.
- */
- uint8_t index;
-
- /**
- * Whether this sampler is used in this shader stage.
- */
- bool active;
- } sampler[MESA_SHADER_TYPES];
+ struct gl_opaque_uniform_index sampler[MESA_SHADER_STAGES];
+
+ struct gl_opaque_uniform_index image[MESA_SHADER_STAGES];
/**
* Storage used by the driver for the uniform
@@ -166,6 +171,19 @@ struct gl_uniform_storage {
bool row_major;
/** @} */
+
+ /**
+ * Index within gl_shader_program::AtomicBuffers[] of the atomic
+ * counter buffer this uniform is stored in, or -1 if this is not
+ * an atomic counter.
+ */
+ int atomic_buffer_index;
+
+ /**
+ * The 'base location' for this uniform in the uniform remap table. For
+ * arrays this is the first element in the array.
+ */
+ unsigned remap_location;
};
#ifdef __cplusplus
diff --git a/dist/Mesa/src/glsl/ir_visitor.h b/dist/Mesa/src/glsl/ir_visitor.h
index bd47ef7d5..40f96ffbc 100644
--- a/dist/Mesa/src/glsl/ir_visitor.h
+++ b/dist/Mesa/src/glsl/ir_visitor.h
@@ -63,6 +63,8 @@ public:
virtual void visit(class ir_if *) = 0;
virtual void visit(class ir_loop *) = 0;
virtual void visit(class ir_loop_jump *) = 0;
+ virtual void visit(class ir_emit_vertex *) = 0;
+ virtual void visit(class ir_end_primitive *) = 0;
/*@}*/
};
@@ -81,6 +83,8 @@ public:
virtual void visit(class ir_assignment *) {}
virtual void visit(class ir_constant *) {}
virtual void visit(class ir_call *) {}
+ virtual void visit(class ir_emit_vertex *) {}
+ virtual void visit(class ir_end_primitive *) {}
};
#endif /* __cplusplus */
diff --git a/dist/Mesa/src/glsl/link_atomics.cpp b/dist/Mesa/src/glsl/link_atomics.cpp
new file mode 100644
index 000000000..d92cdb117
--- /dev/null
+++ b/dist/Mesa/src/glsl/link_atomics.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright © 2013 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 "glsl_parser_extras.h"
+#include "ir.h"
+#include "ir_uniform.h"
+#include "linker.h"
+#include "program/hash_table.h"
+#include "main/macros.h"
+
+namespace {
+ /*
+ * Atomic counter as seen by the program.
+ */
+ struct active_atomic_counter {
+ unsigned id;
+ ir_variable *var;
+ };
+
+ /*
+ * Atomic counter buffer referenced by the program. There is a one
+ * to one correspondence between these and the objects that can be
+ * queried using glGetActiveAtomicCounterBufferiv().
+ */
+ struct active_atomic_buffer {
+ active_atomic_buffer()
+ : counters(0), num_counters(0), stage_references(), size(0)
+ {}
+
+ ~active_atomic_buffer()
+ {
+ free(counters);
+ }
+
+ void push_back(unsigned id, ir_variable *var)
+ {
+ counters = (active_atomic_counter *)
+ realloc(counters, sizeof(active_atomic_counter) * (num_counters + 1));
+
+ counters[num_counters].id = id;
+ counters[num_counters].var = var;
+ num_counters++;
+ }
+
+ active_atomic_counter *counters;
+ unsigned num_counters;
+ unsigned stage_references[MESA_SHADER_STAGES];
+ unsigned size;
+ };
+
+ int
+ cmp_actives(const void *a, const void *b)
+ {
+ const active_atomic_counter *const first = (active_atomic_counter *) a;
+ const active_atomic_counter *const second = (active_atomic_counter *) b;
+
+ return int(first->var->data.atomic.offset) - int(second->var->data.atomic.offset);
+ }
+
+ bool
+ check_atomic_counters_overlap(const ir_variable *x, const ir_variable *y)
+ {
+ return ((x->data.atomic.offset >= y->data.atomic.offset &&
+ x->data.atomic.offset < y->data.atomic.offset + y->type->atomic_size()) ||
+ (y->data.atomic.offset >= x->data.atomic.offset &&
+ y->data.atomic.offset < x->data.atomic.offset + x->type->atomic_size()));
+ }
+
+ active_atomic_buffer *
+ find_active_atomic_counters(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ unsigned *num_buffers)
+ {
+ active_atomic_buffer *const buffers =
+ new active_atomic_buffer[ctx->Const.MaxAtomicBufferBindings];
+
+ *num_buffers = 0;
+
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; ++i) {
+ struct gl_shader *sh = prog->_LinkedShaders[i];
+ if (sh == NULL)
+ continue;
+
+ foreach_list(node, sh->ir) {
+ ir_variable *var = ((ir_instruction *)node)->as_variable();
+
+ if (var && var->type->contains_atomic()) {
+ unsigned id = 0;
+ bool found = prog->UniformHash->get(id, var->name);
+ assert(found);
+ (void) found;
+ active_atomic_buffer *buf = &buffers[var->data.binding];
+
+ /* If this is the first time the buffer is used, increment
+ * the counter of buffers used.
+ */
+ if (buf->size == 0)
+ (*num_buffers)++;
+
+ buf->push_back(id, var);
+
+ buf->stage_references[i]++;
+ buf->size = MAX2(buf->size, var->data.atomic.offset +
+ var->type->atomic_size());
+ }
+ }
+ }
+
+ for (unsigned i = 0; i < ctx->Const.MaxAtomicBufferBindings; i++) {
+ if (buffers[i].size == 0)
+ continue;
+
+ qsort(buffers[i].counters, buffers[i].num_counters,
+ sizeof(active_atomic_counter),
+ cmp_actives);
+
+ for (unsigned j = 1; j < buffers[i].num_counters; j++) {
+ /* If an overlapping counter found, it must be a reference to the
+ * same counter from a different shader stage.
+ */
+ if (check_atomic_counters_overlap(buffers[i].counters[j-1].var,
+ buffers[i].counters[j].var)
+ && strcmp(buffers[i].counters[j-1].var->name,
+ buffers[i].counters[j].var->name) != 0) {
+ linker_error(prog, "Atomic counter %s declared at offset %d "
+ "which is already in use.",
+ buffers[i].counters[j].var->name,
+ buffers[i].counters[j].var->data.atomic.offset);
+ }
+ }
+ }
+ return buffers;
+ }
+}
+
+void
+link_assign_atomic_counter_resources(struct gl_context *ctx,
+ struct gl_shader_program *prog)
+{
+ unsigned num_buffers;
+ active_atomic_buffer *abs =
+ find_active_atomic_counters(ctx, prog, &num_buffers);
+
+ prog->AtomicBuffers = rzalloc_array(prog, gl_active_atomic_buffer,
+ num_buffers);
+ prog->NumAtomicBuffers = num_buffers;
+
+ unsigned i = 0;
+ for (unsigned binding = 0;
+ binding < ctx->Const.MaxAtomicBufferBindings;
+ binding++) {
+
+ /* If the binding was not used, skip.
+ */
+ if (abs[binding].size == 0)
+ continue;
+
+ active_atomic_buffer &ab = abs[binding];
+ gl_active_atomic_buffer &mab = prog->AtomicBuffers[i];
+
+ /* Assign buffer-specific fields. */
+ mab.Binding = binding;
+ mab.MinimumSize = ab.size;
+ mab.Uniforms = rzalloc_array(prog->AtomicBuffers, GLuint,
+ ab.num_counters);
+ mab.NumUniforms = ab.num_counters;
+
+ /* Assign counter-specific fields. */
+ for (unsigned j = 0; j < ab.num_counters; j++) {
+ ir_variable *const var = ab.counters[j].var;
+ const unsigned id = ab.counters[j].id;
+ gl_uniform_storage *const storage = &prog->UniformStorage[id];
+
+ mab.Uniforms[j] = id;
+ var->data.atomic.buffer_index = i;
+ storage->atomic_buffer_index = i;
+ storage->offset = var->data.atomic.offset;
+ storage->array_stride = (var->type->is_array() ?
+ var->type->element_type()->atomic_size() : 0);
+ }
+
+ /* Assign stage-specific fields. */
+ for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j)
+ mab.StageReferences[j] =
+ (ab.stage_references[j] ? GL_TRUE : GL_FALSE);
+
+ i++;
+ }
+
+ delete [] abs;
+ assert(i == num_buffers);
+}
+
+void
+link_check_atomic_counter_resources(struct gl_context *ctx,
+ struct gl_shader_program *prog)
+{
+ unsigned num_buffers;
+ active_atomic_buffer *const abs =
+ find_active_atomic_counters(ctx, prog, &num_buffers);
+ unsigned atomic_counters[MESA_SHADER_STAGES] = {};
+ unsigned atomic_buffers[MESA_SHADER_STAGES] = {};
+ unsigned total_atomic_counters = 0;
+ unsigned total_atomic_buffers = 0;
+
+ /* Sum the required resources. Note that this counts buffers and
+ * counters referenced by several shader stages multiple times
+ * against the combined limit -- That's the behavior the spec
+ * requires.
+ */
+ for (unsigned i = 0; i < ctx->Const.MaxAtomicBufferBindings; i++) {
+ if (abs[i].size == 0)
+ continue;
+
+ for (unsigned j = 0; j < MESA_SHADER_STAGES; ++j) {
+ const unsigned n = abs[i].stage_references[j];
+
+ if (n) {
+ atomic_counters[j] += n;
+ total_atomic_counters += n;
+ atomic_buffers[j]++;
+ total_atomic_buffers++;
+ }
+ }
+ }
+
+ /* Check that they are within the supported limits. */
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (atomic_counters[i] > ctx->Const.Program[i].MaxAtomicCounters)
+ linker_error(prog, "Too many %s shader atomic counters",
+ _mesa_shader_stage_to_string(i));
+
+ if (atomic_buffers[i] > ctx->Const.Program[i].MaxAtomicBuffers)
+ linker_error(prog, "Too many %s shader atomic counter buffers",
+ _mesa_shader_stage_to_string(i));
+ }
+
+ if (total_atomic_counters > ctx->Const.MaxCombinedAtomicCounters)
+ linker_error(prog, "Too many combined atomic counters");
+
+ if (total_atomic_buffers > ctx->Const.MaxCombinedAtomicBuffers)
+ linker_error(prog, "Too many combined atomic buffers");
+
+ delete [] abs;
+}
diff --git a/dist/Mesa/src/glsl/link_interface_blocks.cpp b/dist/Mesa/src/glsl/link_interface_blocks.cpp
index b91860d03..52552cc68 100644
--- a/dist/Mesa/src/glsl/link_interface_blocks.cpp
+++ b/dist/Mesa/src/glsl/link_interface_blocks.cpp
@@ -30,12 +30,230 @@
#include "glsl_symbol_table.h"
#include "linker.h"
#include "main/macros.h"
+#include "program/hash_table.h"
+
+namespace {
+
+/**
+ * Information about a single interface block definition that we need to keep
+ * track of in order to check linkage rules.
+ *
+ * Note: this class is expected to be short lived, so it doesn't make copies
+ * of the strings it references; it simply borrows the pointers from the
+ * ir_variable class.
+ */
+struct interface_block_definition
+{
+ /**
+ * Extract an interface block definition from an ir_variable that
+ * represents either the interface instance (for named interfaces), or a
+ * member of the interface (for unnamed interfaces).
+ */
+ explicit interface_block_definition(const ir_variable *var)
+ : type(var->get_interface_type()),
+ instance_name(NULL),
+ array_size(-1)
+ {
+ if (var->is_interface_instance()) {
+ instance_name = var->name;
+ if (var->type->is_array())
+ array_size = var->type->length;
+ }
+ explicitly_declared = (var->data.how_declared != ir_var_declared_implicitly);
+ }
+
+ /**
+ * Interface block type
+ */
+ const glsl_type *type;
+
+ /**
+ * For a named interface block, the instance name. Otherwise NULL.
+ */
+ const char *instance_name;
+
+ /**
+ * For an interface block array, the array size (or 0 if unsized).
+ * Otherwise -1.
+ */
+ int array_size;
+
+ /**
+ * True if this interface block was explicitly declared in the shader;
+ * false if it was an implicitly declared built-in interface block.
+ */
+ bool explicitly_declared;
+};
+
+
+/**
+ * Check if two interfaces match, according to intrastage interface matching
+ * rules. If they do, and the first interface uses an unsized array, it will
+ * be updated to reflect the array size declared in the second interface.
+ */
+bool
+intrastage_match(interface_block_definition *a,
+ const interface_block_definition *b,
+ ir_variable_mode mode)
+{
+ /* Types must match. */
+ if (a->type != b->type) {
+ /* Exception: if both the interface blocks are implicitly declared,
+ * don't force their types to match. They might mismatch due to the two
+ * shaders using different GLSL versions, and that's ok.
+ */
+ if (a->explicitly_declared || b->explicitly_declared)
+ return false;
+ }
+
+ /* Presence/absence of interface names must match. */
+ if ((a->instance_name == NULL) != (b->instance_name == NULL))
+ return false;
+
+ /* For uniforms, instance names need not match. For shader ins/outs,
+ * it's not clear from the spec whether they need to match, but
+ * Mesa's implementation relies on them matching.
+ */
+ if (a->instance_name != NULL && mode != ir_var_uniform &&
+ strcmp(a->instance_name, b->instance_name) != 0) {
+ return false;
+ }
+
+ /* Array vs. nonarray must be consistent, and sizes must be
+ * consistent, with the exception that unsized arrays match sized
+ * arrays.
+ */
+ if ((a->array_size == -1) != (b->array_size == -1))
+ return false;
+ if (b->array_size != 0) {
+ if (a->array_size == 0)
+ a->array_size = b->array_size;
+ else if (a->array_size != b->array_size)
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ * Check if two interfaces match, according to interstage (in/out) interface
+ * matching rules.
+ *
+ * If \c extra_array_level is true, then vertex-to-geometry shader matching
+ * rules are enforced (i.e. a successful match requires the consumer interface
+ * to be an array and the producer interface to be a non-array).
+ */
bool
-validate_intrastage_interface_blocks(const gl_shader **shader_list,
+interstage_match(const interface_block_definition *producer,
+ const interface_block_definition *consumer,
+ bool extra_array_level)
+{
+ /* Unsized arrays should not occur during interstage linking. They
+ * should have all been assigned a size by link_intrastage_shaders.
+ */
+ assert(consumer->array_size != 0);
+ assert(producer->array_size != 0);
+
+ /* Types must match. */
+ if (consumer->type != producer->type) {
+ /* Exception: if both the interface blocks are implicitly declared,
+ * don't force their types to match. They might mismatch due to the two
+ * shaders using different GLSL versions, and that's ok.
+ */
+ if (consumer->explicitly_declared || producer->explicitly_declared)
+ return false;
+ }
+ if (extra_array_level) {
+ /* Consumer must be an array, and producer must not. */
+ if (consumer->array_size == -1)
+ return false;
+ if (producer->array_size != -1)
+ return false;
+ } else {
+ /* Array vs. nonarray must be consistent, and sizes must be consistent.
+ * Since unsized arrays have been ruled out, we can check this by just
+ * making sure the sizes are equal.
+ */
+ if (consumer->array_size != producer->array_size)
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ * This class keeps track of a mapping from an interface block name to the
+ * necessary information about that interface block to determine whether to
+ * generate a link error.
+ *
+ * Note: this class is expected to be short lived, so it doesn't make copies
+ * of the strings it references; it simply borrows the pointers from the
+ * ir_variable class.
+ */
+class interface_block_definitions
+{
+public:
+ interface_block_definitions()
+ : mem_ctx(ralloc_context(NULL)),
+ ht(hash_table_ctor(0, hash_table_string_hash,
+ hash_table_string_compare))
+ {
+ }
+
+ ~interface_block_definitions()
+ {
+ hash_table_dtor(ht);
+ ralloc_free(mem_ctx);
+ }
+
+ /**
+ * Lookup the interface definition having the given block name. Return
+ * NULL if none is found.
+ */
+ interface_block_definition *lookup(const char *block_name)
+ {
+ return (interface_block_definition *) hash_table_find(ht, block_name);
+ }
+
+ /**
+ * Add a new interface definition.
+ */
+ void store(const interface_block_definition &def)
+ {
+ interface_block_definition *hash_entry =
+ rzalloc(mem_ctx, interface_block_definition);
+ *hash_entry = def;
+ hash_table_insert(ht, hash_entry, def.type->name);
+ }
+
+private:
+ /**
+ * Ralloc context for data structures allocated by this class.
+ */
+ void *mem_ctx;
+
+ /**
+ * Hash table mapping interface block name to an \c
+ * interface_block_definition struct. interface_block_definition structs
+ * are allocated using \c mem_ctx.
+ */
+ hash_table *ht;
+};
+
+
+}; /* anonymous namespace */
+
+
+void
+validate_intrastage_interface_blocks(struct gl_shader_program *prog,
+ const gl_shader **shader_list,
unsigned num_shaders)
{
- glsl_symbol_table interfaces;
+ interface_block_definitions in_interfaces;
+ interface_block_definitions out_interfaces;
+ interface_block_definitions uniform_interfaces;
for (unsigned int i = 0; i < num_shaders; i++) {
if (shader_list[i] == NULL)
@@ -46,65 +264,122 @@ validate_intrastage_interface_blocks(const gl_shader **shader_list,
if (!var)
continue;
- const glsl_type *iface_type = var->interface_type;
+ const glsl_type *iface_type = var->get_interface_type();
if (iface_type == NULL)
continue;
- const glsl_type *old_iface_type =
- interfaces.get_interface(iface_type->name,
- (enum ir_variable_mode) var->mode);
+ interface_block_definitions *definitions;
+ switch (var->data.mode) {
+ case ir_var_shader_in:
+ definitions = &in_interfaces;
+ break;
+ case ir_var_shader_out:
+ definitions = &out_interfaces;
+ break;
+ case ir_var_uniform:
+ definitions = &uniform_interfaces;
+ break;
+ default:
+ /* Only in, out, and uniform interfaces are legal, so we should
+ * never get here.
+ */
+ assert(!"illegal interface type");
+ continue;
+ }
- if (old_iface_type == NULL) {
+ const interface_block_definition def(var);
+ interface_block_definition *prev_def =
+ definitions->lookup(iface_type->name);
+
+ if (prev_def == NULL) {
/* This is the first time we've seen the interface, so save
- * it into our symbol table.
+ * it into the appropriate data structure.
*/
- interfaces.add_interface(iface_type->name, iface_type,
- (enum ir_variable_mode) var->mode);
- } else if (old_iface_type != iface_type) {
- return false;
+ definitions->store(def);
+ } else if (!intrastage_match(prev_def, &def,
+ (ir_variable_mode) var->data.mode)) {
+ linker_error(prog, "definitions of interface block `%s' do not"
+ " match\n", iface_type->name);
+ return;
}
}
}
-
- return true;
}
-bool
-validate_interstage_interface_blocks(const gl_shader *producer,
- const gl_shader *consumer)
+void
+validate_interstage_inout_blocks(struct gl_shader_program *prog,
+ const gl_shader *producer,
+ const gl_shader *consumer)
{
- glsl_symbol_table interfaces;
+ interface_block_definitions definitions;
+ const bool extra_array_level = consumer->Stage == MESA_SHADER_GEOMETRY;
- /* Add non-output interfaces from the consumer to the symbol table. */
+ /* Add input interfaces from the consumer to the symbol table. */
foreach_list(node, consumer->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (!var || !var->interface_type || var->mode == ir_var_shader_out)
+ if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
continue;
- interfaces.add_interface(var->interface_type->name,
- var->interface_type,
- (enum ir_variable_mode) var->mode);
+ definitions.store(interface_block_definition(var));
}
- /* Verify that the producer's interfaces match. */
+ /* Verify that the producer's output interfaces match. */
foreach_list(node, producer->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (!var || !var->interface_type || var->mode == ir_var_shader_in)
+ if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
continue;
- enum ir_variable_mode consumer_mode =
- var->mode == ir_var_uniform ? ir_var_uniform : ir_var_shader_in;
- const glsl_type *expected_type =
- interfaces.get_interface(var->interface_type->name, consumer_mode);
+ interface_block_definition *consumer_def =
+ definitions.lookup(var->get_interface_type()->name);
/* The consumer doesn't use this output block. Ignore it. */
- if (expected_type == NULL)
+ if (consumer_def == NULL)
continue;
- if (var->interface_type != expected_type)
- return false;
+ const interface_block_definition producer_def(var);
+
+ if (!interstage_match(&producer_def, consumer_def, extra_array_level)) {
+ linker_error(prog, "definitions of interface block `%s' do not "
+ "match\n", var->get_interface_type()->name);
+ return;
+ }
}
+}
- return true;
+
+void
+validate_interstage_uniform_blocks(struct gl_shader_program *prog,
+ gl_shader **stages, int num_stages)
+{
+ interface_block_definitions definitions;
+
+ for (int i = 0; i < num_stages; i++) {
+ if (stages[i] == NULL)
+ continue;
+
+ const gl_shader *stage = stages[i];
+ foreach_list(node, stage->ir) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
+ if (!var || !var->get_interface_type() || var->data.mode != ir_var_uniform)
+ continue;
+
+ interface_block_definition *old_def =
+ definitions.lookup(var->get_interface_type()->name);
+ const interface_block_definition new_def(var);
+ if (old_def == NULL) {
+ definitions.store(new_def);
+ } else {
+ /* Interstage uniform matching rules are the same as intrastage
+ * uniform matchin rules (for uniforms, it is as though all
+ * shaders are in the same shader stage).
+ */
+ if (!intrastage_match(old_def, &new_def, ir_var_uniform)) {
+ linker_error(prog, "definitions of interface block `%s' do not "
+ "match\n", var->get_interface_type()->name);
+ return;
+ }
+ }
+ }
+ }
}
diff --git a/dist/Mesa/src/glsl/link_uniform_block_active_visitor.cpp b/dist/Mesa/src/glsl/link_uniform_block_active_visitor.cpp
index 56a8384e9..d19ce20c7 100644
--- a/dist/Mesa/src/glsl/link_uniform_block_active_visitor.cpp
+++ b/dist/Mesa/src/glsl/link_uniform_block_active_visitor.cpp
@@ -27,12 +27,12 @@
link_uniform_block_active *
process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)
{
- const uint32_t h = _mesa_hash_string(var->interface_type->name);
+ const uint32_t h = _mesa_hash_string(var->get_interface_type()->name);
const hash_entry *const existing_block =
- _mesa_hash_table_search(ht, h, var->interface_type->name);
+ _mesa_hash_table_search(ht, h, var->get_interface_type()->name);
const glsl_type *const block_type = var->is_interface_instance()
- ? var->type : var->interface_type;
+ ? var->type : var->get_interface_type();
/* If a block with this block-name has not previously been seen, add it.
@@ -46,7 +46,15 @@ process_block(void *mem_ctx, struct hash_table *ht, ir_variable *var)
b->type = block_type;
b->has_instance_name = var->is_interface_instance();
- _mesa_hash_table_insert(ht, h, var->interface_type->name,
+ if (var->data.explicit_binding) {
+ b->has_binding = true;
+ b->binding = var->data.binding;
+ } else {
+ b->has_binding = false;
+ b->binding = 0;
+ }
+
+ _mesa_hash_table_insert(ht, h, var->get_interface_type()->name,
(void *) b);
return b;
} else {
@@ -90,7 +98,7 @@ link_uniform_block_active_visitor::visit_enter(ir_dereference_array *ir)
if (b == NULL) {
linker_error(prog,
"uniform block `%s' has mismatching definitions",
- var->interface_type->name);
+ var->get_interface_type()->name);
this->success = false;
return visit_stop;
}
@@ -149,7 +157,7 @@ link_uniform_block_active_visitor::visit(ir_dereference_variable *ir)
if (b == NULL) {
linker_error(this->prog,
"uniform block `%s' has mismatching definitions",
- var->interface_type->name);
+ var->get_interface_type()->name);
this->success = false;
return visit_stop;
}
diff --git a/dist/Mesa/src/glsl/link_uniform_block_active_visitor.h b/dist/Mesa/src/glsl/link_uniform_block_active_visitor.h
index fba628a8f..d76dbcaf1 100644
--- a/dist/Mesa/src/glsl/link_uniform_block_active_visitor.h
+++ b/dist/Mesa/src/glsl/link_uniform_block_active_visitor.h
@@ -36,7 +36,10 @@ struct link_uniform_block_active {
unsigned *array_elements;
unsigned num_array_elements;
+ unsigned binding;
+
bool has_instance_name;
+ bool has_binding;
};
class link_uniform_block_active_visitor : public ir_hierarchical_visitor {
diff --git a/dist/Mesa/src/glsl/link_uniform_blocks.cpp b/dist/Mesa/src/glsl/link_uniform_blocks.cpp
index e475147e5..1a0e64318 100644
--- a/dist/Mesa/src/glsl/link_uniform_blocks.cpp
+++ b/dist/Mesa/src/glsl/link_uniform_blocks.cpp
@@ -29,6 +29,8 @@
#include "main/hash_table.h"
#include "program.h"
+namespace {
+
class ubo_visitor : public program_resource_visitor {
public:
ubo_visitor(void *mem_ctx, gl_uniform_buffer_variable *variables,
@@ -147,12 +149,14 @@ private:
}
};
+} /* anonymous namespace */
+
struct block {
const glsl_type *type;
bool has_instance_name;
};
-int
+unsigned
link_uniform_blocks(void *mem_ctx,
struct gl_shader_program *prog,
struct gl_shader **shader_list,
@@ -247,7 +251,17 @@ link_uniform_blocks(void *mem_ctx,
blocks[i].Name = ralloc_asprintf(blocks, "%s[%u]", name,
b->array_elements[j]);
blocks[i].Uniforms = &variables[parcel.index];
- blocks[i].Binding = 0;
+
+ /* The GL_ARB_shading_language_420pack spec says:
+ *
+ * "If the binding identifier is used with a uniform block
+ * instanced as an array then the first element of the array
+ * takes the specified block binding and each subsequent
+ * element takes the next consecutive uniform block binding
+ * point."
+ */
+ blocks[i].Binding = (b->has_binding) ? b->binding + j : 0;
+
blocks[i].UniformBufferSize = 0;
blocks[i]._Packing =
gl_uniform_block_packing(block_type->interface_packing);
@@ -265,7 +279,7 @@ link_uniform_blocks(void *mem_ctx,
} else {
blocks[i].Name = ralloc_strdup(blocks, block_type->name);
blocks[i].Uniforms = &variables[parcel.index];
- blocks[i].Binding = 0;
+ blocks[i].Binding = (b->has_binding) ? b->binding : 0;
blocks[i].UniformBufferSize = 0;
blocks[i]._Packing =
gl_uniform_block_packing(block_type->interface_packing);
diff --git a/dist/Mesa/src/glsl/link_uniform_initializers.cpp b/dist/Mesa/src/glsl/link_uniform_initializers.cpp
index 3f6671047..2100e0517 100644
--- a/dist/Mesa/src/glsl/link_uniform_initializers.cpp
+++ b/dist/Mesa/src/glsl/link_uniform_initializers.cpp
@@ -46,6 +46,18 @@ get_storage(gl_uniform_storage *storage, unsigned num_storage,
return NULL;
}
+static unsigned
+get_uniform_block_index(const gl_shader_program *shProg,
+ const char *uniformBlockName)
+{
+ for (unsigned i = 0; i < shProg->NumUniformBlocks; i++) {
+ if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName))
+ return i;
+ }
+
+ return GL_INVALID_INDEX;
+}
+
void
copy_constant_to_storage(union gl_constant_value *storage,
const ir_constant *val,
@@ -69,6 +81,8 @@ copy_constant_to_storage(union gl_constant_value *storage,
break;
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_IMAGE:
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_INTERFACE:
case GLSL_TYPE_VOID:
case GLSL_TYPE_ERROR:
@@ -82,8 +96,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
}
void
-set_uniform_binding(void *mem_ctx, gl_shader_program *prog,
- const char *name, const glsl_type *type, int binding)
+set_sampler_binding(gl_shader_program *prog, const char *name, int binding)
{
struct gl_uniform_storage *const storage =
get_storage(prog->UniformStorage, prog->NumUserUniformStorage, name);
@@ -93,42 +106,53 @@ set_uniform_binding(void *mem_ctx, gl_shader_program *prog,
return;
}
- if (storage->type->is_sampler()) {
- unsigned elements = MAX2(storage->array_elements, 1);
+ const unsigned elements = MAX2(storage->array_elements, 1);
- /* From section 4.4.4 of the GLSL 4.20 specification:
- * "If the binding identifier is used with an array, the first element
- * of the array takes the specified unit and each subsequent element
- * takes the next consecutive unit."
- */
- for (unsigned int i = 0; i < elements; i++) {
- storage->storage[i].i = binding + i;
- }
+ /* Section 4.4.4 (Opaque-Uniform Layout Qualifiers) of the GLSL 4.20 spec
+ * says:
+ *
+ * "If the binding identifier is used with an array, the first element
+ * of the array takes the specified unit and each subsequent element
+ * takes the next consecutive unit."
+ */
+ for (unsigned int i = 0; i < elements; i++) {
+ storage->storage[i].i = binding + i;
+ }
- for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
- gl_shader *shader = prog->_LinkedShaders[sh];
+ for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
+ gl_shader *shader = prog->_LinkedShaders[sh];
- if (shader && storage->sampler[sh].active) {
- for (unsigned i = 0; i < elements; i++) {
- unsigned index = storage->sampler[sh].index + i;
+ if (shader && storage->sampler[sh].active) {
+ for (unsigned i = 0; i < elements; i++) {
+ unsigned index = storage->sampler[sh].index + i;
- shader->SamplerUnits[index] = storage->storage[i].i;
- }
+ shader->SamplerUnits[index] = storage->storage[i].i;
}
}
- } else if (storage->block_index != -1) {
+ }
+
+ storage->initialized = true;
+}
+
+void
+set_block_binding(gl_shader_program *prog, const char *block_name, int binding)
+{
+ const unsigned block_index = get_uniform_block_index(prog, block_name);
+
+ if (block_index == GL_INVALID_INDEX) {
+ assert(block_index != GL_INVALID_INDEX);
+ return;
+ }
+
/* This is a field of a UBO. val is the binding index. */
- for (int i = 0; i < MESA_SHADER_TYPES; i++) {
- int stage_index = prog->UniformBlockStageIndex[i][storage->block_index];
+ for (int i = 0; i < MESA_SHADER_STAGES; i++) {
+ int stage_index = prog->UniformBlockStageIndex[i][block_index];
if (stage_index != -1) {
struct gl_shader *sh = prog->_LinkedShaders[i];
sh->UniformBlocks[stage_index].Binding = binding;
}
}
- }
-
- storage->initialized = true;
}
void
@@ -193,7 +217,7 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
val->type->components());
if (storage->type->is_sampler()) {
- for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
gl_shader *shader = prog->_LinkedShaders[sh];
if (shader && storage->sampler[sh].active) {
@@ -214,7 +238,7 @@ link_set_uniform_initializers(struct gl_shader_program *prog)
{
void *mem_ctx = NULL;
- for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
+ for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) {
struct gl_shader *shader = prog->_LinkedShaders[i];
if (shader == NULL)
@@ -223,15 +247,60 @@ link_set_uniform_initializers(struct gl_shader_program *prog)
foreach_list(node, shader->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (!var || var->mode != ir_var_uniform)
+ if (!var || var->data.mode != ir_var_uniform)
continue;
if (!mem_ctx)
mem_ctx = ralloc_context(NULL);
- if (var->explicit_binding) {
- linker::set_uniform_binding(mem_ctx, prog, var->name,
- var->type, var->binding);
+ if (var->data.explicit_binding) {
+ const glsl_type *const type = var->type;
+
+ if (type->is_sampler()
+ || (type->is_array() && type->fields.array->is_sampler())) {
+ linker::set_sampler_binding(prog, var->name, var->data.binding);
+ } else if (var->is_in_uniform_block()) {
+ const glsl_type *const iface_type = var->get_interface_type();
+
+ /* If the variable is an array and it is an interface instance,
+ * we need to set the binding for each array element. Just
+ * checking that the variable is an array is not sufficient.
+ * The variable could be an array element of a uniform block
+ * that lacks an instance name. For example:
+ *
+ * uniform U {
+ * float f[4];
+ * };
+ *
+ * In this case "f" would pass is_in_uniform_block (above) and
+ * type->is_array(), but it will fail is_interface_instance().
+ */
+ if (var->is_interface_instance() && var->type->is_array()) {
+ for (unsigned i = 0; i < var->type->length; i++) {
+ const char *name =
+ ralloc_asprintf(mem_ctx, "%s[%u]", iface_type->name, i);
+
+ /* Section 4.4.3 (Uniform Block Layout Qualifiers) of the
+ * GLSL 4.20 spec says:
+ *
+ * "If the binding identifier is used with a uniform
+ * block instanced as an array then the first element
+ * of the array takes the specified block binding and
+ * each subsequent element takes the next consecutive
+ * uniform block binding point."
+ */
+ linker::set_block_binding(prog, name,
+ var->data.binding + i);
+ }
+ } else {
+ linker::set_block_binding(prog, iface_type->name,
+ var->data.binding);
+ }
+ } else if (type->contains_atomic()) {
+ /* we don't actually need to do anything. */
+ } else {
+ assert(!"Explicit binding not on a sampler, UBO or atomic.");
+ }
} else if (var->constant_value) {
linker::set_uniform_initializer(mem_ctx, prog, var->name,
var->type, var->constant_value);
diff --git a/dist/Mesa/src/glsl/link_uniforms.cpp b/dist/Mesa/src/glsl/link_uniforms.cpp
index 6cec96e3f..29dc0b196 100644
--- a/dist/Mesa/src/glsl/link_uniforms.cpp
+++ b/dist/Mesa/src/glsl/link_uniforms.cpp
@@ -75,7 +75,63 @@ program_resource_visitor::process(ir_variable *var)
*/
/* Only strdup the name if we actually will need to modify it. */
- if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
+ if (var->data.from_named_ifc_block_array) {
+ /* lower_named_interface_blocks created this variable by lowering an
+ * interface block array to an array variable. For example if the
+ * original source code was:
+ *
+ * out Blk { vec4 bar } foo[3];
+ *
+ * Then the variable is now:
+ *
+ * out vec4 bar[3];
+ *
+ * We need to visit each array element using the names constructed like
+ * so:
+ *
+ * Blk[0].bar
+ * Blk[1].bar
+ * Blk[2].bar
+ */
+ assert(t->is_array());
+ const glsl_type *ifc_type = var->get_interface_type();
+ char *name = ralloc_strdup(NULL, ifc_type->name);
+ size_t name_length = strlen(name);
+ for (unsigned i = 0; i < t->length; i++) {
+ size_t new_length = name_length;
+ ralloc_asprintf_rewrite_tail(&name, &new_length, "[%u].%s", i,
+ var->name);
+ /* Note: row_major is only meaningful for uniform blocks, and
+ * lowering is only applied to non-uniform interface blocks, so we
+ * can safely pass false for row_major.
+ */
+ recursion(var->type, &name, new_length, false, NULL);
+ }
+ ralloc_free(name);
+ } else if (var->data.from_named_ifc_block_nonarray) {
+ /* lower_named_interface_blocks created this variable by lowering a
+ * named interface block (non-array) to an ordinary variable. For
+ * example if the original source code was:
+ *
+ * out Blk { vec4 bar } foo;
+ *
+ * Then the variable is now:
+ *
+ * out vec4 bar;
+ *
+ * We need to visit this variable using the name:
+ *
+ * Blk.bar
+ */
+ const glsl_type *ifc_type = var->get_interface_type();
+ char *name = ralloc_asprintf(NULL, "%s.%s", ifc_type->name, var->name);
+ /* Note: row_major is only meaningful for uniform blocks, and lowering
+ * is only applied to non-uniform interface blocks, so we can safely
+ * pass false for row_major.
+ */
+ recursion(var->type, &name, strlen(name), false, NULL);
+ ralloc_free(name);
+ } else if (t->is_record() || (t->is_array() && t->fields.array->is_record())) {
char *name = ralloc_strdup(NULL, var->name);
recursion(var->type, &name, strlen(name), false, NULL);
ralloc_free(name);
@@ -156,7 +212,7 @@ program_resource_visitor::recursion(const glsl_type *t, char **name,
void
program_resource_visitor::visit_field(const glsl_type *type, const char *name,
bool row_major,
- const glsl_type *record_type)
+ const glsl_type *)
{
visit_field(type, name, row_major);
}
@@ -168,6 +224,8 @@ program_resource_visitor::visit_field(const glsl_struct_field *field)
/* empty */
}
+namespace {
+
/**
* Class to help calculate the storage requirements for a set of uniforms
*
@@ -182,7 +240,8 @@ class count_uniform_size : public program_resource_visitor {
public:
count_uniform_size(struct string_to_uint_map *map)
: num_active_uniforms(0), num_values(0), num_shader_samplers(0),
- num_shader_uniform_components(0), is_ubo_var(false), map(map)
+ num_shader_images(0), num_shader_uniform_components(0),
+ is_ubo_var(false), map(map)
{
/* empty */
}
@@ -190,6 +249,7 @@ public:
void start_shader()
{
this->num_shader_samplers = 0;
+ this->num_shader_images = 0;
this->num_shader_uniform_components = 0;
}
@@ -197,8 +257,8 @@ public:
{
this->is_ubo_var = var->is_in_uniform_block();
if (var->is_interface_instance())
- program_resource_visitor::process(var->interface_type,
- var->interface_type->name);
+ program_resource_visitor::process(var->get_interface_type(),
+ var->get_interface_type()->name);
else
program_resource_visitor::process(var);
}
@@ -219,6 +279,11 @@ public:
unsigned num_shader_samplers;
/**
+ * Number of images used
+ */
+ unsigned num_shader_images;
+
+ /**
* Number of uniforms used in the current shader
*/
unsigned num_shader_uniform_components;
@@ -245,6 +310,15 @@ private:
if (type->contains_sampler()) {
this->num_shader_samplers +=
type->is_array() ? type->array_size() : 1;
+ } else if (type->contains_image()) {
+ this->num_shader_images += values;
+
+ /* As drivers are likely to represent image uniforms as
+ * scalar indices, count them against the limit of uniform
+ * components in the default block. The spec allows image
+ * uniforms to use up no more than one scalar slot.
+ */
+ this->num_shader_uniform_components += values;
} else {
/* Accumulate the total number of uniform slots used by this shader.
* Note that samplers do not count against this limit because they
@@ -272,6 +346,8 @@ private:
struct string_to_uint_map *map;
};
+} /* anonymous namespace */
+
/**
* Class to help parcel out pieces of backing storage to uniforms
*
@@ -296,14 +372,15 @@ public:
{
}
- void start_shader(gl_shader_type shader_type)
+ void start_shader(gl_shader_stage shader_type)
{
- assert(shader_type < MESA_SHADER_TYPES);
+ assert(shader_type < MESA_SHADER_STAGES);
this->shader_type = shader_type;
this->shader_samplers_used = 0;
this->shader_shadow_samplers = 0;
this->next_sampler = 0;
+ this->next_image = 0;
memset(this->targets, 0, sizeof(this->targets));
}
@@ -313,10 +390,10 @@ public:
ubo_block_index = -1;
if (var->is_in_uniform_block()) {
if (var->is_interface_instance() && var->type->is_array()) {
- unsigned l = strlen(var->interface_type->name);
+ unsigned l = strlen(var->get_interface_type()->name);
for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
- if (strncmp(var->interface_type->name,
+ if (strncmp(var->get_interface_type()->name,
prog->UniformBlocks[i].Name,
l) == 0
&& prog->UniformBlocks[i].Name[l] == '[') {
@@ -326,7 +403,7 @@ public:
}
} else {
for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
- if (strcmp(var->interface_type->name,
+ if (strcmp(var->get_interface_type()->name,
prog->UniformBlocks[i].Name) == 0) {
ubo_block_index = i;
break;
@@ -348,17 +425,18 @@ public:
const struct gl_uniform_block *const block =
&prog->UniformBlocks[ubo_block_index];
- assert(var->location != -1);
+ assert(var->data.location != -1);
const struct gl_uniform_buffer_variable *const ubo_var =
- &block->Uniforms[var->location];
+ &block->Uniforms[var->data.location];
ubo_row_major = ubo_var->RowMajor;
ubo_byte_offset = ubo_var->Offset;
}
if (var->is_interface_instance())
- process(var->interface_type, var->interface_type->name);
+ process(var->get_interface_type(),
+ var->get_interface_type()->name);
else
process(var);
} else
@@ -368,7 +446,7 @@ public:
int ubo_block_index;
int ubo_byte_offset;
bool ubo_row_major;
- gl_shader_type shader_type;
+ gl_shader_stage shader_type;
private:
void handle_samplers(const glsl_type *base_type,
@@ -399,6 +477,24 @@ private:
}
}
+ void handle_images(const glsl_type *base_type,
+ struct gl_uniform_storage *uniform)
+ {
+ if (base_type->is_image()) {
+ uniform->image[shader_type].index = this->next_image;
+ uniform->image[shader_type].active = true;
+
+ /* Increment the image index by 1 for non-arrays and by the
+ * number of array elements for arrays.
+ */
+ this->next_image += MAX2(1, uniform->array_elements);
+
+ } else {
+ uniform->image[shader_type].index = ~0;
+ uniform->image[shader_type].active = false;
+ }
+ }
+
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
{
@@ -434,8 +530,9 @@ private:
base_type = type;
}
- /* This assigns sampler uniforms to sampler units. */
+ /* This assigns uniform indices to sampler and image uniforms. */
handle_samplers(base_type, &this->uniforms[id]);
+ handle_images(base_type, &this->uniforms[id]);
/* If there is already storage associated with this uniform, it means
* that it was set while processing an earlier shader stage. For
@@ -452,6 +549,7 @@ private:
this->uniforms[id].num_driver_storage = 0;
this->uniforms[id].driver_storage = NULL;
this->uniforms[id].storage = this->values;
+ this->uniforms[id].atomic_buffer_index = -1;
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
@@ -492,6 +590,7 @@ private:
struct gl_uniform_storage *uniforms;
unsigned next_sampler;
+ unsigned next_image;
public:
union gl_constant_value *values;
@@ -575,10 +674,10 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
if ((var == NULL) || !var->is_in_uniform_block())
continue;
- assert(var->mode == ir_var_uniform);
+ assert(var->data.mode == ir_var_uniform);
if (var->is_interface_instance()) {
- var->location = 0;
+ var->data.location = 0;
continue;
}
@@ -607,13 +706,13 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
if (strncmp(var->name, begin, l) == 0) {
found = true;
- var->location = j;
+ var->data.location = j;
break;
}
} else if (!strcmp(var->name,
shader->UniformBlocks[i].Uniforms[j].Name)) {
found = true;
- var->location = j;
+ var->data.location = j;
break;
}
}
@@ -658,6 +757,41 @@ link_assign_uniform_block_offsets(struct gl_shader *shader)
}
}
+/**
+ * Scan the program for image uniforms and store image unit access
+ * information into the gl_shader data structure.
+ */
+static void
+link_set_image_access_qualifiers(struct gl_shader_program *prog)
+{
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ gl_shader *sh = prog->_LinkedShaders[i];
+
+ if (sh == NULL)
+ continue;
+
+ foreach_list(node, sh->ir) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
+
+ if (var && var->data.mode == ir_var_uniform &&
+ var->type->contains_image()) {
+ unsigned id = 0;
+ bool found = prog->UniformHash->get(id, var->name);
+ assert(found);
+ (void) found;
+ const gl_uniform_storage *storage = &prog->UniformStorage[id];
+ const unsigned index = storage->image[i].index;
+ const GLenum access = (var->data.image.read_only ? GL_READ_ONLY :
+ var->data.image.write_only ? GL_WRITE_ONLY :
+ GL_READ_WRITE);
+
+ for (unsigned j = 0; j < MAX2(1, storage->array_elements); ++j)
+ sh->ImageAccess[index + j] = access;
+ }
+ }
+ }
+}
+
void
link_assign_uniform_locations(struct gl_shader_program *prog)
{
@@ -665,6 +799,10 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
prog->UniformStorage = NULL;
prog->NumUserUniformStorage = 0;
+ ralloc_free(prog->UniformRemapTable);
+ prog->UniformRemapTable = NULL;
+ prog->NumUniformRemapTable = 0;
+
if (prog->UniformHash != NULL) {
prog->UniformHash->clear();
} else {
@@ -679,7 +817,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
* glGetUniformLocation.
*/
count_uniform_size uniform_size(prog->UniformHash);
- for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
struct gl_shader *sh = prog->_LinkedShaders[i];
if (sh == NULL)
@@ -695,6 +833,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
* types cannot have initializers."
*/
memset(sh->SamplerUnits, 0, sizeof(sh->SamplerUnits));
+ memset(sh->ImageUnits, 0, sizeof(sh->ImageUnits));
link_update_uniform_buffer_variables(sh);
@@ -705,7 +844,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform))
+ if ((var == NULL) || (var->data.mode != ir_var_uniform))
continue;
/* FINISHME: Update code to process built-in uniforms!
@@ -720,6 +859,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
}
sh->num_samplers = uniform_size.num_shader_samplers;
+ sh->NumImages = uniform_size.num_shader_images;
sh->num_uniform_components = uniform_size.num_shader_uniform_components;
sh->num_combined_uniform_components = sh->num_uniform_components;
@@ -747,16 +887,16 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data);
- for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
if (prog->_LinkedShaders[i] == NULL)
continue;
- parcel.start_shader((gl_shader_type)i);
+ parcel.start_shader((gl_shader_stage)i);
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform))
+ if ((var == NULL) || (var->data.mode != ir_var_uniform))
continue;
/* FINISHME: Update code to process built-in uniforms!
@@ -775,19 +915,28 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
}
- /* Determine the size of the largest uniform array queryable via
- * glGetUniformLocation. Using this as the location scale guarantees that
- * there is enough "room" for the array index to be stored in the low order
- * part of the uniform location. It also makes the locations be more
- * tightly packed.
- */
- unsigned max_array_size = 1;
+ /* Build the uniform remap table that is used to set/get uniform locations */
for (unsigned i = 0; i < num_user_uniforms; i++) {
- if (uniforms[i].array_elements > max_array_size)
- max_array_size = uniforms[i].array_elements;
- }
- prog->UniformLocationBaseScale = max_array_size;
+ /* how many new entries for this uniform? */
+ const unsigned entries = MAX2(1, uniforms[i].array_elements);
+
+ /* resize remap table to fit new entries */
+ prog->UniformRemapTable =
+ reralloc(prog,
+ prog->UniformRemapTable,
+ gl_uniform_storage *,
+ prog->NumUniformRemapTable + entries);
+
+ /* set pointers for this uniform */
+ for (unsigned j = 0; j < entries; j++)
+ prog->UniformRemapTable[prog->NumUniformRemapTable+j] = &uniforms[i];
+
+ /* set the base location in remap table for the uniform */
+ uniforms[i].remap_location = prog->NumUniformRemapTable;
+
+ prog->NumUniformRemapTable += entries;
+ }
#ifndef NDEBUG
for (unsigned i = 0; i < num_user_uniforms; i++) {
@@ -800,6 +949,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
prog->NumUserUniformStorage = num_user_uniforms;
prog->UniformStorage = uniforms;
+ link_set_image_access_qualifiers(prog);
link_set_uniform_initializers(prog);
return;
diff --git a/dist/Mesa/src/glsl/link_varyings.cpp b/dist/Mesa/src/glsl/link_varyings.cpp
index 51cbdaa0e..ac38a2f31 100644
--- a/dist/Mesa/src/glsl/link_varyings.cpp
+++ b/dist/Mesa/src/glsl/link_varyings.cpp
@@ -41,118 +41,232 @@
/**
+ * Validate the types and qualifiers of an output from one stage against the
+ * matching input to another stage.
+ */
+static void
+cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
+ const ir_variable *input,
+ const ir_variable *output,
+ gl_shader_stage consumer_stage,
+ gl_shader_stage producer_stage)
+{
+ /* Check that the types match between stages.
+ */
+ const glsl_type *type_to_match = input->type;
+ if (consumer_stage == MESA_SHADER_GEOMETRY) {
+ assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
+ type_to_match = type_to_match->element_type();
+ }
+ if (type_to_match != output->type) {
+ /* There is a bit of a special case for gl_TexCoord. This
+ * built-in is unsized by default. Applications that variable
+ * access it must redeclare it with a size. There is some
+ * language in the GLSL spec that implies the fragment shader
+ * and vertex shader do not have to agree on this size. Other
+ * driver behave this way, and one or two applications seem to
+ * rely on it.
+ *
+ * Neither declaration needs to be modified here because the array
+ * sizes are fixed later when update_array_sizes is called.
+ *
+ * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
+ *
+ * "Unlike user-defined varying variables, the built-in
+ * varying variables don't have a strict one-to-one
+ * correspondence between the vertex language and the
+ * fragment language."
+ */
+ if (!output->type->is_array()
+ || (strncmp("gl_", output->name, 3) != 0)) {
+ linker_error(prog,
+ "%s shader output `%s' declared as type `%s', "
+ "but %s shader input declared as type `%s'\n",
+ _mesa_shader_stage_to_string(producer_stage),
+ output->name,
+ output->type->name,
+ _mesa_shader_stage_to_string(consumer_stage),
+ input->type->name);
+ return;
+ }
+ }
+
+ /* Check that all of the qualifiers match between stages.
+ */
+ if (input->data.centroid != output->data.centroid) {
+ linker_error(prog,
+ "%s shader output `%s' %s centroid qualifier, "
+ "but %s shader input %s centroid qualifier\n",
+ _mesa_shader_stage_to_string(producer_stage),
+ output->name,
+ (output->data.centroid) ? "has" : "lacks",
+ _mesa_shader_stage_to_string(consumer_stage),
+ (input->data.centroid) ? "has" : "lacks");
+ return;
+ }
+
+ if (input->data.sample != output->data.sample) {
+ linker_error(prog,
+ "%s shader output `%s' %s sample qualifier, "
+ "but %s shader input %s sample qualifier\n",
+ _mesa_shader_stage_to_string(producer_stage),
+ output->name,
+ (output->data.sample) ? "has" : "lacks",
+ _mesa_shader_stage_to_string(consumer_stage),
+ (input->data.sample) ? "has" : "lacks");
+ return;
+ }
+
+ if (input->data.invariant != output->data.invariant) {
+ linker_error(prog,
+ "%s shader output `%s' %s invariant qualifier, "
+ "but %s shader input %s invariant qualifier\n",
+ _mesa_shader_stage_to_string(producer_stage),
+ output->name,
+ (output->data.invariant) ? "has" : "lacks",
+ _mesa_shader_stage_to_string(consumer_stage),
+ (input->data.invariant) ? "has" : "lacks");
+ return;
+ }
+
+ if (input->data.interpolation != output->data.interpolation) {
+ linker_error(prog,
+ "%s shader output `%s' specifies %s "
+ "interpolation qualifier, "
+ "but %s shader input specifies %s "
+ "interpolation qualifier\n",
+ _mesa_shader_stage_to_string(producer_stage),
+ output->name,
+ interpolation_string(output->data.interpolation),
+ _mesa_shader_stage_to_string(consumer_stage),
+ interpolation_string(input->data.interpolation));
+ return;
+ }
+}
+
+/**
+ * Validate front and back color outputs against single color input
+ */
+static void
+cross_validate_front_and_back_color(struct gl_shader_program *prog,
+ const ir_variable *input,
+ const ir_variable *front_color,
+ const ir_variable *back_color,
+ gl_shader_stage consumer_stage,
+ gl_shader_stage producer_stage)
+{
+ if (front_color != NULL && front_color->data.assigned)
+ cross_validate_types_and_qualifiers(prog, input, front_color,
+ consumer_stage, producer_stage);
+
+ if (back_color != NULL && back_color->data.assigned)
+ cross_validate_types_and_qualifiers(prog, input, back_color,
+ consumer_stage, producer_stage);
+}
+
+/**
* Validate that outputs from one stage match inputs of another
*/
-bool
+void
cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer)
{
glsl_symbol_table parameters;
- const char *const producer_stage =
- _mesa_glsl_shader_target_name(producer->Type);
- const char *const consumer_stage =
- _mesa_glsl_shader_target_name(consumer->Type);
+ ir_variable *explicit_locations[MAX_VARYING] = { NULL, };
/* Find all shader outputs in the "producer" stage.
*/
foreach_list(node, producer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_shader_out))
+ if ((var == NULL) || (var->data.mode != ir_var_shader_out))
continue;
- parameters.add_variable(var);
+ if (!var->data.explicit_location
+ || var->data.location < VARYING_SLOT_VAR0)
+ parameters.add_variable(var);
+ else {
+ /* User-defined varyings with explicit locations are handled
+ * differently because they do not need to have matching names.
+ */
+ const unsigned idx = var->data.location - VARYING_SLOT_VAR0;
+
+ if (explicit_locations[idx] != NULL) {
+ linker_error(prog,
+ "%s shader has multiple outputs explicitly "
+ "assigned to location %d\n",
+ _mesa_shader_stage_to_string(producer->Stage),
+ idx);
+ return;
+ }
+
+ explicit_locations[idx] = var;
+ }
}
/* Find all shader inputs in the "consumer" stage. Any variables that have
* matching outputs already in the symbol table must have the same type and
* qualifiers.
+ *
+ * Exception: if the consumer is the geometry shader, then the inputs
+ * should be arrays and the type of the array element should match the type
+ * of the corresponding producer output.
*/
foreach_list(node, consumer->ir) {
ir_variable *const input = ((ir_instruction *) node)->as_variable();
- if ((input == NULL) || (input->mode != ir_var_shader_in))
+ if ((input == NULL) || (input->data.mode != ir_var_shader_in))
continue;
- ir_variable *const output = parameters.get_variable(input->name);
- if (output != NULL) {
- /* Check that the types match between stages.
- */
- if (input->type != output->type) {
- /* There is a bit of a special case for gl_TexCoord. This
- * built-in is unsized by default. Applications that variable
- * access it must redeclare it with a size. There is some
- * language in the GLSL spec that implies the fragment shader
- * and vertex shader do not have to agree on this size. Other
- * driver behave this way, and one or two applications seem to
- * rely on it.
- *
- * Neither declaration needs to be modified here because the array
- * sizes are fixed later when update_array_sizes is called.
- *
- * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
- *
- * "Unlike user-defined varying variables, the built-in
- * varying variables don't have a strict one-to-one
- * correspondence between the vertex language and the
- * fragment language."
- */
- if (!output->type->is_array()
- || (strncmp("gl_", output->name, 3) != 0)) {
- linker_error(prog,
- "%s shader output `%s' declared as type `%s', "
- "but %s shader input declared as type `%s'\n",
- producer_stage, output->name,
- output->type->name,
- consumer_stage, input->type->name);
- return false;
- }
- }
-
- /* Check that all of the qualifiers match between stages.
- */
- if (input->centroid != output->centroid) {
- linker_error(prog,
- "%s shader output `%s' %s centroid qualifier, "
- "but %s shader input %s centroid qualifier\n",
- producer_stage,
- output->name,
- (output->centroid) ? "has" : "lacks",
- consumer_stage,
- (input->centroid) ? "has" : "lacks");
- return false;
- }
-
- if (input->invariant != output->invariant) {
- linker_error(prog,
- "%s shader output `%s' %s invariant qualifier, "
- "but %s shader input %s invariant qualifier\n",
- producer_stage,
- output->name,
- (output->invariant) ? "has" : "lacks",
- consumer_stage,
- (input->invariant) ? "has" : "lacks");
- return false;
- }
-
- if (input->interpolation != output->interpolation) {
- linker_error(prog,
- "%s shader output `%s' specifies %s "
- "interpolation qualifier, "
- "but %s shader input specifies %s "
- "interpolation qualifier\n",
- producer_stage,
- output->name,
- output->interpolation_string(),
- consumer_stage,
- input->interpolation_string());
- return false;
- }
+ if (strcmp(input->name, "gl_Color") == 0 && input->data.used) {
+ const ir_variable *const front_color =
+ parameters.get_variable("gl_FrontColor");
+
+ const ir_variable *const back_color =
+ parameters.get_variable("gl_BackColor");
+
+ cross_validate_front_and_back_color(prog, input,
+ front_color, back_color,
+ consumer->Stage, producer->Stage);
+ } else if (strcmp(input->name, "gl_SecondaryColor") == 0 && input->data.used) {
+ const ir_variable *const front_color =
+ parameters.get_variable("gl_FrontSecondaryColor");
+
+ const ir_variable *const back_color =
+ parameters.get_variable("gl_BackSecondaryColor");
+
+ cross_validate_front_and_back_color(prog, input,
+ front_color, back_color,
+ consumer->Stage, producer->Stage);
+ } else {
+ /* The rules for connecting inputs and outputs change in the presence
+ * of explicit locations. In this case, we no longer care about the
+ * names of the variables. Instead, we care only about the
+ * explicitly assigned location.
+ */
+ ir_variable *output = NULL;
+ if (input->data.explicit_location
+ && input->data.location >= VARYING_SLOT_VAR0) {
+ output = explicit_locations[input->data.location - VARYING_SLOT_VAR0];
+
+ if (output == NULL) {
+ linker_error(prog,
+ "%s shader input `%s' with explicit location "
+ "has no matching output\n",
+ _mesa_shader_stage_to_string(consumer->Stage),
+ input->name);
+ }
+ } else {
+ output = parameters.get_variable(input->name);
+ }
+
+ if (output != NULL) {
+ cross_validate_types_and_qualifiers(prog, input, output,
+ consumer->Stage, producer->Stage);
+ }
}
}
-
- return true;
}
@@ -165,8 +279,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
* will fail to find any matching variable.
*/
void
-tfeedback_decl::init(struct gl_context *ctx, struct gl_shader_program *prog,
- const void *mem_ctx, const char *input)
+tfeedback_decl::init(struct gl_context *ctx, const void *mem_ctx,
+ const char *input)
{
/* We don't have to be pedantic about what is a valid GLSL variable name,
* because any variable with an invalid name can't exist in the IR anyway.
@@ -255,8 +369,8 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
assert(this->is_varying());
unsigned fine_location
- = this->matched_candidate->toplevel_var->location * 4
- + this->matched_candidate->toplevel_var->location_frac
+ = this->matched_candidate->toplevel_var->data.location * 4
+ + this->matched_candidate->toplevel_var->data.location_frac
+ this->matched_candidate->offset;
if (this->matched_candidate->type->is_array()) {
@@ -266,7 +380,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
const unsigned vector_elements =
this->matched_candidate->type->fields.array->vector_elements;
unsigned actual_array_size = this->is_clip_distance_mesa ?
- prog->Vert.ClipDistanceArraySize :
+ prog->LastClipDistanceArraySize :
this->matched_candidate->type->array_size();
if (this->is_subscripted) {
@@ -436,7 +550,7 @@ parse_tfeedback_decls(struct gl_context *ctx, struct gl_shader_program *prog,
char **varying_names, tfeedback_decl *decls)
{
for (unsigned i = 0; i < num_names; ++i) {
- decls[i].init(ctx, prog, mem_ctx, varying_names[i]);
+ decls[i].init(ctx, mem_ctx, varying_names[i]);
if (!decls[i].is_varying())
continue;
@@ -535,6 +649,7 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
return true;
}
+namespace {
/**
* Data structure recording the relationship between outputs of one shader
@@ -547,7 +662,7 @@ public:
~varying_matches();
void record(ir_variable *producer_var, ir_variable *consumer_var);
unsigned assign_locations();
- void store_locations(unsigned producer_base, unsigned consumer_base) const;
+ void store_locations() const;
private:
/**
@@ -573,8 +688,8 @@ private:
PACKING_ORDER_VEC3,
};
- static unsigned compute_packing_class(ir_variable *var);
- static packing_order_enum compute_packing_order(ir_variable *var);
+ static unsigned compute_packing_class(const ir_variable *var);
+ static packing_order_enum compute_packing_order(const ir_variable *var);
static int match_comparator(const void *x_generic, const void *y_generic);
/**
@@ -627,6 +742,7 @@ private:
const bool consumer_is_fs;
};
+} /* anonymous namespace */
varying_matches::varying_matches(bool disable_varying_packing,
bool consumer_is_fs)
@@ -670,7 +786,10 @@ varying_matches::~varying_matches()
void
varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
{
- if (!producer_var->is_unmatched_generic_inout) {
+ assert(producer_var != NULL || consumer_var != NULL);
+
+ if ((producer_var && !producer_var->data.is_unmatched_generic_inout)
+ || (consumer_var && !consumer_var->data.is_unmatched_generic_inout)) {
/* Either a location already exists for this variable (since it is part
* of fixed functionality), or it has already been recorded as part of a
* previous match.
@@ -688,12 +807,14 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
* regardless of where they appear. We can trivially satisfy that
* requirement by changing the interpolation type to flat here.
*/
- producer_var->centroid = false;
- producer_var->interpolation = INTERP_QUALIFIER_FLAT;
+ producer_var->data.centroid = false;
+ producer_var->data.sample = false;
+ producer_var->data.interpolation = INTERP_QUALIFIER_FLAT;
if (consumer_var) {
- consumer_var->centroid = false;
- consumer_var->interpolation = INTERP_QUALIFIER_FLAT;
+ consumer_var->data.centroid = false;
+ consumer_var->data.sample = false;
+ consumer_var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
}
@@ -703,26 +824,30 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
realloc(this->matches,
sizeof(*this->matches) * this->matches_capacity);
}
+
+ const ir_variable *const var = (producer_var != NULL)
+ ? producer_var : consumer_var;
+
this->matches[this->num_matches].packing_class
- = this->compute_packing_class(producer_var);
+ = this->compute_packing_class(var);
this->matches[this->num_matches].packing_order
- = this->compute_packing_order(producer_var);
+ = this->compute_packing_order(var);
if (this->disable_varying_packing) {
- unsigned slots = producer_var->type->is_array()
- ? (producer_var->type->length
- * producer_var->type->fields.array->matrix_columns)
- : producer_var->type->matrix_columns;
+ unsigned slots = var->type->is_array()
+ ? (var->type->length * var->type->fields.array->matrix_columns)
+ : var->type->matrix_columns;
this->matches[this->num_matches].num_components = 4 * slots;
} else {
this->matches[this->num_matches].num_components
- = producer_var->type->component_slots();
+ = var->type->component_slots();
}
this->matches[this->num_matches].producer_var = producer_var;
this->matches[this->num_matches].consumer_var = consumer_var;
this->num_matches++;
- producer_var->is_unmatched_generic_inout = 0;
+ if (producer_var)
+ producer_var->data.is_unmatched_generic_inout = 0;
if (consumer_var)
- consumer_var->is_unmatched_generic_inout = 0;
+ consumer_var->data.is_unmatched_generic_inout = 0;
}
@@ -764,8 +889,7 @@ varying_matches::assign_locations()
* assignments that were made by varying_matches::assign_locations().
*/
void
-varying_matches::store_locations(unsigned producer_base,
- unsigned consumer_base) const
+varying_matches::store_locations() const
{
for (unsigned i = 0; i < this->num_matches; i++) {
ir_variable *producer_var = this->matches[i].producer_var;
@@ -774,12 +898,15 @@ varying_matches::store_locations(unsigned producer_base,
unsigned slot = generic_location / 4;
unsigned offset = generic_location % 4;
- producer_var->location = producer_base + slot;
- producer_var->location_frac = offset;
+ if (producer_var) {
+ producer_var->data.location = VARYING_SLOT_VAR0 + slot;
+ producer_var->data.location_frac = offset;
+ }
+
if (consumer_var) {
- assert(consumer_var->location == -1);
- consumer_var->location = consumer_base + slot;
- consumer_var->location_frac = offset;
+ assert(consumer_var->data.location == -1);
+ consumer_var->data.location = VARYING_SLOT_VAR0 + slot;
+ consumer_var->data.location_frac = offset;
}
}
}
@@ -791,7 +918,7 @@ varying_matches::store_locations(unsigned producer_base,
* be safely backed into the same vec4.
*/
unsigned
-varying_matches::compute_packing_class(ir_variable *var)
+varying_matches::compute_packing_class(const ir_variable *var)
{
/* Without help from the back-end, there is no way to pack together
* variables with different interpolation types, because
@@ -809,9 +936,9 @@ varying_matches::compute_packing_class(ir_variable *var)
*
* Therefore, the packing class depends only on the interpolation type.
*/
- unsigned packing_class = var->centroid ? 1 : 0;
+ unsigned packing_class = var->data.centroid | (var->data.sample << 1);
packing_class *= 4;
- packing_class += var->interpolation;
+ packing_class += var->data.interpolation;
return packing_class;
}
@@ -822,7 +949,7 @@ varying_matches::compute_packing_class(ir_variable *var)
* other varyings in the same packing class.
*/
varying_matches::packing_order_enum
-varying_matches::compute_packing_order(ir_variable *var)
+varying_matches::compute_packing_order(const ir_variable *var)
{
const glsl_type *element_type = var->type;
@@ -865,12 +992,12 @@ varying_matches::match_comparator(const void *x_generic, const void *y_generic)
* varyings, but excludes variables such as gl_FrontFacing and gl_FragCoord.
*/
static bool
-is_varying_var(GLenum shaderType, const ir_variable *var)
+is_varying_var(gl_shader_stage stage, const ir_variable *var)
{
/* Only fragment shaders will take a varying variable as an input */
- if (shaderType == GL_FRAGMENT_SHADER &&
- var->mode == ir_var_shader_in) {
- switch (var->location) {
+ if (stage == MESA_SHADER_FRAGMENT &&
+ var->data.mode == ir_var_shader_in) {
+ switch (var->data.location) {
case VARYING_SLOT_POS:
case VARYING_SLOT_FACE:
case VARYING_SLOT_PNTC:
@@ -908,8 +1035,8 @@ public:
this->toplevel_var = var;
this->varying_floats = 0;
if (var->is_interface_instance())
- program_resource_visitor::process(var->interface_type,
- var->interface_type->name);
+ program_resource_visitor::process(var->get_interface_type(),
+ var->get_interface_type()->name);
else
program_resource_visitor::process(var);
}
@@ -959,6 +1086,157 @@ private:
};
+namespace linker {
+
+bool
+populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
+ hash_table *consumer_inputs,
+ hash_table *consumer_interface_inputs,
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX])
+{
+ memset(consumer_inputs_with_locations,
+ 0,
+ sizeof(consumer_inputs_with_locations[0]) * VARYING_SLOT_MAX);
+
+ foreach_list(node, ir) {
+ ir_variable *const input_var = ((ir_instruction *) node)->as_variable();
+
+ if ((input_var != NULL) && (input_var->data.mode == ir_var_shader_in)) {
+ if (input_var->type->is_interface())
+ return false;
+
+ if (input_var->data.explicit_location) {
+ /* assign_varying_locations only cares about finding the
+ * ir_variable at the start of a contiguous location block.
+ *
+ * - For !producer, consumer_inputs_with_locations isn't used.
+ *
+ * - For !consumer, consumer_inputs_with_locations is empty.
+ *
+ * For consumer && producer, if you were trying to set some
+ * ir_variable to the middle of a location block on the other side
+ * of producer/consumer, cross_validate_outputs_to_inputs() should
+ * be link-erroring due to either type mismatch or location
+ * overlaps. If the variables do match up, then they've got a
+ * matching data.location and you only looked at
+ * consumer_inputs_with_locations[var->data.location], not any
+ * following entries for the array/structure.
+ */
+ consumer_inputs_with_locations[input_var->data.location] =
+ input_var;
+ } else if (input_var->get_interface_type() != NULL) {
+ char *const iface_field_name =
+ ralloc_asprintf(mem_ctx, "%s.%s",
+ input_var->get_interface_type()->name,
+ input_var->name);
+ hash_table_insert(consumer_interface_inputs, input_var,
+ iface_field_name);
+ } else {
+ hash_table_insert(consumer_inputs, input_var,
+ ralloc_strdup(mem_ctx, input_var->name));
+ }
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Find a variable from the consumer that "matches" the specified variable
+ *
+ * This function only finds inputs with names that match. There is no
+ * validation (here) that the types, etc. are compatible.
+ */
+ir_variable *
+get_matching_input(void *mem_ctx,
+ const ir_variable *output_var,
+ hash_table *consumer_inputs,
+ hash_table *consumer_interface_inputs,
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX])
+{
+ ir_variable *input_var;
+
+ if (output_var->data.explicit_location) {
+ input_var = consumer_inputs_with_locations[output_var->data.location];
+ } else if (output_var->get_interface_type() != NULL) {
+ char *const iface_field_name =
+ ralloc_asprintf(mem_ctx, "%s.%s",
+ output_var->get_interface_type()->name,
+ output_var->name);
+ input_var =
+ (ir_variable *) hash_table_find(consumer_interface_inputs,
+ iface_field_name);
+ } else {
+ input_var =
+ (ir_variable *) hash_table_find(consumer_inputs, output_var->name);
+ }
+
+ return (input_var == NULL || input_var->data.mode != ir_var_shader_in)
+ ? NULL : input_var;
+}
+
+}
+
+static int
+io_variable_cmp(const void *_a, const void *_b)
+{
+ const ir_variable *const a = *(const ir_variable **) _a;
+ const ir_variable *const b = *(const ir_variable **) _b;
+
+ if (a->data.explicit_location && b->data.explicit_location)
+ return b->data.location - a->data.location;
+
+ if (a->data.explicit_location && !b->data.explicit_location)
+ return 1;
+
+ if (!a->data.explicit_location && b->data.explicit_location)
+ return -1;
+
+ return -strcmp(a->name, b->name);
+}
+
+/**
+ * Sort the shader IO variables into canonical order
+ */
+static void
+canonicalize_shader_io(exec_list *ir, enum ir_variable_mode io_mode)
+{
+ ir_variable *var_table[MAX_PROGRAM_OUTPUTS * 4];
+ unsigned num_variables = 0;
+
+ foreach_list(node, ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var == NULL || var->data.mode != io_mode)
+ continue;
+
+ /* If we have already encountered more I/O variables that could
+ * successfully link, bail.
+ */
+ if (num_variables == ARRAY_SIZE(var_table))
+ return;
+
+ var_table[num_variables++] = var;
+ }
+
+ if (num_variables == 0)
+ return;
+
+ /* Sort the list in reverse order (io_variable_cmp handles this). Later
+ * we're going to push the variables on to the IR list as a stack, so we
+ * want the last variable (in canonical order) to be first in the list.
+ */
+ qsort(var_table, num_variables, sizeof(var_table[0]), io_variable_cmp);
+
+ /* Remove the variable from it's current location in the IR, and put it at
+ * the front.
+ */
+ for (unsigned i = 0; i < num_variables; i++) {
+ var_table[i]->remove();
+ ir->push_head(var_table[i]);
+ }
+}
+
/**
* Assign locations for all variables that are produced in one pipeline stage
* (the "producer") and consumed in the next stage (the "consumer").
@@ -975,6 +1253,9 @@ private:
* each of these objects that matches one of the outputs of the
* producer.
*
+ * \param gs_input_vertices: if \c consumer is a geometry shader, this is the
+ * number of input vertices it accepts. Otherwise zero.
+ *
* When num_tfeedback_decls is nonzero, it is permissible for the consumer to
* be NULL. In this case, varying locations are assigned solely based on the
* requirements of transform feedback.
@@ -985,79 +1266,96 @@ assign_varying_locations(struct gl_context *ctx,
struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
- tfeedback_decl *tfeedback_decls)
+ tfeedback_decl *tfeedback_decls,
+ unsigned gs_input_vertices)
{
- const unsigned producer_base = VARYING_SLOT_VAR0;
- const unsigned consumer_base = VARYING_SLOT_VAR0;
varying_matches matches(ctx->Const.DisableVaryingPacking,
- consumer && consumer->Type == GL_FRAGMENT_SHADER);
+ consumer && consumer->Stage == MESA_SHADER_FRAGMENT);
hash_table *tfeedback_candidates
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
hash_table *consumer_inputs
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
hash_table *consumer_interface_inputs
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX] = {
+ NULL,
+ };
- /* Operate in a total of three passes.
+ /* Operate in a total of four passes.
*
- * 1. Assign locations for any matching inputs and outputs.
+ * 1. Sort inputs / outputs into a canonical order. This is necessary so
+ * that inputs / outputs of separable shaders will be assigned
+ * predictable locations regardless of the order in which declarations
+ * appeared in the shader source.
*
- * 2. Mark output variables in the producer that do not have locations as
+ * 2. Assign locations for any matching inputs and outputs.
+ *
+ * 3. Mark output variables in the producer that do not have locations as
* not being outputs. This lets the optimizer eliminate them.
*
- * 3. Mark input variables in the consumer that do not have locations as
+ * 4. Mark input variables in the consumer that do not have locations as
* not being inputs. This lets the optimizer eliminate them.
*/
+ if (consumer)
+ canonicalize_shader_io(consumer->ir, ir_var_shader_in);
+
+ if (producer)
+ canonicalize_shader_io(producer->ir, ir_var_shader_out);
+
+ if (consumer
+ && !linker::populate_consumer_input_sets(mem_ctx,
+ consumer->ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ consumer_inputs_with_locations)) {
+ assert(!"populate_consumer_input_sets failed");
+ hash_table_dtor(tfeedback_candidates);
+ hash_table_dtor(consumer_inputs);
+ hash_table_dtor(consumer_interface_inputs);
+ return false;
+ }
- if (consumer) {
- foreach_list(node, consumer->ir) {
- ir_variable *const input_var =
+ if (producer) {
+ foreach_list(node, producer->ir) {
+ ir_variable *const output_var =
((ir_instruction *) node)->as_variable();
- if ((input_var != NULL) && (input_var->mode == ir_var_shader_in)) {
- if (input_var->interface_type != NULL) {
- char *const iface_field_name =
- ralloc_asprintf(mem_ctx, "%s.%s",
- input_var->interface_type->name,
- input_var->name);
- hash_table_insert(consumer_interface_inputs, input_var,
- iface_field_name);
- } else {
- hash_table_insert(consumer_inputs, input_var,
- ralloc_strdup(mem_ctx, input_var->name));
- }
- }
- }
- }
+ if ((output_var == NULL) ||
+ (output_var->data.mode != ir_var_shader_out))
+ continue;
- foreach_list(node, producer->ir) {
- ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
+ tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
+ g.process(output_var);
- if ((output_var == NULL) || (output_var->mode != ir_var_shader_out))
- continue;
+ ir_variable *const input_var =
+ linker::get_matching_input(mem_ctx, output_var, consumer_inputs,
+ consumer_interface_inputs,
+ consumer_inputs_with_locations);
- tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
- g.process(output_var);
-
- ir_variable *input_var;
- if (output_var->interface_type != NULL) {
- char *const iface_field_name =
- ralloc_asprintf(mem_ctx, "%s.%s",
- output_var->interface_type->name,
- output_var->name);
- input_var =
- (ir_variable *) hash_table_find(consumer_interface_inputs,
- iface_field_name);
- } else {
- input_var =
- (ir_variable *) hash_table_find(consumer_inputs, output_var->name);
+ /* If a matching input variable was found, add this ouptut (and the
+ * input) to the set. If this is a separable program and there is no
+ * consumer stage, add the output.
+ */
+ if (input_var || (prog->SeparateShader && consumer == NULL)) {
+ matches.record(output_var, input_var);
+ }
}
+ } else {
+ /* If there's no producer stage, then this must be a separable program.
+ * For example, we may have a program that has just a fragment shader.
+ * Later this program will be used with some arbitrary vertex (or
+ * geometry) shader program. This means that locations must be assigned
+ * for all the inputs.
+ */
+ foreach_list(node, consumer->ir) {
+ ir_variable *const input_var =
+ ((ir_instruction *) node)->as_variable();
- if (input_var && input_var->mode != ir_var_shader_in)
- input_var = NULL;
+ if ((input_var == NULL) ||
+ (input_var->data.mode != ir_var_shader_in))
+ continue;
- if (input_var) {
- matches.record(output_var, input_var);
+ matches.record(NULL, input_var);
}
}
@@ -1075,12 +1373,12 @@ assign_varying_locations(struct gl_context *ctx,
return false;
}
- if (matched_candidate->toplevel_var->is_unmatched_generic_inout)
+ if (matched_candidate->toplevel_var->data.is_unmatched_generic_inout)
matches.record(matched_candidate->toplevel_var, NULL);
}
const unsigned slots_used = matches.assign_locations();
- matches.store_locations(producer_base, consumer_base);
+ matches.store_locations();
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
if (!tfeedback_decls[i].is_varying())
@@ -1105,20 +1403,22 @@ assign_varying_locations(struct gl_context *ctx,
*/
assert(!ctx->Extensions.EXT_transform_feedback);
} else {
- lower_packed_varyings(mem_ctx, producer_base, slots_used,
- ir_var_shader_out, producer);
+ if (producer) {
+ lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out,
+ 0, producer);
+ }
if (consumer) {
- lower_packed_varyings(mem_ctx, consumer_base, slots_used,
- ir_var_shader_in, consumer);
+ lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in,
+ gs_input_vertices, consumer);
}
}
- if (consumer) {
+ if (consumer && producer) {
foreach_list(node, consumer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (var && var->mode == ir_var_shader_in &&
- var->is_unmatched_generic_inout) {
+ if (var && var->data.mode == ir_var_shader_in &&
+ var->data.is_unmatched_generic_inout) {
if (prog->Version <= 120) {
/* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
*
@@ -1135,15 +1435,15 @@ assign_varying_locations(struct gl_context *ctx,
linker_error(prog, "%s shader varying %s not written "
"by %s shader\n.",
- _mesa_glsl_shader_target_name(consumer->Type),
+ _mesa_shader_stage_to_string(consumer->Stage),
var->name,
- _mesa_glsl_shader_target_name(producer->Type));
+ _mesa_shader_stage_to_string(producer->Stage));
}
/* An 'in' variable is only really a shader input if its
* value is written by the previous stage.
*/
- var->mode = ir_var_auto;
+ var->data.mode = ir_var_auto;
}
}
}
@@ -1152,40 +1452,79 @@ assign_varying_locations(struct gl_context *ctx,
}
bool
-check_against_varying_limit(struct gl_context *ctx,
- struct gl_shader_program *prog,
- gl_shader *consumer)
+check_against_output_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *producer)
{
- unsigned varying_vectors = 0;
+ unsigned output_vectors = 0;
- foreach_list(node, consumer->ir) {
+ foreach_list(node, producer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (var && var->mode == ir_var_shader_in &&
- is_varying_var(consumer->Type, var)) {
- /* The packing rules used for vertex shader inputs are also
- * used for fragment shader inputs.
- */
- varying_vectors += count_attribute_slots(var->type);
+ if (var && var->data.mode == ir_var_shader_out &&
+ is_varying_var(producer->Stage, var)) {
+ output_vectors += var->type->count_attribute_slots();
}
}
- if (ctx->API == API_OPENGLES2 || prog->IsES) {
- if (varying_vectors > ctx->Const.MaxVarying) {
- linker_error(prog, "shader uses too many varying vectors "
+ assert(producer->Stage != MESA_SHADER_FRAGMENT);
+ unsigned max_output_components =
+ ctx->Const.Program[producer->Stage].MaxOutputComponents;
+
+ const unsigned output_components = output_vectors * 4;
+ if (output_components > max_output_components) {
+ if (ctx->API == API_OPENGLES2 || prog->IsES)
+ linker_error(prog, "shader uses too many output vectors "
"(%u > %u)\n",
- varying_vectors, ctx->Const.MaxVarying);
- return false;
- }
- } else {
- const unsigned float_components = varying_vectors * 4;
- if (float_components > ctx->Const.MaxVarying * 4) {
- linker_error(prog, "shader uses too many varying components "
+ output_vectors,
+ max_output_components / 4);
+ else
+ linker_error(prog, "shader uses too many output components "
"(%u > %u)\n",
- float_components, ctx->Const.MaxVarying * 4);
- return false;
+ output_components,
+ max_output_components);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool
+check_against_input_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *consumer)
+{
+ unsigned input_vectors = 0;
+
+ foreach_list(node, consumer->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var && var->data.mode == ir_var_shader_in &&
+ is_varying_var(consumer->Stage, var)) {
+ input_vectors += var->type->count_attribute_slots();
}
}
+ assert(consumer->Stage != MESA_SHADER_VERTEX);
+ unsigned max_input_components =
+ ctx->Const.Program[consumer->Stage].MaxInputComponents;
+
+ const unsigned input_components = input_vectors * 4;
+ if (input_components > max_input_components) {
+ if (ctx->API == API_OPENGLES2 || prog->IsES)
+ linker_error(prog, "shader uses too many input vectors "
+ "(%u > %u)\n",
+ input_vectors,
+ max_input_components / 4);
+ else
+ linker_error(prog, "shader uses too many input components "
+ "(%u > %u)\n",
+ input_components,
+ max_input_components);
+
+ return false;
+ }
+
return true;
}
diff --git a/dist/Mesa/src/glsl/link_varyings.h b/dist/Mesa/src/glsl/link_varyings.h
index 7f7be353b..6fa268176 100644
--- a/dist/Mesa/src/glsl/link_varyings.h
+++ b/dist/Mesa/src/glsl/link_varyings.h
@@ -91,8 +91,7 @@ struct tfeedback_candidate
class tfeedback_decl
{
public:
- void init(struct gl_context *ctx, struct gl_shader_program *prog,
- const void *mem_ctx, const char *input);
+ void init(struct gl_context *ctx, const void *mem_ctx, const char *input);
static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
bool assign_location(struct gl_context *ctx,
struct gl_shader_program *prog);
@@ -214,7 +213,7 @@ private:
};
-bool
+void
cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer);
@@ -234,11 +233,17 @@ assign_varying_locations(struct gl_context *ctx,
struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer,
unsigned num_tfeedback_decls,
- tfeedback_decl *tfeedback_decls);
+ tfeedback_decl *tfeedback_decls,
+ unsigned gs_input_vertices);
+
+bool
+check_against_output_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *producer);
bool
-check_against_varying_limit(struct gl_context *ctx,
- struct gl_shader_program *prog,
- gl_shader *consumer);
+check_against_input_limit(struct gl_context *ctx,
+ struct gl_shader_program *prog,
+ gl_shader *consumer);
#endif /* GLSL_LINK_VARYINGS_H */
diff --git a/dist/Mesa/src/glsl/list.h b/dist/Mesa/src/glsl/list.h
index 1d46365fa..694b686b0 100644
--- a/dist/Mesa/src/glsl/list.h
+++ b/dist/Mesa/src/glsl/list.h
@@ -76,24 +76,7 @@ struct exec_node {
struct exec_node *prev;
#ifdef __cplusplus
- /* Callers of this ralloc-based new need not call delete. It's
- * easier to just ralloc_free 'ctx' (or any of its ancestors). */
- static void* operator new(size_t size, void *ctx)
- {
- void *node;
-
- node = ralloc_size(ctx, size);
- assert(node != NULL);
-
- return node;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * ralloc_free in that case. */
- static void operator delete(void *node)
- {
- ralloc_free(node);
- }
+ DECLARE_RALLOC_CXX_OPERATORS(exec_node)
exec_node() : next(NULL), prev(NULL)
{
@@ -223,86 +206,15 @@ struct exec_node {
#ifdef __cplusplus
struct exec_node;
-
-class iterator {
-public:
- void next()
- {
- }
-
- void *get()
- {
- return NULL;
- }
-
- bool has_next() const
- {
- return false;
- }
-};
-
-class exec_list_iterator : public iterator {
-public:
- exec_list_iterator(exec_node *n) : node(n), _next(n->next)
- {
- /* empty */
- }
-
- void next()
- {
- node = _next;
- _next = node->next;
- }
-
- void remove()
- {
- node->remove();
- }
-
- exec_node *get()
- {
- return node;
- }
-
- bool has_next() const
- {
- return _next != NULL;
- }
-
-private:
- exec_node *node;
- exec_node *_next;
-};
-
-#define foreach_iter(iter_type, iter, container) \
- for (iter_type iter = (container) . iterator(); iter.has_next(); iter.next())
#endif
-
struct exec_list {
struct exec_node *head;
struct exec_node *tail;
struct exec_node *tail_pred;
#ifdef __cplusplus
- /* Callers of this ralloc-based new need not call delete. It's
- * easier to just ralloc_free 'ctx' (or any of its ancestors). */
- static void* operator new(size_t size, void *ctx)
- {
- void *node;
-
- node = ralloc_size(ctx, size);
- assert(node != NULL);
-
- return node;
- }
-
- /* If the user *does* call delete, that's OK, we will just
- * ralloc_free in that case. */
- static void operator delete(void *node)
- {
- ralloc_free(node);
- }
+ DECLARE_RALLOC_CXX_OPERATORS(exec_list)
exec_list()
{
@@ -438,16 +350,6 @@ struct exec_list {
*/
source->make_empty();
}
-
- exec_list_iterator iterator()
- {
- return exec_list_iterator(head);
- }
-
- exec_list_iterator iterator() const
- {
- return exec_list_iterator((exec_node *) head);
- }
#endif
};
@@ -481,6 +383,22 @@ inline void exec_node::insert_before(exec_list *before)
; (__node)->next != NULL \
; (__node) = (__node)->next)
+/**
+ * Iterate through two lists at once. Stops at the end of the shorter list.
+ *
+ * This is safe against either current node being removed or replaced.
+ */
+#define foreach_two_lists(__node1, __list1, __node2, __list2) \
+ for (exec_node * __node1 = (__list1)->head, \
+ * __node2 = (__list2)->head, \
+ * __next1 = __node1->next, \
+ * __next2 = __node2->next \
+ ; __next1 != NULL && __next2 != NULL \
+ ; __node1 = __next1, \
+ __node2 = __next2, \
+ __next1 = __next1->next, \
+ __next2 = __next2->next)
+
#define foreach_list_const(__node, __list) \
for (const exec_node * __node = (__list)->head \
; (__node)->next != NULL \
diff --git a/dist/Mesa/src/glsl/loop_controls.cpp b/dist/Mesa/src/glsl/loop_controls.cpp
index 79c820436..3db06ad18 100644
--- a/dist/Mesa/src/glsl/loop_controls.cpp
+++ b/dist/Mesa/src/glsl/loop_controls.cpp
@@ -151,6 +151,7 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
return (valid_loop) ? iter_value : -1;
}
+namespace {
class loop_control_visitor : public ir_hierarchical_visitor {
public:
@@ -167,6 +168,7 @@ public:
bool progress;
};
+} /* anonymous namespace */
ir_visitor_status
loop_control_visitor::visit_leave(ir_loop *ir)
@@ -181,114 +183,41 @@ loop_control_visitor::visit_leave(ir_loop *ir)
return visit_continue;
}
- /* Search the loop terminating conditions for one of the form 'i < c' where
- * i is a loop induction variable, c is a constant, and < is any relative
- * operator.
- */
- int max_iterations = ls->max_iterations;
-
- if(ir->from && ir->to && ir->increment)
- max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp);
-
- if(max_iterations < 0)
- max_iterations = INT_MAX;
+ if (ls->limiting_terminator != NULL) {
+ /* If the limiting terminator has an iteration count of zero, then we've
+ * proven that the loop cannot run, so delete it.
+ */
+ int iterations = ls->limiting_terminator->iterations;
+ if (iterations == 0) {
+ ir->remove();
+ this->progress = true;
+ return visit_continue;
+ }
+ }
+ /* Remove the conditional break statements associated with all terminators
+ * that are associated with a fixed iteration count, except for the one
+ * associated with the limiting terminator--that one needs to stay, since
+ * it terminates the loop. Exception: if the loop still has a normative
+ * bound, then that terminates the loop, so we don't even need the limiting
+ * terminator.
+ */
foreach_list(node, &ls->terminators) {
loop_terminator *t = (loop_terminator *) node;
- ir_if *if_stmt = t->ir;
- /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
- * about the former here.
- */
- ir_expression *cond = if_stmt->condition->as_expression();
- if (cond == NULL)
- continue;
-
- switch (cond->operation) {
- case ir_binop_less:
- case ir_binop_greater:
- case ir_binop_lequal:
- case ir_binop_gequal: {
- /* The expressions that we care about will either be of the form
- * 'counter < limit' or 'limit < counter'. Figure out which is
- * which.
- */
- ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
- ir_constant *limit = cond->operands[1]->as_constant();
- enum ir_expression_operation cmp = cond->operation;
-
- if (limit == NULL) {
- counter = cond->operands[1]->as_dereference_variable();
- limit = cond->operands[0]->as_constant();
-
- switch (cmp) {
- case ir_binop_less: cmp = ir_binop_greater; break;
- case ir_binop_greater: cmp = ir_binop_less; break;
- case ir_binop_lequal: cmp = ir_binop_gequal; break;
- case ir_binop_gequal: cmp = ir_binop_lequal; break;
- default: assert(!"Should not get here.");
- }
- }
-
- if ((counter == NULL) || (limit == NULL))
- break;
-
- ir_variable *var = counter->variable_referenced();
-
- ir_rvalue *init = find_initial_value(ir, var);
-
- foreach_list(iv_node, &ls->induction_variables) {
- loop_variable *lv = (loop_variable *) iv_node;
-
- if (lv->var == var) {
- const int iterations = calculate_iterations(init, limit,
- lv->increment,
- cmp);
- if (iterations >= 0) {
- /* If the new iteration count is lower than the previously
- * believed iteration count, update the loop control values.
- */
- if (iterations < max_iterations) {
- ir->from = init->clone(ir, NULL);
- ir->to = limit->clone(ir, NULL);
- ir->increment = lv->increment->clone(ir, NULL);
- ir->counter = lv->var;
- ir->cmp = cmp;
-
- max_iterations = iterations;
- }
-
- /* Remove the conditional break statement. The loop
- * controls are now set such that the exit condition will be
- * satisfied.
- */
- if_stmt->remove();
-
- assert(ls->num_loop_jumps > 0);
- ls->num_loop_jumps--;
-
- this->progress = true;
- }
-
- break;
- }
- }
- break;
- }
+ if (t->iterations < 0)
+ continue;
- default:
- break;
+ if (t != ls->limiting_terminator) {
+ t->ir->remove();
+
+ assert(ls->num_loop_jumps > 0);
+ ls->num_loop_jumps--;
+
+ this->progress = true;
}
}
- /* If we have proven the one of the loop exit conditions is satisifed before
- * running the loop once, remove the loop.
- */
- if (max_iterations == 0)
- ir->remove();
- else
- ls->max_iterations = max_iterations;
-
return visit_continue;
}
diff --git a/dist/Mesa/src/glsl/loop_unroll.cpp b/dist/Mesa/src/glsl/loop_unroll.cpp
index 3434fde62..da532804a 100644
--- a/dist/Mesa/src/glsl/loop_unroll.cpp
+++ b/dist/Mesa/src/glsl/loop_unroll.cpp
@@ -25,23 +25,33 @@
#include "loop_analysis.h"
#include "ir_hierarchical_visitor.h"
+#include "main/mtypes.h"
+
+namespace {
+
class loop_unroll_visitor : public ir_hierarchical_visitor {
public:
- loop_unroll_visitor(loop_state *state, unsigned max_iterations)
+ loop_unroll_visitor(loop_state *state,
+ const struct gl_shader_compiler_options *options)
{
this->state = state;
this->progress = false;
- this->max_iterations = max_iterations;
+ this->options = options;
}
virtual ir_visitor_status visit_leave(ir_loop *ir);
+ void simple_unroll(ir_loop *ir, int iterations);
+ void complex_unroll(ir_loop *ir, int iterations,
+ bool continue_from_then_branch);
+ void splice_post_if_instructions(ir_if *ir_if, exec_list *splice_dest);
loop_state *state;
bool progress;
- unsigned max_iterations;
+ const struct gl_shader_compiler_options *options;
};
+} /* anonymous namespace */
static bool
is_break(ir_instruction *ir)
@@ -53,36 +63,221 @@ is_break(ir_instruction *ir)
class loop_unroll_count : public ir_hierarchical_visitor {
public:
int nodes;
- bool fail;
+ bool unsupported_variable_indexing;
+ /* If there are nested loops, the node count will be inaccurate. */
+ bool nested_loop;
- loop_unroll_count(exec_list *list)
+ loop_unroll_count(exec_list *list, loop_variable_state *ls,
+ const struct gl_shader_compiler_options *options)
+ : ls(ls), options(options)
{
nodes = 0;
- fail = false;
+ nested_loop = false;
+ unsupported_variable_indexing = false;
run(list);
}
- virtual ir_visitor_status visit_enter(ir_assignment *ir)
+ virtual ir_visitor_status visit_enter(ir_assignment *)
{
nodes++;
return visit_continue;
}
- virtual ir_visitor_status visit_enter(ir_expression *ir)
+ virtual ir_visitor_status visit_enter(ir_expression *)
{
nodes++;
return visit_continue;
}
- virtual ir_visitor_status visit_enter(ir_loop *ir)
+ virtual ir_visitor_status visit_enter(ir_loop *)
{
- fail = true;
+ nested_loop = true;
return visit_continue;
}
+
+ virtual ir_visitor_status visit_enter(ir_dereference_array *ir)
+ {
+ /* Check for arrays variably-indexed by a loop induction variable.
+ * Unrolling the loop may convert that access into constant-indexing.
+ *
+ * Many drivers don't support particular kinds of variable indexing,
+ * and have to resort to using lower_variable_index_to_cond_assign to
+ * handle it. This results in huge amounts of horrible code, so we'd
+ * like to avoid that if possible. Here, we just note that it will
+ * happen.
+ */
+ if ((ir->array->type->is_array() || ir->array->type->is_matrix()) &&
+ !ir->array_index->as_constant()) {
+ ir_variable *array = ir->array->variable_referenced();
+ loop_variable *lv = ls->get(ir->array_index->variable_referenced());
+ if (array && lv && lv->is_induction_var()) {
+ switch (array->data.mode) {
+ case ir_var_auto:
+ case ir_var_temporary:
+ case ir_var_const_in:
+ case ir_var_function_in:
+ case ir_var_function_out:
+ case ir_var_function_inout:
+ if (options->EmitNoIndirectTemp)
+ unsupported_variable_indexing = true;
+ break;
+ case ir_var_uniform:
+ if (options->EmitNoIndirectUniform)
+ unsupported_variable_indexing = true;
+ break;
+ case ir_var_shader_in:
+ if (options->EmitNoIndirectInput)
+ unsupported_variable_indexing = true;
+ break;
+ case ir_var_shader_out:
+ if (options->EmitNoIndirectOutput)
+ unsupported_variable_indexing = true;
+ break;
+ }
+ }
+ }
+ return visit_continue;
+ }
+
+private:
+ loop_variable_state *ls;
+ const struct gl_shader_compiler_options *options;
};
+/**
+ * Unroll a loop which does not contain any jumps. For example, if the input
+ * is:
+ *
+ * (loop (...) ...instrs...)
+ *
+ * And the iteration count is 3, the output will be:
+ *
+ * ...instrs... ...instrs... ...instrs...
+ */
+void
+loop_unroll_visitor::simple_unroll(ir_loop *ir, int iterations)
+{
+ void *const mem_ctx = ralloc_parent(ir);
+
+ for (int i = 0; i < iterations; i++) {
+ exec_list copy_list;
+
+ copy_list.make_empty();
+ clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
+
+ ir->insert_before(&copy_list);
+ }
+
+ /* The loop has been replaced by the unrolled copies. Remove the original
+ * loop from the IR sequence.
+ */
+ ir->remove();
+
+ this->progress = true;
+}
+
+
+/**
+ * Unroll a loop whose last statement is an ir_if. If \c
+ * continue_from_then_branch is true, the loop is repeated only when the
+ * "then" branch of the if is taken; otherwise it is repeated only when the
+ * "else" branch of the if is taken.
+ *
+ * For example, if the input is:
+ *
+ * (loop (...)
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...)
+ * (...else_instrs...)))
+ *
+ * And the iteration count is 3, and \c continue_from_then_branch is true,
+ * then the output will be:
+ *
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...)
+ * (...else_instrs...)))
+ * (...else_instrs...)))
+ * (...else_instrs))
+ */
+void
+loop_unroll_visitor::complex_unroll(ir_loop *ir, int iterations,
+ bool continue_from_then_branch)
+{
+ void *const mem_ctx = ralloc_parent(ir);
+ ir_instruction *ir_to_replace = ir;
+
+ for (int i = 0; i < iterations; i++) {
+ exec_list copy_list;
+
+ copy_list.make_empty();
+ clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
+
+ ir_if *ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
+ assert(ir_if != NULL);
+
+ ir_to_replace->insert_before(&copy_list);
+ ir_to_replace->remove();
+
+ /* placeholder that will be removed in the next iteration */
+ ir_to_replace =
+ new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+
+ exec_list *const list = (continue_from_then_branch)
+ ? &ir_if->then_instructions : &ir_if->else_instructions;
+
+ list->push_tail(ir_to_replace);
+ }
+
+ ir_to_replace->remove();
+
+ this->progress = true;
+}
+
+
+/**
+ * Move all of the instructions which follow \c ir_if to the end of
+ * \c splice_dest.
+ *
+ * For example, in the code snippet:
+ *
+ * (if (cond)
+ * (...then_instructions...
+ * break)
+ * (...else_instructions...))
+ * ...post_if_instructions...
+ *
+ * If \c ir_if points to the "if" instruction, and \c splice_dest points to
+ * (...else_instructions...), the code snippet is transformed into:
+ *
+ * (if (cond)
+ * (...then_instructions...
+ * break)
+ * (...else_instructions...
+ * ...post_if_instructions...))
+ */
+void
+loop_unroll_visitor::splice_post_if_instructions(ir_if *ir_if,
+ exec_list *splice_dest)
+{
+ while (!ir_if->get_next()->is_tail_sentinel()) {
+ ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
+
+ move_ir->remove();
+ splice_dest->push_tail(move_ir);
+ }
+}
+
+
ir_visitor_status
loop_unroll_visitor::visit_leave(ir_loop *ir)
{
@@ -97,155 +292,117 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
return visit_continue;
}
- iterations = ls->max_iterations;
-
/* Don't try to unroll loops where the number of iterations is not known
* at compile-time.
*/
- if (iterations < 0)
+ if (ls->limiting_terminator == NULL)
return visit_continue;
+ iterations = ls->limiting_terminator->iterations;
+
+ const int max_iterations = options->MaxUnrollIterations;
+
/* Don't try to unroll loops that have zillions of iterations either.
*/
- if (iterations > (int) max_iterations)
+ if (iterations > max_iterations)
return visit_continue;
/* Don't try to unroll nested loops and loops with a huge body.
*/
- loop_unroll_count count(&ir->body_instructions);
+ loop_unroll_count count(&ir->body_instructions, ls, options);
- if (count.fail || count.nodes * iterations > (int)max_iterations * 5)
- return visit_continue;
+ bool loop_too_large =
+ count.nested_loop || count.nodes * iterations > max_iterations * 5;
- if (ls->num_loop_jumps > 1)
+ if (loop_too_large && !count.unsupported_variable_indexing)
return visit_continue;
- else if (ls->num_loop_jumps) {
- ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
- assert(last_ir != NULL);
-
- if (is_break(last_ir)) {
- /* If the only loop-jump is a break at the end of the loop, the loop
- * will execute exactly once. Remove the break, set the iteration
- * count, and fall through to the normal unroller.
- */
- last_ir->remove();
- iterations = 1;
-
- this->progress = true;
- } else {
- ir_if *ir_if = NULL;
- ir_instruction *break_ir = NULL;
- bool continue_from_then_branch = false;
-
- foreach_list(node, &ir->body_instructions) {
- /* recognize loops in the form produced by ir_lower_jumps */
- ir_instruction *cur_ir = (ir_instruction *) node;
-
- ir_if = cur_ir->as_if();
- if (ir_if != NULL) {
- /* Determine which if-statement branch, if any, ends with a
- * break. The branch that did *not* have the break will get a
- * temporary continue inserted in each iteration of the loop
- * unroll.
- *
- * Note that since ls->num_loop_jumps is <= 1, it is impossible
- * for both branches to end with a break.
- */
- ir_instruction *ir_if_last =
- (ir_instruction *) ir_if->then_instructions.get_tail();
-
- if (is_break(ir_if_last)) {
- continue_from_then_branch = false;
- break_ir = ir_if_last;
- break;
- } else {
- ir_if_last =
- (ir_instruction *) ir_if->else_instructions.get_tail();
-
- if (is_break(ir_if_last)) {
- break_ir = ir_if_last;
- continue_from_then_branch = true;
- break;
- }
- }
- }
- }
-
- if (break_ir == NULL)
- return visit_continue;
-
- /* move instructions after then if in the continue branch */
- while (!ir_if->get_next()->is_tail_sentinel()) {
- ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
-
- move_ir->remove();
- if (continue_from_then_branch)
- ir_if->then_instructions.push_tail(move_ir);
- else
- ir_if->else_instructions.push_tail(move_ir);
- }
-
- /* Remove the break from the if-statement.
- */
- break_ir->remove();
- void *const mem_ctx = ralloc_parent(ir);
- ir_instruction *ir_to_replace = ir;
-
- for (int i = 0; i < iterations; i++) {
- exec_list copy_list;
+ /* Note: the limiting terminator contributes 1 to ls->num_loop_jumps.
+ * We'll be removing the limiting terminator before we unroll.
+ */
+ assert(ls->num_loop_jumps > 0);
+ unsigned predicted_num_loop_jumps = ls->num_loop_jumps - 1;
- copy_list.make_empty();
- clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
+ if (predicted_num_loop_jumps > 1)
+ return visit_continue;
- ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
- assert(ir_if != NULL);
+ if (predicted_num_loop_jumps == 0) {
+ ls->limiting_terminator->ir->remove();
+ simple_unroll(ir, iterations);
+ return visit_continue;
+ }
- ir_to_replace->insert_before(&copy_list);
- ir_to_replace->remove();
+ ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
+ assert(last_ir != NULL);
- /* placeholder that will be removed in the next iteration */
- ir_to_replace =
- new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+ if (is_break(last_ir)) {
+ /* If the only loop-jump is a break at the end of the loop, the loop
+ * will execute exactly once. Remove the break and use the simple
+ * unroller with an iteration count of 1.
+ */
+ last_ir->remove();
- exec_list *const list = (continue_from_then_branch)
- ? &ir_if->then_instructions : &ir_if->else_instructions;
+ ls->limiting_terminator->ir->remove();
+ simple_unroll(ir, 1);
+ return visit_continue;
+ }
- list->push_tail(ir_to_replace);
+ foreach_list(node, &ir->body_instructions) {
+ /* recognize loops in the form produced by ir_lower_jumps */
+ ir_instruction *cur_ir = (ir_instruction *) node;
+
+ /* Skip the limiting terminator, since it will go away when we
+ * unroll.
+ */
+ if (cur_ir == ls->limiting_terminator->ir)
+ continue;
+
+ ir_if *ir_if = cur_ir->as_if();
+ if (ir_if != NULL) {
+ /* Determine which if-statement branch, if any, ends with a
+ * break. The branch that did *not* have the break will get a
+ * temporary continue inserted in each iteration of the loop
+ * unroll.
+ *
+ * Note that since ls->num_loop_jumps is <= 1, it is impossible
+ * for both branches to end with a break.
+ */
+ ir_instruction *ir_if_last =
+ (ir_instruction *) ir_if->then_instructions.get_tail();
+
+ if (is_break(ir_if_last)) {
+ ls->limiting_terminator->ir->remove();
+ splice_post_if_instructions(ir_if, &ir_if->else_instructions);
+ ir_if_last->remove();
+ complex_unroll(ir, iterations, false);
+ return visit_continue;
+ } else {
+ ir_if_last =
+ (ir_instruction *) ir_if->else_instructions.get_tail();
+
+ if (is_break(ir_if_last)) {
+ ls->limiting_terminator->ir->remove();
+ splice_post_if_instructions(ir_if, &ir_if->then_instructions);
+ ir_if_last->remove();
+ complex_unroll(ir, iterations, true);
+ return visit_continue;
+ }
}
-
- ir_to_replace->remove();
-
- this->progress = true;
- return visit_continue;
}
}
- void *const mem_ctx = ralloc_parent(ir);
-
- for (int i = 0; i < iterations; i++) {
- exec_list copy_list;
-
- copy_list.make_empty();
- clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
-
- ir->insert_before(&copy_list);
- }
-
- /* The loop has been replaced by the unrolled copies. Remove the original
- * loop from the IR sequence.
+ /* Did not find the break statement. It must be in a complex if-nesting,
+ * so don't try to unroll.
*/
- ir->remove();
-
- this->progress = true;
return visit_continue;
}
bool
-unroll_loops(exec_list *instructions, loop_state *ls, unsigned max_iterations)
+unroll_loops(exec_list *instructions, loop_state *ls,
+ const struct gl_shader_compiler_options *options)
{
- loop_unroll_visitor v(ls, max_iterations);
+ loop_unroll_visitor v(ls, options);
v.run(instructions);
diff --git a/dist/Mesa/src/glsl/lower_clip_distance.cpp b/dist/Mesa/src/glsl/lower_clip_distance.cpp
index 50cd31552..2d6138d5a 100644
--- a/dist/Mesa/src/glsl/lower_clip_distance.cpp
+++ b/dist/Mesa/src/glsl/lower_clip_distance.cpp
@@ -50,16 +50,21 @@
#include "ir.h"
#include "program/prog_instruction.h" /* For WRITEMASK_* */
+namespace {
+
class lower_clip_distance_visitor : public ir_rvalue_visitor {
public:
- lower_clip_distance_visitor()
- : progress(false), old_clip_distance_var(NULL),
- new_clip_distance_var(NULL)
+ explicit lower_clip_distance_visitor(gl_shader_stage shader_stage)
+ : progress(false), old_clip_distance_1d_var(NULL),
+ old_clip_distance_2d_var(NULL), new_clip_distance_1d_var(NULL),
+ new_clip_distance_2d_var(NULL), shader_stage(shader_stage)
{
}
virtual ir_visitor_status visit(ir_variable *);
void create_indices(ir_rvalue*, ir_rvalue *&, ir_rvalue *&);
+ bool is_clip_distance_vec8(ir_rvalue *ir);
+ ir_rvalue *lower_clip_distance_vec8(ir_rvalue *ir);
virtual ir_visitor_status visit_leave(ir_assignment *);
void visit_new_assignment(ir_assignment *ir);
virtual ir_visitor_status visit_leave(ir_call *);
@@ -72,15 +77,31 @@ public:
/**
* Pointer to the declaration of gl_ClipDistance, if found.
+ *
+ * Note:
+ *
+ * - the 2d_var is for geometry shader input only.
+ *
+ * - since gl_ClipDistance is available in geometry shaders as both an
+ * input and an output, it's possible for both old_clip_distance_1d_var
+ * and old_clip_distance_2d_var to be non-null.
*/
- ir_variable *old_clip_distance_var;
+ ir_variable *old_clip_distance_1d_var;
+ ir_variable *old_clip_distance_2d_var;
/**
* Pointer to the newly-created gl_ClipDistanceMESA variable.
*/
- ir_variable *new_clip_distance_var;
+ ir_variable *new_clip_distance_1d_var;
+ ir_variable *new_clip_distance_2d_var;
+
+ /**
+ * Type of shader we are compiling (e.g. MESA_SHADER_VERTEX)
+ */
+ const gl_shader_stage shader_stage;
};
+} /* anonymous namespace */
/**
* Replace any declaration of gl_ClipDistance as an array of floats with a
@@ -89,30 +110,61 @@ public:
ir_visitor_status
lower_clip_distance_visitor::visit(ir_variable *ir)
{
- /* No point in looking for the declaration of gl_ClipDistance if
- * we've already found it.
- */
- if (this->old_clip_distance_var)
+ if (!ir->name || strcmp(ir->name, "gl_ClipDistance") != 0)
return visit_continue;
+ assert (ir->type->is_array());
+
+ if (!ir->type->element_type()->is_array()) {
+ /* 1D gl_ClipDistance (used for vertex and geometry output, and fragment
+ * input).
+ */
+ if (this->old_clip_distance_1d_var)
+ return visit_continue;
- if (ir->name && strcmp(ir->name, "gl_ClipDistance") == 0) {
this->progress = true;
- this->old_clip_distance_var = ir;
- assert (ir->type->is_array());
+ this->old_clip_distance_1d_var = ir;
assert (ir->type->element_type() == glsl_type::float_type);
unsigned new_size = (ir->type->array_size() + 3) / 4;
/* Clone the old var so that we inherit all of its properties */
- this->new_clip_distance_var = ir->clone(ralloc_parent(ir), NULL);
+ this->new_clip_distance_1d_var = ir->clone(ralloc_parent(ir), NULL);
/* And change the properties that we need to change */
- this->new_clip_distance_var->name
- = ralloc_strdup(this->new_clip_distance_var, "gl_ClipDistanceMESA");
- this->new_clip_distance_var->type
+ this->new_clip_distance_1d_var->name
+ = ralloc_strdup(this->new_clip_distance_1d_var,
+ "gl_ClipDistanceMESA");
+ this->new_clip_distance_1d_var->type
= glsl_type::get_array_instance(glsl_type::vec4_type, new_size);
- this->new_clip_distance_var->max_array_access = ir->max_array_access / 4;
+ this->new_clip_distance_1d_var->data.max_array_access
+ = ir->data.max_array_access / 4;
+
+ ir->replace_with(this->new_clip_distance_1d_var);
+ } else {
+ /* 2D gl_ClipDistance (used for geometry input). */
+ assert(ir->data.mode == ir_var_shader_in &&
+ this->shader_stage == MESA_SHADER_GEOMETRY);
+ if (this->old_clip_distance_2d_var)
+ return visit_continue;
- ir->replace_with(this->new_clip_distance_var);
+ this->progress = true;
+ this->old_clip_distance_2d_var = ir;
+ assert (ir->type->element_type()->element_type() == glsl_type::float_type);
+ unsigned new_size = (ir->type->element_type()->array_size() + 3) / 4;
+
+ /* Clone the old var so that we inherit all of its properties */
+ this->new_clip_distance_2d_var = ir->clone(ralloc_parent(ir), NULL);
+
+ /* And change the properties that we need to change */
+ this->new_clip_distance_2d_var->name
+ = ralloc_strdup(this->new_clip_distance_2d_var, "gl_ClipDistanceMESA");
+ this->new_clip_distance_2d_var->type = glsl_type::get_array_instance(
+ glsl_type::get_array_instance(glsl_type::vec4_type,
+ new_size),
+ ir->type->array_size());
+ this->new_clip_distance_2d_var->data.max_array_access
+ = ir->data.max_array_access / 4;
+
+ ir->replace_with(this->new_clip_distance_2d_var);
}
return visit_continue;
}
@@ -177,39 +229,111 @@ lower_clip_distance_visitor::create_indices(ir_rvalue *old_index,
}
+/**
+ * Determine whether the given rvalue describes an array of 8 floats that
+ * needs to be lowered to an array of 2 vec4's; that is, determine whether it
+ * matches one of the following patterns:
+ *
+ * - gl_ClipDistance (if gl_ClipDistance is 1D)
+ * - gl_ClipDistance[i] (if gl_ClipDistance is 2D)
+ */
+bool
+lower_clip_distance_visitor::is_clip_distance_vec8(ir_rvalue *ir)
+{
+ /* Note that geometry shaders contain gl_ClipDistance both as an input
+ * (which is a 2D array) and an output (which is a 1D array), so it's
+ * possible for both this->old_clip_distance_1d_var and
+ * this->old_clip_distance_2d_var to be non-NULL in the same shader.
+ */
+
+ if (this->old_clip_distance_1d_var) {
+ ir_dereference_variable *var_ref = ir->as_dereference_variable();
+ if (var_ref && var_ref->var == this->old_clip_distance_1d_var)
+ return true;
+ }
+ if (this->old_clip_distance_2d_var) {
+ /* 2D clip distance is only possible as a geometry input */
+ assert(this->shader_stage == MESA_SHADER_GEOMETRY);
+
+ ir_dereference_array *array_ref = ir->as_dereference_array();
+ if (array_ref) {
+ ir_dereference_variable *var_ref =
+ array_ref->array->as_dereference_variable();
+ if (var_ref && var_ref->var == this->old_clip_distance_2d_var)
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
+ * If the given ir satisfies is_clip_distance_vec8(), return new ir
+ * representing its lowered equivalent. That is, map:
+ *
+ * - gl_ClipDistance => gl_ClipDistanceMESA (if gl_ClipDistance is 1D)
+ * - gl_ClipDistance[i] => gl_ClipDistanceMESA[i] (if gl_ClipDistance is 2D)
+ *
+ * Otherwise return NULL.
+ */
+ir_rvalue *
+lower_clip_distance_visitor::lower_clip_distance_vec8(ir_rvalue *ir)
+{
+ if (this->old_clip_distance_1d_var) {
+ ir_dereference_variable *var_ref = ir->as_dereference_variable();
+ if (var_ref && var_ref->var == this->old_clip_distance_1d_var) {
+ return new(ralloc_parent(ir))
+ ir_dereference_variable(this->new_clip_distance_1d_var);
+ }
+ }
+ if (this->old_clip_distance_2d_var) {
+ /* 2D clip distance is only possible as a geometry input */
+ assert(this->shader_stage == MESA_SHADER_GEOMETRY);
+
+ ir_dereference_array *array_ref = ir->as_dereference_array();
+ if (array_ref) {
+ ir_dereference_variable *var_ref =
+ array_ref->array->as_dereference_variable();
+ if (var_ref && var_ref->var == this->old_clip_distance_2d_var) {
+ return new(ralloc_parent(ir))
+ ir_dereference_array(this->new_clip_distance_2d_var,
+ array_ref->array_index);
+ }
+ }
+ }
+ return NULL;
+}
+
+
void
lower_clip_distance_visitor::handle_rvalue(ir_rvalue **rv)
{
- /* If the gl_ClipDistance var hasn't been declared yet, then
- * there's no way this deref can refer to it.
- */
- if (!this->old_clip_distance_var || *rv == NULL)
+ if (*rv == NULL)
return;
ir_dereference_array *const array_deref = (*rv)->as_dereference_array();
if (array_deref == NULL)
return;
- /* Replace any expression that indexes into the gl_ClipDistance array
+ /* Replace any expression that indexes one of the floats in gl_ClipDistance
* with an expression that indexes into one of the vec4's in
* gl_ClipDistanceMESA and accesses the appropriate component.
*/
- ir_dereference_variable *old_var_ref =
- array_deref->array->as_dereference_variable();
- if (old_var_ref && old_var_ref->var == this->old_clip_distance_var) {
+ ir_rvalue *lowered_vec8 =
+ this->lower_clip_distance_vec8(array_deref->array);
+ if (lowered_vec8 != NULL) {
this->progress = true;
ir_rvalue *array_index;
ir_rvalue *swizzle_index;
this->create_indices(array_deref->array_index, array_index, swizzle_index);
void *mem_ctx = ralloc_parent(array_deref);
- ir_dereference_array *const ClipDistanceMESA_deref =
- new(mem_ctx) ir_dereference_array(this->new_clip_distance_var,
- array_index);
+ ir_dereference_array *const new_array_deref =
+ new(mem_ctx) ir_dereference_array(lowered_vec8, array_index);
ir_expression *const expr =
new(mem_ctx) ir_expression(ir_binop_vector_extract,
- ClipDistanceMESA_deref,
+ new_array_deref,
swizzle_index);
*rv = expr;
@@ -243,10 +367,16 @@ lower_clip_distance_visitor::fix_lhs(ir_assignment *ir)
}
/**
- * Replace any assignment having gl_ClipDistance (undereferenced) as its LHS
- * or RHS with a sequence of assignments, one for each component of the array.
- * Each of these assignments is lowered to refer to gl_ClipDistanceMESA as
- * appropriate.
+ * Replace any assignment having the 1D gl_ClipDistance (undereferenced) as
+ * its LHS or RHS with a sequence of assignments, one for each component of
+ * the array. Each of these assignments is lowered to refer to
+ * gl_ClipDistanceMESA as appropriate.
+ *
+ * We need to do a similar replacement for 2D gl_ClipDistance, however since
+ * it's an input, the only case we need to address is where a 1D slice of it
+ * is the entire RHS of an assignment, e.g.:
+ *
+ * foo = gl_in[i].gl_ClipDistance
*/
ir_visitor_status
lower_clip_distance_visitor::visit_leave(ir_assignment *ir)
@@ -256,22 +386,20 @@ lower_clip_distance_visitor::visit_leave(ir_assignment *ir)
*/
ir_rvalue_visitor::visit_leave(ir);
- ir_dereference_variable *lhs_var = ir->lhs->as_dereference_variable();
- ir_dereference_variable *rhs_var = ir->rhs->as_dereference_variable();
- if ((lhs_var && lhs_var->var == this->old_clip_distance_var)
- || (rhs_var && rhs_var->var == this->old_clip_distance_var)) {
- /* LHS or RHS of the assignment is the entire gl_ClipDistance array.
- * Since we are reshaping gl_ClipDistance from an array of floats to an
- * array of vec4's, this isn't going to work as a bulk assignment
- * anymore, so unroll it to element-by-element assignments and lower
- * each of them.
+ if (this->is_clip_distance_vec8(ir->lhs) ||
+ this->is_clip_distance_vec8(ir->rhs)) {
+ /* LHS or RHS of the assignment is the entire 1D gl_ClipDistance array
+ * (or a 1D slice of a 2D gl_ClipDistance input array). Since we are
+ * reshaping gl_ClipDistance from an array of floats to an array of
+ * vec4's, this isn't going to work as a bulk assignment anymore, so
+ * unroll it to element-by-element assignments and lower each of them.
*
* Note: to unroll into element-by-element assignments, we need to make
* clones of the LHS and RHS. This is safe because expressions and
* l-values are side-effect free.
*/
void *ctx = ralloc_parent(ir);
- int array_size = this->old_clip_distance_var->type->array_size();
+ int array_size = ir->lhs->type->array_size();
for (int i = 0; i < array_size; ++i) {
ir_dereference_array *new_lhs = new(ctx) ir_dereference_array(
ir->lhs->clone(ctx, NULL), new(ctx) ir_constant(i));
@@ -331,11 +459,17 @@ lower_clip_distance_visitor::visit_new_assignment(ir_assignment *ir)
/**
- * If gl_ClipDistance appears as an argument in an ir_call expression, replace
- * it with a temporary variable, and make sure the ir_call is preceded and/or
- * followed by assignments that copy the contents of the temporary variable to
- * and/or from gl_ClipDistance. Each of these assignments is then lowered to
- * refer to gl_ClipDistanceMESA.
+ * If a 1D gl_ClipDistance variable appears as an argument in an ir_call
+ * expression, replace it with a temporary variable, and make sure the ir_call
+ * is preceded and/or followed by assignments that copy the contents of the
+ * temporary variable to and/or from gl_ClipDistance. Each of these
+ * assignments is then lowered to refer to gl_ClipDistanceMESA.
+ *
+ * We need to do a similar replacement for 2D gl_ClipDistance, however since
+ * it's an input, the only case we need to address is where a 1D slice of it
+ * is passed as an "in" parameter to an ir_call, e.g.:
+ *
+ * foo(gl_in[i].gl_ClipDistance)
*/
ir_visitor_status
lower_clip_distance_visitor::visit_leave(ir_call *ir)
@@ -354,20 +488,20 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir)
formal_param_node = formal_param_node->next;
actual_param_node = actual_param_node->next;
- ir_dereference_variable *deref = actual_param->as_dereference_variable();
- if (deref && deref->var == this->old_clip_distance_var) {
- /* User is trying to pass the whole gl_ClipDistance array to a
- * function call. Since we are reshaping gl_ClipDistance from an
- * array of floats to an array of vec4's, this isn't going to work
- * anymore, so use a temporary array instead.
+ if (this->is_clip_distance_vec8(actual_param)) {
+ /* User is trying to pass the whole 1D gl_ClipDistance array (or a 1D
+ * slice of a 2D gl_ClipDistance array) to a function call. Since we
+ * are reshaping gl_ClipDistance from an array of floats to an array
+ * of vec4's, this isn't going to work anymore, so use a temporary
+ * array instead.
*/
ir_variable *temp_clip_distance = new(ctx) ir_variable(
actual_param->type, "temp_clip_distance", ir_var_temporary);
this->base_ir->insert_before(temp_clip_distance);
actual_param->replace_with(
new(ctx) ir_dereference_variable(temp_clip_distance));
- if (formal_param->mode == ir_var_function_in
- || formal_param->mode == ir_var_function_inout) {
+ if (formal_param->data.mode == ir_var_function_in
+ || formal_param->data.mode == ir_var_function_inout) {
/* Copy from gl_ClipDistance to the temporary before the call.
* Since we are going to insert this copy before the current
* instruction, we need to visit it afterwards to make sure it
@@ -375,19 +509,19 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir)
*/
ir_assignment *new_assignment = new(ctx) ir_assignment(
new(ctx) ir_dereference_variable(temp_clip_distance),
- new(ctx) ir_dereference_variable(old_clip_distance_var));
+ actual_param->clone(ctx, NULL));
this->base_ir->insert_before(new_assignment);
this->visit_new_assignment(new_assignment);
}
- if (formal_param->mode == ir_var_function_out
- || formal_param->mode == ir_var_function_inout) {
+ if (formal_param->data.mode == ir_var_function_out
+ || formal_param->data.mode == ir_var_function_inout) {
/* Copy from the temporary to gl_ClipDistance after the call.
* Since visit_list_elements() has already decided which
* instruction it's going to visit next, we need to visit
* afterwards to make sure it gets lowered.
*/
ir_assignment *new_assignment = new(ctx) ir_assignment(
- new(ctx) ir_dereference_variable(old_clip_distance_var),
+ actual_param->clone(ctx, NULL),
new(ctx) ir_dereference_variable(temp_clip_distance));
this->base_ir->insert_after(new_assignment);
this->visit_new_assignment(new_assignment);
@@ -402,12 +536,14 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir)
bool
lower_clip_distance(gl_shader *shader)
{
- lower_clip_distance_visitor v;
+ lower_clip_distance_visitor v(shader->Stage);
visit_list_elements(&v, shader->ir);
- if (v.new_clip_distance_var)
- shader->symbols->add_variable(v.new_clip_distance_var);
+ if (v.new_clip_distance_1d_var)
+ shader->symbols->add_variable(v.new_clip_distance_1d_var);
+ if (v.new_clip_distance_2d_var)
+ shader->symbols->add_variable(v.new_clip_distance_2d_var);
return v.progress;
}
diff --git a/dist/Mesa/src/glsl/lower_discard.cpp b/dist/Mesa/src/glsl/lower_discard.cpp
index cafd2dd3b..f2757d120 100644
--- a/dist/Mesa/src/glsl/lower_discard.cpp
+++ b/dist/Mesa/src/glsl/lower_discard.cpp
@@ -108,6 +108,8 @@
#include "glsl_types.h"
#include "ir.h"
+namespace {
+
class lower_discard_visitor : public ir_hierarchical_visitor {
public:
lower_discard_visitor()
@@ -120,6 +122,7 @@ public:
bool progress;
};
+} /* anonymous namespace */
bool
lower_discard(exec_list *instructions)
diff --git a/dist/Mesa/src/glsl/lower_discard_flow.cpp b/dist/Mesa/src/glsl/lower_discard_flow.cpp
index d385c1435..1bc56d79e 100644
--- a/dist/Mesa/src/glsl/lower_discard_flow.cpp
+++ b/dist/Mesa/src/glsl/lower_discard_flow.cpp
@@ -48,6 +48,8 @@
#include "ir.h"
#include "program/hash_table.h"
+namespace {
+
class lower_discard_flow_visitor : public ir_hierarchical_visitor {
public:
lower_discard_flow_visitor(ir_variable *discarded)
@@ -71,6 +73,8 @@ public:
void *mem_ctx;
};
+} /* anonymous namespace */
+
ir_visitor_status
lower_discard_flow_visitor::visit_enter(ir_loop_jump *ir)
{
diff --git a/dist/Mesa/src/glsl/lower_mat_op_to_vec.cpp b/dist/Mesa/src/glsl/lower_mat_op_to_vec.cpp
index 08cae29fa..105ee0d3f 100644
--- a/dist/Mesa/src/glsl/lower_mat_op_to_vec.cpp
+++ b/dist/Mesa/src/glsl/lower_mat_op_to_vec.cpp
@@ -35,6 +35,8 @@
#include "ir_expression_flattening.h"
#include "glsl_types.h"
+namespace {
+
class ir_mat_op_to_vec_visitor : public ir_hierarchical_visitor {
public:
ir_mat_op_to_vec_visitor()
@@ -63,6 +65,8 @@ public:
bool made_progress;
};
+} /* anonymous namespace */
+
static bool
mat_op_to_vec_predicate(ir_instruction *ir)
{
diff --git a/dist/Mesa/src/glsl/lower_named_interface_blocks.cpp b/dist/Mesa/src/glsl/lower_named_interface_blocks.cpp
index d0d491d3d..04e0d36e6 100644
--- a/dist/Mesa/src/glsl/lower_named_interface_blocks.cpp
+++ b/dist/Mesa/src/glsl/lower_named_interface_blocks.cpp
@@ -65,6 +65,8 @@
#include "ir_rvalue_visitor.h"
#include "program/hash_table.h"
+namespace {
+
class flatten_named_interface_blocks_declarations : public ir_rvalue_visitor
{
public:
@@ -83,6 +85,8 @@ public:
virtual void handle_rvalue(ir_rvalue **rvalue);
};
+} /* anonymous namespace */
+
void
flatten_named_interface_blocks_declarations::run(exec_list *instructions)
{
@@ -104,7 +108,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
* but, this will require changes to the other uniform block
* support code.
*/
- if (var->mode == ir_var_uniform)
+ if (var->data.mode == ir_var_uniform)
continue;
const glsl_type * iface_t = var->type;
@@ -121,37 +125,41 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
for (unsigned i = 0; i < iface_t->length; i++) {
const char * field_name = iface_t->fields.structure[i].name;
char *iface_field_name =
- ralloc_asprintf(mem_ctx, "%s.%s",
- iface_t->name, field_name);
+ ralloc_asprintf(mem_ctx, "%s.%s.%s",
+ iface_t->name, var->name, field_name);
ir_variable *found_var =
(ir_variable *) hash_table_find(interface_namespace,
iface_field_name);
if (!found_var) {
ir_variable *new_var;
+ char *var_name =
+ ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name);
if (array_t == NULL) {
- char *var_name =
- ralloc_strdup(mem_ctx, iface_t->fields.structure[i].name);
new_var =
new(mem_ctx) ir_variable(iface_t->fields.structure[i].type,
var_name,
- (ir_variable_mode) var->mode);
+ (ir_variable_mode) var->data.mode);
+ new_var->data.from_named_ifc_block_nonarray = 1;
} else {
const glsl_type *new_array_type =
glsl_type::get_array_instance(
iface_t->fields.structure[i].type,
array_t->length);
- char *var_name =
- ralloc_asprintf(mem_ctx, "%s[%d]",
- iface_t->fields.structure[i].name,
- array_t->length);
new_var =
new(mem_ctx) ir_variable(new_array_type,
var_name,
- (ir_variable_mode) var->mode);
+ (ir_variable_mode) var->data.mode);
+ new_var->data.from_named_ifc_block_array = 1;
}
-
- new_var->interface_type = iface_t;
+ new_var->data.location = iface_t->fields.structure[i].location;
+ new_var->data.explicit_location = (new_var->data.location >= 0);
+ new_var->data.interpolation =
+ iface_t->fields.structure[i].interpolation;
+ new_var->data.centroid = iface_t->fields.structure[i].centroid;
+ new_var->data.sample = iface_t->fields.structure[i].sample;
+
+ new_var->init_interface_type(iface_t);
hash_table_insert(interface_namespace, new_var,
iface_field_name);
insert_pos->insert_after(new_var);
@@ -204,13 +212,13 @@ flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
* but, this will require changes to the other uniform block
* support code.
*/
- if (var->mode == ir_var_uniform)
+ if (var->data.mode == ir_var_uniform)
return;
- if (var->interface_type != NULL) {
+ if (var->get_interface_type() != NULL) {
char *iface_field_name =
- ralloc_asprintf(mem_ctx, "%s.%s", var->interface_type->name,
- ir->field);
+ ralloc_asprintf(mem_ctx, "%s.%s.%s", var->get_interface_type()->name,
+ var->name, ir->field);
/* Find the variable in the set of flattened interface blocks */
ir_variable *found_var =
(ir_variable *) hash_table_find(interface_namespace,
diff --git a/dist/Mesa/src/glsl/lower_offset_array.cpp b/dist/Mesa/src/glsl/lower_offset_array.cpp
new file mode 100644
index 000000000..0c235eda3
--- /dev/null
+++ b/dist/Mesa/src/glsl/lower_offset_array.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+/**
+ * \file brw_lower_offset_array.cpp
+ *
+ * IR lower pass to decompose ir_texture ir_tg4 with an array of offsets
+ * into four ir_tg4s with a single ivec2 offset, select the .w component of each,
+ * and return those four values packed into a gvec4.
+ *
+ * \author Chris Forbes <chrisf@ijw.co.nz>
+ */
+
+#include "glsl_types.h"
+#include "ir.h"
+#include "ir_builder.h"
+#include "ir_optimization.h"
+#include "ir_rvalue_visitor.h"
+
+using namespace ir_builder;
+
+class brw_lower_offset_array_visitor : public ir_rvalue_visitor {
+public:
+ brw_lower_offset_array_visitor()
+ {
+ progress = false;
+ }
+
+ void handle_rvalue(ir_rvalue **rv);
+
+ bool progress;
+};
+
+void
+brw_lower_offset_array_visitor::handle_rvalue(ir_rvalue **rv)
+{
+ if (*rv == NULL || (*rv)->ir_type != ir_type_texture)
+ return;
+
+ ir_texture *ir = (ir_texture *) *rv;
+ if (ir->op != ir_tg4 || !ir->offset || !ir->offset->type->is_array())
+ return;
+
+ void *mem_ctx = ralloc_parent(ir);
+
+ ir_variable *var = new (mem_ctx) ir_variable(ir->type, "result", ir_var_auto);
+ base_ir->insert_before(var);
+
+ for (int i = 0; i < 4; i++) {
+ ir_texture *tex = ir->clone(mem_ctx, NULL);
+ tex->offset = new (mem_ctx) ir_dereference_array(tex->offset,
+ new (mem_ctx) ir_constant(i));
+
+ base_ir->insert_before(assign(var, swizzle_w(tex), 1 << i));
+ }
+
+ *rv = new (mem_ctx) ir_dereference_variable(var);
+
+ progress = true;
+}
+
+bool
+lower_offset_arrays(exec_list *instructions)
+{
+ brw_lower_offset_array_visitor v;
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/dist/Mesa/src/glsl/lower_output_reads.cpp b/dist/Mesa/src/glsl/lower_output_reads.cpp
index b93e254ec..afe17766b 100644
--- a/dist/Mesa/src/glsl/lower_output_reads.cpp
+++ b/dist/Mesa/src/glsl/lower_output_reads.cpp
@@ -37,6 +37,8 @@
* main() function to copy the final values to the actual shader outputs.
*/
+namespace {
+
class output_read_remover : public ir_hierarchical_visitor {
protected:
/**
@@ -50,10 +52,13 @@ public:
output_read_remover();
~output_read_remover();
virtual ir_visitor_status visit(class ir_dereference_variable *);
+ virtual ir_visitor_status visit(class ir_emit_vertex *);
virtual ir_visitor_status visit_leave(class ir_return *);
virtual ir_visitor_status visit_leave(class ir_function_signature *);
};
+} /* anonymous namespace */
+
/**
* Hash function for the output variables - computes the hash of the name.
* NOTE: We're using the name string to ensure that the hash doesn't depend
@@ -86,7 +91,7 @@ output_read_remover::~output_read_remover()
ir_visitor_status
output_read_remover::visit(ir_dereference_variable *ir)
{
- if (ir->var->mode != ir_var_shader_out)
+ if (ir->var->data.mode != ir_var_shader_out)
return visit_continue;
ir_variable *temp = (ir_variable *) hash_table_find(replacements, ir->var);
@@ -117,7 +122,9 @@ copy(void *ctx, ir_variable *output, ir_variable *temp)
return new(ctx) ir_assignment(lhs, rhs);
}
-/** Insert a copy-back assignment before a "return" statement */
+/** Insert a copy-back assignment before a "return" statement or a call to
+ * EmitVertex().
+ */
static void
emit_return_copy(const void *key, void *data, void *closure)
{
@@ -141,6 +148,14 @@ output_read_remover::visit_leave(ir_return *ir)
}
ir_visitor_status
+output_read_remover::visit(ir_emit_vertex *ir)
+{
+ hash_table_call_foreach(replacements, emit_return_copy, ir);
+ hash_table_clear(replacements);
+ return visit_continue;
+}
+
+ir_visitor_status
output_read_remover::visit_leave(ir_function_signature *sig)
{
if (strcmp(sig->function_name(), "main") != 0)
diff --git a/dist/Mesa/src/glsl/lower_packed_varyings.cpp b/dist/Mesa/src/glsl/lower_packed_varyings.cpp
index cdf2289b4..e8654748f 100644
--- a/dist/Mesa/src/glsl/lower_packed_varyings.cpp
+++ b/dist/Mesa/src/glsl/lower_packed_varyings.cpp
@@ -74,12 +74,82 @@
* This lowering pass also handles varyings whose type is a struct or an array
* of struct. Structs are packed in order and with no gaps, so there may be a
* performance penalty due to structure elements being double-parked.
+ *
+ * Lowering of geometry shader inputs is slightly more complex, since geometry
+ * inputs are always arrays, so we need to lower arrays to arrays. For
+ * example, the following input:
+ *
+ * in struct Foo {
+ * float f;
+ * vec3 v;
+ * vec2 a[2];
+ * } arr[3]; // location=4, location_frac=0
+ *
+ * Would get lowered like this if it occurred in a fragment shader:
+ *
+ * struct Foo {
+ * float f;
+ * vec3 v;
+ * vec2 a[2];
+ * } arr[3];
+ * in vec4 packed4; // location=4, location_frac=0
+ * in vec4 packed5; // location=5, location_frac=0
+ * in vec4 packed6; // location=6, location_frac=0
+ * in vec4 packed7; // location=7, location_frac=0
+ * in vec4 packed8; // location=8, location_frac=0
+ * in vec4 packed9; // location=9, location_frac=0
+ *
+ * main()
+ * {
+ * arr[0].f = packed4.x;
+ * arr[0].v = packed4.yzw;
+ * arr[0].a[0] = packed5.xy;
+ * arr[0].a[1] = packed5.zw;
+ * arr[1].f = packed6.x;
+ * arr[1].v = packed6.yzw;
+ * arr[1].a[0] = packed7.xy;
+ * arr[1].a[1] = packed7.zw;
+ * arr[2].f = packed8.x;
+ * arr[2].v = packed8.yzw;
+ * arr[2].a[0] = packed9.xy;
+ * arr[2].a[1] = packed9.zw;
+ * ...
+ * }
+ *
+ * But it would get lowered like this if it occurred in a geometry shader:
+ *
+ * struct Foo {
+ * float f;
+ * vec3 v;
+ * vec2 a[2];
+ * } arr[3];
+ * in vec4 packed4[3]; // location=4, location_frac=0
+ * in vec4 packed5[3]; // location=5, location_frac=0
+ *
+ * main()
+ * {
+ * arr[0].f = packed4[0].x;
+ * arr[0].v = packed4[0].yzw;
+ * arr[0].a[0] = packed5[0].xy;
+ * arr[0].a[1] = packed5[0].zw;
+ * arr[1].f = packed4[1].x;
+ * arr[1].v = packed4[1].yzw;
+ * arr[1].a[0] = packed5[1].xy;
+ * arr[1].a[1] = packed5[1].zw;
+ * arr[2].f = packed4[2].x;
+ * arr[2].v = packed4[2].yzw;
+ * arr[2].a[0] = packed5[2].xy;
+ * arr[2].a[1] = packed5[2].zw;
+ * ...
+ * }
*/
#include "glsl_symbol_table.h"
#include "ir.h"
#include "ir_optimization.h"
+namespace {
+
/**
* Visitor that performs varying packing. For each varying declared in the
* shader, this visitor determines whether it needs to be packed. If so, it
@@ -90,10 +160,10 @@
class lower_packed_varyings_visitor
{
public:
- lower_packed_varyings_visitor(void *mem_ctx, unsigned location_base,
- unsigned locations_used,
+ lower_packed_varyings_visitor(void *mem_ctx, unsigned locations_used,
ir_variable_mode mode,
- exec_list *main_instructions);
+ unsigned gs_input_vertices,
+ exec_list *out_instructions);
void run(exec_list *instructions);
@@ -101,13 +171,16 @@ private:
ir_assignment *bitwise_assign_pack(ir_rvalue *lhs, ir_rvalue *rhs);
ir_assignment *bitwise_assign_unpack(ir_rvalue *lhs, ir_rvalue *rhs);
unsigned lower_rvalue(ir_rvalue *rvalue, unsigned fine_location,
- ir_variable *unpacked_var, const char *name);
+ ir_variable *unpacked_var, const char *name,
+ bool gs_input_toplevel, unsigned vertex_index);
unsigned lower_arraylike(ir_rvalue *rvalue, unsigned array_size,
unsigned fine_location,
- ir_variable *unpacked_var, const char *name);
- ir_variable *get_packed_varying(unsigned location,
- ir_variable *unpacked_var,
- const char *name);
+ ir_variable *unpacked_var, const char *name,
+ bool gs_input_toplevel, unsigned vertex_index);
+ ir_dereference *get_packed_varying_deref(unsigned location,
+ ir_variable *unpacked_var,
+ const char *name,
+ unsigned vertex_index);
bool needs_lowering(ir_variable *var);
/**
@@ -116,18 +189,10 @@ private:
void * const mem_ctx;
/**
- * Location representing the first generic varying slot for this shader
- * stage (e.g. VARYING_SLOT_VAR0 if we are packing vertex shader outputs).
- * Varyings whose location is less than this value are assumed to
- * correspond to special fixed function hardware, so they are not lowered.
- */
- const unsigned location_base;
-
- /**
* Number of generic varying slots which are used by this shader. This is
- * used to allocate temporary intermediate data structures. If any any
- * varying used by this shader has a location greater than or equal to
- * location_base + locations_used, an assertion will fire.
+ * used to allocate temporary intermediate data structures. If any varying
+ * used by this shader has a location greater than or equal to
+ * VARYING_SLOT_VAR0 + locations_used, an assertion will fire.
*/
const unsigned locations_used;
@@ -145,23 +210,32 @@ private:
const ir_variable_mode mode;
/**
- * List of instructions corresponding to the main() function. This is
- * where we add instructions to pack or unpack the varyings.
+ * If we are currently lowering geometry shader inputs, the number of input
+ * vertices the geometry shader accepts. Otherwise zero.
+ */
+ const unsigned gs_input_vertices;
+
+ /**
+ * Exec list into which the visitor should insert the packing instructions.
+ * Caller provides this list; it should insert the instructions into the
+ * appropriate place in the shader once the visitor has finished running.
*/
- exec_list *main_instructions;
+ exec_list *out_instructions;
};
+} /* anonymous namespace */
+
lower_packed_varyings_visitor::lower_packed_varyings_visitor(
- void *mem_ctx, unsigned location_base, unsigned locations_used,
- ir_variable_mode mode, exec_list *main_instructions)
+ void *mem_ctx, unsigned locations_used, ir_variable_mode mode,
+ unsigned gs_input_vertices, exec_list *out_instructions)
: mem_ctx(mem_ctx),
- location_base(location_base),
locations_used(locations_used),
packed_varyings((ir_variable **)
rzalloc_array_size(mem_ctx, sizeof(*packed_varyings),
locations_used)),
mode(mode),
- main_instructions(main_instructions)
+ gs_input_vertices(gs_input_vertices),
+ out_instructions(out_instructions)
{
}
@@ -173,8 +247,8 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
if (var == NULL)
continue;
- if (var->mode != this->mode ||
- var->location < (int) this->location_base ||
+ if (var->data.mode != this->mode ||
+ var->data.location < VARYING_SLOT_VAR0 ||
!this->needs_lowering(var))
continue;
@@ -183,19 +257,19 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
* safe, caller should ensure that integral varyings always use flat
* interpolation, even when this is not required by GLSL.
*/
- assert(var->interpolation == INTERP_QUALIFIER_FLAT ||
+ assert(var->data.interpolation == INTERP_QUALIFIER_FLAT ||
!var->type->contains_integer());
/* Change the old varying into an ordinary global. */
- var->mode = ir_var_auto;
+ var->data.mode = ir_var_auto;
/* Create a reference to the old varying. */
ir_dereference_variable *deref
= new(this->mem_ctx) ir_dereference_variable(var);
/* Recursively pack or unpack it. */
- this->lower_rvalue(deref, var->location * 4 + var->location_frac, var,
- var->name);
+ this->lower_rvalue(deref, var->data.location * 4 + var->data.location_frac, var,
+ var->name, this->gs_input_vertices != 0, 0);
}
}
@@ -277,6 +351,15 @@ lower_packed_varyings_visitor::bitwise_assign_unpack(ir_rvalue *lhs,
* in multiples of a float, rather than multiples of a vec4 as is used
* elsewhere in Mesa.
*
+ * \param gs_input_toplevel should be set to true if we are lowering geometry
+ * shader inputs, and we are currently lowering the whole input variable
+ * (i.e. we are lowering the array whose index selects the vertex).
+ *
+ * \param vertex_index: if we are lowering geometry shader inputs, and the
+ * level of the array that we are currently lowering is *not* the top level,
+ * then this indicates which vertex we are currently lowering. Otherwise it
+ * is ignored.
+ *
* \return the location where the next constituent vector (after this one)
* should be packed.
*/
@@ -284,8 +367,15 @@ unsigned
lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
unsigned fine_location,
ir_variable *unpacked_var,
- const char *name)
+ const char *name,
+ bool gs_input_toplevel,
+ unsigned vertex_index)
{
+ /* When gs_input_toplevel is set, we should be looking at a geometry shader
+ * input array.
+ */
+ assert(!gs_input_toplevel || rvalue->type->is_array());
+
if (rvalue->type->is_record()) {
for (unsigned i = 0; i < rvalue->type->length; i++) {
if (i != 0)
@@ -296,7 +386,8 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
char *deref_name
= ralloc_asprintf(this->mem_ctx, "%s.%s", name, field_name);
fine_location = this->lower_rvalue(dereference_record, fine_location,
- unpacked_var, deref_name);
+ unpacked_var, deref_name, false,
+ vertex_index);
}
return fine_location;
} else if (rvalue->type->is_array()) {
@@ -304,13 +395,15 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
* sequence.
*/
return this->lower_arraylike(rvalue, rvalue->type->array_size(),
- fine_location, unpacked_var, name);
+ fine_location, unpacked_var, name,
+ gs_input_toplevel, vertex_index);
} else if (rvalue->type->is_matrix()) {
/* Matrices are packed/unpacked by considering each column vector in
* sequence.
*/
return this->lower_arraylike(rvalue, rvalue->type->matrix_columns,
- fine_location, unpacked_var, name);
+ fine_location, unpacked_var, name,
+ false, vertex_index);
} else if (rvalue->type->vector_elements + fine_location % 4 > 4) {
/* This vector is going to be "double parked" across two varying slots,
* so handle it as two separate assignments.
@@ -340,9 +433,10 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
char *right_name
= ralloc_asprintf(this->mem_ctx, "%s.%s", name, right_swizzle_name);
fine_location = this->lower_rvalue(left_swizzle, fine_location,
- unpacked_var, left_name);
+ unpacked_var, left_name, false,
+ vertex_index);
return this->lower_rvalue(right_swizzle, fine_location, unpacked_var,
- right_name);
+ right_name, false, vertex_index);
} else {
/* No special handling is necessary; pack the rvalue into the
* varying.
@@ -353,19 +447,19 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
unsigned location_frac = fine_location % 4;
for (unsigned i = 0; i < components; ++i)
swizzle_values[i] = i + location_frac;
- ir_dereference_variable *packed_deref = new(this->mem_ctx)
- ir_dereference_variable(this->get_packed_varying(location,
- unpacked_var, name));
+ ir_dereference *packed_deref =
+ this->get_packed_varying_deref(location, unpacked_var, name,
+ vertex_index);
ir_swizzle *swizzle = new(this->mem_ctx)
ir_swizzle(packed_deref, swizzle_values, components);
if (this->mode == ir_var_shader_out) {
ir_assignment *assignment
= this->bitwise_assign_pack(swizzle, rvalue);
- this->main_instructions->push_tail(assignment);
+ this->out_instructions->push_tail(assignment);
} else {
ir_assignment *assignment
= this->bitwise_assign_unpack(rvalue, swizzle);
- this->main_instructions->push_head(assignment);
+ this->out_instructions->push_tail(assignment);
}
return fine_location + components;
}
@@ -376,13 +470,24 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue *rvalue,
* constituent elements, accessing each one using an ir_dereference_array.
* This takes care of both arrays and matrices, since ir_dereference_array
* treats a matrix like an array of its column vectors.
+ *
+ * \param gs_input_toplevel should be set to true if we are lowering geometry
+ * shader inputs, and we are currently lowering the whole input variable
+ * (i.e. we are lowering the array whose index selects the vertex).
+ *
+ * \param vertex_index: if we are lowering geometry shader inputs, and the
+ * level of the array that we are currently lowering is *not* the top level,
+ * then this indicates which vertex we are currently lowering. Otherwise it
+ * is ignored.
*/
unsigned
lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
unsigned array_size,
unsigned fine_location,
ir_variable *unpacked_var,
- const char *name)
+ const char *name,
+ bool gs_input_toplevel,
+ unsigned vertex_index)
{
for (unsigned i = 0; i < array_size; i++) {
if (i != 0)
@@ -390,10 +495,21 @@ lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
ir_constant *constant = new(this->mem_ctx) ir_constant(i);
ir_dereference_array *dereference_array = new(this->mem_ctx)
ir_dereference_array(rvalue, constant);
- char *subscripted_name
- = ralloc_asprintf(this->mem_ctx, "%s[%d]", name, i);
- fine_location = this->lower_rvalue(dereference_array, fine_location,
- unpacked_var, subscripted_name);
+ if (gs_input_toplevel) {
+ /* Geometry shader inputs are a special case. Instead of storing
+ * each element of the array at a different location, all elements
+ * are at the same location, but with a different vertex index.
+ */
+ (void) this->lower_rvalue(dereference_array, fine_location,
+ unpacked_var, name, false, i);
+ } else {
+ char *subscripted_name
+ = ralloc_asprintf(this->mem_ctx, "%s[%d]", name, i);
+ fine_location =
+ this->lower_rvalue(dereference_array, fine_location,
+ unpacked_var, subscripted_name,
+ false, vertex_index);
+ }
}
return fine_location;
}
@@ -406,40 +522,79 @@ lower_packed_varyings_visitor::lower_arraylike(ir_rvalue *rvalue,
* The newly created varying inherits its interpolation parameters from \c
* unpacked_var. Its base type is ivec4 if we are lowering a flat varying,
* vec4 otherwise.
+ *
+ * \param vertex_index: if we are lowering geometry shader inputs, then this
+ * indicates which vertex we are currently lowering. Otherwise it is ignored.
*/
-ir_variable *
-lower_packed_varyings_visitor::get_packed_varying(unsigned location,
- ir_variable *unpacked_var,
- const char *name)
+ir_dereference *
+lower_packed_varyings_visitor::get_packed_varying_deref(
+ unsigned location, ir_variable *unpacked_var, const char *name,
+ unsigned vertex_index)
{
- unsigned slot = location - this->location_base;
+ unsigned slot = location - VARYING_SLOT_VAR0;
assert(slot < locations_used);
if (this->packed_varyings[slot] == NULL) {
char *packed_name = ralloc_asprintf(this->mem_ctx, "packed:%s", name);
const glsl_type *packed_type;
- if (unpacked_var->interpolation == INTERP_QUALIFIER_FLAT)
+ if (unpacked_var->data.interpolation == INTERP_QUALIFIER_FLAT)
packed_type = glsl_type::ivec4_type;
else
packed_type = glsl_type::vec4_type;
+ if (this->gs_input_vertices != 0) {
+ packed_type =
+ glsl_type::get_array_instance(packed_type,
+ this->gs_input_vertices);
+ }
ir_variable *packed_var = new(this->mem_ctx)
ir_variable(packed_type, packed_name, this->mode);
- packed_var->centroid = unpacked_var->centroid;
- packed_var->interpolation = unpacked_var->interpolation;
- packed_var->location = location;
+ if (this->gs_input_vertices != 0) {
+ /* Prevent update_array_sizes() from messing with the size of the
+ * array.
+ */
+ packed_var->data.max_array_access = this->gs_input_vertices - 1;
+ }
+ packed_var->data.centroid = unpacked_var->data.centroid;
+ packed_var->data.sample = unpacked_var->data.sample;
+ packed_var->data.interpolation = unpacked_var->data.interpolation;
+ packed_var->data.location = location;
unpacked_var->insert_before(packed_var);
this->packed_varyings[slot] = packed_var;
} else {
- ralloc_asprintf_append((char **) &this->packed_varyings[slot]->name,
- ",%s", name);
+ /* For geometry shader inputs, only update the packed variable name the
+ * first time we visit each component.
+ */
+ if (this->gs_input_vertices == 0 || vertex_index == 0) {
+ ralloc_asprintf_append((char **) &this->packed_varyings[slot]->name,
+ ",%s", name);
+ }
}
- return this->packed_varyings[slot];
+
+ ir_dereference *deref = new(this->mem_ctx)
+ ir_dereference_variable(this->packed_varyings[slot]);
+ if (this->gs_input_vertices != 0) {
+ /* When lowering GS inputs, the packed variable is an array, so we need
+ * to dereference it using vertex_index.
+ */
+ ir_constant *constant = new(this->mem_ctx) ir_constant(vertex_index);
+ deref = new(this->mem_ctx) ir_dereference_array(deref, constant);
+ }
+ return deref;
}
bool
lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
{
- /* Things composed of vec4's don't need lowering. Everything else does. */
+ /* Things composed of vec4's and varyings with explicitly assigned
+ * locations don't need lowering. Everything else does.
+ */
+ if (var->data.explicit_location)
+ return false;
+
const glsl_type *type = var->type;
+ if (this->gs_input_vertices != 0) {
+ assert(type->is_array());
+ type = type->element_type();
+ }
if (type->is_array())
type = type->fields.array;
if (type->vector_elements == 4)
@@ -447,19 +602,80 @@ lower_packed_varyings_visitor::needs_lowering(ir_variable *var)
return true;
}
+
+/**
+ * Visitor that splices varying packing code before every use of EmitVertex()
+ * in a geometry shader.
+ */
+class lower_packed_varyings_gs_splicer : public ir_hierarchical_visitor
+{
+public:
+ explicit lower_packed_varyings_gs_splicer(void *mem_ctx,
+ const exec_list *instructions);
+
+ virtual ir_visitor_status visit(ir_emit_vertex *ev);
+
+private:
+ /**
+ * Memory context used to allocate new instructions for the shader.
+ */
+ void * const mem_ctx;
+
+ /**
+ * Instructions that should be spliced into place before each EmitVertex()
+ * call.
+ */
+ const exec_list *instructions;
+};
+
+
+lower_packed_varyings_gs_splicer::lower_packed_varyings_gs_splicer(
+ void *mem_ctx, const exec_list *instructions)
+ : mem_ctx(mem_ctx), instructions(instructions)
+{
+}
+
+
+ir_visitor_status
+lower_packed_varyings_gs_splicer::visit(ir_emit_vertex *ev)
+{
+ foreach_list(node, this->instructions) {
+ ir_instruction *ir = (ir_instruction *) node;
+ ev->insert_before(ir->clone(this->mem_ctx, NULL));
+ }
+ return visit_continue;
+}
+
+
void
-lower_packed_varyings(void *mem_ctx, unsigned location_base,
- unsigned locations_used, ir_variable_mode mode,
+lower_packed_varyings(void *mem_ctx, unsigned locations_used,
+ ir_variable_mode mode, unsigned gs_input_vertices,
gl_shader *shader)
{
exec_list *instructions = shader->ir;
ir_function *main_func = shader->symbols->get_function("main");
exec_list void_parameters;
ir_function_signature *main_func_sig
- = main_func->matching_signature(&void_parameters);
- exec_list *main_instructions = &main_func_sig->body;
- lower_packed_varyings_visitor visitor(mem_ctx, location_base,
- locations_used, mode,
- main_instructions);
+ = main_func->matching_signature(NULL, &void_parameters);
+ exec_list new_instructions;
+ lower_packed_varyings_visitor visitor(mem_ctx, locations_used, mode,
+ gs_input_vertices, &new_instructions);
visitor.run(instructions);
+ if (mode == ir_var_shader_out) {
+ if (shader->Stage == MESA_SHADER_GEOMETRY) {
+ /* For geometry shaders, outputs need to be lowered before each call
+ * to EmitVertex()
+ */
+ lower_packed_varyings_gs_splicer splicer(mem_ctx, &new_instructions);
+ splicer.run(instructions);
+ } else {
+ /* For other shader types, outputs need to be lowered at the end of
+ * main()
+ */
+ main_func_sig->body.append_list(&new_instructions);
+ }
+ } else {
+ /* Shader inputs need to be lowered at the beginning of main() */
+ main_func_sig->body.head->insert_before(&new_instructions);
+ }
}
diff --git a/dist/Mesa/src/glsl/lower_texture_projection.cpp b/dist/Mesa/src/glsl/lower_texture_projection.cpp
index 6e3aaecce..16d637680 100644
--- a/dist/Mesa/src/glsl/lower_texture_projection.cpp
+++ b/dist/Mesa/src/glsl/lower_texture_projection.cpp
@@ -37,6 +37,8 @@
#include "ir.h"
+namespace {
+
class lower_texture_projection_visitor : public ir_hierarchical_visitor {
public:
lower_texture_projection_visitor()
@@ -49,6 +51,8 @@ public:
bool progress;
};
+} /* anonymous namespace */
+
ir_visitor_status
lower_texture_projection_visitor::visit_leave(ir_texture *ir)
{
diff --git a/dist/Mesa/src/glsl/lower_ubo_reference.cpp b/dist/Mesa/src/glsl/lower_ubo_reference.cpp
index aade203e7..90e65bd0e 100644
--- a/dist/Mesa/src/glsl/lower_ubo_reference.cpp
+++ b/dist/Mesa/src/glsl/lower_ubo_reference.cpp
@@ -132,7 +132,8 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
mem_ctx = ralloc_parent(*rvalue);
const char *const field_name =
- interface_field_name(mem_ctx, (char *) var->interface_type->name, deref);
+ interface_field_name(mem_ctx, (char *) var->get_interface_type()->name,
+ deref);
this->uniform_block = -1;
for (unsigned i = 0; i < shader->NumUniformBlocks; i++) {
@@ -142,7 +143,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
struct gl_uniform_block *block = &shader->UniformBlocks[i];
this->ubo_var = var->is_interface_instance()
- ? &block->Uniforms[0] : &block->Uniforms[var->location];
+ ? &block->Uniforms[0] : &block->Uniforms[var->data.location];
break;
}
@@ -193,12 +194,16 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
array_stride = glsl_align(array_stride, 16);
}
- ir_constant *const_index = deref_array->array_index->as_constant();
+ ir_rvalue *array_index = deref_array->array_index;
+ if (array_index->type->base_type == GLSL_TYPE_INT)
+ array_index = i2u(array_index);
+
+ ir_constant *const_index = array_index->as_constant();
if (const_index) {
- const_offset += array_stride * const_index->value.i[0];
+ const_offset += array_stride * const_index->value.u[0];
} else {
offset = add(offset,
- mul(deref_array->array_index,
+ mul(array_index,
new(mem_ctx) ir_constant(array_stride)));
}
deref = deref_array->array->as_dereference();
diff --git a/dist/Mesa/src/glsl/lower_vector.cpp b/dist/Mesa/src/glsl/lower_vector.cpp
index 0cd6909db..a658410ae 100644
--- a/dist/Mesa/src/glsl/lower_vector.cpp
+++ b/dist/Mesa/src/glsl/lower_vector.cpp
@@ -31,9 +31,11 @@
#include "ir.h"
#include "ir_rvalue_visitor.h"
+namespace {
+
class lower_vector_visitor : public ir_rvalue_visitor {
public:
- lower_vector_visitor() : progress(false)
+ lower_vector_visitor() : dont_lower_swz(false), progress(false)
{
/* empty */
}
@@ -48,6 +50,8 @@ public:
bool progress;
};
+} /* anonymous namespace */
+
/**
* Determine if an IR expression tree looks like an extended swizzle
*
diff --git a/dist/Mesa/src/glsl/lower_vector_insert.cpp b/dist/Mesa/src/glsl/lower_vector_insert.cpp
index 0e640cc32..6d7cfa942 100644
--- a/dist/Mesa/src/glsl/lower_vector_insert.cpp
+++ b/dist/Mesa/src/glsl/lower_vector_insert.cpp
@@ -27,6 +27,8 @@
using namespace ir_builder;
+namespace {
+
class vector_insert_visitor : public ir_rvalue_visitor {
public:
vector_insert_visitor(bool lower_nonconstant_index)
@@ -48,6 +50,7 @@ public:
bool lower_nonconstant_index;
};
+} /* anonymous namespace */
void
vector_insert_visitor::handle_rvalue(ir_rvalue **rv)
diff --git a/dist/Mesa/src/glsl/opt_algebraic.cpp b/dist/Mesa/src/glsl/opt_algebraic.cpp
index d706a6ad1..9d5539252 100644
--- a/dist/Mesa/src/glsl/opt_algebraic.cpp
+++ b/dist/Mesa/src/glsl/opt_algebraic.cpp
@@ -32,8 +32,11 @@
#include "ir_visitor.h"
#include "ir_rvalue_visitor.h"
#include "ir_optimization.h"
+#include "ir_builder.h"
#include "glsl_types.h"
+using namespace ir_builder;
+
namespace {
/**
@@ -42,10 +45,11 @@ namespace {
class ir_algebraic_visitor : public ir_rvalue_visitor {
public:
- ir_algebraic_visitor()
+ ir_algebraic_visitor(bool native_integers)
{
this->progress = false;
this->mem_ctx = NULL;
+ this->native_integers = native_integers;
}
virtual ~ir_algebraic_visitor()
@@ -67,6 +71,7 @@ public:
void *mem_ctx;
+ bool native_integers;
bool progress;
};
@@ -85,6 +90,18 @@ is_vec_one(ir_constant *ir)
}
static inline bool
+is_vec_two(ir_constant *ir)
+{
+ return (ir == NULL) ? false : ir->is_value(2.0, 2);
+}
+
+static inline bool
+is_vec_negative_one(ir_constant *ir)
+{
+ return (ir == NULL) ? false : ir->is_negative_one();
+}
+
+static inline bool
is_vec_basis(ir_constant *ir)
{
return (ir == NULL) ? false : ir->is_basis();
@@ -188,7 +205,6 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
{
ir_constant *op_const[4] = {NULL, NULL, NULL, NULL};
ir_expression *op_expr[4] = {NULL, NULL, NULL, NULL};
- ir_expression *temp;
unsigned int i;
assert(ir->get_num_operands() <= 4);
@@ -204,6 +220,69 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
this->mem_ctx = ralloc_parent(ir);
switch (ir->operation) {
+ case ir_unop_bit_not:
+ if (op_expr[0] && op_expr[0]->operation == ir_unop_bit_not)
+ return op_expr[0]->operands[0];
+ break;
+
+ case ir_unop_abs:
+ if (op_expr[0] == NULL)
+ break;
+
+ switch (op_expr[0]->operation) {
+ case ir_unop_abs:
+ case ir_unop_neg:
+ return abs(op_expr[0]->operands[0]);
+ default:
+ break;
+ }
+ break;
+
+ case ir_unop_neg:
+ if (op_expr[0] == NULL)
+ break;
+
+ if (op_expr[0]->operation == ir_unop_neg) {
+ return op_expr[0]->operands[0];
+ }
+ break;
+
+ case ir_unop_exp:
+ if (op_expr[0] == NULL)
+ break;
+
+ if (op_expr[0]->operation == ir_unop_log) {
+ return op_expr[0]->operands[0];
+ }
+ break;
+
+ case ir_unop_log:
+ if (op_expr[0] == NULL)
+ break;
+
+ if (op_expr[0]->operation == ir_unop_exp) {
+ return op_expr[0]->operands[0];
+ }
+ break;
+
+ case ir_unop_exp2:
+ if (op_expr[0] == NULL)
+ break;
+
+ if (op_expr[0]->operation == ir_unop_log2) {
+ return op_expr[0]->operands[0];
+ }
+ break;
+
+ case ir_unop_log2:
+ if (op_expr[0] == NULL)
+ break;
+
+ if (op_expr[0]->operation == ir_unop_exp2) {
+ return op_expr[0]->operands[0];
+ }
+ break;
+
case ir_unop_logic_not: {
enum ir_expression_operation new_op = ir_unop_logic_not;
@@ -227,7 +306,6 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
}
if (new_op != ir_unop_logic_not) {
- this->progress = true;
return new(mem_ctx) ir_expression(new_op,
ir->type,
op_expr[0]->operands[0],
@@ -238,90 +316,120 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
}
case ir_binop_add:
- if (is_vec_zero(op_const[0])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[1]);
- }
- if (is_vec_zero(op_const[1])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[0]);
- }
+ if (is_vec_zero(op_const[0]))
+ return ir->operands[1];
+ if (is_vec_zero(op_const[1]))
+ return ir->operands[0];
/* Reassociate addition of constants so that we can do constant
* folding.
*/
if (op_const[0] && !op_const[1])
- reassociate_constant(ir, 0, op_const[0],
- ir->operands[1]->as_expression());
+ reassociate_constant(ir, 0, op_const[0], op_expr[1]);
if (op_const[1] && !op_const[0])
- reassociate_constant(ir, 1, op_const[1],
- ir->operands[0]->as_expression());
+ reassociate_constant(ir, 1, op_const[1], op_expr[0]);
+
+ /* Replace (-x + y) * a + x and commutative variations with lrp(x, y, a).
+ *
+ * (-x + y) * a + x
+ * (x * -a) + (y * a) + x
+ * x + (x * -a) + (y * a)
+ * x * (1 - a) + y * a
+ * lrp(x, y, a)
+ */
+ for (int mul_pos = 0; mul_pos < 2; mul_pos++) {
+ ir_expression *mul = op_expr[mul_pos];
+
+ if (!mul || mul->operation != ir_binop_mul)
+ continue;
+
+ /* Multiply found on one of the operands. Now check for an
+ * inner addition operation.
+ */
+ for (int inner_add_pos = 0; inner_add_pos < 2; inner_add_pos++) {
+ ir_expression *inner_add =
+ mul->operands[inner_add_pos]->as_expression();
+
+ if (!inner_add || inner_add->operation != ir_binop_add)
+ continue;
+
+ /* Inner addition found on one of the operands. Now check for
+ * one of the operands of the inner addition to be the negative
+ * of x_operand.
+ */
+ for (int neg_pos = 0; neg_pos < 2; neg_pos++) {
+ ir_expression *neg =
+ inner_add->operands[neg_pos]->as_expression();
+
+ if (!neg || neg->operation != ir_unop_neg)
+ continue;
+
+ ir_rvalue *x_operand = ir->operands[1 - mul_pos];
+
+ if (!neg->operands[0]->equals(x_operand))
+ continue;
+
+ ir_rvalue *y_operand = inner_add->operands[1 - neg_pos];
+ ir_rvalue *a_operand = mul->operands[1 - inner_add_pos];
+
+ if (x_operand->type != y_operand->type ||
+ x_operand->type != a_operand->type)
+ continue;
+
+ return lrp(x_operand, y_operand, a_operand);
+ }
+ }
+ }
break;
case ir_binop_sub:
- if (is_vec_zero(op_const[0])) {
- this->progress = true;
- temp = new(mem_ctx) ir_expression(ir_unop_neg,
- ir->operands[1]->type,
- ir->operands[1],
- NULL);
- return swizzle_if_required(ir, temp);
- }
- if (is_vec_zero(op_const[1])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[0]);
- }
+ if (is_vec_zero(op_const[0]))
+ return neg(ir->operands[1]);
+ if (is_vec_zero(op_const[1]))
+ return ir->operands[0];
break;
case ir_binop_mul:
- if (is_vec_one(op_const[0])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[1]);
- }
- if (is_vec_one(op_const[1])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[0]);
- }
+ if (is_vec_one(op_const[0]))
+ return ir->operands[1];
+ if (is_vec_one(op_const[1]))
+ return ir->operands[0];
- if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
- this->progress = true;
+ if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1]))
return ir_constant::zero(ir, ir->type);
- }
+
+ if (is_vec_negative_one(op_const[0]))
+ return neg(ir->operands[1]);
+ if (is_vec_negative_one(op_const[1]))
+ return neg(ir->operands[0]);
+
/* Reassociate multiplication of constants so that we can do
* constant folding.
*/
if (op_const[0] && !op_const[1])
- reassociate_constant(ir, 0, op_const[0],
- ir->operands[1]->as_expression());
+ reassociate_constant(ir, 0, op_const[0], op_expr[1]);
if (op_const[1] && !op_const[0])
- reassociate_constant(ir, 1, op_const[1],
- ir->operands[0]->as_expression());
+ reassociate_constant(ir, 1, op_const[1], op_expr[0]);
break;
case ir_binop_div:
if (is_vec_one(op_const[0]) && ir->type->base_type == GLSL_TYPE_FLOAT) {
- this->progress = true;
- temp = new(mem_ctx) ir_expression(ir_unop_rcp,
+ return new(mem_ctx) ir_expression(ir_unop_rcp,
ir->operands[1]->type,
ir->operands[1],
NULL);
- return swizzle_if_required(ir, temp);
- }
- if (is_vec_one(op_const[1])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[0]);
}
+ if (is_vec_one(op_const[1]))
+ return ir->operands[0];
break;
case ir_binop_dot:
- if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
- this->progress = true;
+ if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1]))
return ir_constant::zero(mem_ctx, ir->type);
- }
+
if (is_vec_basis(op_const[0])) {
- this->progress = true;
unsigned component = 0;
for (unsigned c = 0; c < op_const[0]->type->vector_elements; c++) {
if (op_const[0]->value.f[c] == 1.0)
@@ -330,7 +438,6 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
return new(mem_ctx) ir_swizzle(ir->operands[1], component, 0, 0, 0, 1);
}
if (is_vec_basis(op_const[1])) {
- this->progress = true;
unsigned component = 0;
for (unsigned c = 0; c < op_const[1]->type->vector_elements; c++) {
if (op_const[1]->value.f[c] == 1.0)
@@ -340,46 +447,77 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
}
break;
+ case ir_binop_less:
+ case ir_binop_lequal:
+ case ir_binop_greater:
+ case ir_binop_gequal:
+ case ir_binop_equal:
+ case ir_binop_nequal:
+ for (int add_pos = 0; add_pos < 2; add_pos++) {
+ ir_expression *add = op_expr[add_pos];
+
+ if (!add || add->operation != ir_binop_add)
+ continue;
+
+ ir_constant *zero = op_const[1 - add_pos];
+ if (!is_vec_zero(zero))
+ continue;
+
+ return new(mem_ctx) ir_expression(ir->operation,
+ add->operands[0],
+ neg(add->operands[1]));
+ }
+ break;
+
+ case ir_binop_rshift:
+ case ir_binop_lshift:
+ /* 0 >> x == 0 */
+ if (is_vec_zero(op_const[0]))
+ return ir->operands[0];
+ /* x >> 0 == x */
+ if (is_vec_zero(op_const[1]))
+ return ir->operands[0];
+ break;
+
case ir_binop_logic_and:
- /* FINISHME: Also simplify (a && a) to (a). */
if (is_vec_one(op_const[0])) {
- this->progress = true;
return ir->operands[1];
} else if (is_vec_one(op_const[1])) {
- this->progress = true;
return ir->operands[0];
} else if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
- this->progress = true;
return ir_constant::zero(mem_ctx, ir->type);
+ } else if (op_expr[0] && op_expr[0]->operation == ir_unop_logic_not &&
+ op_expr[1] && op_expr[1]->operation == ir_unop_logic_not) {
+ /* De Morgan's Law:
+ * (not A) and (not B) === not (A or B)
+ */
+ return logic_not(logic_or(op_expr[0]->operands[0],
+ op_expr[1]->operands[0]));
+ } else if (ir->operands[0]->equals(ir->operands[1])) {
+ /* (a && a) == a */
+ return ir->operands[0];
}
break;
case ir_binop_logic_xor:
- /* FINISHME: Also simplify (a ^^ a) to (false). */
if (is_vec_zero(op_const[0])) {
- this->progress = true;
return ir->operands[1];
} else if (is_vec_zero(op_const[1])) {
- this->progress = true;
return ir->operands[0];
} else if (is_vec_one(op_const[0])) {
- this->progress = true;
- return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type,
- ir->operands[1], NULL);
+ return logic_not(ir->operands[1]);
} else if (is_vec_one(op_const[1])) {
- this->progress = true;
- return new(mem_ctx) ir_expression(ir_unop_logic_not, ir->type,
- ir->operands[0], NULL);
+ return logic_not(ir->operands[0]);
+ } else if (ir->operands[0]->equals(ir->operands[1])) {
+ /* (a ^^ a) == false */
+ return ir_constant::zero(mem_ctx, ir->type);
}
break;
case ir_binop_logic_or:
- /* FINISHME: Also simplify (a || a) to (a). */
if (is_vec_zero(op_const[0])) {
- this->progress = true;
return ir->operands[1];
} else if (is_vec_zero(op_const[1])) {
- this->progress = true;
return ir->operands[0];
} else if (is_vec_one(op_const[0]) || is_vec_one(op_const[1])) {
ir_constant_data data;
@@ -387,45 +525,97 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
for (unsigned i = 0; i < 16; i++)
data.b[i] = true;
- this->progress = true;
return new(mem_ctx) ir_constant(ir->type, &data);
+ } else if (op_expr[0] && op_expr[0]->operation == ir_unop_logic_not &&
+ op_expr[1] && op_expr[1]->operation == ir_unop_logic_not) {
+ /* De Morgan's Law:
+ * (not A) or (not B) === not (A and B)
+ */
+ return logic_not(logic_and(op_expr[0]->operands[0],
+ op_expr[1]->operands[0]));
+ } else if (ir->operands[0]->equals(ir->operands[1])) {
+ /* (a || a) == a */
+ return ir->operands[0];
+ }
+ break;
+
+ case ir_binop_pow:
+ /* 1^x == 1 */
+ if (is_vec_one(op_const[0]))
+ return op_const[0];
+
+ /* x^1 == x */
+ if (is_vec_one(op_const[1]))
+ return ir->operands[0];
+
+ /* pow(2,x) == exp2(x) */
+ if (is_vec_two(op_const[0]))
+ return expr(ir_unop_exp2, ir->operands[1]);
+
+ if (is_vec_two(op_const[1])) {
+ ir_variable *x = new(ir) ir_variable(ir->operands[1]->type, "x",
+ ir_var_temporary);
+ base_ir->insert_before(x);
+ base_ir->insert_before(assign(x, ir->operands[0]));
+ return mul(x, x);
}
+
break;
case ir_unop_rcp:
- if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) {
- this->progress = true;
+ if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp)
return op_expr[0]->operands[0];
- }
- /* FINISHME: We should do rcp(rsq(x)) -> sqrt(x) for some
- * backends, except that some backends will have done sqrt ->
- * rcp(rsq(x)) and we don't want to undo it for them.
+ /* While ir_to_mesa.cpp will lower sqrt(x) to rcp(rsq(x)), it does so at
+ * its IR level, so we can always apply this transformation.
*/
+ if (op_expr[0] && op_expr[0]->operation == ir_unop_rsq)
+ return sqrt(op_expr[0]->operands[0]);
/* As far as we know, all backends are OK with rsq. */
if (op_expr[0] && op_expr[0]->operation == ir_unop_sqrt) {
- this->progress = true;
- temp = new(mem_ctx) ir_expression(ir_unop_rsq,
- op_expr[0]->operands[0]->type,
- op_expr[0]->operands[0],
- NULL);
- return swizzle_if_required(ir, temp);
+ return rsq(op_expr[0]->operands[0]);
}
break;
+ case ir_triop_fma:
+ /* Operands are op0 * op1 + op2. */
+ if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1])) {
+ return ir->operands[2];
+ } else if (is_vec_zero(op_const[2])) {
+ return mul(ir->operands[0], ir->operands[1]);
+ } else if (is_vec_one(op_const[0])) {
+ return add(ir->operands[1], ir->operands[2]);
+ } else if (is_vec_one(op_const[1])) {
+ return add(ir->operands[0], ir->operands[2]);
+ }
+ break;
+
case ir_triop_lrp:
/* Operands are (x, y, a). */
if (is_vec_zero(op_const[2])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[0]);
+ return ir->operands[0];
} else if (is_vec_one(op_const[2])) {
- this->progress = true;
- return swizzle_if_required(ir, ir->operands[1]);
+ return ir->operands[1];
+ } else if (ir->operands[0]->equals(ir->operands[1])) {
+ return ir->operands[0];
+ } else if (is_vec_zero(op_const[0])) {
+ return mul(ir->operands[1], ir->operands[2]);
+ } else if (is_vec_zero(op_const[1])) {
+ unsigned op2_components = ir->operands[2]->type->vector_elements;
+ ir_constant *one = new(mem_ctx) ir_constant(1.0f, op2_components);
+ return mul(ir->operands[0], add(one, neg(ir->operands[2])));
}
break;
+ case ir_triop_csel:
+ if (is_vec_one(op_const[0]))
+ return ir->operands[1];
+ if (is_vec_zero(op_const[0]))
+ return ir->operands[2];
+ break;
+
default:
break;
}
@@ -443,13 +633,23 @@ ir_algebraic_visitor::handle_rvalue(ir_rvalue **rvalue)
if (!expr || expr->operation == ir_quadop_vector)
return;
- *rvalue = handle_expression(expr);
+ ir_rvalue *new_rvalue = handle_expression(expr);
+ if (new_rvalue == *rvalue)
+ return;
+
+ /* If the expr used to be some vec OP scalar returning a vector, and the
+ * optimization gave us back a scalar, we still need to turn it into a
+ * vector.
+ */
+ *rvalue = swizzle_if_required(expr, new_rvalue);
+
+ this->progress = true;
}
bool
-do_algebraic(exec_list *instructions)
+do_algebraic(exec_list *instructions, bool native_integers)
{
- ir_algebraic_visitor v;
+ ir_algebraic_visitor v(native_integers);
visit_list_elements(&v, instructions);
diff --git a/dist/Mesa/src/glsl/opt_array_splitting.cpp b/dist/Mesa/src/glsl/opt_array_splitting.cpp
index f4a7ef99b..97d3a57e9 100644
--- a/dist/Mesa/src/glsl/opt_array_splitting.cpp
+++ b/dist/Mesa/src/glsl/opt_array_splitting.cpp
@@ -40,6 +40,8 @@
static bool debug = false;
+namespace {
+
namespace opt_array_splitting {
class variable_entry : public exec_node
@@ -77,6 +79,7 @@ public:
};
} /* namespace */
+
using namespace opt_array_splitting;
/**
@@ -112,13 +115,15 @@ public:
void *mem_ctx;
};
+} /* namespace */
+
variable_entry *
ir_array_reference_visitor::get_variable_entry(ir_variable *var)
{
assert(var);
- if (var->mode != ir_var_auto &&
- var->mode != ir_var_temporary)
+ if (var->data.mode != ir_var_auto &&
+ var->data.mode != ir_var_temporary)
return NULL;
if (!(var->type->is_array() || var->type->is_matrix()))
@@ -127,11 +132,11 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
/* If the array hasn't been sized yet, we can't split it. After
* linking, this should be resolved.
*/
- if (var->type->is_array() && var->type->length == 0)
+ if (var->type->is_unsized_array())
return NULL;
- foreach_iter(exec_list_iterator, iter, this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, &this->variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (entry->var == var)
return entry;
}
@@ -219,8 +224,8 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
}
/* Trim out variables we found that we can't split. */
- foreach_iter(exec_list_iterator, iter, variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list_safe(n, &variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (debug) {
printf("array %s@%p: decl %d, split %d\n",
@@ -265,8 +270,8 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
{
assert(var);
- foreach_iter(exec_list_iterator, iter, *this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, this->variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (entry->var == var) {
return entry;
}
@@ -363,8 +368,8 @@ optimize_split_arrays(exec_list *instructions, bool linked)
/* Replace the decls of the arrays to be split with their split
* components.
*/
- foreach_iter(exec_list_iterator, iter, refs.variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, &refs.variable_list) {
+ variable_entry *entry = (variable_entry *) n;
const struct glsl_type *type = entry->var->type;
const struct glsl_type *subtype;
@@ -395,7 +400,7 @@ optimize_split_arrays(exec_list *instructions, bool linked)
visit_list_elements(&split, instructions);
if (debug)
- _mesa_print_ir(instructions, NULL);
+ _mesa_print_ir(stdout, instructions, NULL);
ralloc_free(mem_ctx);
diff --git a/dist/Mesa/src/glsl/opt_cse.cpp b/dist/Mesa/src/glsl/opt_cse.cpp
new file mode 100644
index 000000000..1b8782bcb
--- /dev/null
+++ b/dist/Mesa/src/glsl/opt_cse.cpp
@@ -0,0 +1,423 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+/**
+ * \file opt_cse.cpp
+ *
+ * constant subexpression elimination at the GLSL IR level.
+ *
+ * Compare to brw_fs_cse.cpp for a more complete CSE implementation. This one
+ * is generic and handles texture operations, but it's rather simple currently
+ * and doesn't support modification of variables in the available expressions
+ * list, so it can't do variables other than uniforms or shader inputs.
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_visitor.h"
+#include "ir_basic_block.h"
+#include "ir_optimization.h"
+#include "ir_builder.h"
+#include "glsl_types.h"
+
+using namespace ir_builder;
+
+static bool debug = false;
+
+namespace {
+
+/**
+ * This is the record of an available expression for common subexpression
+ * elimination.
+ */
+class ae_entry : public exec_node
+{
+public:
+ ae_entry(ir_instruction *base_ir, ir_rvalue **val)
+ : val(val), base_ir(base_ir)
+ {
+ assert(val);
+ assert(*val);
+ assert(base_ir);
+
+ var = NULL;
+ }
+
+ /**
+ * The pointer to the expression that we might be able to reuse
+ *
+ * Note the double pointer -- this is the place in the base_ir expression
+ * tree that we would rewrite to move the expression out to a new variable
+ * assignment.
+ */
+ ir_rvalue **val;
+
+ /**
+ * Root instruction in the basic block where the expression appeared.
+ *
+ * This is used so that we can insert the new variable declaration into the
+ * instruction stream (since *val is just somewhere in base_ir's expression
+ * tree).
+ */
+ ir_instruction *base_ir;
+
+ /**
+ * The variable that the expression has been stored in, if it's been CSEd
+ * once already.
+ */
+ ir_variable *var;
+};
+
+class cse_visitor : public ir_rvalue_visitor {
+public:
+ cse_visitor(exec_list *validate_instructions)
+ : validate_instructions(validate_instructions)
+ {
+ progress = false;
+ mem_ctx = ralloc_context(NULL);
+ this->ae = new(mem_ctx) exec_list;
+ }
+ ~cse_visitor()
+ {
+ ralloc_free(mem_ctx);
+ }
+
+ virtual ir_visitor_status visit_enter(ir_function_signature *ir);
+ virtual ir_visitor_status visit_enter(ir_loop *ir);
+ virtual ir_visitor_status visit_enter(ir_if *ir);
+ virtual ir_visitor_status visit_enter(ir_call *ir);
+ virtual void handle_rvalue(ir_rvalue **rvalue);
+
+ bool progress;
+
+private:
+ void *mem_ctx;
+
+ ir_rvalue *try_cse(ir_rvalue *rvalue);
+ void add_to_ae(ir_rvalue **rvalue);
+
+ /** List of ae_entry: The available expressions to reuse */
+ exec_list *ae;
+
+ /**
+ * The whole shader, so that we can validate_ir_tree in debug mode.
+ *
+ * This proved quite useful when trying to get the tree manipulation
+ * right.
+ */
+ exec_list *validate_instructions;
+};
+
+/**
+ * Visitor to walk an expression tree to check that all variables referenced
+ * are constants.
+ */
+class is_cse_candidate_visitor : public ir_hierarchical_visitor
+{
+public:
+
+ is_cse_candidate_visitor()
+ : ok(true)
+ {
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir);
+
+ bool ok;
+};
+
+
+class contains_rvalue_visitor : public ir_rvalue_visitor
+{
+public:
+
+ contains_rvalue_visitor(ir_rvalue *val)
+ : val(val)
+ {
+ found = false;
+ }
+
+ virtual void handle_rvalue(ir_rvalue **rvalue);
+
+ bool found;
+
+private:
+ ir_rvalue *val;
+};
+
+} /* unnamed namespace */
+
+static void
+dump_ae(exec_list *ae)
+{
+ int i = 0;
+
+ printf("CSE: AE contents:\n");
+ foreach_list(node, ae) {
+ ae_entry *entry = (ae_entry *)node;
+
+ printf("CSE: AE %2d (%p): ", i, entry);
+ (*entry->val)->print();
+ printf("\n");
+
+ if (entry->var)
+ printf("CSE: in var %p:\n", entry->var);
+
+ i++;
+ }
+}
+
+ir_visitor_status
+is_cse_candidate_visitor::visit(ir_dereference_variable *ir)
+{
+ /* Currently, since we don't handle kills of the ae based on variables
+ * getting assigned, we can only handle constant variables.
+ */
+ if (ir->var->data.read_only) {
+ return visit_continue;
+ } else {
+ ok = false;
+ return visit_stop;
+ }
+}
+
+void
+contains_rvalue_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (*rvalue == val)
+ found = true;
+}
+
+static bool
+contains_rvalue(ir_rvalue *haystack, ir_rvalue *needle)
+{
+ contains_rvalue_visitor v(needle);
+ haystack->accept(&v);
+ return v.found;
+}
+
+static bool
+is_cse_candidate(ir_rvalue *ir)
+{
+ /* Our temporary variable assignment generation isn't ready to handle
+ * anything bigger than a vector.
+ */
+ if (!ir->type->is_vector() && !ir->type->is_scalar())
+ return false;
+
+ /* Only handle expressions and textures currently. We may want to extend
+ * to variable-index array dereferences at some point.
+ */
+ switch (ir->ir_type) {
+ case ir_type_expression:
+ case ir_type_texture:
+ break;
+ default:
+ return false;
+ }
+
+ is_cse_candidate_visitor v;
+
+ ir->accept(&v);
+
+ return v.ok;
+}
+
+/**
+ * Tries to find and return a reference to a previous computation of a given
+ * expression.
+ *
+ * Walk the list of available expressions checking if any of them match the
+ * rvalue, and if so, move the previous copy of the expression to a temporary
+ * and return a reference of the temporary.
+ */
+ir_rvalue *
+cse_visitor::try_cse(ir_rvalue *rvalue)
+{
+ foreach_list(node, ae) {
+ ae_entry *entry = (ae_entry *)node;
+
+ if (debug) {
+ printf("Comparing to AE %p: ", entry);
+ (*entry->val)->print();
+ printf("\n");
+ }
+
+ if (!rvalue->equals(*entry->val))
+ continue;
+
+ if (debug) {
+ printf("CSE: Replacing: ");
+ (*entry->val)->print();
+ printf("\n");
+ printf("CSE: with: ");
+ rvalue->print();
+ printf("\n");
+ }
+
+ if (!entry->var) {
+ ir_instruction *base_ir = entry->base_ir;
+
+ ir_variable *var = new(rvalue) ir_variable(rvalue->type,
+ "cse",
+ ir_var_auto);
+
+ /* Write the previous expression result into a new variable. */
+ base_ir->insert_before(var);
+ ir_assignment *assignment = assign(var, *entry->val);
+ base_ir->insert_before(assignment);
+
+ /* Replace the expression in the original tree with a deref of the
+ * variable, but keep tracking the expression for further reuse.
+ */
+ *entry->val = new(rvalue) ir_dereference_variable(var);
+ entry->val = &assignment->rhs;
+
+ entry->var = var;
+
+ /* Update the base_irs in the AE list. We have to be sure that
+ * they're correct -- expressions from our base_ir that weren't moved
+ * need to stay in this base_ir (so that later consumption of them
+ * puts new variables between our new variable and our base_ir), but
+ * expressions from our base_ir that we *did* move need base_ir
+ * updated so that any further elimination from inside gets its new
+ * assignments put before our new assignment.
+ */
+ foreach_list(fixup_node, ae) {
+ ae_entry *fixup_entry = (ae_entry *)fixup_node;
+ if (contains_rvalue(assignment->rhs, *fixup_entry->val))
+ fixup_entry->base_ir = assignment;
+ }
+
+ if (debug)
+ dump_ae(ae);
+ }
+
+ /* Replace the expression in our current tree with the variable. */
+ return new(rvalue) ir_dereference_variable(entry->var);
+ }
+
+ return NULL;
+}
+
+/** Add the rvalue to the list of available expressions for CSE. */
+void
+cse_visitor::add_to_ae(ir_rvalue **rvalue)
+{
+ if (debug) {
+ printf("CSE: Add to AE: ");
+ (*rvalue)->print();
+ printf("\n");
+ }
+
+ ae->push_tail(new(mem_ctx) ae_entry(base_ir, rvalue));
+
+ if (debug)
+ dump_ae(ae);
+}
+
+void
+cse_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ if (debug) {
+ printf("CSE: handle_rvalue ");
+ (*rvalue)->print();
+ printf("\n");
+ }
+
+ if (!is_cse_candidate(*rvalue))
+ return;
+
+ ir_rvalue *new_rvalue = try_cse(*rvalue);
+ if (new_rvalue) {
+ *rvalue = new_rvalue;
+ progress = true;
+
+ if (debug)
+ validate_ir_tree(validate_instructions);
+ } else {
+ add_to_ae(rvalue);
+ }
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_if *ir)
+{
+ handle_rvalue(&ir->condition);
+
+ ae->make_empty();
+ visit_list_elements(this, &ir->then_instructions);
+
+ ae->make_empty();
+ visit_list_elements(this, &ir->else_instructions);
+
+ ae->make_empty();
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_function_signature *ir)
+{
+ ae->make_empty();
+ visit_list_elements(this, &ir->body);
+
+ ae->make_empty();
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_loop *ir)
+{
+ ae->make_empty();
+ visit_list_elements(this, &ir->body_instructions);
+
+ ae->make_empty();
+ return visit_continue_with_parent;
+}
+
+ir_visitor_status
+cse_visitor::visit_enter(ir_call *)
+{
+ /* Because call is an exec_list of ir_rvalues, handle_rvalue gets passed a
+ * pointer to the (ir_rvalue *) on the stack. Since we save those pointers
+ * in the AE list, we can't let handle_rvalue get called.
+ */
+ return visit_continue_with_parent;
+}
+
+/**
+ * Does a (uniform-value) constant subexpression elimination pass on the code
+ * present in the instruction stream.
+ */
+bool
+do_cse(exec_list *instructions)
+{
+ cse_visitor v(instructions);
+
+ visit_list_elements(&v, instructions);
+
+ return v.progress;
+}
diff --git a/dist/Mesa/src/glsl/opt_dead_builtin_varyings.cpp b/dist/Mesa/src/glsl/opt_dead_builtin_varyings.cpp
index 6745d5c64..6612592aa 100644
--- a/dist/Mesa/src/glsl/opt_dead_builtin_varyings.cpp
+++ b/dist/Mesa/src/glsl/opt_dead_builtin_varyings.cpp
@@ -42,9 +42,11 @@
* If any texture coordinate slots can be eliminated, the gl_TexCoord array is
* broken down into separate vec4 variables with locations equal to
* VARYING_SLOT_TEX0 + i.
+ *
+ * The same is done for the gl_FragData fragment shader output.
*/
-#include "main/imports.h" /* for snprintf */
+#include "main/core.h" /* for snprintf and ARRAY_SIZE */
#include "ir.h"
#include "ir_rvalue_visitor.h"
#include "ir_optimization.h"
@@ -52,6 +54,7 @@
#include "glsl_types.h"
#include "link_varyings.h"
+namespace {
/**
* This obtains detailed information about built-in varyings from shader code.
@@ -59,10 +62,14 @@
class varying_info_visitor : public ir_hierarchical_visitor {
public:
/* "mode" can be either ir_var_shader_in or ir_var_shader_out */
- varying_info_visitor(ir_variable_mode mode)
+ varying_info_visitor(ir_variable_mode mode, bool find_frag_outputs = false)
: lower_texcoord_array(true),
texcoord_array(NULL),
texcoord_usage(0),
+ find_frag_outputs(find_frag_outputs),
+ lower_fragdata_array(true),
+ fragdata_array(NULL),
+ fragdata_usage(0),
color_usage(0),
tfeedback_color_usage(0),
fog(NULL),
@@ -78,8 +85,27 @@ public:
{
ir_variable *var = ir->variable_referenced();
- if (var && var->mode == this->mode &&
- var->location == VARYING_SLOT_TEX0) {
+ if (!var || var->data.mode != this->mode)
+ return visit_continue;
+
+ if (this->find_frag_outputs && var->data.location == FRAG_RESULT_DATA0) {
+ this->fragdata_array = var;
+
+ ir_constant *index = ir->array_index->as_constant();
+ if (index == NULL) {
+ /* This is variable indexing. */
+ this->fragdata_usage |= (1 << var->type->array_size()) - 1;
+ this->lower_fragdata_array = false;
+ }
+ else {
+ this->fragdata_usage |= 1 << index->get_uint_component(0);
+ }
+
+ /* Don't visit the leaves of ir_dereference_array. */
+ return visit_continue_with_parent;
+ }
+
+ if (!this->find_frag_outputs && var->data.location == VARYING_SLOT_TEX0) {
this->texcoord_array = var;
ir_constant *index = ir->array_index->as_constant();
@@ -104,8 +130,17 @@ public:
{
ir_variable *var = ir->variable_referenced();
- if (var->mode == this->mode && var->type->is_array() &&
- var->location == VARYING_SLOT_TEX0) {
+ if (var->data.mode != this->mode || !var->type->is_array())
+ return visit_continue;
+
+ if (this->find_frag_outputs && var->data.location == FRAG_RESULT_DATA0) {
+ /* This is a whole array dereference. */
+ this->fragdata_usage |= (1 << var->type->array_size()) - 1;
+ this->lower_fragdata_array = false;
+ return visit_continue;
+ }
+
+ if (!this->find_frag_outputs && var->data.location == VARYING_SLOT_TEX0) {
/* This is a whole array dereference like "gl_TexCoord = x;",
* there's probably no point in lowering that.
*/
@@ -117,11 +152,15 @@ public:
virtual ir_visitor_status visit(ir_variable *var)
{
- if (var->mode != this->mode)
+ if (var->data.mode != this->mode)
+ return visit_continue;
+
+ /* Nothing to do here for fragment outputs. */
+ if (this->find_frag_outputs)
return visit_continue;
/* Handle colors and fog. */
- switch (var->location) {
+ switch (var->data.location) {
case VARYING_SLOT_COL0:
this->color[0] = var;
this->color_usage |= 1;
@@ -184,12 +223,20 @@ public:
if (!this->texcoord_array) {
this->lower_texcoord_array = false;
}
+ if (!this->fragdata_array) {
+ this->lower_fragdata_array = false;
+ }
}
bool lower_texcoord_array;
ir_variable *texcoord_array;
unsigned texcoord_usage; /* bitmask */
+ bool find_frag_outputs; /* false if it's looking for varyings */
+ bool lower_fragdata_array;
+ ir_variable *fragdata_array;
+ unsigned fragdata_usage; /* bitmask */
+
ir_variable *color[2];
ir_variable *backcolor[2];
unsigned color_usage; /* bitmask */
@@ -221,6 +268,7 @@ public:
{
void *const ctx = ir;
+ memset(this->new_fragdata, 0, sizeof(this->new_fragdata));
memset(this->new_texcoord, 0, sizeof(this->new_texcoord));
memset(this->new_color, 0, sizeof(this->new_color));
memset(this->new_backcolor, 0, sizeof(this->new_backcolor));
@@ -235,31 +283,16 @@ public:
* occurences of gl_TexCoord will be replaced with.
*/
if (info->lower_texcoord_array) {
- for (int i = MAX_TEXTURE_COORD_UNITS-1; i >= 0; i--) {
- if (info->texcoord_usage & (1 << i)) {
- char name[32];
-
- if (!(external_texcoord_usage & (1 << i))) {
- /* This varying is unused in the next stage. Declare
- * a temporary instead of an output. */
- snprintf(name, 32, "gl_%s_TexCoord%i_dummy", mode_str, i);
- this->new_texcoord[i] =
- new (ctx) ir_variable(glsl_type::vec4_type, name,
- ir_var_temporary);
- }
- else {
- snprintf(name, 32, "gl_%s_TexCoord%i", mode_str, i);
- this->new_texcoord[i] =
- new(ctx) ir_variable(glsl_type::vec4_type, name,
- info->mode);
- this->new_texcoord[i]->location = VARYING_SLOT_TEX0 + i;
- this->new_texcoord[i]->explicit_location = true;
- this->new_texcoord[i]->explicit_index = 0;
- }
-
- ir->head->insert_before(new_texcoord[i]);
- }
- }
+ prepare_array(ir, this->new_texcoord, ARRAY_SIZE(this->new_texcoord),
+ VARYING_SLOT_TEX0, "TexCoord", mode_str,
+ info->texcoord_usage, external_texcoord_usage);
+ }
+
+ /* Handle gl_FragData in the same way like gl_TexCoord. */
+ if (info->lower_fragdata_array) {
+ prepare_array(ir, this->new_fragdata, ARRAY_SIZE(this->new_fragdata),
+ FRAG_RESULT_DATA0, "FragData", mode_str,
+ info->fragdata_usage, (1 << MAX_DRAW_BUFFERS) - 1);
}
/* Create dummy variables which will replace set-but-unused color and
@@ -300,6 +333,41 @@ public:
visit_list_elements(this, ir);
}
+ void prepare_array(exec_list *ir,
+ struct ir_variable **new_var,
+ int max_elements, unsigned start_location,
+ const char *var_name, const char *mode_str,
+ unsigned usage, unsigned external_usage)
+ {
+ void *const ctx = ir;
+
+ for (int i = max_elements-1; i >= 0; i--) {
+ if (usage & (1 << i)) {
+ char name[32];
+
+ if (!(external_usage & (1 << i))) {
+ /* This varying is unused in the next stage. Declare
+ * a temporary instead of an output. */
+ snprintf(name, 32, "gl_%s_%s%i_dummy", mode_str, var_name, i);
+ new_var[i] =
+ new (ctx) ir_variable(glsl_type::vec4_type, name,
+ ir_var_temporary);
+ }
+ else {
+ snprintf(name, 32, "gl_%s_%s%i", mode_str, var_name, i);
+ new_var[i] =
+ new(ctx) ir_variable(glsl_type::vec4_type, name,
+ this->info->mode);
+ new_var[i]->data.location = start_location + i;
+ new_var[i]->data.explicit_location = true;
+ new_var[i]->data.explicit_index = 0;
+ }
+
+ ir->head->insert_before(new_var[i]);
+ }
+ }
+ }
+
virtual ir_visitor_status visit(ir_variable *var)
{
/* Remove the gl_TexCoord array. */
@@ -308,6 +376,12 @@ public:
var->remove();
}
+ /* Remove the gl_FragData array. */
+ if (this->info->lower_fragdata_array &&
+ var == this->info->fragdata_array) {
+ var->remove();
+ }
+
/* Replace set-but-unused color and fog outputs with dummy variables. */
for (int i = 0; i < 2; i++) {
if (var == this->info->color[i] && this->new_color[i]) {
@@ -349,6 +423,19 @@ public:
}
}
+ /* Same for gl_FragData. */
+ if (this->info->lower_fragdata_array) {
+ /* gl_FragData[i] occurence */
+ ir_dereference_array *const da = (*rvalue)->as_dereference_array();
+
+ if (da && da->variable_referenced() == this->info->fragdata_array) {
+ unsigned i = da->array_index->as_constant()->get_uint_component(0);
+
+ *rvalue = new(ctx) ir_dereference_variable(this->new_fragdata[i]);
+ return;
+ }
+ }
+
/* Replace set-but-unused color and fog outputs with dummy variables. */
ir_dereference_variable *const dv = (*rvalue)->as_dereference_variable();
if (!dv)
@@ -391,12 +478,14 @@ public:
private:
const varying_info_visitor *info;
- struct ir_variable *new_texcoord[MAX_TEXTURE_COORD_UNITS];
- struct ir_variable *new_color[2];
- struct ir_variable *new_backcolor[2];
- struct ir_variable *new_fog;
+ ir_variable *new_fragdata[MAX_DRAW_BUFFERS];
+ ir_variable *new_texcoord[MAX_TEXTURE_COORD_UNITS];
+ ir_variable *new_color[2];
+ ir_variable *new_backcolor[2];
+ ir_variable *new_fog;
};
+} /* anonymous namespace */
static void
lower_texcoord_array(exec_list *ir, const varying_info_visitor *info)
@@ -406,6 +495,15 @@ lower_texcoord_array(exec_list *ir, const varying_info_visitor *info)
1 | 2, true);
}
+static void
+lower_fragdata_array(exec_list *ir)
+{
+ varying_info_visitor info(ir_var_shader_out, true);
+ info.get(ir, 0, NULL);
+
+ replace_varyings_visitor(ir, &info, 0, 0, 0);
+}
+
void
do_dead_builtin_varyings(struct gl_context *ctx,
@@ -413,16 +511,16 @@ do_dead_builtin_varyings(struct gl_context *ctx,
unsigned num_tfeedback_decls,
tfeedback_decl *tfeedback_decls)
{
- /* This optimization has no effect with the core context and GLES2, because
- * the built-in varyings we're eliminating here are not available there.
- *
- * EXT_separate_shader_objects doesn't allow this optimization,
- * because a program object can be bound partially (e.g. only one
- * stage of a program object can be bound).
+ /* Lower the gl_FragData array to separate variables. */
+ if (consumer && consumer->Stage == MESA_SHADER_FRAGMENT) {
+ lower_fragdata_array(consumer->ir);
+ }
+
+ /* Lowering of built-in varyings has no effect with the core context and
+ * GLES2, because they are not available there.
*/
if (ctx->API == API_OPENGL_CORE ||
- ctx->API == API_OPENGLES2 ||
- ctx->Extensions.EXT_separate_shader_objects) {
+ ctx->API == API_OPENGLES2) {
return;
}
@@ -471,7 +569,7 @@ do_dead_builtin_varyings(struct gl_context *ctx,
* This doesn't prevent elimination of the gl_TexCoord elements which
* are not read by the fragment shader. We want to eliminate those anyway.
*/
- if (consumer->Type == GL_FRAGMENT_SHADER) {
+ if (consumer->Stage == MESA_SHADER_FRAGMENT) {
producer_info.texcoord_usage = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
}
diff --git a/dist/Mesa/src/glsl/opt_dead_code.cpp b/dist/Mesa/src/glsl/opt_dead_code.cpp
index b65e5c2ce..af53d94fd 100644
--- a/dist/Mesa/src/glsl/opt_dead_code.cpp
+++ b/dist/Mesa/src/glsl/opt_dead_code.cpp
@@ -79,9 +79,9 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
/* Remove a single dead assignment to the variable we found.
* Don't do so if it's a shader or function output, though.
*/
- if (entry->var->mode != ir_var_function_out &&
- entry->var->mode != ir_var_function_inout &&
- entry->var->mode != ir_var_shader_out) {
+ if (entry->var->data.mode != ir_var_function_out &&
+ entry->var->data.mode != ir_var_function_inout &&
+ entry->var->data.mode != ir_var_shader_out) {
entry->assign->remove();
progress = true;
@@ -99,7 +99,7 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
* stage. Also, once uniform locations have been assigned, the
* declaration cannot be deleted.
*/
- if (entry->var->mode == ir_var_uniform &&
+ if (entry->var->data.mode == ir_var_uniform &&
(uniform_locations_assigned ||
entry->var->constant_value))
continue;
@@ -129,13 +129,12 @@ do_dead_code_unlinked(exec_list *instructions)
{
bool progress = false;
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_function *f = ir->as_function();
if (f) {
- foreach_iter(exec_list_iterator, sigiter, *f) {
- ir_function_signature *sig =
- (ir_function_signature *) sigiter.get();
+ foreach_list(signode, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) signode;
/* The setting of the uniform_locations_assigned flag here is
* irrelevent. If there is a uniform declaration encountered
* inside the body of the function, something has already gone
diff --git a/dist/Mesa/src/glsl/opt_flip_matrices.cpp b/dist/Mesa/src/glsl/opt_flip_matrices.cpp
index 2107b1d47..9044fd680 100644
--- a/dist/Mesa/src/glsl/opt_flip_matrices.cpp
+++ b/dist/Mesa/src/glsl/opt_flip_matrices.cpp
@@ -104,8 +104,8 @@ matrix_flipper::visit_enter(ir_expression *ir)
var_ref->var = texmat_transpose;
- texmat_transpose->max_array_access =
- MAX2(texmat_transpose->max_array_access, mat_var->max_array_access);
+ texmat_transpose->data.max_array_access =
+ MAX2(texmat_transpose->data.max_array_access, mat_var->data.max_array_access);
progress = true;
}
diff --git a/dist/Mesa/src/glsl/opt_vectorize.cpp b/dist/Mesa/src/glsl/opt_vectorize.cpp
new file mode 100644
index 000000000..f9a3b6183
--- /dev/null
+++ b/dist/Mesa/src/glsl/opt_vectorize.cpp
@@ -0,0 +1,395 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+/**
+ * \file opt_vectorize.cpp
+ *
+ * Combines scalar assignments of the same expression (modulo swizzle) to
+ * multiple channels of the same variable into a single vectorized expression
+ * and assignment.
+ *
+ * Many generated shaders contain scalarized code. That is, they contain
+ *
+ * r1.x = log2(v0.x);
+ * r1.y = log2(v0.y);
+ * r1.z = log2(v0.z);
+ *
+ * rather than
+ *
+ * r1.xyz = log2(v0.xyz);
+ *
+ * We look for consecutive assignments of the same expression (modulo swizzle)
+ * to each channel of the same variable.
+ *
+ * For instance, we want to convert these three scalar operations
+ *
+ * (assign (x) (var_ref r1) (expression float log2 (swiz x (var_ref v0))))
+ * (assign (y) (var_ref r1) (expression float log2 (swiz y (var_ref v0))))
+ * (assign (z) (var_ref r1) (expression float log2 (swiz z (var_ref v0))))
+ *
+ * into a single vector operation
+ *
+ * (assign (xyz) (var_ref r1) (expression vec3 log2 (swiz xyz (var_ref v0))))
+ */
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_optimization.h"
+#include "glsl_types.h"
+#include "program/prog_instruction.h"
+
+namespace {
+
+class ir_vectorize_visitor : public ir_hierarchical_visitor {
+public:
+ void clear()
+ {
+ assignment[0] = NULL;
+ assignment[1] = NULL;
+ assignment[2] = NULL;
+ assignment[3] = NULL;
+ current_assignment = NULL;
+ last_assignment = NULL;
+ channels = 0;
+ has_swizzle = false;
+ }
+
+ ir_vectorize_visitor()
+ {
+ clear();
+ progress = false;
+ }
+
+ virtual ir_visitor_status visit_enter(ir_assignment *);
+ virtual ir_visitor_status visit_enter(ir_swizzle *);
+ virtual ir_visitor_status visit_enter(ir_dereference_array *);
+ virtual ir_visitor_status visit_enter(ir_expression *);
+ virtual ir_visitor_status visit_enter(ir_if *);
+ virtual ir_visitor_status visit_enter(ir_loop *);
+
+ virtual ir_visitor_status visit_leave(ir_assignment *);
+
+ void try_vectorize();
+
+ ir_assignment *assignment[4];
+ ir_assignment *current_assignment, *last_assignment;
+ unsigned channels;
+ bool has_swizzle;
+
+ bool progress;
+};
+
+} /* unnamed namespace */
+
+/**
+ * Rewrites the swizzles and types of a right-hand side of an assignment.
+ *
+ * From the example above, this function would be called (by visit_tree()) on
+ * the nodes of the tree (expression float log2 (swiz z (var_ref v0))),
+ * rewriting it into (expression vec3 log2 (swiz xyz (var_ref v0))).
+ *
+ * The function operates on ir_expressions (and its operands) and ir_swizzles.
+ * For expressions it sets a new type and swizzles any non-expression and non-
+ * swizzle scalar operands into appropriately sized vector arguments. For
+ * example, if combining
+ *
+ * (assign (x) (var_ref r1) (expression float + (swiz x (var_ref v0) (var_ref v1))))
+ * (assign (y) (var_ref r1) (expression float + (swiz y (var_ref v0) (var_ref v1))))
+ *
+ * where v1 is a scalar, rewrite_swizzle() would insert a swizzle on
+ * (var_ref v1) such that the final result was
+ *
+ * (assign (xy) (var_ref r1) (expression vec2 + (swiz xy (var_ref v0))
+ * (swiz xx (var_ref v1))))
+ *
+ * For swizzles, it sets a new type, and if the variable being swizzled is a
+ * vector it overwrites the swizzle mask with the ir_swizzle_mask passed as the
+ * data parameter. If the swizzled variable is scalar, then the swizzle was
+ * added by an earlier call to rewrite_swizzle() on an expression, so the
+ * mask should not be modified.
+ */
+static void
+rewrite_swizzle(ir_instruction *ir, void *data)
+{
+ ir_swizzle_mask *mask = (ir_swizzle_mask *)data;
+
+ switch (ir->ir_type) {
+ case ir_type_swizzle: {
+ ir_swizzle *swz = (ir_swizzle *)ir;
+ if (swz->val->type->is_vector()) {
+ swz->mask = *mask;
+ }
+ swz->type = glsl_type::get_instance(swz->type->base_type,
+ mask->num_components, 1);
+ break;
+ }
+ case ir_type_expression: {
+ ir_expression *expr = (ir_expression *)ir;
+ expr->type = glsl_type::get_instance(expr->type->base_type,
+ mask->num_components, 1);
+ for (unsigned i = 0; i < 4; i++) {
+ if (expr->operands[i]) {
+ ir_rvalue *rval = expr->operands[i]->as_rvalue();
+ if (rval && rval->type->is_scalar() &&
+ !rval->as_expression() && !rval->as_swizzle()) {
+ expr->operands[i] = new(ir) ir_swizzle(rval, 0, 0, 0, 0,
+ mask->num_components);
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * Attempt to vectorize the previously saved assignments, and clear them from
+ * consideration.
+ *
+ * If the assignments are able to be combined, it modifies in-place the last
+ * assignment seen to be an equivalent vector form of the scalar assignments.
+ * It then removes the other now obsolete scalar assignments.
+ */
+void
+ir_vectorize_visitor::try_vectorize()
+{
+ if (this->last_assignment && this->channels > 1) {
+ ir_swizzle_mask mask = {0, 0, 0, 0, channels, 0};
+
+ this->last_assignment->write_mask = 0;
+
+ for (unsigned i = 0, j = 0; i < 4; i++) {
+ if (this->assignment[i]) {
+ this->last_assignment->write_mask |= 1 << i;
+
+ if (this->assignment[i] != this->last_assignment) {
+ this->assignment[i]->remove();
+ }
+
+ switch (j) {
+ case 0: mask.x = i; break;
+ case 1: mask.y = i; break;
+ case 2: mask.z = i; break;
+ case 3: mask.w = i; break;
+ }
+
+ j++;
+ }
+ }
+
+ visit_tree(this->last_assignment->rhs, rewrite_swizzle, &mask);
+
+ this->progress = true;
+ }
+ clear();
+}
+
+/**
+ * Returns whether the write mask is a single channel.
+ */
+static bool
+single_channel_write_mask(unsigned write_mask)
+{
+ return write_mask != 0 && (write_mask & (write_mask - 1)) == 0;
+}
+
+/**
+ * Translates single-channeled write mask to single-channeled swizzle.
+ */
+static unsigned
+write_mask_to_swizzle(unsigned write_mask)
+{
+ switch (write_mask) {
+ case WRITEMASK_X: return SWIZZLE_X;
+ case WRITEMASK_Y: return SWIZZLE_Y;
+ case WRITEMASK_Z: return SWIZZLE_Z;
+ case WRITEMASK_W: return SWIZZLE_W;
+ }
+ assert(!"not reached");
+ unreachable();
+}
+
+/**
+ * Returns whether a single-channeled write mask matches a swizzle.
+ */
+static bool
+write_mask_matches_swizzle(unsigned write_mask,
+ const ir_swizzle *swz)
+{
+ return ((write_mask == WRITEMASK_X && swz->mask.x == SWIZZLE_X) ||
+ (write_mask == WRITEMASK_Y && swz->mask.x == SWIZZLE_Y) ||
+ (write_mask == WRITEMASK_Z && swz->mask.x == SWIZZLE_Z) ||
+ (write_mask == WRITEMASK_W && swz->mask.x == SWIZZLE_W));
+}
+
+/**
+ * Upon entering an ir_assignment, attempt to vectorize the currently tracked
+ * assignments if the current assignment is not suitable. Keep a pointer to
+ * the current assignment.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_enter(ir_assignment *ir)
+{
+ ir_dereference *lhs = this->last_assignment != NULL ?
+ this->last_assignment->lhs : NULL;
+ ir_rvalue *rhs = this->last_assignment != NULL ?
+ this->last_assignment->rhs : NULL;
+
+ if (ir->condition ||
+ this->channels >= 4 ||
+ !single_channel_write_mask(ir->write_mask) ||
+ this->assignment[write_mask_to_swizzle(ir->write_mask)] != NULL ||
+ (lhs && !ir->lhs->equals(lhs)) ||
+ (rhs && !ir->rhs->equals(rhs, ir_type_swizzle))) {
+ try_vectorize();
+ }
+
+ this->current_assignment = ir;
+
+ return visit_continue;
+}
+
+/**
+ * Upon entering an ir_swizzle, set ::has_swizzle if we're visiting from an
+ * ir_assignment (i.e., that ::current_assignment is set) and the swizzle mask
+ * matches the current assignment's write mask.
+ *
+ * If the write mask doesn't match the swizzle mask, remove the current
+ * assignment from further consideration.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_enter(ir_swizzle *ir)
+{
+ if (this->current_assignment) {
+ if (write_mask_matches_swizzle(this->current_assignment->write_mask, ir)) {
+ this->has_swizzle = true;
+ } else {
+ this->current_assignment = NULL;
+ }
+ }
+ return visit_continue;
+}
+
+/* Upon entering an ir_array_dereference, remove the current assignment from
+ * further consideration. Since the index of an array dereference must scalar,
+ * we are not able to vectorize it.
+ *
+ * FINISHME: If all of scalar indices are identical we could vectorize.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_enter(ir_dereference_array *)
+{
+ this->current_assignment = NULL;
+ return visit_continue_with_parent;
+}
+
+/**
+ * Upon entering an ir_expression, remove the current assignment from further
+ * consideration if the expression operates horizontally on vectors.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_enter(ir_expression *ir)
+{
+ if (ir->is_horizontal()) {
+ this->current_assignment = NULL;
+ return visit_continue_with_parent;
+ }
+ return visit_continue;
+}
+
+/* Since there is no statement to visit between the "then" and "else"
+ * instructions try to vectorize before, in between, and after them to avoid
+ * combining statements from different basic blocks.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_enter(ir_if *ir)
+{
+ try_vectorize();
+
+ visit_list_elements(this, &ir->then_instructions);
+ try_vectorize();
+
+ visit_list_elements(this, &ir->else_instructions);
+ try_vectorize();
+
+ return visit_continue_with_parent;
+}
+
+/* Since there is no statement to visit between the instructions in the body of
+ * the loop and the instructions after it try to vectorize before and after the
+ * body to avoid combining statements from different basic blocks.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_enter(ir_loop *ir)
+{
+ try_vectorize();
+
+ visit_list_elements(this, &ir->body_instructions);
+ try_vectorize();
+
+ return visit_continue_with_parent;
+}
+
+/**
+ * Upon leaving an ir_assignment, save a pointer to it in ::assignment[] if
+ * the swizzle mask(s) found were appropriate. Also save a pointer in
+ * ::last_assignment so that we can compare future assignments with it.
+ *
+ * Finally, clear ::current_assignment and ::has_swizzle.
+ */
+ir_visitor_status
+ir_vectorize_visitor::visit_leave(ir_assignment *ir)
+{
+ if (this->has_swizzle && this->current_assignment) {
+ assert(this->current_assignment == ir);
+
+ unsigned channel = write_mask_to_swizzle(this->current_assignment->write_mask);
+ this->assignment[channel] = ir;
+ this->channels++;
+
+ this->last_assignment = this->current_assignment;
+ }
+ this->current_assignment = NULL;
+ this->has_swizzle = false;
+ return visit_continue;
+}
+
+/**
+ * Combines scalar assignments of the same expression (modulo swizzle) to
+ * multiple channels of the same variable into a single vectorized expression
+ * and assignment.
+ */
+bool
+do_vectorize(exec_list *instructions)
+{
+ ir_vectorize_visitor v;
+
+ v.run(instructions);
+
+ /* Try to vectorize the last assignments seen. */
+ v.try_vectorize();
+
+ return v.progress;
+}
diff --git a/dist/Mesa/src/glsl/ralloc.h b/dist/Mesa/src/glsl/ralloc.h
index 67eb93833..4581a7a4e 100644
--- a/dist/Mesa/src/glsl/ralloc.h
+++ b/dist/Mesa/src/glsl/ralloc.h
@@ -404,4 +404,42 @@ bool ralloc_vasprintf_append(char **str, const char *fmt, va_list args);
} /* end of extern "C" */
#endif
+/**
+ * Declare C++ new and delete operators which use ralloc.
+ *
+ * Placing this macro in the body of a class makes it possible to do:
+ *
+ * TYPE *var = new(mem_ctx) TYPE(...);
+ * delete var;
+ *
+ * which is more idiomatic in C++ than calling ralloc.
+ */
+#define DECLARE_RALLOC_CXX_OPERATORS(TYPE) \
+private: \
+ static void _ralloc_destructor(void *p) \
+ { \
+ reinterpret_cast<TYPE *>(p)->~TYPE(); \
+ } \
+public: \
+ static void* operator new(size_t size, void *mem_ctx) \
+ { \
+ void *p = ralloc_size(mem_ctx, size); \
+ assert(p != NULL); \
+ if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \
+ ralloc_set_destructor(p, _ralloc_destructor); \
+ return p; \
+ } \
+ \
+ static void operator delete(void *p) \
+ { \
+ /* The object's destructor is guaranteed to have already been \
+ * called by the delete operator at this point -- Make sure it's \
+ * not called again. \
+ */ \
+ if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \
+ ralloc_set_destructor(p, NULL); \
+ ralloc_free(p); \
+ }
+
+
#endif
diff --git a/dist/Mesa/src/glsl/standalone_scaffolding.cpp b/dist/Mesa/src/glsl/standalone_scaffolding.cpp
index 11cd6cdc0..6c25010b7 100644
--- a/dist/Mesa/src/glsl/standalone_scaffolding.cpp
+++ b/dist/Mesa/src/glsl/standalone_scaffolding.cpp
@@ -76,6 +76,7 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
shader = rzalloc(NULL, struct gl_shader);
if (shader) {
shader->Type = type;
+ shader->Stage = _mesa_shader_enum_to_shader_stage(type);
shader->Name = name;
shader->RefCount = 1;
}
@@ -90,21 +91,36 @@ 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_compute_shader = true;
+ ctx->Extensions.ARB_conservative_depth = true;
ctx->Extensions.ARB_draw_instanced = true;
+ ctx->Extensions.ARB_ES2_compatibility = true;
+ ctx->Extensions.ARB_ES3_compatibility = true;
+ ctx->Extensions.ARB_explicit_attrib_location = true;
ctx->Extensions.ARB_fragment_coord_conventions = true;
- 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->Extensions.ARB_gpu_shader5 = true;
+ ctx->Extensions.ARB_sample_shading = true;
ctx->Extensions.ARB_shader_bit_encoding = true;
+ ctx->Extensions.ARB_shader_stencil_export = true;
+ ctx->Extensions.ARB_shader_texture_lod = true;
+ ctx->Extensions.ARB_shading_language_420pack = true;
ctx->Extensions.ARB_shading_language_packing = true;
- ctx->Extensions.OES_standard_derivatives = true;
ctx->Extensions.ARB_texture_cube_map_array = true;
+ ctx->Extensions.ARB_texture_gather = true;
ctx->Extensions.ARB_texture_multisample = true;
+ ctx->Extensions.ARB_texture_query_levels = true;
ctx->Extensions.ARB_texture_query_lod = true;
- ctx->Extensions.ARB_gpu_shader5 = true;
+ ctx->Extensions.ARB_uniform_buffer_object = true;
+ ctx->Extensions.ARB_viewport_array = true;
+
+ ctx->Extensions.OES_EGL_image_external = true;
+ ctx->Extensions.OES_standard_derivatives = true;
+
+ ctx->Extensions.EXT_shader_integer_mix = true;
+ ctx->Extensions.EXT_texture3D = true;
+ ctx->Extensions.EXT_texture_array = true;
+
+ ctx->Extensions.NV_texture_rectangle = true;
ctx->Const.GLSLVersion = 120;
@@ -113,16 +129,29 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
ctx->Const.MaxClipPlanes = 6;
ctx->Const.MaxTextureUnits = 2;
ctx->Const.MaxTextureCoordUnits = 2;
- ctx->Const.VertexProgram.MaxAttribs = 16;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
- ctx->Const.VertexProgram.MaxUniformComponents = 512;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
ctx->Const.MaxVarying = 8; /* == gl_MaxVaryingFloats / 4 */
- ctx->Const.VertexProgram.MaxTextureImageUnits = 0;
+ ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
ctx->Const.MaxCombinedTextureImageUnits = 2;
- ctx->Const.FragmentProgram.MaxTextureImageUnits = 2;
- ctx->Const.FragmentProgram.MaxUniformComponents = 64;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 2;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64;
+ ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 32;
ctx->Const.MaxDrawBuffers = 1;
+ ctx->Const.MaxComputeWorkGroupCount[0] = 65535;
+ ctx->Const.MaxComputeWorkGroupCount[1] = 65535;
+ ctx->Const.MaxComputeWorkGroupCount[2] = 65535;
+ ctx->Const.MaxComputeWorkGroupSize[0] = 1024;
+ ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
+ ctx->Const.MaxComputeWorkGroupSize[2] = 64;
+ ctx->Const.MaxComputeWorkGroupInvocations = 1024;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024;
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */
+ ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */
/* Set up default shader compiler options. */
struct gl_shader_compiler_options options;
@@ -133,6 +162,6 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api)
/* Default pragma settings */
options.DefaultPragmas.Optimize = true;
- for (int sh = 0; sh < MESA_SHADER_TYPES; ++sh)
+ for (int sh = 0; sh < MESA_SHADER_STAGES; ++sh)
memcpy(&ctx->ShaderCompilerOptions[sh], &options, sizeof(options));
}
diff --git a/dist/Mesa/src/glsl/standalone_scaffolding.h b/dist/Mesa/src/glsl/standalone_scaffolding.h
index 7afb1c313..df783afdb 100644
--- a/dist/Mesa/src/glsl/standalone_scaffolding.h
+++ b/dist/Mesa/src/glsl/standalone_scaffolding.h
@@ -48,8 +48,8 @@ extern "C" void
_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,
const char *msg, int len);
-static inline gl_shader_type
-_mesa_shader_type_to_index(GLenum v)
+static inline gl_shader_stage
+_mesa_shader_enum_to_shader_stage(GLenum v)
{
switch (v) {
case GL_VERTEX_SHADER:
@@ -58,9 +58,11 @@ _mesa_shader_type_to_index(GLenum v)
return MESA_SHADER_FRAGMENT;
case GL_GEOMETRY_SHADER:
return MESA_SHADER_GEOMETRY;
+ case GL_COMPUTE_SHADER:
+ return MESA_SHADER_COMPUTE;
default:
- assert(!"bad value in _mesa_shader_type_to_index()");
- return MESA_SHADER_TYPES;
+ assert(!"bad value in _mesa_shader_enum_to_shader_stage()");
+ return MESA_SHADER_VERTEX;
}
}
diff --git a/dist/Mesa/src/glsl/test_optpass.cpp b/dist/Mesa/src/glsl/test_optpass.cpp
index 67e2ab2b1..db5cb2662 100644
--- a/dist/Mesa/src/glsl/test_optpass.cpp
+++ b/dist/Mesa/src/glsl/test_optpass.cpp
@@ -62,11 +62,10 @@ do_optimization(struct exec_list *ir, const char *optimization,
int int_3;
int int_4;
- if (sscanf(optimization, "do_common_optimization ( %d , %d ) ",
- &int_0, &int_1) == 2) {
- return do_common_optimization(ir, int_0 != 0, false, int_1, options);
+ if (sscanf(optimization, "do_common_optimization ( %d ) ", &int_0) == 1) {
+ return do_common_optimization(ir, int_0 != 0, false, options, true);
} else if (strcmp(optimization, "do_algebraic") == 0) {
- return do_algebraic(ir);
+ return do_algebraic(ir, true);
} else if (strcmp(optimization, "do_constant_folding") == 0) {
return do_constant_folding(ir);
} else if (strcmp(optimization, "do_constant_variable") == 0) {
@@ -204,11 +203,12 @@ int test_optpass(int argc, char **argv)
struct gl_shader *shader = rzalloc(NULL, struct gl_shader);
shader->Type = shader_type;
+ shader->Stage = _mesa_shader_enum_to_shader_stage(shader_type);
string input = read_stdin_to_eof();
struct _mesa_glsl_parse_state *state
- = new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
+ = new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
if (input_format_ir) {
shader->ir = new(shader) exec_list;
@@ -234,7 +234,7 @@ int test_optpass(int argc, char **argv)
/* Print out the initial IR */
if (!state->error && !quiet) {
printf("*** pre-optimization IR:\n");
- _mesa_print_ir(shader->ir, state);
+ _mesa_print_ir(stdout, shader->ir, state);
printf("\n--\n");
}
@@ -242,7 +242,7 @@ int test_optpass(int argc, char **argv)
if (!state->error) {
GLboolean progress;
const struct gl_shader_compiler_options *options =
- &ctx->ShaderCompilerOptions[_mesa_shader_type_to_index(shader_type)];
+ &ctx->ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader_type)];
do {
progress = do_optimization_passes(shader->ir, &argv[optind],
argc - optind, quiet != 0, options);
@@ -254,7 +254,7 @@ int test_optpass(int argc, char **argv)
if (!quiet) {
printf("*** resulting IR:\n");
}
- _mesa_print_ir(shader->ir, state);
+ _mesa_print_ir(stdout, shader->ir, state);
if (!quiet) {
printf("\n--\n");
}
diff --git a/dist/Mesa/src/glsl/tests/builtin_variable_test.cpp b/dist/Mesa/src/glsl/tests/builtin_variable_test.cpp
new file mode 100644
index 000000000..3fdfce57d
--- /dev/null
+++ b/dist/Mesa/src/glsl/tests/builtin_variable_test.cpp
@@ -0,0 +1,394 @@
+/*
+ * Copyright © 2013 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 <gtest/gtest.h>
+#include "standalone_scaffolding.h"
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "ralloc.h"
+#include "ir.h"
+#include "glsl_parser_extras.h"
+#include "glsl_symbol_table.h"
+
+class common_builtin : public ::testing::Test {
+public:
+ common_builtin(GLenum shader_type)
+ : shader_type(shader_type)
+ {
+ /* empty */
+ }
+
+ virtual void SetUp();
+ virtual void TearDown();
+
+ void string_starts_with_prefix(const char *str, const char *prefix);
+ void names_start_with_gl();
+ void uniforms_and_system_values_dont_have_explicit_location();
+ void constants_are_constant();
+ void no_invalid_variable_modes();
+
+ GLenum shader_type;
+ struct _mesa_glsl_parse_state *state;
+ struct gl_shader *shader;
+ void *mem_ctx;
+ gl_context ctx;
+ exec_list ir;
+};
+
+void
+common_builtin::SetUp()
+{
+ this->mem_ctx = ralloc_context(NULL);
+ this->ir.make_empty();
+
+ initialize_context_to_defaults(&this->ctx, API_OPENGL_COMPAT);
+
+ this->shader = rzalloc(this->mem_ctx, gl_shader);
+ this->shader->Type = this->shader_type;
+ this->shader->Stage = _mesa_shader_enum_to_shader_stage(this->shader_type);
+
+ this->state =
+ new(mem_ctx) _mesa_glsl_parse_state(&this->ctx, this->shader->Stage,
+ this->shader);
+
+ _mesa_glsl_initialize_types(this->state);
+ _mesa_glsl_initialize_variables(&this->ir, this->state);
+}
+
+void
+common_builtin::TearDown()
+{
+ ralloc_free(this->mem_ctx);
+ this->mem_ctx = NULL;
+}
+
+void
+common_builtin::string_starts_with_prefix(const char *str, const char *prefix)
+{
+ const size_t len = strlen(prefix);
+ char *const name_prefix = new char[len + 1];
+
+ strncpy(name_prefix, str, len);
+ name_prefix[len] = '\0';
+ EXPECT_STREQ(prefix, name_prefix) << "Bad name " << str;
+
+ delete [] name_prefix;
+}
+
+void
+common_builtin::names_start_with_gl()
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ string_starts_with_prefix(var->name, "gl_");
+ }
+}
+
+void
+common_builtin::uniforms_and_system_values_dont_have_explicit_location()
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_system_value)
+ continue;
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+ }
+}
+
+void
+common_builtin::constants_are_constant()
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_auto)
+ continue;
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+ EXPECT_TRUE(var->data.read_only);
+ }
+}
+
+void
+common_builtin::no_invalid_variable_modes()
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ switch (var->data.mode) {
+ case ir_var_auto:
+ case ir_var_uniform:
+ case ir_var_shader_in:
+ case ir_var_shader_out:
+ case ir_var_system_value:
+ break;
+
+ default:
+ ADD_FAILURE() << "Built-in variable " << var->name
+ << " has an invalid mode " << int(var->data.mode);
+ break;
+ }
+ }
+}
+
+/************************************************************/
+
+class vertex_builtin : public common_builtin {
+public:
+ vertex_builtin()
+ : common_builtin(GL_VERTEX_SHADER)
+ {
+ /* empty */
+ }
+};
+
+TEST_F(vertex_builtin, names_start_with_gl)
+{
+ common_builtin::names_start_with_gl();
+}
+
+TEST_F(vertex_builtin, inputs_have_explicit_location)
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_shader_in)
+ continue;
+
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_NE(-1, var->data.location);
+ EXPECT_GT(VERT_ATTRIB_GENERIC0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ }
+}
+
+TEST_F(vertex_builtin, outputs_have_explicit_location)
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_shader_out)
+ continue;
+
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_NE(-1, var->data.location);
+ EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+
+ /* Several varyings only exist in the fragment shader. Be sure that no
+ * outputs with these locations exist.
+ */
+ EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
+ EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
+ EXPECT_NE(VARYING_SLOT_PRIMITIVE_ID, var->data.location);
+ }
+}
+
+TEST_F(vertex_builtin, uniforms_and_system_values_dont_have_explicit_location)
+{
+ common_builtin::uniforms_and_system_values_dont_have_explicit_location();
+}
+
+TEST_F(vertex_builtin, constants_are_constant)
+{
+ common_builtin::constants_are_constant();
+}
+
+TEST_F(vertex_builtin, no_invalid_variable_modes)
+{
+ common_builtin::no_invalid_variable_modes();
+}
+
+/********************************************************************/
+
+class fragment_builtin : public common_builtin {
+public:
+ fragment_builtin()
+ : common_builtin(GL_FRAGMENT_SHADER)
+ {
+ /* empty */
+ }
+};
+
+TEST_F(fragment_builtin, names_start_with_gl)
+{
+ common_builtin::names_start_with_gl();
+}
+
+TEST_F(fragment_builtin, inputs_have_explicit_location)
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_shader_in)
+ continue;
+
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_NE(-1, var->data.location);
+ EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+
+ /* Several varyings only exist in the vertex / geometry shader. Be sure
+ * that no inputs with these locations exist.
+ */
+ EXPECT_TRUE(_mesa_varying_slot_in_fs((gl_varying_slot) var->data.location));
+ }
+}
+
+TEST_F(fragment_builtin, outputs_have_explicit_location)
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_shader_out)
+ continue;
+
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_NE(-1, var->data.location);
+
+ /* gl_FragData[] has location FRAG_RESULT_DATA0. Locations beyond that
+ * are invalid.
+ */
+ EXPECT_GE(FRAG_RESULT_DATA0, var->data.location);
+
+ EXPECT_EQ(0u, var->data.location_frac);
+ }
+}
+
+TEST_F(fragment_builtin, uniforms_and_system_values_dont_have_explicit_location)
+{
+ common_builtin::uniforms_and_system_values_dont_have_explicit_location();
+}
+
+TEST_F(fragment_builtin, constants_are_constant)
+{
+ common_builtin::constants_are_constant();
+}
+
+TEST_F(fragment_builtin, no_invalid_variable_modes)
+{
+ common_builtin::no_invalid_variable_modes();
+}
+
+/********************************************************************/
+
+class geometry_builtin : public common_builtin {
+public:
+ geometry_builtin()
+ : common_builtin(GL_GEOMETRY_SHADER)
+ {
+ /* empty */
+ }
+};
+
+TEST_F(geometry_builtin, names_start_with_gl)
+{
+ common_builtin::names_start_with_gl();
+}
+
+TEST_F(geometry_builtin, inputs_have_explicit_location)
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_shader_in)
+ continue;
+
+ if (var->is_interface_instance()) {
+ EXPECT_STREQ("gl_in", var->name);
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ ASSERT_TRUE(var->type->is_array());
+
+ const glsl_type *const instance_type = var->type->fields.array;
+
+ for (unsigned i = 0; i < instance_type->length; i++) {
+ const glsl_struct_field *const input =
+ &instance_type->fields.structure[i];
+
+ string_starts_with_prefix(input->name, "gl_");
+ EXPECT_NE(-1, input->location);
+ EXPECT_GT(VARYING_SLOT_VAR0, input->location);
+
+ /* Several varyings only exist in the fragment shader. Be sure
+ * that no inputs with these locations exist.
+ */
+ EXPECT_NE(VARYING_SLOT_PNTC, input->location);
+ EXPECT_NE(VARYING_SLOT_FACE, input->location);
+ }
+ } else {
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_NE(-1, var->data.location);
+ EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ }
+
+ /* Several varyings only exist in the fragment shader. Be sure that no
+ * inputs with these locations exist.
+ */
+ EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
+ EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
+ }
+}
+
+TEST_F(geometry_builtin, outputs_have_explicit_location)
+{
+ foreach_list(node, &this->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var->data.mode != ir_var_shader_out)
+ continue;
+
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_NE(-1, var->data.location);
+ EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+
+ /* Several varyings only exist in the fragment shader. Be sure that no
+ * outputs with these locations exist.
+ */
+ EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
+ EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
+ }
+}
+
+TEST_F(geometry_builtin, uniforms_and_system_values_dont_have_explicit_location)
+{
+ common_builtin::uniforms_and_system_values_dont_have_explicit_location();
+}
+
+TEST_F(geometry_builtin, constants_are_constant)
+{
+ common_builtin::constants_are_constant();
+}
+
+TEST_F(geometry_builtin, no_invalid_variable_modes)
+{
+ common_builtin::no_invalid_variable_modes();
+}
diff --git a/dist/Mesa/src/glsl/tests/common.c b/dist/Mesa/src/glsl/tests/common.c
new file mode 100644
index 000000000..d69f54d1d
--- /dev/null
+++ b/dist/Mesa/src/glsl/tests/common.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2014 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 <stdio.h>
+#include "main/errors.h"
+
+void
+_mesa_error_no_memory(const char *caller)
+{
+ fprintf(stderr, "Mesa error: out of memory in %s", caller);
+}
diff --git a/dist/Mesa/src/glsl/tests/general_ir_test.cpp b/dist/Mesa/src/glsl/tests/general_ir_test.cpp
new file mode 100644
index 000000000..862fa19ab
--- /dev/null
+++ b/dist/Mesa/src/glsl/tests/general_ir_test.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2013 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 <gtest/gtest.h>
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "ralloc.h"
+#include "ir.h"
+
+TEST(ir_variable_constructor, interface)
+{
+ void *mem_ctx = ralloc_context(NULL);
+
+ static const glsl_struct_field f[] = {
+ {
+ glsl_type::vec(4),
+ "v",
+ false
+ }
+ };
+
+ const glsl_type *const interface =
+ glsl_type::get_interface_instance(f,
+ ARRAY_SIZE(f),
+ GLSL_INTERFACE_PACKING_STD140,
+ "simple_interface");
+
+ static const char name[] = "named_instance";
+
+ ir_variable *const v =
+ new(mem_ctx) ir_variable(interface, name, ir_var_uniform);
+
+ EXPECT_STREQ(name, v->name);
+ EXPECT_NE(name, v->name);
+ EXPECT_EQ(interface, v->type);
+ EXPECT_EQ(interface, v->get_interface_type());
+}
+
+TEST(ir_variable_constructor, interface_array)
+{
+ void *mem_ctx = ralloc_context(NULL);
+
+ static const glsl_struct_field f[] = {
+ {
+ glsl_type::vec(4),
+ "v",
+ false
+ }
+ };
+
+ const glsl_type *const interface =
+ glsl_type::get_interface_instance(f,
+ ARRAY_SIZE(f),
+ GLSL_INTERFACE_PACKING_STD140,
+ "simple_interface");
+
+ const glsl_type *const interface_array =
+ glsl_type::get_array_instance(interface, 2);
+
+ static const char name[] = "array_instance";
+
+ ir_variable *const v =
+ new(mem_ctx) ir_variable(interface_array, name, ir_var_uniform);
+
+ EXPECT_STREQ(name, v->name);
+ EXPECT_NE(name, v->name);
+ EXPECT_EQ(interface_array, v->type);
+ EXPECT_EQ(interface, v->get_interface_type());
+}
diff --git a/dist/Mesa/src/glsl/tests/invalidate_locations_test.cpp b/dist/Mesa/src/glsl/tests/invalidate_locations_test.cpp
new file mode 100644
index 000000000..997592fc9
--- /dev/null
+++ b/dist/Mesa/src/glsl/tests/invalidate_locations_test.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright © 2013 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 <gtest/gtest.h>
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "ralloc.h"
+#include "ir.h"
+#include "linker.h"
+
+/**
+ * \file varyings_test.cpp
+ *
+ * Test various aspects of linking shader stage inputs and outputs.
+ */
+
+class invalidate_locations : public ::testing::Test {
+public:
+ virtual void SetUp();
+ virtual void TearDown();
+
+ void *mem_ctx;
+ exec_list ir;
+};
+
+void
+invalidate_locations::SetUp()
+{
+ this->mem_ctx = ralloc_context(NULL);
+ this->ir.make_empty();
+}
+
+void
+invalidate_locations::TearDown()
+{
+ ralloc_free(this->mem_ctx);
+ this->mem_ctx = NULL;
+}
+
+TEST_F(invalidate_locations, simple_vertex_in_generic)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "a",
+ ir_var_shader_in);
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ var->data.location = VERT_ATTRIB_GENERIC0;
+ var->data.location_frac = 2;
+
+ ir.push_tail(var);
+
+ link_invalidate_variable_locations(&ir);
+
+ EXPECT_EQ(-1, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_TRUE(var->data.is_unmatched_generic_inout);
+}
+
+TEST_F(invalidate_locations, explicit_location_vertex_in_generic)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "a",
+ ir_var_shader_in);
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ var->data.location = VERT_ATTRIB_GENERIC0;
+ var->data.explicit_location = true;
+
+ ir.push_tail(var);
+
+ link_invalidate_variable_locations(&ir);
+
+ EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_FALSE(var->data.is_unmatched_generic_inout);
+}
+
+TEST_F(invalidate_locations, explicit_location_frac_vertex_in_generic)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "a",
+ ir_var_shader_in);
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ var->data.location = VERT_ATTRIB_GENERIC0;
+ var->data.location_frac = 2;
+ var->data.explicit_location = true;
+
+ ir.push_tail(var);
+
+ link_invalidate_variable_locations(&ir);
+
+ EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->data.location);
+ EXPECT_EQ(2u, var->data.location_frac);
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_FALSE(var->data.is_unmatched_generic_inout);
+}
+
+TEST_F(invalidate_locations, vertex_in_builtin)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "gl_Vertex",
+ ir_var_shader_in);
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ var->data.location = VERT_ATTRIB_POS;
+ var->data.explicit_location = true;
+
+ ir.push_tail(var);
+
+ link_invalidate_variable_locations(&ir);
+
+ EXPECT_EQ(VERT_ATTRIB_POS, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_FALSE(var->data.is_unmatched_generic_inout);
+}
+
+TEST_F(invalidate_locations, simple_vertex_out_generic)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "a",
+ ir_var_shader_out);
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ var->data.location = VARYING_SLOT_VAR0;
+
+ ir.push_tail(var);
+
+ link_invalidate_variable_locations(&ir);
+
+ EXPECT_EQ(-1, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_TRUE(var->data.is_unmatched_generic_inout);
+}
+
+TEST_F(invalidate_locations, vertex_out_builtin)
+{
+ ir_variable *const var =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "gl_FrontColor",
+ ir_var_shader_out);
+
+ EXPECT_FALSE(var->data.explicit_location);
+ EXPECT_EQ(-1, var->data.location);
+
+ var->data.location = VARYING_SLOT_COL0;
+ var->data.explicit_location = true;
+
+ ir.push_tail(var);
+
+ link_invalidate_variable_locations(&ir);
+
+ EXPECT_EQ(VARYING_SLOT_COL0, var->data.location);
+ EXPECT_EQ(0u, var->data.location_frac);
+ EXPECT_TRUE(var->data.explicit_location);
+ EXPECT_FALSE(var->data.is_unmatched_generic_inout);
+}
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/create_test_cases.py b/dist/Mesa/src/glsl/tests/lower_jumps/create_test_cases.py
index fbc6f0a84..9974681e0 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/create_test_cases.py
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/create_test_cases.py
@@ -291,7 +291,7 @@ def create_test_case(doc_string, input_sexp, expected_sexp, test_name,
args = ['../../glsl_test', 'optpass', '--quiet', '--input-ir', optimization]
test_file = '{0}.opt_test'.format(test_name)
with open(test_file, 'w') as f:
- f.write('#!/bin/bash\n#\n# This file was generated by create_test_cases.py.\n#\n')
+ f.write('#!/usr/bin/env bash\n#\n# This file was generated by create_test_cases.py.\n#\n')
f.write(doc_string)
f.write('{0} <<EOF\n'.format(bash_quote(*args)))
f.write('{0}\nEOF\n'.format(input_str))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test
index 01ad7087a..b412ba8f2 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,6 +8,6 @@
((declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) break))))))
EOF
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test.expected
index d4bb6fc02..56ef3e424 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_1.opt_test.expected
@@ -1,5 +1,5 @@
((declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) break))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test
index 0be22f953..f5de80339 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (in) float b) (declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(if (expression bool > (var_ref b) (constant float (0.000000))) (break)
())))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test.expected
index a4cb2d6a1..dc231f975 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_2.opt_test.expected
@@ -1,7 +1,7 @@
((declare (in) float b) (declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
- (if (expression bool > (var_ref b) (constant float (0.000000))) (break)
+ (if (expression bool > (var_ref b) (constant float (0.0))) (break)
())))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test
index 4149360b5..60368bc1d 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -9,7 +9,7 @@
((declare (in) float b) (declare (out) float a) (declare (out) float c)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(if (expression bool > (var_ref b) (constant float (0.000000)))
((assign (x) (var_ref c) (constant float (1.000000))) break)
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test.expected
index 325f7b49a..8131b66ff 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_3.opt_test.expected
@@ -1,8 +1,8 @@
((declare (in) float b) (declare (out) float a) (declare (out) float c)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
- (if (expression bool > (var_ref b) (constant float (0.000000)))
+ (if (expression bool > (var_ref b) (constant float (0.0)))
((assign (x) (var_ref c) (constant float (1.000000))) break)
())))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test
index 70458bb4f..cde319793 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (in) float b) (declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(if (expression bool > (var_ref b) (constant float (0.000000))) ()
(break))))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test.expected
index a7735457c..94dcb37be 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_4.opt_test.expected
@@ -1,7 +1,7 @@
((declare (in) float b) (declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
- (if (expression bool > (var_ref b) (constant float (0.000000))) ()
+ (if (expression bool > (var_ref b) (constant float (0.0))) ()
(break))))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test
index da9eef110..157b5892f 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -9,7 +9,7 @@
((declare (in) float b) (declare (out) float a) (declare (out) float c)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(if (expression bool > (var_ref b) (constant float (0.000000))) ()
((assign (x) (var_ref c) (constant float (1.000000))) break))))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test.expected
index 0dd4a5293..5b46ccb67 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_5.opt_test.expected
@@ -1,7 +1,7 @@
((declare (in) float b) (declare (out) float a) (declare (out) float c)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
- (if (expression bool > (var_ref b) (constant float (0.000000))) ()
+ (if (expression bool > (var_ref b) (constant float (0.0))) ()
((assign (x) (var_ref c) (constant float (1.000000))) break))))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test
index 9440dfec8..4767df13e 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -12,7 +12,7 @@
(declare (in) float cb)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((if (expression bool > (var_ref a) (constant float (0.000000)))
((if (expression bool > (var_ref ba) (constant float (0.000000)))
((if (expression bool > (var_ref bb) (constant float (0.000000)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test.expected
index 8222328e0..967ce642a 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_breaks_6.opt_test.expected
@@ -5,18 +5,18 @@
(signature void (parameters)
((declare (temporary) bool break_flag)
(assign (x) (var_ref break_flag) (constant bool (0)))
- (loop () () () ()
+ (loop
((declare (temporary) bool execute_flag)
(assign (x) (var_ref execute_flag) (constant bool (1)))
- (if (expression bool > (var_ref a) (constant float (0.000000)))
- ((if (expression bool > (var_ref ba) (constant float (0.000000)))
- ((if (expression bool > (var_ref bb) (constant float (0.000000)))
+ (if (expression bool > (var_ref a) (constant float (0.0)))
+ ((if (expression bool > (var_ref ba) (constant float (0.0)))
+ ((if (expression bool > (var_ref bb) (constant float (0.0)))
((assign (x) (var_ref execute_flag) (constant bool (0))))
()))
())
(if (var_ref execute_flag)
- ((if (expression bool > (var_ref ca) (constant float (0.000000)))
- ((if (expression bool > (var_ref cb) (constant float (0.000000)))
+ ((if (expression bool > (var_ref ca) (constant float (0.0)))
+ ((if (expression bool > (var_ref cb) (constant float (0.0)))
((assign (x) (var_ref break_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test
index 379aa59b5..164914a42 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -10,7 +10,7 @@
((declare (in) float aa) (declare (in) float ab) (declare (in) float b)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((if (expression bool > (var_ref aa) (constant float (0.000000)))
((if (expression bool > (var_ref ab) (constant float (0.000000)))
(continue)
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test.expected
index 7c6e73f77..841073ed9 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_guarded_conditional_break.opt_test.expected
@@ -3,16 +3,16 @@
(signature void (parameters)
((declare (temporary) bool break_flag)
(assign (x) (var_ref break_flag) (constant bool (0)))
- (loop () () () ()
+ (loop
((declare (temporary) bool execute_flag)
(assign (x) (var_ref execute_flag) (constant bool (1)))
- (if (expression bool > (var_ref aa) (constant float (0.000000)))
- ((if (expression bool > (var_ref ab) (constant float (0.000000)))
+ (if (expression bool > (var_ref aa) (constant float (0.0)))
+ ((if (expression bool > (var_ref ab) (constant float (0.0)))
((assign (x) (var_ref execute_flag) (constant bool (0))))
()))
())
(if (var_ref execute_flag)
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
((assign (x) (var_ref break_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test
index 15f3c41d5..1a5c09690 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -19,7 +19,7 @@
((return))
()))
())
- (loop () () () ()
+ (loop
((if (expression bool > (var_ref b) (constant float (0.000000)))
((if (expression bool > (var_ref c) (constant float (0.000000))) (break)
(continue)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test.expected
index bf45c2c93..cf2ef3f08 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_pulled_out_jump.opt_test.expected
@@ -7,16 +7,16 @@
(assign (x) (var_ref execute_flag) (constant bool (1)))
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (if (expression bool > (var_ref aa) (constant float (0.000000)))
- ((if (expression bool > (var_ref ab) (constant float (0.000000)))
+ (if (expression bool > (var_ref aa) (constant float (0.0)))
+ ((if (expression bool > (var_ref ab) (constant float (0.0)))
((assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
())
(if (var_ref execute_flag)
- ((loop () () () ()
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
- ((if (expression bool > (var_ref c) (constant float (0.000000))) ()
+ ((loop
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
+ ((if (expression bool > (var_ref c) (constant float (0.0))) ()
(continue)))
((assign (x) (var_ref return_flag) (constant bool (1)))))
break))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_1.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_1.opt_test
index a1f895bbf..e73c51208 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_1.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_1.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_2.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_2.opt_test
index 61673d4ef..da2dc7ee2 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_2.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_2.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test
index 9881e2492..9509781fe 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test.expected
index d4835e96b..5b62bbcde 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_3.opt_test.expected
@@ -6,8 +6,8 @@
(declare (temporary) float return_value)
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (if (expression bool > (var_ref a) (constant float (0.000000)))
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
+ (if (expression bool > (var_ref a) (constant float (0.0)))
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
((assign (x) (var_ref return_value) (constant float (1.000000)))
(assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test
index 9f54c67a1..c5bb9c898 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test.expected
index b551a066f..07c6842d2 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_4.opt_test.expected
@@ -6,7 +6,7 @@
(declare (temporary) float return_value)
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (if (expression bool > (var_ref a) (constant float (0.000000)))
+ (if (expression bool > (var_ref a) (constant float (0.0)))
((assign (x) (var_ref return_value) (constant float (1.000000)))
(assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test
index 5f97bfd3f..fdb1d0ed2 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test.expected
index e8b36f144..7e3fe314f 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_false.opt_test.expected
@@ -1,8 +1,8 @@
((declare (in) float a) (declare (in) float b)
(function main
(signature void (parameters)
- ((if (expression bool > (var_ref a) (constant float (0.000000)))
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
+ ((if (expression bool > (var_ref a) (constant float (0.0)))
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
((return))
()))
())))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test
index 59c7ba1dd..939ec8b0e 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test.expected
index e15a97d1d..b47f5a433 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_main_true.opt_test.expected
@@ -5,8 +5,8 @@
(assign (x) (var_ref execute_flag) (constant bool (1)))
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (if (expression bool > (var_ref a) (constant float (0.000000)))
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
+ (if (expression bool > (var_ref a) (constant float (0.0)))
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
((assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test
index 40e784e33..92a4e8a62 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test.expected
index 07db6e708..7424968b2 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_false.opt_test.expected
@@ -1,8 +1,8 @@
((declare (in) float a) (declare (in) float b)
(function sub
(signature void (parameters)
- ((if (expression bool > (var_ref a) (constant float (0.000000)))
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
+ ((if (expression bool > (var_ref a) (constant float (0.0)))
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
((return))
()))
())))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test
index 9fe6b90f0..789414ecb 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test.expected
index 311098023..1a3eae5da 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_returns_sub_true.opt_test.expected
@@ -5,8 +5,8 @@
(assign (x) (var_ref execute_flag) (constant bool (1)))
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (if (expression bool > (var_ref a) (constant float (0.000000)))
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
+ (if (expression bool > (var_ref a) (constant float (0.0)))
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
((assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test
index e71681314..5d6e51cff 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test.expected
index 271cd3b46..c0b51e1ba 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/lower_unified_returns.opt_test.expected
@@ -6,15 +6,15 @@
(assign (x) (var_ref execute_flag) (constant bool (1)))
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (if (expression bool > (var_ref aa) (constant float (0.000000)))
- ((if (expression bool > (var_ref ab) (constant float (0.000000)))
+ (if (expression bool > (var_ref aa) (constant float (0.0)))
+ ((if (expression bool > (var_ref ab) (constant float (0.0)))
((assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
())
(if (var_ref execute_flag)
- ((if (expression bool > (var_ref b) (constant float (0.000000)))
- ((if (expression bool > (var_ref c) (constant float (0.000000))) () ())
+ ((if (expression bool > (var_ref b) (constant float (0.0)))
+ ((if (expression bool > (var_ref c) (constant float (0.0))) () ())
(assign (x) (var_ref return_flag) (constant bool (1)))
(assign (x) (var_ref execute_flag) (constant bool (0))))
()))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test
index 18efc37f6..8403bb204 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,6 +8,6 @@
((declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) continue))))))
EOF
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test.expected
index d2a02c6f3..98b74d71e 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/remove_continue_at_end_of_loop.opt_test.expected
@@ -1,5 +1,5 @@
((declare (out) float a)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test
index 79c0e8245..1f62e7349 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (out) float a) (declare (out) float b)
(function sub
(signature float (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(return (constant float (2.000000)))))
(assign (x) (var_ref b) (constant float (3.000000)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test.expected
index 2cf117a5e..040d383b6 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_nothing.opt_test.expected
@@ -1,7 +1,7 @@
((declare (out) float a) (declare (out) float b)
(function sub
(signature float (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(return (constant float (2.000000)))))
(assign (x) (var_ref b) (constant float (3.000000)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test
index 920d2ad9f..42c4e7529 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (out) float a) (declare (out) float b)
(function sub
(signature float (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(return (constant float (2.000000)))))
(assign (x) (var_ref b) (constant float (3.000000)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test.expected
index 0bab8f16f..792cbf69a 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return.opt_test.expected
@@ -6,7 +6,7 @@
(declare (temporary) float return_value)
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (loop () () () ()
+ (loop
((assign (x) (var_ref a) (constant float (1.000000)))
(assign (x) (var_ref return_value) (constant float (2.000000)))
(assign (x) (var_ref return_flag) (constant bool (1)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test
index 99f1f8635..b3eef39b7 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (out) float a) (declare (out) float b)
(function sub
(signature float (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000)))
(return (constant float (2.000000)))))
(assign (x) (var_ref b) (constant float (3.000000)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test.expected
index 0bab8f16f..792cbf69a 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_non_void_at_end_of_loop_lower_return_and_break.opt_test.expected
@@ -6,7 +6,7 @@
(declare (temporary) float return_value)
(declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (loop () () () ()
+ (loop
((assign (x) (var_ref a) (constant float (1.000000)))
(assign (x) (var_ref return_value) (constant float (2.000000)))
(assign (x) (var_ref return_flag) (constant bool (1)))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test
index 63487d326..0408282d0 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (out) float a) (declare (out) float b)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) (return)))
(assign (x) (var_ref b) (constant float (2.000000)))))))
EOF
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test.expected
index 0bd8037bf..569213e99 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_nothing.opt_test.expected
@@ -1,6 +1,6 @@
((declare (out) float a) (declare (out) float b)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) (return)))
(assign (x) (var_ref b) (constant float (2.000000)))))))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test
index 523c92a68..a7e65c86c 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (out) float a) (declare (out) float b)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) (return)))
(assign (x) (var_ref b) (constant float (2.000000)))))))
EOF
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test.expected
index 53814eaac..66f3aeca5 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return.opt_test.expected
@@ -3,7 +3,7 @@
(signature void (parameters)
((declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (loop () () () ()
+ (loop
((assign (x) (var_ref a) (constant float (1.000000)))
(assign (x) (var_ref return_flag) (constant bool (1)))
break))
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test
index 22b5581cb..7a5efe581 100755
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
# This file was generated by create_test_cases.py.
#
@@ -8,7 +8,7 @@
((declare (out) float a) (declare (out) float b)
(function main
(signature void (parameters)
- ((loop () () () ()
+ ((loop
((assign (x) (var_ref a) (constant float (1.000000))) (return)))
(assign (x) (var_ref b) (constant float (2.000000)))))))
EOF
diff --git a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test.expected b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test.expected
index 53814eaac..66f3aeca5 100644
--- a/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test.expected
+++ b/dist/Mesa/src/glsl/tests/lower_jumps/return_void_at_end_of_loop_lower_return_and_break.opt_test.expected
@@ -3,7 +3,7 @@
(signature void (parameters)
((declare (temporary) bool return_flag)
(assign (x) (var_ref return_flag) (constant bool (0)))
- (loop () () () ()
+ (loop
((assign (x) (var_ref a) (constant float (1.000000)))
(assign (x) (var_ref return_flag) (constant bool (1)))
break))
diff --git a/dist/Mesa/src/glsl/tests/optimization-test b/dist/Mesa/src/glsl/tests/optimization-test
index 59383f8f9..8ca777691 100755
--- a/dist/Mesa/src/glsl/tests/optimization-test
+++ b/dist/Mesa/src/glsl/tests/optimization-test
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
if [ ! -z "$srcdir" ]; then
compare_ir=`pwd`/tests/compare_ir
diff --git a/dist/Mesa/src/glsl/tests/sampler_types_test.cpp b/dist/Mesa/src/glsl/tests/sampler_types_test.cpp
new file mode 100644
index 000000000..86d329a83
--- /dev/null
+++ b/dist/Mesa/src/glsl/tests/sampler_types_test.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright © 2013 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 <gtest/gtest.h>
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "ralloc.h"
+#include "ir.h"
+
+/**
+ * \file sampler_types_test.cpp
+ *
+ * Test that built-in sampler types have the right properties.
+ */
+
+#define ARRAY EXPECT_TRUE(type->sampler_array);
+#define NONARRAY EXPECT_FALSE(type->sampler_array);
+#define SHADOW EXPECT_TRUE(type->sampler_shadow);
+#define COLOR EXPECT_FALSE(type->sampler_shadow);
+
+#define T(TYPE, DIM, DATA_TYPE, ARR, SHAD, COMPS) \
+TEST(sampler_types, TYPE) \
+{ \
+ const glsl_type *type = glsl_type::TYPE##_type; \
+ EXPECT_EQ(GLSL_TYPE_SAMPLER, type->base_type); \
+ EXPECT_EQ(DIM, type->sampler_dimensionality); \
+ EXPECT_EQ(DATA_TYPE, type->sampler_type); \
+ ARR; \
+ SHAD; \
+ EXPECT_EQ(COMPS, type->coordinate_components()); \
+}
+
+T( sampler1D, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 1)
+T( sampler2D, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2)
+T( sampler3D, GLSL_SAMPLER_DIM_3D, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 3)
+T( samplerCube, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 3)
+T( sampler1DArray, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, ARRAY, COLOR, 2)
+T( sampler2DArray, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, ARRAY, COLOR, 3)
+T( samplerCubeArray, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, ARRAY, COLOR, 4)
+T( sampler2DRect, GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2)
+T( samplerBuffer, GLSL_SAMPLER_DIM_BUF, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 1)
+T( sampler2DMS, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2)
+T( sampler2DMSArray, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_FLOAT, ARRAY, COLOR, 3)
+T(isampler1D, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_INT, NONARRAY, COLOR, 1)
+T(isampler2D, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_INT, NONARRAY, COLOR, 2)
+T(isampler3D, GLSL_SAMPLER_DIM_3D, GLSL_TYPE_INT, NONARRAY, COLOR, 3)
+T(isamplerCube, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_INT, NONARRAY, COLOR, 3)
+T(isampler1DArray, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_INT, ARRAY, COLOR, 2)
+T(isampler2DArray, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_INT, ARRAY, COLOR, 3)
+T(isamplerCubeArray, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_INT, ARRAY, COLOR, 4)
+T(isampler2DRect, GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_INT, NONARRAY, COLOR, 2)
+T(isamplerBuffer, GLSL_SAMPLER_DIM_BUF, GLSL_TYPE_INT, NONARRAY, COLOR, 1)
+T(isampler2DMS, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_INT, NONARRAY, COLOR, 2)
+T(isampler2DMSArray, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_INT, ARRAY, COLOR, 3)
+T(usampler1D, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_UINT, NONARRAY, COLOR, 1)
+T(usampler2D, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_UINT, NONARRAY, COLOR, 2)
+T(usampler3D, GLSL_SAMPLER_DIM_3D, GLSL_TYPE_UINT, NONARRAY, COLOR, 3)
+T(usamplerCube, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_UINT, NONARRAY, COLOR, 3)
+T(usampler1DArray, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_UINT, ARRAY, COLOR, 2)
+T(usampler2DArray, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_UINT, ARRAY, COLOR, 3)
+T(usamplerCubeArray, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_UINT, ARRAY, COLOR, 4)
+T(usampler2DRect, GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_UINT, NONARRAY, COLOR, 2)
+T(usamplerBuffer, GLSL_SAMPLER_DIM_BUF, GLSL_TYPE_UINT, NONARRAY, COLOR, 1)
+T(usampler2DMS, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_UINT, NONARRAY, COLOR, 2)
+T(usampler2DMSArray, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_UINT, ARRAY, COLOR, 3)
+
+T(sampler1DShadow, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 1)
+T(sampler2DShadow, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 2)
+T(samplerCubeShadow, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 3)
+
+T(sampler1DArrayShadow,
+ GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, ARRAY, SHADOW, 2)
+T(sampler2DArrayShadow,
+ GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, ARRAY, SHADOW, 3)
+T(samplerCubeArrayShadow,
+ GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, ARRAY, SHADOW, 4)
+T(sampler2DRectShadow,
+ GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 2)
+
+T(samplerExternalOES,
+ GLSL_SAMPLER_DIM_EXTERNAL, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2)
diff --git a/dist/Mesa/src/glsl/tests/set_uniform_initializer_tests.cpp b/dist/Mesa/src/glsl/tests/set_uniform_initializer_tests.cpp
index 5c6d4a514..be202b3d5 100644
--- a/dist/Mesa/src/glsl/tests/set_uniform_initializer_tests.cpp
+++ b/dist/Mesa/src/glsl/tests/set_uniform_initializer_tests.cpp
@@ -116,7 +116,7 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
prog->UniformStorage[index_to_set].type = type;
prog->UniformStorage[index_to_set].array_elements = array_size;
prog->UniformStorage[index_to_set].initialized = false;
- for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
prog->UniformStorage[index_to_set].sampler[sh].index = ~0;
prog->UniformStorage[index_to_set].sampler[sh].active = false;
}
@@ -137,7 +137,7 @@ establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage,
prog->UniformStorage[i].type = glsl_type::void_type;
prog->UniformStorage[i].array_elements = 0;
prog->UniformStorage[i].initialized = false;
- for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
prog->UniformStorage[i].sampler[sh].index = ~0;
prog->UniformStorage[i].sampler[sh].active = false;
}
diff --git a/dist/Mesa/src/glsl/tests/uniform_initializer_utils.cpp b/dist/Mesa/src/glsl/tests/uniform_initializer_utils.cpp
index a04f5ddc4..5e86c2432 100644
--- a/dist/Mesa/src/glsl/tests/uniform_initializer_utils.cpp
+++ b/dist/Mesa/src/glsl/tests/uniform_initializer_utils.cpp
@@ -92,6 +92,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
case GLSL_TYPE_BOOL:
data.b[i] = bool(values[idx]);
break;
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_VOID:
@@ -119,6 +120,7 @@ generate_data_element(void *mem_ctx, const glsl_type *type,
case GLSL_TYPE_BOOL:
ASSERT_EQ(data.b[i], val->value.b[i]);
break;
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_VOID:
@@ -217,6 +219,7 @@ verify_data(gl_constant_value *storage, unsigned storage_array_size,
case GLSL_TYPE_BOOL:
EXPECT_EQ(int(val->value.b[i]), storage[i].i);
break;
+ case GLSL_TYPE_ATOMIC_UINT:
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_ARRAY:
case GLSL_TYPE_VOID:
diff --git a/dist/Mesa/src/glsl/tests/varyings_test.cpp b/dist/Mesa/src/glsl/tests/varyings_test.cpp
new file mode 100644
index 000000000..662fc0e40
--- /dev/null
+++ b/dist/Mesa/src/glsl/tests/varyings_test.cpp
@@ -0,0 +1,357 @@
+/*
+ * Copyright © 2013 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 <gtest/gtest.h>
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "ralloc.h"
+#include "ir.h"
+#include "program/hash_table.h"
+
+/**
+ * \file varyings_test.cpp
+ *
+ * Test various aspects of linking shader stage inputs and outputs.
+ */
+
+namespace linker {
+bool
+populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
+ hash_table *consumer_inputs,
+ hash_table *consumer_interface_inputs,
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX]);
+
+ir_variable *
+get_matching_input(void *mem_ctx,
+ const ir_variable *output_var,
+ hash_table *consumer_inputs,
+ hash_table *consumer_interface_inputs,
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX]);
+}
+
+class link_varyings : public ::testing::Test {
+public:
+ link_varyings();
+
+ virtual void SetUp();
+ virtual void TearDown();
+
+ char *interface_field_name(const glsl_type *iface, unsigned field = 0)
+ {
+ return ralloc_asprintf(mem_ctx,
+ "%s.%s",
+ iface->name,
+ iface->fields.structure[field].name);
+ }
+
+ void *mem_ctx;
+ exec_list ir;
+ hash_table *consumer_inputs;
+ hash_table *consumer_interface_inputs;
+
+ const glsl_type *simple_interface;
+ ir_variable *junk[VARYING_SLOT_MAX];
+};
+
+link_varyings::link_varyings()
+{
+ static const glsl_struct_field f[] = {
+ {
+ glsl_type::vec(4),
+ "v",
+ false,
+ 0,
+ 0,
+ 0,
+ 0
+ }
+ };
+
+ this->simple_interface =
+ glsl_type::get_interface_instance(f,
+ ARRAY_SIZE(f),
+ GLSL_INTERFACE_PACKING_STD140,
+ "simple_interface");
+}
+
+void
+link_varyings::SetUp()
+{
+ this->mem_ctx = ralloc_context(NULL);
+ this->ir.make_empty();
+
+ this->consumer_inputs
+ = hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
+
+ this->consumer_interface_inputs
+ = hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
+}
+
+void
+link_varyings::TearDown()
+{
+ ralloc_free(this->mem_ctx);
+ this->mem_ctx = NULL;
+
+ hash_table_dtor(this->consumer_inputs);
+ this->consumer_inputs = NULL;
+ hash_table_dtor(this->consumer_interface_inputs);
+ this->consumer_interface_inputs = NULL;
+}
+
+/**
+ * Hash table callback function that counts the elements in the table
+ *
+ * \sa num_elements
+ */
+static void
+ht_count_callback(const void *, void *, void *closure)
+{
+ unsigned int *counter = (unsigned int *) closure;
+
+ (*counter)++;
+}
+
+/**
+ * Helper function to count the number of elements in a hash table.
+ */
+static unsigned
+num_elements(hash_table *ht)
+{
+ unsigned int counter = 0;
+
+ hash_table_call_foreach(ht, ht_count_callback, (void *) &counter);
+
+ return counter;
+}
+
+/**
+ * Helper function to determine whether a hash table is empty.
+ */
+static bool
+is_empty(hash_table *ht)
+{
+ return num_elements(ht) == 0;
+}
+
+TEST_F(link_varyings, single_simple_input)
+{
+ ir_variable *const v =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "a",
+ ir_var_shader_in);
+
+
+ ir.push_tail(v);
+
+ ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+
+ EXPECT_EQ((void *) v, hash_table_find(consumer_inputs, "a"));
+ EXPECT_EQ(1u, num_elements(consumer_inputs));
+ EXPECT_TRUE(is_empty(consumer_interface_inputs));
+}
+
+TEST_F(link_varyings, gl_ClipDistance)
+{
+ const glsl_type *const array_8_of_float =
+ glsl_type::get_array_instance(glsl_type::vec(1), 8);
+
+ ir_variable *const clipdistance =
+ new(mem_ctx) ir_variable(array_8_of_float,
+ "gl_ClipDistance",
+ ir_var_shader_in);
+
+ clipdistance->data.explicit_location = true;
+ clipdistance->data.location = VARYING_SLOT_CLIP_DIST0;
+ clipdistance->data.explicit_index = 0;
+
+ ir.push_tail(clipdistance);
+
+ ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+
+ EXPECT_EQ(clipdistance, junk[VARYING_SLOT_CLIP_DIST0]);
+ EXPECT_TRUE(is_empty(consumer_inputs));
+ EXPECT_TRUE(is_empty(consumer_interface_inputs));
+}
+
+TEST_F(link_varyings, single_interface_input)
+{
+ ir_variable *const v =
+ new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type,
+ simple_interface->fields.structure[0].name,
+ ir_var_shader_in);
+
+ v->init_interface_type(simple_interface);
+
+ ir.push_tail(v);
+
+ ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+ char *const full_name = interface_field_name(simple_interface);
+
+ EXPECT_EQ((void *) v, hash_table_find(consumer_interface_inputs, full_name));
+ EXPECT_EQ(1u, num_elements(consumer_interface_inputs));
+ EXPECT_TRUE(is_empty(consumer_inputs));
+}
+
+TEST_F(link_varyings, one_interface_and_one_simple_input)
+{
+ ir_variable *const v =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ "a",
+ ir_var_shader_in);
+
+
+ ir.push_tail(v);
+
+ ir_variable *const iface =
+ new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type,
+ simple_interface->fields.structure[0].name,
+ ir_var_shader_in);
+
+ iface->init_interface_type(simple_interface);
+
+ ir.push_tail(iface);
+
+ ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+
+ char *const iface_field_name = interface_field_name(simple_interface);
+
+ EXPECT_EQ((void *) iface, hash_table_find(consumer_interface_inputs,
+ iface_field_name));
+ EXPECT_EQ(1u, num_elements(consumer_interface_inputs));
+
+ EXPECT_EQ((void *) v, hash_table_find(consumer_inputs, "a"));
+ EXPECT_EQ(1u, num_elements(consumer_inputs));
+}
+
+TEST_F(link_varyings, invalid_interface_input)
+{
+ ir_variable *const v =
+ new(mem_ctx) ir_variable(simple_interface,
+ "named_interface",
+ ir_var_shader_in);
+
+ ASSERT_EQ(simple_interface, v->get_interface_type());
+
+ ir.push_tail(v);
+
+ EXPECT_FALSE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+}
+
+TEST_F(link_varyings, interface_field_doesnt_match_noninterface)
+{
+ char *const iface_field_name = interface_field_name(simple_interface);
+
+ /* The input shader has a single input variable name "a.v"
+ */
+ ir_variable *const in_v =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ iface_field_name,
+ ir_var_shader_in);
+
+ ir.push_tail(in_v);
+
+ ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+
+ /* Create an output variable, "v", that is part of an interface block named
+ * "a". They should not match.
+ */
+ ir_variable *const out_v =
+ new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type,
+ simple_interface->fields.structure[0].name,
+ ir_var_shader_in);
+
+ out_v->init_interface_type(simple_interface);
+
+ ir_variable *const match =
+ linker::get_matching_input(mem_ctx,
+ out_v,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk);
+
+ EXPECT_EQ(NULL, match);
+}
+
+TEST_F(link_varyings, interface_field_doesnt_match_noninterface_vice_versa)
+{
+ char *const iface_field_name = interface_field_name(simple_interface);
+
+ /* In input shader has a single variable, "v", that is part of an interface
+ * block named "a".
+ */
+ ir_variable *const in_v =
+ new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type,
+ simple_interface->fields.structure[0].name,
+ ir_var_shader_in);
+
+ in_v->init_interface_type(simple_interface);
+
+ ir.push_tail(in_v);
+
+ ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx,
+ &ir,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk));
+
+ /* Create an output variable "a.v". They should not match.
+ */
+ ir_variable *const out_v =
+ new(mem_ctx) ir_variable(glsl_type::vec(4),
+ iface_field_name,
+ ir_var_shader_out);
+
+ ir_variable *const match =
+ linker::get_matching_input(mem_ctx,
+ out_v,
+ consumer_inputs,
+ consumer_interface_inputs,
+ junk);
+
+ EXPECT_EQ(NULL, match);
+}