aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/glsl/.gitignore2
-rw-r--r--mesalib/src/glsl/Android.mk26
-rw-r--r--mesalib/src/glsl/Makefile.am17
-rw-r--r--mesalib/src/glsl/Makefile.sources18
-rw-r--r--mesalib/src/glsl/SConscript66
-rw-r--r--mesalib/src/glsl/ast_function.cpp35
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp2
-rw-r--r--mesalib/src/glsl/builtin_compiler/.gitignore5
-rw-r--r--mesalib/src/glsl/builtin_compiler/Makefile.am98
-rw-r--r--mesalib/src/glsl/builtin_compiler/builtin_stubs.cpp39
-rw-r--r--mesalib/src/glsl/builtin_functions.cpp3542
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp3
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h4
-rw-r--r--mesalib/src/glsl/ir.cpp71
-rw-r--r--mesalib/src/glsl/ir.h58
-rw-r--r--mesalib/src/glsl/ir_builder.cpp129
-rw-r--r--mesalib/src/glsl/ir_builder.h28
-rw-r--r--mesalib/src/glsl/ir_clone.cpp2
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp10
-rw-r--r--mesalib/src/glsl/ir_function.cpp19
-rw-r--r--mesalib/src/glsl/ir_reader.cpp18
-rw-r--r--mesalib/src/glsl/ir_validate.cpp7
-rw-r--r--mesalib/src/glsl/link_functions.cpp9
-rw-r--r--mesalib/src/glsl/linker.cpp8
-rw-r--r--mesalib/src/glsl/lower_packed_varyings.cpp2
-rw-r--r--mesalib/src/glsl/main.cpp2
-rw-r--r--mesalib/src/glsl/opt_dead_builtin_varyings.cpp8
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/mtypes.h3
-rw-r--r--mesalib/src/mesa/main/queryobj.c2
-rw-r--r--mesalib/src/mesa/main/samplerobj.c3
-rw-r--r--mesalib/src/mesa/main/texstate.c8
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp3
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp3
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec.c12
36 files changed, 3942 insertions, 324 deletions
diff --git a/mesalib/src/glsl/.gitignore b/mesalib/src/glsl/.gitignore
index 2cf5b0007..43720f60b 100644
--- a/mesalib/src/glsl/.gitignore
+++ b/mesalib/src/glsl/.gitignore
@@ -3,6 +3,4 @@ glsl_lexer.cpp
glsl_parser.cpp
glsl_parser.h
glsl_parser.output
-builtin_function.cpp
-builtincompiler
glsl_test
diff --git a/mesalib/src/glsl/Android.mk b/mesalib/src/glsl/Android.mk
index f088e67cb..8a3942652 100644
--- a/mesalib/src/glsl/Android.mk
+++ b/mesalib/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/mesalib/src/glsl/Makefile.am b/mesalib/src/glsl/Makefile.am
index 2bbad3d65..9352848d6 100644
--- a/mesalib/src/glsl/Makefile.am
+++ b/mesalib/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 \
@@ -72,31 +70,21 @@ tests_ralloc_test_LDADD = \
$(top_builddir)/src/gtest/libgtest.la \
$(PTHREAD_LIBS)
-if CROSS_COMPILING
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
-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_test_SOURCES = \
$(top_srcdir)/src/mesa/main/hash_table.c \
@@ -168,6 +156,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/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index 979c4165f..2f7bfa163 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/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 \
@@ -104,20 +105,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/mesalib/src/glsl/SConscript b/mesalib/src/glsl/SConscript
index c4ab97c1e..e386bdfb1 100644
--- a/mesalib/src/glsl/SConscript
+++ b/mesalib/src/glsl/SConscript
@@ -53,55 +53,25 @@ if env['msvc']:
env.Prepend(CPPPATH = ['#/src/getopt'])
env.PrependUnique(LIBS = [getopt])
-if env['crosscompile'] and not env['embedded']:
- Import('builtin_glsl_function')
-else:
- # Copy these files to avoid generation object files into src/mesa/program
- env.Prepend(CPPPATH = ['#src/mesa/main'])
- env.Command('hash_table.c', '#src/mesa/main/hash_table.c', Copy('$TARGET', '$SOURCE'))
- env.Command('imports.c', '#src/mesa/main/imports.c', Copy('$TARGET', '$SOURCE'))
- # Copy these files to avoid generation object files into src/mesa/program
- env.Prepend(CPPPATH = ['#src/mesa/program'])
- env.Command('prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE'))
- env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
-
- compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES'])
-
- mesa_objs = env.StaticObject([
- 'hash_table.c',
- 'imports.c',
- 'prog_hash_table.c',
- 'symbol_table.c',
- ])
-
- compiler_objs += mesa_objs
-
- builtin_compiler = env.Program(
- target = 'builtin_compiler/builtin_compiler',
- source = compiler_objs + glsl_sources + \
- source_lists['BUILTIN_COMPILER_CXX_FILES'],
- )
-
- # SCons builtin dependency scanner doesn't detect that glsl_lexer.ll
- # depends on glsl_parser.h
- env.Depends(builtin_compiler, glsl_parser)
-
- builtin_glsl_function = env.CodeGenerate(
- target = 'builtin_function.cpp',
- script = 'builtins/tools/generate_builtins.py',
- source = builtin_compiler,
- command = python_cmd + ' $SCRIPT $SOURCE > $TARGET'
- )
-
- env.Depends(builtin_glsl_function, ['builtins/tools/generate_builtins.py', '#src/glsl/builtins/tools/texture_builtins.py'] + Glob('builtins/ir/*'))
-
- Export('builtin_glsl_function')
-
- if env['hostonly']:
- Return()
-
+# Copy these files to avoid generation object files into src/mesa/program
+env.Prepend(CPPPATH = ['#src/mesa/main'])
+env.Command('hash_table.c', '#src/mesa/main/hash_table.c', Copy('$TARGET', '$SOURCE'))
+env.Command('imports.c', '#src/mesa/main/imports.c', Copy('$TARGET', '$SOURCE'))
+# Copy these files to avoid generation object files into src/mesa/program
+env.Prepend(CPPPATH = ['#src/mesa/program'])
+env.Command('prog_hash_table.c', '#src/mesa/program/prog_hash_table.c', Copy('$TARGET', '$SOURCE'))
+env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
+
+compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES'])
+
+mesa_objs = env.StaticObject([
+ 'hash_table.c',
+ 'imports.c',
+ 'prog_hash_table.c',
+ 'symbol_table.c',
+])
-glsl_sources += builtin_glsl_function
+compiler_objs += mesa_objs
glsl = env.ConvenienceLibrary(
target = 'glsl',
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index 7df2b6925..02aad4f8f 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -388,7 +388,8 @@ match_function_by_name(const char *name,
if (f != NULL) {
/* Look for a match in the local shader. If exact, we're done. */
bool is_exact = false;
- sig = local_sig = f->matching_signature(actual_parameters, &is_exact);
+ sig = local_sig = f->matching_signature(state, actual_parameters,
+ &is_exact);
if (is_exact)
goto done;
@@ -402,33 +403,8 @@ match_function_by_name(const char *name,
}
/* Local shader has no exact candidates; check the built-ins. */
- _mesa_glsl_initialize_functions(state);
- for (unsigned i = 0; i < state->num_builtins_to_link; i++) {
- ir_function *builtin =
- state->builtins_to_link[i]->symbols->get_function(name);
- if (builtin == NULL)
- continue;
-
- bool is_exact = false;
- ir_function_signature *builtin_sig =
- builtin->matching_signature(actual_parameters, &is_exact);
-
- if (builtin_sig == NULL)
- continue;
-
- /* If the built-in signature is exact, we can stop. */
- if (is_exact) {
- sig = builtin_sig;
- goto done;
- }
-
- if (sig == NULL) {
- /* We found an inexact match, which is better than nothing. However,
- * we should keep searching for an exact match.
- */
- sig = builtin_sig;
- }
- }
+ _mesa_glsl_initialize_builtin_functions();
+ sig = _mesa_glsl_find_builtin_function(state, name, actual_parameters);
done:
if (sig != NULL) {
@@ -471,6 +447,9 @@ no_matching_function_error(const char *name,
foreach_list (node, &f->signatures) {
ir_function_signature *sig = (ir_function_signature *) node;
+ if (sig->is_builtin() && !sig->is_builtin_available(state))
+ continue;
+
str = prototype_string(sig->return_type, f->name, &sig->parameters);
_mesa_glsl_error(loc, state, "%s%s", prefix, str);
ralloc_free(str);
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 52059e4bf..2316cf8e5 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -3576,7 +3576,7 @@ ast_function::hir(exec_list *instructions,
*/
f = state->symbols->get_function(name);
if (f != NULL && (state->es_shader || f->has_user_signature())) {
- sig = f->exact_matching_signature(&hir_parameters);
+ sig = f->exact_matching_signature(state, &hir_parameters);
if (sig != NULL) {
const char *badvar = sig->qualifiers_match(&hir_parameters);
if (badvar != NULL) {
diff --git a/mesalib/src/glsl/builtin_compiler/.gitignore b/mesalib/src/glsl/builtin_compiler/.gitignore
deleted file mode 100644
index ea7d5de9c..000000000
--- a/mesalib/src/glsl/builtin_compiler/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-builtin_compiler
-glcpp-lex.c
-glcpp-parse.c
-glcpp-parse.h
-glcpp-parse.output
diff --git a/mesalib/src/glsl/builtin_compiler/Makefile.am b/mesalib/src/glsl/builtin_compiler/Makefile.am
deleted file mode 100644
index 5f1a995c3..000000000
--- a/mesalib/src/glsl/builtin_compiler/Makefile.am
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright © 2012 Jon TURNEY
-# Copyright © 2012 Thierry Reding
-#
-# 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.
-
-AM_CFLAGS = \
- -I $(top_srcdir)/include \
- -I $(top_srcdir)/src/mapi \
- -I $(top_srcdir)/src/mesa \
- -I $(GLSL_SRCDIR) \
- -I $(GLSL_SRCDIR)/glcpp \
- -I $(GLSL_BUILDDIR) \
- $(VISIBILITY_CFLAGS)
-
-if CROSS_COMPILING
-proxyCC = @CC_FOR_BUILD@
-proxyCFLAGS = @CFLAGS_FOR_BUILD@
-proxyCPP = @CPP_FOR_BUILD@
-proxyCPPFLAGS = @CPPFLAGS_FOR_BUILD@
-proxyCXX = @CXX_FOR_BUILD@
-proxyCXXFLAGS = @CXXFLAGS_FOR_BUILD@
-proxyLD = @LD_FOR_BUILD@
-proxyLDFLAGS = @LDFLAGS_FOR_BUILD@
-AM_CFLAGS += $(DEFINES_FOR_BUILD)
-else
-proxyCC = @CC@
-proxyCFLAGS = @CFLAGS@
-proxyCPP = @CPP@
-proxyCPPFLAGS = @CPPFLAGS@
-proxyCXX = @CXX@
-proxyCXXFLAGS = @CXXFLAGS@
-proxyLD = @LD@
-proxyLDFLAGS = @LDFLAGS@
-AM_CFLAGS += $(DEFINES)
-endif
-
-CC = $(proxyCC)
-CFLAGS = $(proxyCFLAGS)
-CPP = $(proxyCPP)
-CPPFLAGS = $(proxyCPPFLAGS)
-CXX = $(proxyCXX)
-CXXFLAGS = $(proxyCXXFLAGS)
-LD = $(proxyLD)
-LDFLAGS = $(proxyLDFLAGS)
-
-AM_CXXFLAGS = $(AM_CFLAGS)
-
-include ../Makefile.sources
-
-noinst_PROGRAMS = builtin_compiler
-
-if !CROSS_COMPILING
-noinst_LTLIBRARIES = libglslcore.la libglcpp.la
-
-libglcpp_la_SOURCES = \
- $(LIBGLCPP_GENERATED_FILES) \
- $(LIBGLCPP_FILES)
-
-libglslcore_la_SOURCES = \
- $(BUILTIN_COMPILER_GENERATED_CXX_FILES) \
- $(LIBGLSL_FILES)
-endif
-
-builtin_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 \
- $(BUILTIN_COMPILER_CXX_FILES) \
- $(GLSL_COMPILER_CXX_FILES)
-
-if CROSS_COMPILING
-builtin_compiler_SOURCES += \
- $(LIBGLCPP_GENERATED_FILES) \
- $(LIBGLCPP_FILES) \
- $(BUILTIN_COMPILER_GENERATED_CXX_FILES) \
- $(LIBGLSL_FILES)
-builtin_compiler_CPPFLAGS = $(AM_CPPFLAGS)
-else
-builtin_compiler_LDADD = libglslcore.la libglcpp.la
-endif
diff --git a/mesalib/src/glsl/builtin_compiler/builtin_stubs.cpp b/mesalib/src/glsl/builtin_compiler/builtin_stubs.cpp
deleted file mode 100644
index dfa5d324e..000000000
--- a/mesalib/src/glsl/builtin_compiler/builtin_stubs.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright © 2010 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 "glsl_parser_extras.h"
-
-/* A dummy file. When compiling prototypes, we don't care about builtins.
- * We really don't want to half-compile builtin_functions.cpp and fail, though.
- */
-void
-_mesa_glsl_release_functions(void)
-{
-}
-
-void
-_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state)
-{
- (void) state;
-}
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
new file mode 100644
index 000000000..5d8f171b9
--- /dev/null
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -0,0 +1,3542 @@
+/*
+ * 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>
+
+using namespace ir_builder;
+
+/**
+ * Availability predicates:
+ * @{
+ */
+static bool
+always_available(const _mesa_glsl_parse_state *state)
+{
+ return true;
+}
+
+static bool
+compatibility_vs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->target == vertex_shader &&
+ state->language_version <= 130 &&
+ !state->es_shader;
+}
+
+static bool
+fs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->target == fragment_shader;
+}
+
+static bool
+gs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->target == geometry_shader;
+}
+
+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->target == fragment_shader;
+}
+
+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->target == fragment_shader;
+}
+
+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->target == vertex_shader ||
+ 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->MESA_shader_integer_mix_enable;
+}
+
+static bool
+shader_packing(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shading_language_packing_enable ||
+ state->is_version(400, 0);
+}
+
+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
+gpu_shader5(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(400, 0) || state->ARB_gpu_shader5_enable;
+}
+
+static bool
+vs_texture_array(const _mesa_glsl_parse_state *state)
+{
+ return state->target == vertex_shader &&
+ state->EXT_texture_array_enable;
+}
+
+static bool
+fs_texture_array(const _mesa_glsl_parse_state *state)
+{
+ return state->target == fragment_shader &&
+ 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->target == fragment_shader &&
+ (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_lod(const _mesa_glsl_parse_state *state)
+{
+ return state->target == fragment_shader &&
+ state->ARB_texture_query_lod_enable;
+}
+
+/* Desktop GL or OES_standard_derivatives + fragment shader only */
+static bool
+fs_oes_derivatives(const _mesa_glsl_parse_state *state)
+{
+ return state->target == fragment_shader &&
+ (!state->es_shader || 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->target == fragment_shader &&
+ (!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);
+}
+/** @} */
+
+/******************************************************************************/
+
+/**
+ * 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);
+
+private:
+ void *mem_ctx;
+ /**
+ * 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;
+
+ /** Global variables used by built-in functions. */
+ ir_variable *gl_ModelViewProjectionMatrix;
+ ir_variable *gl_Vertex;
+
+ void create_shader();
+ 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);
+ ir_constant *imm(int i);
+ ir_constant *imm(unsigned u);
+ 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);
+
+ /** Create a new function and add the given signatures. */
+ void add_function(const char *name, ...);
+
+ 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
+
+ ir_function_signature *_texture(ir_texture_opcode opcode,
+ builtin_available_predicate avail,
+ const glsl_type *return_type,
+ const glsl_type *sampler_type,
+ int coord_size,
+ 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(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)
+#undef B0
+#undef B1
+#undef B2
+#undef B3
+#undef BA1
+#undef BA2
+ /** @} */
+};
+
+/**
+ * Core builtin_builder functionality:
+ * @{
+ */
+builtin_builder::builtin_builder()
+{
+ 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->builtins_to_link[0] = shader;
+ state->num_builtins_to_link = 1;
+
+ 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_builtins();
+}
+
+void
+builtin_builder::release()
+{
+ ralloc_free(mem_ctx);
+ mem_ctx = 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 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), NULL);
+ add_function("packSnorm2x16", _packSnorm2x16(shader_packing_or_es3), NULL);
+ add_function("packUnorm4x8", _packUnorm4x8(shader_packing), NULL);
+ add_function("packSnorm4x8", _packSnorm4x8(shader_packing), NULL);
+ add_function("unpackUnorm2x16", _unpackUnorm2x16(shader_packing_or_es3), NULL);
+ add_function("unpackSnorm2x16", _unpackSnorm2x16(shader_packing_or_es3), NULL);
+ add_function("unpackUnorm4x8", _unpackUnorm4x8(shader_packing), NULL);
+ add_function("unpackSnorm4x8", _unpackSnorm4x8(shader_packing), 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, 1, glsl_type::float_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isamplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usamplerCube_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::samplerCubeShadow_type, 3, glsl_type::vec4_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_tex, texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_tex, texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_tex, texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, 4, glsl_type::vec4_type),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, 3, 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, 2, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec2_type),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec3_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isamplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usamplerCube_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::samplerCubeShadow_type, 3, glsl_type::vec4_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txb, fs_texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_txb, fs_texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_txb, fs_texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, 4, glsl_type::vec4_type),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureLod",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isamplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usamplerCube_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txl, texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_txl, texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_txl, texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, 4, glsl_type::vec4_type),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureOffset",
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txb, v130_fs_only, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txb, v130_fs_only, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+ NULL);
+
+ add_function("textureProj",
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, 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, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_tex, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txb, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ NULL);
+
+ add_function("textureLodOffset",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+ NULL);
+
+ add_function("textureProjLod",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureProjLodOffset",
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txl, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ NULL);
+
+ add_function("textureGrad",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isamplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usamplerCube_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec3_type),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::samplerCubeShadow_type, 3, glsl_type::vec4_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type),
+
+ _texture(ir_txd, texture_cube_map_array, glsl_type::vec4_type, glsl_type::samplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_txd, texture_cube_map_array, glsl_type::ivec4_type, glsl_type::isamplerCubeArray_type, 4, glsl_type::vec4_type),
+ _texture(ir_txd, texture_cube_map_array, glsl_type::uvec4_type, glsl_type::usamplerCubeArray_type, 4, glsl_type::vec4_type),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, 3, glsl_type::vec4_type),
+ NULL);
+
+ add_function("textureGradOffset",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::float_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1DArray_type, 2, glsl_type::vec2_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DArray_type, 3, glsl_type::vec3_type, TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type, TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, 3, glsl_type::vec4_type, TEX_OFFSET),
+ NULL);
+
+ add_function("textureProjGrad",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureProjGradOffset",
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::uvec4_type, glsl_type::usampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT | TEX_OFFSET),
+ _texture(ir_txd, v130, glsl_type::float_type, glsl_type::sampler2DShadow_type, 2, 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("texture1D",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ NULL);
+
+ add_function("texture1DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture1DProj",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture1DLod",
+ _texture(ir_txl, tex1d_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ NULL);
+
+ add_function("texture1DArrayLod",
+ _texture(ir_txl, vs_texture_array, glsl_type::vec4_type, glsl_type::sampler1DArray_type, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture1DProjLod",
+ _texture(ir_txl, tex1d_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txl, tex1d_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture2D",
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ _texture(ir_tex, texture_external, glsl_type::vec4_type, glsl_type::samplerExternalOES_type, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture2DProj",
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_tex, texture_external, glsl_type::vec4_type, glsl_type::samplerExternalOES_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, texture_external, glsl_type::vec4_type, glsl_type::samplerExternalOES_type, 2, 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, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DArrayLod",
+ _texture(ir_txl, vs_texture_array, glsl_type::vec4_type, glsl_type::sampler2DArray_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture2DProjLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture3D",
+ _texture(ir_tex, tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, fs_tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture3DProj",
+ _texture(ir_tex, tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, fs_tex3d, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture3DLod",
+ _texture(ir_txl, tex3d_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture3DProjLod",
+ _texture(ir_txl, tex3d_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureCube",
+ _texture(ir_tex, always_available, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ _texture(ir_txb, fs_only, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("textureCubeLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture2DRect",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DRectProj",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow1D",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2D",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DArray",
+ _texture(ir_tex, texture_array, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, 3, glsl_type::vec4_type),
+ _texture(ir_txb, fs_texture_array, glsl_type::vec4_type, glsl_type::sampler2DArrayShadow_type, 3, glsl_type::vec4_type),
+ NULL);
+
+ add_function("shadow1DProj",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DProj",
+ _texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ _texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow1DLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DArrayLod",
+ _texture(ir_txl, vs_texture_array, glsl_type::vec4_type, glsl_type::sampler1DArrayShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DProjLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DProjLod",
+ _texture(ir_txl, v110_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DRect",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DRectProj",
+ _texture(ir_tex, texture_rectangle, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture1DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::float_type),
+ NULL);
+
+ add_function("texture1DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec2_type, TEX_PROJECT),
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1D_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture2DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2D_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("texture3DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("texture3DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler3D_type, 3, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("textureCubeGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::samplerCube_type, 3, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow1DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler1DShadow_type, 1, glsl_type::vec4_type, TEX_PROJECT),
+ NULL);
+
+ add_function("shadow2DGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DProjGradARB",
+ _texture(ir_txd, shader_texture_lod, glsl_type::vec4_type, glsl_type::sampler2DShadow_type, 2, 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, 2, glsl_type::vec2_type),
+ NULL);
+
+ add_function("texture2DRectProjGradARB",
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, glsl_type::vec3_type, TEX_PROJECT),
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRect_type, 2, 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, 2, glsl_type::vec3_type),
+ NULL);
+
+ add_function("shadow2DRectProjGradARB",
+ _texture(ir_txd, shader_texture_lod_and_rect, glsl_type::vec4_type, glsl_type::sampler2DRectShadow_type, 2, glsl_type::vec4_type, TEX_PROJECT),
+ 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)
+#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;
+
+ sig->is_defined = true;
+
+ if (false) {
+ exec_list stuff;
+ stuff.push_tail(sig);
+ validate_ir_tree(&stuff);
+ }
+
+ f->add_signature(sig);
+ }
+
+ shader->symbols->add_function(f);
+}
+
+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)
+{
+ return new(mem_ctx) ir_constant(f);
+}
+
+ir_constant *
+builtin_builder::imm(int i)
+{
+ return new(mem_ctx) ir_constant(i);
+}
+
+ir_constant *
+builtin_builder::imm(unsigned u)
+{
+ return new(mem_ctx) ir_constant(u);
+}
+
+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);
+
+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(1.5707964f),
+ mul(sqrt(sub(imm(1.0f), abs(x))),
+ add(imm(1.5707964f),
+ mul(abs(x),
+ add(imm(-0.21460183f),
+ mul(abs(x),
+ add(imm(0.086566724f),
+ mul(abs(x), imm(-0.03102955f))))))))));
+}
+
+
+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(1.5707964f), 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(3.141593f))),
+ assign(r, sub(r, imm(3.141593f)))));
+ outer_then.emit(inner_if);
+
+ /* Else... */
+ outer_if->else_instructions.push_tail(
+ assign(r, mul(sign(y), imm(1.5707965f))));
+
+ 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(dotlike(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(dotlike(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(dotlike(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, dotlike(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,
+ int coord_size,
+ 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);
+
+ 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);
+
+ /* The shadow comparitor is normally in the Z component, but a few types
+ * have sufficiently large coordinates that it's in W.
+ */
+ if (sampler_type->sampler_shadow)
+ 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) {
+ 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", ir_var_const_in);
+ sig->parameters.push_tail(offset);
+ tex->offset = var_ref(offset);
+ }
+
+ /* 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;
+}
+
+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(fma(a, b, c)));
+
+ return sig;
+}
+/** @} */
+
+/******************************************************************************/
+
+/* The singleton instance of builtin_builder. */
+static builtin_builder builtins;
+
+/**
+ * External API (exposing the built-in module to the rest of the compiler):
+ * @{
+ */
+void
+_mesa_glsl_initialize_builtin_functions()
+{
+ builtins.initialize();
+}
+
+void
+_mesa_glsl_release_builtin_functions()
+{
+ builtins.release();
+}
+
+ir_function_signature *
+_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
+ const char *name, exec_list *actual_parameters)
+{
+ return builtins.find(state, name, actual_parameters);
+}
+/** @} */
diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y
index ff5bdfe5d..fb1c1d046 100644
--- a/mesalib/src/glsl/glcpp/glcpp-parse.y
+++ b/mesalib/src/glsl/glcpp/glcpp-parse.y
@@ -1245,6 +1245,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
if (extensions->ARB_shading_language_420pack)
add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
+
+ if (extensions->MESA_shader_integer_mix)
+ add_builtin_define(parser, "GL_MESA_shader_integer_mix", 1);
}
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 8669b7762..1e4d7c7ab 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -517,6 +517,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
EXT(ARB_texture_query_lod, true, false, ARB_texture_query_lod),
EXT(ARB_gpu_shader5, true, false, ARB_gpu_shader5),
EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer),
+ EXT(MESA_shader_integer_mix, true, true, MESA_shader_integer_mix),
};
#undef EXT
@@ -1625,7 +1626,7 @@ _mesa_destroy_shader_compiler(void)
void
_mesa_destroy_shader_compiler_caches(void)
{
- _mesa_glsl_release_functions();
+ _mesa_glsl_release_builtin_functions();
}
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index 440c15bb8..15abbbc99 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -113,7 +113,7 @@ struct _mesa_glsl_parse_state {
* feature.
*/
bool is_version(unsigned required_glsl_version,
- unsigned required_glsl_es_version)
+ unsigned required_glsl_es_version) const
{
unsigned required_version = this->es_shader ?
required_glsl_es_version : required_glsl_version;
@@ -315,6 +315,8 @@ struct _mesa_glsl_parse_state {
bool AMD_vertex_shader_layer_warn;
bool ARB_shading_language_420pack_enable;
bool ARB_shading_language_420pack_warn;
+ bool MESA_shader_integer_mix_enable;
+ bool MESA_shader_integer_mix_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index c6d96d8da..1b1799958 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -250,6 +250,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_cos_reduced:
case ir_unop_dFdx:
case ir_unop_dFdy:
+ case ir_unop_bitfield_reverse:
this->type = op0->type;
break;
@@ -257,6 +258,9 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_b2i:
case ir_unop_u2i:
case ir_unop_bitcast_f2i:
+ case ir_unop_bit_count:
+ case ir_unop_find_msb:
+ case ir_unop_find_lsb:
this->type = glsl_type::get_instance(GLSL_TYPE_INT,
op0->type->vector_elements, 1);
break;
@@ -396,6 +400,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
case ir_binop_lshift:
case ir_binop_rshift:
+ case ir_binop_bfm:
this->type = op0->type;
break;
@@ -409,6 +414,38 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
}
}
+ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
+ ir_rvalue *op2)
+{
+ this->ir_type = ir_type_expression;
+
+ this->operation = ir_expression_operation(op);
+ this->operands[0] = op0;
+ this->operands[1] = op1;
+ this->operands[2] = op2;
+ this->operands[3] = NULL;
+
+ assert(op > ir_last_binop && op <= ir_last_triop);
+
+ switch (this->operation) {
+ case ir_triop_fma:
+ case ir_triop_lrp:
+ case ir_triop_bitfield_extract:
+ case ir_triop_vector_insert:
+ this->type = op0->type;
+ break;
+
+ case ir_triop_bfi:
+ case ir_triop_csel:
+ this->type = op1->type;
+ break;
+
+ default:
+ assert(!"not reached: missing automatic type setup for ir_expression");
+ this->type = glsl_type::float_type;
+ }
+}
+
unsigned int
ir_expression::get_num_operands(ir_expression_operation op)
{
@@ -517,6 +554,7 @@ static const char *const operator_strs[] = {
"vector_extract",
"fma",
"lrp",
+ "csel",
"bfi",
"bitfield_extract",
"vector_insert",
@@ -1579,15 +1617,40 @@ ir_variable::determine_interpolation_mode(bool flat_shade)
}
-ir_function_signature::ir_function_signature(const glsl_type *return_type)
- : return_type(return_type), is_defined(false), _function(NULL)
+ir_function_signature::ir_function_signature(const glsl_type *return_type,
+ builtin_available_predicate b)
+ : return_type(return_type), is_defined(false), builtin_avail(b),
+ _function(NULL)
{
this->ir_type = ir_type_function_signature;
- this->is_builtin = false;
this->origin = NULL;
}
+bool
+ir_function_signature::is_builtin() const
+{
+ return builtin_avail != NULL;
+}
+
+
+bool
+ir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const
+{
+ /* We can't call the predicate without a state pointer, so just say that
+ * the signature is available. At compile time, we need the filtering,
+ * but also receive a valid state pointer. At link time, we're resolving
+ * imported built-in prototypes to their definitions, which will always
+ * be an exact match. So we can skip the filtering.
+ */
+ if (state == NULL)
+ return true;
+
+ assert(builtin_avail != NULL);
+ return builtin_avail(state);
+}
+
+
static bool
modes_match(unsigned a, unsigned b)
{
@@ -1659,7 +1722,7 @@ ir_function::has_user_signature()
{
foreach_list(n, &this->signatures) {
ir_function_signature *const sig = (ir_function_signature *) n;
- if (!sig->is_builtin)
+ if (!sig->is_builtin())
return true;
}
return false;
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index b45e6cbd8..2637b40e2 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -591,6 +591,11 @@ public:
const glsl_type *interface_type;
};
+/**
+ * A function that returns whether a built-in function is available in the
+ * current shading language (based on version, ES or desktop, and extensions).
+ */
+typedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *);
/*@{*/
/**
@@ -602,7 +607,8 @@ class ir_function_signature : public ir_instruction {
* an ir_function.
*/
public:
- ir_function_signature(const glsl_type *return_type);
+ ir_function_signature(const glsl_type *return_type,
+ builtin_available_predicate builtin_avail = NULL);
virtual ir_function_signature *clone(void *mem_ctx,
struct hash_table *ht) const;
@@ -678,12 +684,21 @@ public:
unsigned is_defined:1;
/** Whether or not this function signature is a built-in. */
- unsigned is_builtin:1;
+ bool is_builtin() const;
+
+ /** Whether or not a built-in is available for this shader. */
+ bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
/** Body of instructions in the function. */
struct exec_list body;
private:
+ /**
+ * A function pointer to a predicate that answers whether a built-in
+ * function is available in the current shader. NULL if not a built-in.
+ */
+ builtin_available_predicate builtin_avail;
+
/** Function of which this signature is one overload. */
class ir_function *_function;
@@ -750,20 +765,23 @@ public:
* Find a signature that matches a set of actual parameters, taking implicit
* conversions into account. Also flags whether the match was exact.
*/
- ir_function_signature *matching_signature(const exec_list *actual_param,
+ ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
+ const exec_list *actual_param,
bool *match_is_exact);
/**
* Find a signature that matches a set of actual parameters, taking implicit
* conversions into account.
*/
- ir_function_signature *matching_signature(const exec_list *actual_param);
+ ir_function_signature *matching_signature(_mesa_glsl_parse_state *state,
+ const exec_list *actual_param);
/**
* Find a signature that exactly matches a set of actual parameters without
* any implicit type conversions.
*/
- ir_function_signature *exact_matching_signature(const exec_list *actual_ps);
+ ir_function_signature *exact_matching_signature(_mesa_glsl_parse_state *state,
+ const exec_list *actual_ps);
/**
* Name of the function.
@@ -1179,6 +1197,18 @@ enum ir_expression_operation {
ir_triop_lrp,
/**
+ * \name Conditional Select
+ *
+ * A vector conditional select instruction (like ?:, but operating per-
+ * component on vectors).
+ *
+ * \see lower_instructions_visitor::ldexp_to_arith
+ */
+ /*@{*/
+ ir_triop_csel,
+ /*@}*/
+
+ /**
* \name Second half of a lowered bitfieldInsert() operation.
*
* \see lower_instructions::bitfield_insert_to_bfm_bfi
@@ -1234,6 +1264,11 @@ public:
*/
ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1);
+ /**
+ * Constructor for ternary operation expressions
+ */
+ ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2);
+
virtual ir_expression *as_expression()
{
return this;
@@ -1309,7 +1344,7 @@ public:
ir_type = ir_type_call;
assert(callee->return_type != NULL);
actual_parameters->move_nodes_to(& this->actual_parameters);
- this->use_builtin = callee->is_builtin;
+ this->use_builtin = callee->is_builtin();
}
virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
@@ -1550,6 +1585,7 @@ public:
shadow_comparitor(NULL), offset(NULL)
{
this->ir_type = ir_type_texture;
+ memset(&lod_info, 0, sizeof(lod_info));
}
virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
@@ -2103,9 +2139,19 @@ extern void
_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state);
extern void
+_mesa_glsl_initialize_builtin_functions();
+
+extern ir_function_signature *
+_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
+ const char *name, exec_list *actual_parameters);
+
+extern void
_mesa_glsl_release_functions(void);
extern void
+_mesa_glsl_release_builtin_functions(void);
+
+extern void
reparent_ir(exec_list *list, void *mem_ctx);
struct glsl_symbol_table;
diff --git a/mesalib/src/glsl/ir_builder.cpp b/mesalib/src/glsl/ir_builder.cpp
index 7d9cf5e47..98b432295 100644
--- a/mesalib/src/glsl/ir_builder.cpp
+++ b/mesalib/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);
@@ -203,6 +231,17 @@ ir_expression *dot(operand a, operand b)
return expr(ir_binop_dot, a, b);
}
+/* dot for vectors, mul for scalars */
+ir_expression *dotlike(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);
+}
+
ir_expression*
clamp(operand a, operand b, operand c)
{
@@ -225,6 +264,54 @@ 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)
{
@@ -381,6 +468,44 @@ 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/mesalib/src/glsl/ir_builder.h b/mesalib/src/glsl/ir_builder.h
index 7049476a1..6a5f77119 100644
--- a/mesalib/src/glsl/ir_builder.h
+++ b/mesalib/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,18 +122,32 @@ 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 *div(operand a, operand b);
ir_expression *round_even(operand a);
ir_expression *dot(operand a, operand b);
+ir_expression *dotlike(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);
@@ -164,7 +178,15 @@ 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 *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/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index a75b3b762..fb303b0b7 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -329,7 +329,7 @@ ir_function_signature::clone_prototype(void *mem_ctx, struct hash_table *ht) con
new(mem_ctx) ir_function_signature(this->return_type);
copy->is_defined = false;
- copy->is_builtin = this->is_builtin;
+ copy->builtin_avail = this->builtin_avail;
copy->origin = this;
/* Clone the parameter list, but NOT the body.
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index bf019b955..a67470bf3 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -395,6 +395,7 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
case ir_binop_lshift:
case ir_binop_rshift:
case ir_binop_vector_extract:
+ case ir_triop_csel:
case ir_triop_bitfield_extract:
break;
@@ -1399,6 +1400,13 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
break;
}
+ case ir_triop_csel:
+ for (unsigned c = 0; c < components; c++) {
+ data.u[c] = op[0]->value.b[c] ? op[1]->value.u[c]
+ : op[2]->value.u[c];
+ }
+ break;
+
case ir_triop_vector_insert: {
const unsigned idx = op[2]->value.u[0];
@@ -1840,7 +1848,7 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters, s
* "Function calls to user-defined functions (non-built-in functions)
* cannot be used to form constant expressions."
*/
- if (!this->is_builtin)
+ if (!this->is_builtin())
return NULL;
/*
diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp
index fe4209c77..53cf469d9 100644
--- a/mesalib/src/glsl/ir_function.cpp
+++ b/mesalib/src/glsl/ir_function.cpp
@@ -116,14 +116,16 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b)
ir_function_signature *
-ir_function::matching_signature(const exec_list *actual_parameters)
+ir_function::matching_signature(_mesa_glsl_parse_state *state,
+ const exec_list *actual_parameters)
{
bool is_exact;
- return matching_signature(actual_parameters, &is_exact);
+ return matching_signature(state, actual_parameters, &is_exact);
}
ir_function_signature *
-ir_function::matching_signature(const exec_list *actual_parameters,
+ir_function::matching_signature(_mesa_glsl_parse_state *state,
+ const exec_list *actual_parameters,
bool *is_exact)
{
ir_function_signature *match = NULL;
@@ -143,6 +145,10 @@ ir_function::matching_signature(const exec_list *actual_parameters,
ir_function_signature *const sig =
(ir_function_signature *) iter.get();
+ /* Skip over any built-ins that aren't available in this shader. */
+ if (sig->is_builtin() && !sig->is_builtin_available(state))
+ continue;
+
switch (parameter_lists_match(& sig->parameters, actual_parameters)) {
case PARAMETER_LIST_EXACT_MATCH:
*is_exact = true;
@@ -203,12 +209,17 @@ parameter_lists_match_exact(const exec_list *list_a, const exec_list *list_b)
}
ir_function_signature *
-ir_function::exact_matching_signature(const exec_list *actual_parameters)
+ir_function::exact_matching_signature(_mesa_glsl_parse_state *state,
+ const exec_list *actual_parameters)
{
foreach_iter(exec_list_iterator, iter, signatures) {
ir_function_signature *const sig =
(ir_function_signature *) iter.get();
+ /* Skip over any built-ins that aren't available in this shader. */
+ if (sig->is_builtin() && !sig->is_builtin_available(state))
+ continue;
+
if (parameter_lists_match_exact(&sig->parameters, actual_parameters))
return sig;
}
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index f263fe810..ec35b682e 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -211,6 +211,12 @@ ir_reader::read_function(s_expression *expr, bool skip_body)
return added ? f : NULL;
}
+static bool
+always_available(const _mesa_glsl_parse_state *)
+{
+ return true;
+}
+
void
ir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body)
{
@@ -248,11 +254,15 @@ ir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body)
hir_parameters.push_tail(var);
}
- ir_function_signature *sig = f->exact_matching_signature(&hir_parameters);
+ ir_function_signature *sig =
+ f->exact_matching_signature(state, &hir_parameters);
if (sig == NULL && skip_body) {
/* If scanning for prototypes, generate a new signature. */
- sig = new(mem_ctx) ir_function_signature(return_type);
- sig->is_builtin = true;
+ /* ir_reader doesn't know what languages support a given built-in, so
+ * just say that they're always available. For now, other mechanisms
+ * guarantee the right built-ins are available.
+ */
+ sig = new(mem_ctx) ir_function_signature(return_type, always_available);
f->add_signature(sig);
} else if (sig != NULL) {
const char *badvar = sig->qualifiers_match(&hir_parameters);
@@ -659,7 +669,7 @@ ir_reader::read_call(s_expression *expr)
return NULL;
}
- ir_function_signature *callee = f->matching_signature(&parameters);
+ ir_function_signature *callee = f->matching_signature(state, &parameters);
if (callee == NULL) {
ir_read_error(expr, "couldn't find matching signature for function "
"%s", name->value());
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 37f26febe..ae3f09daf 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -529,6 +529,13 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->operands[2]->type == ir->operands[0]->type || ir->operands[2]->type == glsl_type::float_type);
break;
+ case ir_triop_csel:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
+ assert(ir->type->vector_elements == ir->operands[0]->type->vector_elements);
+ assert(ir->type == ir->operands[1]->type);
+ assert(ir->type == ir->operands[2]->type);
+ break;
+
case ir_triop_bfi:
assert(ir->operands[0]->type->is_integer());
assert(ir->operands[1]->type == ir->operands[2]->type);
diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp
index dd6f24716..9e96365e6 100644
--- a/mesalib/src/glsl/link_functions.cpp
+++ b/mesalib/src/glsl/link_functions.cpp
@@ -113,10 +113,10 @@ public:
}
ir_function_signature *linked_sig =
- f->exact_matching_signature(&callee->parameters);
+ f->exact_matching_signature(NULL, &callee->parameters);
if ((linked_sig == NULL)
|| ((linked_sig != NULL)
- && (linked_sig->is_builtin != ir->use_builtin))) {
+ && (linked_sig->is_builtin() != ir->use_builtin))) {
linked_sig = new(linked) ir_function_signature(callee->return_type);
f->add_signature(linked_sig);
}
@@ -288,7 +288,8 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
if (f == NULL)
continue;
- ir_function_signature *sig = f->matching_signature(actual_parameters);
+ ir_function_signature *sig =
+ f->matching_signature(NULL, actual_parameters);
if ((sig == NULL) || !sig->is_defined)
continue;
@@ -297,7 +298,7 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
* signature that we found isn't a built-in, keep looking. Also keep
* looking if we expect a non-built-in but found a built-in.
*/
- if (use_builtin != sig->is_builtin)
+ if (use_builtin != sig->is_builtin())
continue;
return sig;
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 8430096ac..65afc2e69 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -982,7 +982,7 @@ get_main_function_signature(gl_shader *sh)
* We don't have to check for multiple definitions of main (in multiple
* shaders) because that would have already been caught above.
*/
- ir_function_signature *sig = f->matching_signature(&void_parameters);
+ ir_function_signature *sig = f->matching_signature(NULL, &void_parameters);
if ((sig != NULL) && sig->is_defined) {
return sig;
}
@@ -1163,14 +1163,14 @@ link_intrastage_shaders(void *mem_ctx,
ir_function_signature *sig =
(ir_function_signature *) iter.get();
- if (!sig->is_defined || sig->is_builtin)
+ if (!sig->is_defined || sig->is_builtin())
continue;
ir_function_signature *other_sig =
- other->exact_matching_signature(& sig->parameters);
+ other->exact_matching_signature(NULL, &sig->parameters);
if ((other_sig != NULL) && other_sig->is_defined
- && !other_sig->is_builtin) {
+ && !other_sig->is_builtin()) {
linker_error(prog, "function `%s' is multiply defined",
f->name);
return NULL;
diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp
index 31a50bba5..4f617225c 100644
--- a/mesalib/src/glsl/lower_packed_varyings.cpp
+++ b/mesalib/src/glsl/lower_packed_varyings.cpp
@@ -658,7 +658,7 @@ lower_packed_varyings(void *mem_ctx, unsigned location_base,
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);
+ = main_func->matching_signature(NULL, &void_parameters);
exec_list new_instructions;
lower_packed_varyings_visitor visitor(mem_ctx, location_base,
locations_used, mode,
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index e13d5c452..57bec44be 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -230,7 +230,7 @@ main(int argc, char **argv)
ralloc_free(whole_program);
_mesa_glsl_release_types();
- _mesa_glsl_release_functions();
+ _mesa_glsl_release_builtin_functions();
return status;
}
diff --git a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
index 6745d5c64..3cdd13038 100644
--- a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
+++ b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
@@ -391,10 +391,10 @@ 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_texcoord[MAX_TEXTURE_COORD_UNITS];
+ ir_variable *new_color[2];
+ ir_variable *new_backcolor[2];
+ ir_variable *new_fog;
};
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index f60157f8c..88fcde3b9 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -311,6 +311,7 @@ static const struct extension extension_table[] = {
{ "GL_IBM_texture_mirrored_repeat", o(dummy_true), GLL, 1998 },
{ "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GLL, 1999 },
{ "GL_MESA_pack_invert", o(MESA_pack_invert), GL, 2002 },
+ { "GL_MESA_shader_integer_mix", o(MESA_shader_integer_mix), GL | ES3, 2013 },
{ "GL_MESA_texture_array", o(MESA_texture_array), GLL, 2007 },
{ "GL_MESA_texture_signed_rgba", o(EXT_texture_snorm), GL, 2009 },
{ "GL_MESA_window_pos", o(dummy_true), GLL, 2000 },
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index ef16c5910..ca7111e50 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -3154,8 +3154,9 @@ struct gl_extensions
GLboolean ATI_fragment_shader;
GLboolean ATI_separate_stencil;
GLboolean MESA_pack_invert;
- GLboolean MESA_ycbcr_texture;
+ GLboolean MESA_shader_integer_mix;
GLboolean MESA_texture_array;
+ GLboolean MESA_ycbcr_texture;
GLboolean NV_conditional_render;
GLboolean NV_fog_distance;
GLboolean NV_fragment_program_option;
diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c
index 6b636f4cb..a18013369 100644
--- a/mesalib/src/mesa/main/queryobj.c
+++ b/mesalib/src/mesa/main/queryobj.c
@@ -43,7 +43,7 @@
static struct gl_query_object *
_mesa_new_query_object(struct gl_context *ctx, GLuint id)
{
- struct gl_query_object *q = MALLOC_STRUCT(gl_query_object);
+ struct gl_query_object *q = CALLOC_STRUCT(gl_query_object);
(void) ctx;
if (q) {
q->Id = id;
diff --git a/mesalib/src/mesa/main/samplerobj.c b/mesalib/src/mesa/main/samplerobj.c
index 39cfcd086..c3b612c76 100644
--- a/mesalib/src/mesa/main/samplerobj.c
+++ b/mesalib/src/mesa/main/samplerobj.c
@@ -569,7 +569,8 @@ static GLuint
set_sampler_cube_map_seamless(struct gl_context *ctx,
struct gl_sampler_object *samp, GLboolean param)
{
- if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
+ if (!_mesa_is_desktop_gl(ctx)
+ || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
return INVALID_PNAME;
if (samp->CubeMapSeamless == param)
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index dad69a8f6..ad80dcfaa 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -810,6 +810,14 @@ _mesa_init_texture(struct gl_context *ctx)
ctx->Texture.CurrentUnit = 0; /* multitexture */
ctx->Texture._EnabledUnits = 0x0;
+ /* Appendix F.2 of the OpenGL ES 3.0 spec says:
+ *
+ * "OpenGL ES 3.0 requires that all cube map filtering be
+ * seamless. OpenGL ES 2.0 specified that a single cube map face be
+ * selected and used for filtering."
+ */
+ ctx->Texture.CubeMapSeamless = _mesa_is_gles3(ctx);
+
for (u = 0; u < Elements(ctx->Texture.Unit); u++)
init_texture_unit(ctx, u);
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 340a4497f..510235cae 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -837,7 +837,7 @@ ir_to_mesa_visitor::visit(ir_function *ir)
const ir_function_signature *sig;
exec_list empty;
- sig = ir->matching_signature(&empty);
+ sig = ir->matching_signature(NULL, &empty);
assert(sig);
@@ -1497,6 +1497,7 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
case ir_triop_bitfield_extract:
case ir_triop_vector_insert:
case ir_quadop_bitfield_insert:
+ case ir_triop_csel:
assert(!"not supported");
break;
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 37779d4e5..1c9174c91 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1209,7 +1209,7 @@ glsl_to_tgsi_visitor::visit(ir_function *ir)
const ir_function_signature *sig;
exec_list empty;
- sig = ir->matching_signature(&empty);
+ sig = ir->matching_signature(NULL, &empty);
assert(sig);
@@ -1979,6 +1979,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
case ir_quadop_vector:
case ir_binop_vector_extract:
case ir_triop_vector_insert:
+ case ir_triop_csel:
/* This operation is not supported, or should have already been handled.
*/
assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");
diff --git a/mesalib/src/mesa/vbo/vbo_exec.c b/mesalib/src/mesa/vbo/vbo_exec.c
index 9c20bdef2..aa2c7b07b 100644
--- a/mesalib/src/mesa/vbo/vbo_exec.c
+++ b/mesalib/src/mesa/vbo/vbo_exec.c
@@ -149,6 +149,18 @@ vbo_count_tessellated_primitives(GLenum mode, GLuint count,
case GL_QUADS:
num_primitives = (count / 4) * 2;
break;
+ case GL_LINES_ADJACENCY:
+ num_primitives = count / 4;
+ break;
+ case GL_LINE_STRIP_ADJACENCY:
+ num_primitives = count >= 4 ? count - 3 : 0;
+ break;
+ case GL_TRIANGLES_ADJACENCY:
+ num_primitives = count / 6;
+ break;
+ case GL_TRIANGLE_STRIP_ADJACENCY:
+ num_primitives = count >= 6 ? (count - 4) / 2 : 0;
+ break;
default:
assert(!"Unexpected primitive type in count_tessellated_primitives");
num_primitives = 0;