diff -Nru love-11.1/aclocal.m4 love-11.3/aclocal.m4 --- love-11.1/aclocal.m4 2018-04-15 18:31:59.000000000 +0000 +++ love-11.3/aclocal.m4 2019-10-27 13:45:19.000000000 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.1 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -21,7 +21,7 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 12 (pkg-config-0.29.2) +# serial 11 (pkg-config-0.29.1) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -63,7 +63,7 @@ dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.2]) +[m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -164,7 +164,7 @@ AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $2]) +AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -174,11 +174,11 @@ See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs @@ -195,7 +195,7 @@ _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -296,6 +296,74 @@ AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR +dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------ +dnl +dnl Prepare a "--with-" configure option using the lowercase +dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and +dnl PKG_CHECK_MODULES in a single macro. +AC_DEFUN([PKG_WITH_MODULES], +[ +m4_pushdef([with_arg], m4_tolower([$1])) + +m4_pushdef([description], + [m4_default([$5], [build with ]with_arg[ support])]) + +m4_pushdef([def_arg], [m4_default([$6], [auto])]) +m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) +m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) + +m4_case(def_arg, + [yes],[m4_pushdef([with_without], [--without-]with_arg)], + [m4_pushdef([with_without],[--with-]with_arg)]) + +AC_ARG_WITH(with_arg, + AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, + [AS_TR_SH([with_]with_arg)=def_arg]) + +AS_CASE([$AS_TR_SH([with_]with_arg)], + [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], + [auto],[PKG_CHECK_MODULES([$1],[$2], + [m4_n([def_action_if_found]) $3], + [m4_n([def_action_if_not_found]) $4])]) + +m4_popdef([with_arg]) +m4_popdef([description]) +m4_popdef([def_arg]) + +])dnl PKG_WITH_MODULES + +dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ----------------------------------------------- +dnl +dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES +dnl check._[VARIABLE-PREFIX] is exported as make variable. +AC_DEFUN([PKG_HAVE_WITH_MODULES], +[ +PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) + +AM_CONDITIONAL([HAVE_][$1], + [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) +])dnl PKG_HAVE_WITH_MODULES + +dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, +dnl [DESCRIPTION], [DEFAULT]) +dnl ------------------------------------------------------ +dnl +dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after +dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make +dnl and preprocessor variable. +AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], +[ +PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) + +AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], + [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) +])dnl PKG_HAVE_DEFINE_WITH_MODULES + # Configure paths for SDL # Sam Lantinga 9/21/99 # stolen from Manish Singh @@ -372,7 +440,7 @@ done fi - if test -d $sdl_framework; then + if test x"$sdl_framework" != x && test -d "$sdl_framework"; then AC_MSG_RESULT($sdl_framework) sdl_framework_dir=`dirname $sdl_framework` SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include" @@ -531,7 +599,7 @@ rm -f conf.sdltest ]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -543,10 +611,10 @@ # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.16.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -562,12 +630,12 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.16.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# Copyright (C) 2011-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -629,7 +697,7 @@ # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -681,7 +749,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -712,7 +780,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -903,13 +971,12 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -917,49 +984,41 @@ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -968,18 +1027,17 @@ # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1066,8 +1124,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -1134,7 +1192,7 @@ Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -1176,7 +1234,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1197,7 +1255,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 2003-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1218,7 +1276,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1226,49 +1284,42 @@ # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1307,7 +1358,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1336,7 +1387,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1383,7 +1434,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1402,7 +1453,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1483,7 +1534,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1543,7 +1594,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1571,7 +1622,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1590,7 +1641,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru love-11.1/changes.txt love-11.3/changes.txt --- love-11.1/changes.txt 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/changes.txt 2019-10-27 13:44:49.000000000 +0000 @@ -1,3 +1,85 @@ +LOVE 11.3 [Mysterious Mysteries] +-------------------------------- + +Released: N/A + +* Added support for FLAC audio files. +* Added support for microphone recording on Android. +* Added t.audio.mic (false by default). On Android, setting it to true requests microphone recording permission from the user. +* Added Decoder:clone. +* Added Data:getFFIPointer. +* Added Joystick:getDeviceInfo. +* Added Joystick:getGamepadMappingString and love.joystick.getGamepadMappingString(guid). +* Added love.math.colorToBytes and love.math.colorFromBytes. +* Added 'usedpiscale' boolean (true by default) to love.window.setMode and love.conf. Disables automatic DPI scaling when false. +* Added love.window.getDisplayOrientation and a love.displayrotated callback. +* Added love.window.get/setVSync, to allow setting vsync without recreating the window. +* Added love.window.getSafeArea. +* Added an optional vertex count parameter to Mesh:setVertices. +* Added support for rgba4, rgb5a1, rgb565, rgb10a2, rg11b10f, r8, rg8, r16, rg16, r16f, rg16f, r32f, and rg32f formats in ImageData and Images. +* Added support for loading .dds files that contain uncompressed pixel data. + +* Changed audio file type detection, so it probes all supported backends for unrecognized extensions. + +* Fixed "bad lightuserdata" errors when running love on some arm64 devices. +* Fixed boot.lua's line numbers in stack traces to match its source code. +* Fixed the deprecation system not fully restarting when love.event.quit("restart") is used. +* Fixed love.isVersionCompatible. +* Fixed named Channels persisting across love.event.quit("restart") occurrences. +* Fixed race conditions when different love.physics Worlds are used in different threads. +* Fixed World:getJoints to return the fully resolved type of the Joint, instead of the base type. +* Fixed love.timer.sleep(0) to return control to the OS scheduler instead of being a no-op. +* Fixed love.math.randomNormal incorrectly using cached state after love.math.setRandomSeed or setRandomState. +* Fixed love.data.hash returning an incorrect hash for certain input sizes. +* Fixed love.data.newByteData to cause a Lua error instead of crashing when invalid arguments are used. +* Fixed the Data-returning variant of love.filesystem.read and File:read to return the number of bytes that were read. +* Fixed love.filesystem's require loaders to error instead of crashing when no argument is given. +* Fixed love.filesystem.mount(Data). +* Fixed a memory leak when loading files in some situations. +* Fixed t.audio.mixwithsystem. +* Fixed audio clicks immediately after playing a Source on iOS. +* Fixed Source:play + Source:stop + Source:play looping the first few ms of sound for streaming Sources on iOS. +* Fixed Source:play + Source:seek looping the first few ms of sound for streaming Sources on iOS. +* Fixed occasional pops in streaming sources on iOS. +* Fixed love.audio.play(sources) to use previously set playback positions on stopped Sources. +* Fixed Source:setEffect(name, true) and Source:getEffect(name) when the effect has no associated Filter. +* Fixed love.audio.newSource(filename, "queue") to cause a Lua error. +* Fixed Source:setPitch to error if the given pitch is <= 0, NaN, or infinity. +* Fixed video seeking and pausing in various scenarios. +* Fixed an audio Source memory leak when a Video gets garbage collected after playing it. +* Fixed video playback support on some Adreno-based Android devices. +* Fixed black fringes around text in some situations. +* Fixed extreme flickering when text moves along non-integer coordinates. +* Fixed the first character in a string sometimes not being processed during text vertex generation. +* Fixed Text:set(" ") not clearing any previously set text in a Text object. +* Fixed love.graphics.getTextureTypes to return a table with boolean values in its fields instead of number values. +* Fixed lines not rendering properly if a single line has more than 65,000 vertices. +* Fixed a pixel shader performance regression on some graphics drivers when OpenGL 3 or OpenGL ES 3 is used. +* Fixed text not showing up on Radeon HD 3000-series graphics cards on Windows. +* Fixed non-integer DPI scale values being truncated to integers in love.graphics.newCanvas. +* Fixed creating depth canvases on Windows systems when using an Intel HD 3000 GPU. +* Fixed automatic batching performance to be more consistent on all operating systems. +* Fixed gammaToLinearPrecise in shaders not being as precise as it should be. +* Fixed ImageData:paste and ImageData:setPixel to have more consistent clamping and rounding of color values when different formats are used. + +LOVE 11.2 [Mysterious Mysteries] +-------------------------------- + +Released: 2018-11-25 + +* Added Source:setAirAbsorption and Source:getAirAbsorption. +* Added Body:setTransform and Body:getTransform. + +* Improved performance of love.graphics.draw slightly on iOS and Android. + +* Fixed filesystem initialization on Windows 10 update 1809. +* Fixed compatibility with Lua 5.2 and 5.3. +* Fixed the explicit format + Data argument variant of love.data.decompress. +* Fixed love.joystick.setGamepadMapping not being able to change existing mappings. +* Fixed a crash on quit on Linux if a custom cursor is active when quitting. +* Fixed a crash in the Data variant of Shader:send when it's called after love.window.setMode. +* Fixed a love.graphics.setCanvas error message to be less confusing. + LOVE 11.1 [Mysterious Mysteries] -------------------------------- diff -Nru love-11.1/config.h.in love-11.3/config.h.in --- love-11.1/config.h.in 2018-04-15 18:32:30.000000000 +0000 +++ love-11.3/config.h.in 2019-10-27 13:45:48.000000000 +0000 @@ -52,6 +52,9 @@ #undef LOVE_ENABLE_DDSPARSE /* */ +#undef LOVE_ENABLE_DR_FLAC + +/* */ #undef LOVE_ENABLE_ENET /* */ diff -Nru love-11.1/configure love-11.3/configure --- love-11.1/configure 2018-04-15 18:32:00.000000000 +0000 +++ love-11.3/configure 2019-10-27 13:45:20.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for love 11.1. +# Generated by GNU Autoconf 2.69 for love 11.3. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='love' PACKAGE_TARNAME='love' -PACKAGE_VERSION='11.1' -PACKAGE_STRING='love 11.1' +PACKAGE_VERSION='11.3' +PACKAGE_STRING='love 11.3' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -671,6 +671,8 @@ LOVE_LIBRARY_GLAD_TRUE LOVE_LIBRARY_ENET_FALSE LOVE_LIBRARY_ENET_TRUE +LOVE_LIBRARY_DR_FLAC_FALSE +LOVE_LIBRARY_DR_FLAC_TRUE LOVE_LIBRARY_DDSPARSE_FALSE LOVE_LIBRARY_DDSPARSE_TRUE LOVE_LIBRARY_BOX2D_FALSE @@ -786,7 +788,6 @@ AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR OBJEXT @@ -862,7 +863,8 @@ PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -1487,7 +1489,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures love 11.1 to adapt to many kinds of systems. +\`configure' configures love 11.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1557,7 +1559,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of love 11.1:";; + short | recursive ) echo "Configuration of love 11.3:";; esac cat <<\_ACEOF @@ -1738,7 +1740,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -love configure 11.1 +love configure 11.3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2541,7 +2543,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by love $as_me 11.1, which was +It was created by love $as_me 11.3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2922,7 +2924,7 @@ -am__api_version='1.15' +am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -3408,7 +3410,7 @@ # Define the identity of the package. PACKAGE='love' - VERSION='11.1' + VERSION='11.3' cat >>confdefs.h <<_ACEOF @@ -3438,8 +3440,8 @@ # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -3606,7 +3608,7 @@ Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3661,45 +3663,45 @@ ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -4876,8 +4878,8 @@ -macro_version='2.4.6.40-6ca5-dirty' -macro_revision='2.4.6.40' +macro_version='2.4.6.42-b88ce' +macro_revision='2.4.6.42' @@ -7010,7 +7012,7 @@ if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ @@ -8942,8 +8944,8 @@ ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -9870,15 +9872,15 @@ case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -10527,12 +10529,12 @@ cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes @@ -10573,7 +10575,7 @@ fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. @@ -11605,8 +11607,8 @@ dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -11662,7 +11664,7 @@ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -14786,8 +14788,8 @@ cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' @@ -16361,7 +16363,7 @@ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -16723,8 +16725,8 @@ dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -16780,7 +16782,7 @@ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -18221,6 +18223,8 @@ + + # does not use pkg-config because of the FILE_OFFSET_BITS.. bit @@ -18620,8 +18624,8 @@ pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}${with_luaversion}" >&5 -$as_echo_n "checking for ${with_lua}${with_luaversion}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -18661,7 +18665,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -18679,8 +18683,8 @@ pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}${with_clean_luaversion}" >&5 -$as_echo_n "checking for ${with_lua}${with_clean_luaversion}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -18720,7 +18724,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -18738,8 +18742,8 @@ pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}" >&5 -$as_echo_n "checking for ${with_lua}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -18779,7 +18783,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -18806,7 +18810,7 @@ and lua_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -18828,12 +18832,12 @@ aclove_lua_found=yes fi elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}" >&5 -$as_echo_n "checking for ${with_lua}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -18873,7 +18877,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -18900,7 +18904,7 @@ and lua_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -18929,12 +18933,12 @@ aclove_lua_found=yes fi elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}${with_clean_luaversion}" >&5 -$as_echo_n "checking for ${with_lua}${with_clean_luaversion}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -18974,7 +18978,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -18992,8 +18996,8 @@ pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}" >&5 -$as_echo_n "checking for ${with_lua}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -19033,7 +19037,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19060,7 +19064,7 @@ and lua_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -19082,12 +19086,12 @@ aclove_lua_found=yes fi elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${with_lua}" >&5 -$as_echo_n "checking for ${with_lua}... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua" >&5 +$as_echo_n "checking for lua... " >&6; } if test -n "$lua_CFLAGS"; then pkg_cv_lua_CFLAGS="$lua_CFLAGS" @@ -19127,7 +19131,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19154,7 +19158,7 @@ and lua_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} @@ -19282,6 +19286,7 @@ $as_echo "$as_me: WARNING: Could not locate lua headers for ${with_lua}${with_luaversion} or ${with_lua}, you probably need to specify them with CPPFLAGS" >&2;} fi + aclove_sdl2_found=no # Check whether --with-sdl-prefix was given. if test "${with_sdl_prefix+set}" = set; then : @@ -19320,8 +19325,8 @@ if test "x$sdl_prefix$sdl_exec_prefix" = x ; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 -$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL" >&5 +$as_echo_n "checking for SDL... " >&6; } if test -n "$SDL_CFLAGS"; then pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" @@ -19361,7 +19366,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19379,7 +19384,7 @@ sdl_pc=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } sdl_pc=no else @@ -19470,7 +19475,7 @@ done fi - if test -d $sdl_framework; then + if test x"$sdl_framework" != x && test -d "$sdl_framework"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sdl_framework" >&5 $as_echo "$sdl_framework" >&6; } sdl_framework_dir=`dirname $sdl_framework` @@ -19593,7 +19598,7 @@ fi fi if test "x$no_sdl" = x ; then - : + aclove_sdl2_found=yes else if test "$SDL2_CONFIG" = "no" ; then echo "*** The sdl2-config script installed by SDL could not be found" @@ -19652,12 +19657,15 @@ fi SDL_CFLAGS="" SDL_LIBS="" - as_fn_error $? "LÖVE needs \"SDL 2\", please install \"SDL 2\" with development files and try again" "$LINENO" 5 + : fi rm -f conf.sdltest + if test "x$aclove_sdl2_found" = xno; then : + as_fn_error $? "LÖVE needs \"SDL 2\", please install \"SDL 2\" with development files and try again" "$LINENO" 5 +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sqrt" >&5 $as_echo_n "checking for library containing sqrt... " >&6; } @@ -19761,7 +19769,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19779,7 +19787,7 @@ as_fn_error $? "LÖVE needs \"zlib\", please install \"zlib\" with development files and try again" "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "LÖVE needs \"zlib\", please install \"zlib\" with development files and try again" "$LINENO" 5 else @@ -19790,6 +19798,65 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 +$as_echo_n "checking for library containing pthread_create... " >&6; } +if ${ac_cv_search_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' pthread; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_search_pthread_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_pthread_create+:} false; then : + break +fi +done +if ${ac_cv_search_pthread_create+:} false; then : + +else + ac_cv_search_pthread_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +$as_echo "$ac_cv_search_pthread_create" >&6; } +ac_res=$ac_cv_search_pthread_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "LÖVE needs \"the POSIX threads library\", please install \"the POSIX threads library\" with development files and try again" "$LINENO" 5 +fi + + # Conditional dependencies if test "x$enable_module_audio" = xyes; then : @@ -19836,7 +19903,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19854,7 +19921,7 @@ as_fn_error $? "LÖVE needs \"OpenAL\", please install \"OpenAL\" with development files and try again" "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "LÖVE needs \"OpenAL\", please install \"OpenAL\" with development files and try again" "$LINENO" 5 else @@ -19910,7 +19977,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -19928,7 +19995,7 @@ as_fn_error $? "LÖVE needs \"FreeType2\", please install \"FreeType2\" with development files and try again" "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "LÖVE needs \"FreeType2\", please install \"FreeType2\" with development files and try again" "$LINENO" 5 else @@ -19985,7 +20052,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -20003,7 +20070,7 @@ as_fn_error $? "LÖVE needs \"libmodplug\", please install \"libmodplug\" with development files and try again" "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "LÖVE needs \"libmodplug\", please install \"libmodplug\" with development files and try again" "$LINENO" 5 else @@ -20057,7 +20124,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -20075,7 +20142,7 @@ as_fn_error $? "LÖVE needs \"libvorbis and libvorbisfile\", please install \"libvorbis and libvorbisfile\" with development files and try again" "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "LÖVE needs \"libvorbis and libvorbisfile\", please install \"libvorbis and libvorbisfile\" with development files and try again" "$LINENO" 5 else @@ -20093,8 +20160,8 @@ pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for theoradec" >&5 -$as_echo_n "checking for theoradec... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for theora" >&5 +$as_echo_n "checking for theora... " >&6; } if test -n "$theora_CFLAGS"; then pkg_cv_theora_CFLAGS="$theora_CFLAGS" @@ -20134,7 +20201,7 @@ if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -20152,7 +20219,7 @@ as_fn_error $? "LÖVE needs \"libtheora\", please install \"libtheora\" with development files and try again" "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "LÖVE needs \"libtheora\", please install \"libtheora\" with development files and try again" "$LINENO" 5 else @@ -20776,6 +20843,20 @@ +if test x"$enable_library_dr_flac" = xyes; then + $as_echo "#define LOVE_ENABLE_DR_FLAC /**/" >>confdefs.h + +fi + if test x$enable_library_dr_flac = xyes; then + LOVE_LIBRARY_DR_FLAC_TRUE= + LOVE_LIBRARY_DR_FLAC_FALSE='#' +else + LOVE_LIBRARY_DR_FLAC_TRUE='#' + LOVE_LIBRARY_DR_FLAC_FALSE= +fi + + + if test x"$enable_library_enet" = xyes; then $as_echo "#define LOVE_ENABLE_ENET /**/" >>confdefs.h @@ -21306,6 +21387,10 @@ as_fn_error $? "conditional \"LOVE_LIBRARY_DDSPARSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${LOVE_LIBRARY_DR_FLAC_TRUE}" && test -z "${LOVE_LIBRARY_DR_FLAC_FALSE}"; then + as_fn_error $? "conditional \"LOVE_LIBRARY_DR_FLAC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${LOVE_LIBRARY_ENET_TRUE}" && test -z "${LOVE_LIBRARY_ENET_FALSE}"; then as_fn_error $? "conditional \"LOVE_LIBRARY_ENET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -21771,7 +21856,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by love $as_me 11.1, which was +This file was extended by love $as_me 11.3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -21837,7 +21922,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -love config.status 11.1 +love config.status 11.3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -21956,7 +22041,7 @@ # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -22954,29 +23039,35 @@ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -22994,53 +23085,48 @@ q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)$/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; "libtool":C) diff -Nru love-11.1/configure.ac love-11.3/configure.ac --- love-11.1/configure.ac 2018-04-15 18:31:50.000000000 +0000 +++ love-11.3/configure.ac 2019-10-27 13:45:08.000000000 +0000 @@ -1,4 +1,4 @@ -AC_INIT([love], [11.1]) +AC_INIT([love], [11.3]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([platform/unix]) AC_CONFIG_MACRO_DIR([platform/unix/m4]) @@ -63,6 +63,7 @@ ACLOVE_DEP_SDL2 ACLOVE_DEP_LIBM ACLOVE_DEP_ZLIB +ACLOVE_DEP_PTHREAD # Conditional dependencies AS_VAR_IF([enable_module_audio], [yes], [ACLOVE_DEP_OPENAL], []) diff -Nru love-11.1/configure-modules-post.ac love-11.3/configure-modules-post.ac --- love-11.1/configure-modules-post.ac 2018-04-15 18:31:52.000000000 +0000 +++ love-11.3/configure-modules-post.ac 2019-10-27 13:45:11.000000000 +0000 @@ -130,6 +130,12 @@ fi AM_CONDITIONAL([LOVE_LIBRARY_DDSPARSE], [test x$enable_library_ddsparse = xyes]) +AH_TEMPLATE([LOVE_ENABLE_DR_FLAC], []) +if test x"$enable_library_dr_flac" = xyes; then + AC_DEFINE([LOVE_ENABLE_DR_FLAC], []) +fi +AM_CONDITIONAL([LOVE_LIBRARY_DR_FLAC], [test x$enable_library_dr_flac = xyes]) + AH_TEMPLATE([LOVE_ENABLE_ENET], []) if test x"$enable_library_enet" = xyes; then AC_DEFINE([LOVE_ENABLE_ENET], []) diff -Nru love-11.1/debian/changelog love-11.3/debian/changelog --- love-11.1/debian/changelog 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/changelog 2020-02-04 00:41:24.000000000 +0000 @@ -1,3 +1,18 @@ +love (11.3-1) unstable; urgency=medium + + * Team upload. + * New upstream release. + * Bump Standards-Version to 4.5.0. + - declare that d/rules does not require root + * Update debhelper compat to 12. + * Drop remaining big-endian architectures. (Closes: #906925) + * Build with stb_image.h from libstb-dev instead of embedded copy. + (Closes: #949634) + * Update copyrights. + * Remove references to removed -doc package. + + -- Reiner Herrmann Tue, 04 Feb 2020 23:58:08 +0100 + love (11.1-2) unstable; urgency=medium * Team upload. diff -Nru love-11.1/debian/clean love-11.3/debian/clean --- love-11.1/debian/clean 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/debian/clean 2020-02-04 00:41:24.000000000 +0000 @@ -0,0 +1 @@ +src/libraries/stb/stb_image.h diff -Nru love-11.1/debian/compat love-11.3/debian/compat --- love-11.1/debian/compat 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -11 diff -Nru love-11.1/debian/control love-11.3/debian/control --- love-11.1/debian/control 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/control 2020-02-04 00:41:24.000000000 +0000 @@ -5,7 +5,7 @@ Uploaders: Miriam Ruiz Build-Depends: - debhelper (>= 11), + debhelper-compat (= 12), libfreetype6-dev, liblua5.1-0-dev, libluajit-5.1-dev [!alpha !ia64 !riscv64 !sh4 !s390x], @@ -15,6 +15,7 @@ libopenal-dev, libphysfs-dev, libsdl2-dev, + libstb-dev, libtheora-dev, libtool, libvorbis-dev, @@ -22,13 +23,14 @@ pkg-config, zip, zlib1g-dev -Standards-Version: 4.2.0 +Standards-Version: 4.5.0 +Rules-Requires-Root: no Homepage: https://love2d.org/ Vcs-Git: https://salsa.debian.org/games-team/love.git Vcs-Browser: https://salsa.debian.org/games-team/love Package: love -Architecture: alpha any-i386 any-amd64 arm64 armel armhf ia64 mips64el mipsel ppc64el powerpc ppc64 riscv64 sh4 x32 +Architecture: alpha any-i386 any-amd64 arm64 armel armhf ia64 mips64el mipsel ppc64el riscv64 sh4 x32 Depends: ${misc:Depends}, ${shlibs:Depends} @@ -45,28 +47,3 @@ independent of operating system. By relying on the Lua scripting language for game-specific programming, it allows even the novice game creator to quickly and efficiently develop an idea into a fully working game. - -#Package: love-doc -#Section: doc -#Architecture: all -#Depends: -# ${misc:Depends} -#Suggests: -# love -#Breaks: -# love (<< 0.9.1-2) -#Replaces: -# love (<< 0.9.1-2) -#Description: 2D game development framework - documentation -# LÖVE was created to be a user-friendly engine in which simple (or -# complicated) games could be made without having extensive knowledge -# of system or graphics functions and without having to dedicate time -# towards developing the same engine features time and time again. -# . -# Developed with cross-platform implementation in mind, it utilizes the -# latest open source libraries to deliver a similar game experience, -# independent of operating system. By relying on the Lua scripting language -# for game-specific programming, it allows even the novice game creator to -# quickly and efficiently develop an idea into a fully working game. -# . -# This package includes the Reference Manual for LÖVE. diff -Nru love-11.1/debian/copyright love-11.3/debian/copyright --- love-11.1/debian/copyright 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/copyright 2020-02-04 00:41:24.000000000 +0000 @@ -4,7 +4,7 @@ Source: https://love2d.org/ Files: * -Copyright: Copyright (c) 2006-2018 LOVE Development Team +Copyright: Copyright (c) 2006-2019 LOVE Development Team Comment: Upstream Authors: Michael Enger Anders Ruud @@ -20,12 +20,6 @@ License: love-artwork Comment: Downloaded from http://love2d.org/logos/, which is now a broken link. -#Files: docs/* -#Copyright: Copyright (C) 2006-2011 LÖVE Development Team. All rights reserved. -#License: FreeBSD-doc -#Comment: -# Downloaded from https://love2d.org/wiki/love on the 11th of Apr. 2014 - Files: platform/unix/love.6 Copyright: 2008-2011 Miriam Ruiz 2013-2018 Bart van Strien @@ -35,6 +29,10 @@ Copyright: 2006-2012 Erin Catto License: Zlib +Files: src/libraries/dr_flac/* +Copyright: 2018 David Reid +License: Unlicense or MIT-no-attribution + Files: src/libraries/utf8/* Copyright: Copyright 2006 Nemanja Trifunovic License: Boost-Software-License @@ -68,7 +66,7 @@ Comment: copy of version 1.3.13; https://github.com/lsalzman/enet Files: src/libraries/ddsparse/* -Copyright: 2013-2017 Alex Szpakowski +Copyright: 2013-2019 Alex Szpakowski License: Zlib Files: src/libraries/Wuff/* @@ -84,8 +82,9 @@ Files: src/libraries/glslang/* Copyright: 2002-2005 3Dlabs Inc. Ltd. 2012-2016 LunarG, Inc. - 2015-2017 Google, Inc. + 2015-2018 Google, Inc. 2002-2010 The ANGLE Project Authors. + 2017 ARM Limited. License: BSD-3-Clause Files: src/libraries/glslang/glslang/MachineIndependent/preprocessor/* @@ -117,7 +116,7 @@ License: MIT or Unlicense Files: src/libraries/tinyexr/* -Copyright: 2014-2017 Syoyo Fujita +Copyright: 2014-2019 Syoyo Fujita 2002 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC License: BSD-3-Clause @@ -164,6 +163,22 @@ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +License: MIT-no-attribution + 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. + . + 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. + License: love-artwork This artwork is provided 'as-is', without any express or implied warranty. In no event will the creators be held liable for any damages @@ -181,31 +196,6 @@ misrepresented as being the original artwork. 3. This notice may not be removed or altered from any vector distribution. -#License: FreeBSD-doc -# Redistribution and use in source (XML) and compiled forms (HTML) with or -# without modification, are permitted provided that the following conditions -# are met: -# . -# 1. Redistributions of source code (XML) must retain the above copyright -# notice, this list of conditions and the following disclaimer as the first -# lines of this file unmodified. -# . -# 2. Redistributions in compiled form (HTML) must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the distribution. -# . -# THIS DOCUMENTATION IS PROVIDED BY THE LOVE DEVELOPMENT TEAM "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE LOVE DEVELOPMENT TEAM BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY -# OF SUCH DAMAGE. - License: Boost-Software-License Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by diff -Nru love-11.1/debian/love-doc.doc-base love-11.3/debian/love-doc.doc-base --- love-11.1/debian/love-doc.doc-base 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/love-doc.doc-base 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -Document: love-doc -Title: LÖVE 0.9.0 Reference Manual -Author: LÖVE Development Team -Abstract: This manual is the official - documentation for the game development - framework LÖVE release 0.9.0, obtained - from the wiki pages -Section: Programming - -Format: HTML -Index: /usr/share/doc/love/html/love.html -Files: /usr/share/doc/love/html/*.html diff -Nru love-11.1/debian/love-doc.install love-11.3/debian/love-doc.install --- love-11.1/debian/love-doc.install 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/love-doc.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -demos/*.love usr/share/doc/love/demos/ -doc/* usr/share/doc/love/html/ diff -Nru love-11.1/debian/love-doc.lintian-overrides love-11.3/debian/love-doc.lintian-overrides --- love-11.1/debian/love-doc.lintian-overrides 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/love-doc.lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -# LGPL is in the copyright file but does not apply to any of Love -love-doc binary: copyright-should-refer-to-common-license-file-for-lgpl diff -Nru love-11.1/debian/love.postinst love-11.3/debian/love.postinst --- love-11.1/debian/love.postinst 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/love.postinst 2020-02-04 00:41:24.000000000 +0000 @@ -23,12 +23,12 @@ update-alternatives --quiet --install \ /usr/bin/love \ love \ - /usr/bin/love-11.1 \ + /usr/bin/love-11.3 \ 10 update-alternatives --quiet --install \ /usr/share/man/man6/love.6.gz \ love.6.gz \ - /usr/share/man/man6/love-11.1.6.gz \ + /usr/share/man/man6/love-11.3.6.gz \ 10 if which update-binfmts >/dev/null; then update-binfmts --import love diff -Nru love-11.1/debian/love.prerm love-11.3/debian/love.prerm --- love-11.1/debian/love.prerm 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/love.prerm 2020-02-04 00:41:24.000000000 +0000 @@ -24,10 +24,10 @@ fi update-alternatives --quiet --remove \ love \ - /usr/bin/love-11.1 + /usr/bin/love-11.3 update-alternatives --quiet --remove \ love.6.gz \ - /usr/share/man/man6/love-11.1.6.gz + /usr/share/man/man6/love-11.3.6.gz ;; failed-upgrade) diff -Nru love-11.1/debian/rules love-11.3/debian/rules --- love-11.1/debian/rules 2018-08-04 14:05:52.000000000 +0000 +++ love-11.3/debian/rules 2020-02-04 00:41:24.000000000 +0000 @@ -17,6 +17,7 @@ dh $@ override_dh_auto_configure: + ln -sf /usr/include/stb/stb_image.h src/libraries/stb/stb_image.h dh_auto_configure -- --disable-shared --enable-static --with-lua=$(LUA_IMPL) # rebuild C++ header files: cd src/scripts/ && lua auto.lua boot nogame diff -Nru love-11.1/license.txt love-11.3/license.txt --- love-11.1/license.txt 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/license.txt 2019-10-27 13:44:49.000000000 +0000 @@ -6,7 +6,7 @@ - LOVE Website: https://love2d.org/ License: zlib - Copyright (c) 2006-2018 LOVE Development Team + Copyright (c) 2006-2019 LOVE Development Team - ENet Website: http://enet.bespin.org/index.html @@ -74,6 +74,12 @@ You can contact the author at : - xxHash source repository : https://github.com/Cyan4973/xxHash + - dr_flac + Website: https://github.com/mackron/dr_libs + Source download: https://github.com/mackron/dr_libs/blob/41bc0e8/dr_flac.h + License: MIT/Expat + Copyright 2018 David Reid + - libmpg123 Website: http://www.mpg123.de/ Source download: http://sourceforge.net/projects/mpg123/files/latest/download diff -Nru love-11.1/Makefile.in love-11.3/Makefile.in --- love-11.1/Makefile.in 2018-04-15 18:32:01.000000000 +0000 +++ love-11.3/Makefile.in 2019-10-27 13:45:21.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -181,7 +181,7 @@ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck + cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, @@ -448,8 +448,8 @@ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -722,7 +722,10 @@ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ diff -Nru love-11.1/platform/unix/ar-lib love-11.3/platform/unix/ar-lib --- love-11.1/platform/unix/ar-lib 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/ar-lib 2018-09-18 13:06:54.000000000 +0000 @@ -4,7 +4,7 @@ me=ar-lib scriptversion=2012-03-01.08; # UTC -# Copyright (C) 2010-2017 Free Software Foundation, Inc. +# Copyright (C) 2010-2018 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify @@ -18,7 +18,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff -Nru love-11.1/platform/unix/compile love-11.3/platform/unix/compile --- love-11.1/platform/unix/compile 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/compile 2018-09-18 13:06:54.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -340,7 +340,7 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru love-11.1/platform/unix/config.guess love-11.3/platform/unix/config.guess --- love-11.1/platform/unix/config.guess 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/config.guess 2018-09-18 13:06:54.000000000 +0000 @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2017-05-27' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -107,9 +107,9 @@ dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; + ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,14 +132,14 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +149,20 @@ LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -169,30 +176,30 @@ # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -208,10 +215,10 @@ ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -219,46 +226,55 @@ # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -310,28 +326,19 @@ # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -343,7 +350,7 @@ echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -370,19 +377,19 @@ sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -395,13 +402,13 @@ SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -410,25 +417,25 @@ ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -439,44 +446,44 @@ # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -485,23 +492,23 @@ #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -527,17 +534,17 @@ AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -554,7 +561,7 @@ echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -566,14 +573,14 @@ if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -584,7 +591,7 @@ exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -598,7 +605,7 @@ exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -607,18 +614,18 @@ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -633,28 +640,28 @@ echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -687,13 +694,13 @@ exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -712,15 +719,15 @@ HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -745,11 +752,11 @@ exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -758,7 +765,7 @@ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -766,9 +773,9 @@ exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -793,128 +800,109 @@ echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -928,63 +916,63 @@ esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -998,70 +986,70 @@ #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1075,34 +1063,34 @@ # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1112,12 +1100,12 @@ *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1127,9 +1115,9 @@ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1149,9 +1137,9 @@ exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1171,9 +1159,9 @@ test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1182,28 +1170,28 @@ test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1214,7 +1202,7 @@ *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1234,23 +1222,23 @@ exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1269,39 +1257,39 @@ echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ @@ -1329,7 +1317,7 @@ # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1337,22 +1325,25 @@ UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk${UNAME_RELEASE} + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1361,7 +1352,7 @@ echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 @@ -1372,7 +1363,7 @@ else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1393,14 +1384,14 @@ echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1409,32 +1400,44 @@ echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff -Nru love-11.1/platform/unix/config.sub love-11.3/platform/unix/config.sub --- love-11.1/platform/unix/config.sub 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/config.sub 2018-09-18 13:06:54.000000000 +0000 @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2017-04-02' +timestamp='2018-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -57,7 +57,7 @@ Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +67,7 @@ version="\ GNU config.sub ($timestamp) -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -94,7 +94,7 @@ *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -112,7 +112,7 @@ # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ @@ -120,16 +120,16 @@ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac @@ -178,44 +178,44 @@ ;; -sco6) os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 @@ -227,10 +227,7 @@ os=-lynxos ;; -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos @@ -299,7 +296,7 @@ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ + | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ @@ -316,7 +313,6 @@ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ - | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -337,7 +333,7 @@ basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown @@ -366,7 +362,7 @@ ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. @@ -461,7 +457,7 @@ # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-unknown + basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -495,7 +491,7 @@ basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -540,7 +536,7 @@ os=-linux ;; blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -548,13 +544,13 @@ os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -643,7 +639,7 @@ basic_machine=rs6000-bull os=-bosx ;; - dpx2* | dpx2*-bull) + dpx2*) basic_machine=m68k-bull os=-sysv3 ;; @@ -652,7 +648,7 @@ os=$os"spe" ;; e500v[12]-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) @@ -744,9 +740,6 @@ hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppa-next) - os=-nextstep3 - ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -759,26 +752,26 @@ basic_machine=i370-ibm ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) + vsta) basic_machine=i386-unknown os=-vsta ;; @@ -797,19 +790,16 @@ os=-sysv ;; leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; - m88k-omron*) - basic_machine=m88k-omron - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -841,10 +831,10 @@ os=-mint ;; mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -863,7 +853,7 @@ os=-msdos ;; ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc @@ -905,7 +895,7 @@ basic_machine=v70-nec os=-sysv ;; - next | m*-next ) + next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) @@ -950,6 +940,9 @@ nsr-tandem) basic_machine=nsr-tandem ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; nsx-tandem) basic_machine=nsx-tandem ;; @@ -985,7 +978,7 @@ os=-linux ;; parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -1001,7 +994,7 @@ basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -1016,16 +1009,16 @@ basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1035,23 +1028,23 @@ ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1105,17 +1098,10 @@ sequent) basic_machine=i386-sequent ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; sh5el) basic_machine=sh5le-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) + simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1134,7 +1120,7 @@ os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1248,9 +1234,6 @@ basic_machine=a29k-wrs os=-vxworks ;; - wasm32) - basic_machine=wasm32-unknown - ;; w65*) basic_machine=w65-wdc os=-none @@ -1259,6 +1242,9 @@ basic_machine=hppa1.1-winbond os=-proelf ;; + x64) + basic_machine=x86_64-pc + ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1267,20 +1253,12 @@ basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; none) basic_machine=none-none os=-none @@ -1309,10 +1287,6 @@ vax) basic_machine=vax-dec ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; pdp11) basic_machine=pdp11-dec ;; @@ -1322,9 +1296,6 @@ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; cydra) basic_machine=cydra-cydrome ;; @@ -1344,7 +1315,7 @@ # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac @@ -1352,10 +1323,10 @@ # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1366,8 +1337,8 @@ if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases that might get confused + # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux @@ -1378,18 +1349,19 @@ -solaris) os=-solaris2 ;; - -svr4*) - os=-sysv4 - ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. + # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ @@ -1399,25 +1371,26 @@ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1434,12 +1407,12 @@ -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1448,10 +1421,10 @@ os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1462,12 +1435,6 @@ -wince*) os=-wince ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; -utek*) os=-bsd ;; @@ -1492,7 +1459,7 @@ -nova*) os=-rtmk-nova ;; - -ns2 ) + -ns2) os=-nextstep2 ;; -nsk*) @@ -1514,7 +1481,7 @@ -oss*) os=-sysv3 ;; - -svr4) + -svr4*) os=-sysv4 ;; -svr3) @@ -1529,24 +1496,28 @@ -ose*) os=-ose ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; - -aros*) - os=-aros - ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; -nacl*) ;; -ios) @@ -1556,7 +1527,7 @@ *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1652,9 +1623,6 @@ *-be) os=-beos ;; - *-haiku) - os=-haiku - ;; *-ibm) os=-aix ;; @@ -1694,7 +1662,7 @@ m88k-omron*) os=-luna ;; - *-next ) + *-next) os=-nextstep ;; *-sequent) @@ -1709,9 +1677,6 @@ i370-*) os=-mvs ;; - *-next) - os=-nextstep3 - ;; *-gould) os=-sysv ;; @@ -1821,15 +1786,15 @@ vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$basic_machine$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff -Nru love-11.1/platform/unix/debian/changelog.in love-11.3/platform/unix/debian/changelog.in --- love-11.1/platform/unix/debian/changelog.in 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/platform/unix/debian/changelog.in 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ -love@LOVE_SUFFIX@ (0.11.0~pre3420ppa3) trusty; urgency=medium +love@LOVE_SUFFIX@ (11.2~pre3458ppa1) trusty; urgency=medium * Upstream testing release - -- Bart van Strien Sat, 31 Mar 2018 13:50:30 +0200 + -- Bart van Strien Tue, 10 Jul 2018 19:22:30 +0200 diff -Nru love-11.1/platform/unix/debian/control.in love-11.3/platform/unix/debian/control.in --- love-11.1/platform/unix/debian/control.in 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/platform/unix/debian/control.in 2019-10-27 13:44:49.000000000 +0000 @@ -35,7 +35,8 @@ Package: love@LOVE_SUFFIX@ Architecture: any Depends: ${misc:Depends}, - ${shlibs:Depends} + ${shlibs:Depends}, + liblove@LOVE_SUFFIX@0 (= ${binary:Version}) Description: 2D game engine LOVE is a free 2D game engine which enables easy game creation in Lua. diff -Nru love-11.1/platform/unix/depcomp love-11.3/platform/unix/depcomp --- love-11.1/platform/unix/depcomp 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/depcomp 2018-09-18 13:06:54.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -783,7 +783,7 @@ # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru love-11.1/platform/unix/deps.m4 love-11.3/platform/unix/deps.m4 --- love-11.1/platform/unix/deps.m4 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/platform/unix/deps.m4 2019-10-27 13:44:49.000000000 +0000 @@ -20,7 +20,12 @@ AC_SEARCH_LIBS([sqrt], [m], [], [LOVE_MSG_ERROR([the C math library])])]) AC_DEFUN([ACLOVE_DEP_SDL2], [ - AM_PATH_SDL2([], [], [LOVE_MSG_ERROR([SDL 2])])]) + aclove_sdl2_found=no + AM_PATH_SDL2([], [aclove_sdl2_found=yes], []) + AS_VAR_IF([aclove_sdl2_found], [no], [LOVE_MSG_ERROR([SDL 2])], [])]) + +AC_DEFUN([ACLOVE_DEP_PTHREAD], [ + AC_SEARCH_LIBS([pthread_create], [pthread], [], [LOVE_MSG_ERROR([the POSIX threads library])])]) # does not use pkg-config because of the FILE_OFFSET_BITS.. bit AC_DEFUN([ACLOVE_DEP_MPG123], [ diff -Nru love-11.1/platform/unix/install-sh love-11.3/platform/unix/install-sh --- love-11.1/platform/unix/install-sh 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/install-sh 2018-09-18 13:06:54.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -271,15 +271,18 @@ fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else dstdir=`dirname "$dst"` @@ -288,6 +291,11 @@ fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then @@ -324,34 +332,43 @@ # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi - rmdir "$tmpdir/d" "$tmpdir" + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; @@ -427,8 +444,8 @@ else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 @@ -493,7 +510,7 @@ done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru love-11.1/platform/unix/love.6 love-11.3/platform/unix/love.6 --- love-11.1/platform/unix/love.6 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/platform/unix/love.6 2019-10-27 13:44:49.000000000 +0000 @@ -12,7 +12,7 @@ .\" 3. This notice may not be removed or altered from any source distribution. .Dd March 31, 2018 .Dt LOVE 6 -.Os LÖVE 11.1 +.Os LÖVE 11.3 .Sh NAME .Nm love .Nd 2D game development framework diff -Nru love-11.1/platform/unix/ltmain.sh love-11.3/platform/unix/ltmain.sh --- love-11.1/platform/unix/ltmain.sh 2018-03-14 08:33:39.000000000 +0000 +++ love-11.3/platform/unix/ltmain.sh 2019-09-30 12:26:46.000000000 +0000 @@ -1,12 +1,12 @@ #! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2016-02-21.11 +## by inline-source v2018-07-24.06 -# libtool (GNU libtool) 2.4.6.40-6ca5-dirty +# libtool (GNU libtool) 2.4.6.42-b88ce # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -31,8 +31,8 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.6.40-6ca5-dirty -package_revision=2.4.6.40 +VERSION=2.4.6.42-b88ce +package_revision=2.4.6.42 ## ------ ## @@ -64,7 +64,7 @@ # libraries, which are installed to $pkgauxdir. # Set a version string for this script. -scriptversion=2017-04-19.12; # UTC +scriptversion=2018-07-24.06; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 @@ -72,7 +72,7 @@ # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Copyright (C) 2004-2017 Bootstrap Authors +# Copyright (C) 2004-2018 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 3 or later @@ -1497,7 +1497,7 @@ # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Copyright (C) 2010-2017 Bootstrap Authors +# Copyright (C) 2010-2018 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license # , and GPL version 3 or later @@ -1510,7 +1510,7 @@ # # Set a version string for this script. -scriptversion=2016-03-06.01; # UTC +scriptversion=2018-07-24.06; # UTC ## ------ ## @@ -2171,12 +2171,12 @@ # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. -scriptversion='(GNU libtool) 2.4.6.40-6ca5-dirty' +scriptversion='(GNU libtool) 2.4.6.42-b88ce' # func_echo ARG... @@ -2267,7 +2267,7 @@ compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6.40-6ca5-dirty + version: $progname (GNU libtool) 2.4.6.42-b88ce automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` diff -Nru love-11.1/platform/unix/m4/libtool.m4 love-11.3/platform/unix/m4/libtool.m4 --- love-11.1/platform/unix/m4/libtool.m4 2018-03-14 08:33:39.000000000 +0000 +++ love-11.3/platform/unix/m4/libtool.m4 2019-09-30 12:26:46.000000000 +0000 @@ -1,6 +1,6 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996-2001, 2003-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2018 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -219,8 +219,8 @@ ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -2587,8 +2587,8 @@ dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' @@ -2644,7 +2644,7 @@ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -4032,7 +4032,7 @@ if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ @@ -4949,7 +4949,7 @@ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -5006,15 +5006,15 @@ case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) @@ -5579,12 +5579,12 @@ cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes @@ -5625,7 +5625,7 @@ fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. @@ -6655,8 +6655,8 @@ cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' diff -Nru love-11.1/platform/unix/m4/lt~obsolete.m4 love-11.3/platform/unix/m4/lt~obsolete.m4 --- love-11.1/platform/unix/m4/lt~obsolete.m4 2018-03-14 08:33:39.000000000 +0000 +++ love-11.3/platform/unix/m4/lt~obsolete.m4 2019-09-30 12:26:46.000000000 +0000 @@ -1,6 +1,6 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007, 2009, 2011-2017 Free Software +# Copyright (C) 2004-2005, 2007, 2009, 2011-2018 Free Software # Foundation, Inc. # Written by Scott James Remnant, 2004. # diff -Nru love-11.1/platform/unix/m4/ltoptions.m4 love-11.3/platform/unix/m4/ltoptions.m4 --- love-11.1/platform/unix/m4/ltoptions.m4 2018-03-14 08:33:39.000000000 +0000 +++ love-11.3/platform/unix/m4/ltoptions.m4 2019-09-30 12:26:46.000000000 +0000 @@ -1,6 +1,6 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004-2005, 2007-2009, 2011-2017 Free Software +# Copyright (C) 2004-2005, 2007-2009, 2011-2018 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # diff -Nru love-11.1/platform/unix/m4/ltsugar.m4 love-11.3/platform/unix/m4/ltsugar.m4 --- love-11.1/platform/unix/m4/ltsugar.m4 2018-03-14 08:33:39.000000000 +0000 +++ love-11.3/platform/unix/m4/ltsugar.m4 2019-09-30 12:26:46.000000000 +0000 @@ -1,6 +1,6 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007-2008, 2011-2017 Free Software +# Copyright (C) 2004-2005, 2007-2008, 2011-2018 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # diff -Nru love-11.1/platform/unix/m4/ltversion.m4 love-11.3/platform/unix/m4/ltversion.m4 --- love-11.1/platform/unix/m4/ltversion.m4 2018-03-14 08:33:39.000000000 +0000 +++ love-11.3/platform/unix/m4/ltversion.m4 2019-09-30 12:26:46.000000000 +0000 @@ -1,6 +1,6 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004, 2011-2017 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2018 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +9,15 @@ # @configure_input@ -# serial 4219 ltversion.m4 +# serial 4221 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.6.40-6ca5-dirty]) -m4_define([LT_PACKAGE_REVISION], [2.4.6.40]) +m4_define([LT_PACKAGE_VERSION], [2.4.6.42-b88ce]) +m4_define([LT_PACKAGE_REVISION], [2.4.6.42]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6.40-6ca5-dirty' -macro_revision='2.4.6.40' +[macro_version='2.4.6.42-b88ce' +macro_revision='2.4.6.42' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff -Nru love-11.1/platform/unix/missing love-11.3/platform/unix/missing --- love-11.1/platform/unix/missing 2017-07-06 14:08:33.000000000 +0000 +++ love-11.3/platform/unix/missing 2018-09-18 13:06:54.000000000 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2016-01-11.22; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ exit $st fi -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software program_details () { @@ -207,7 +207,7 @@ exit $st # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" diff -Nru love-11.1/readme.md love-11.3/readme.md --- love-11.1/readme.md 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/readme.md 2019-10-27 13:44:49.000000000 +0000 @@ -6,15 +6,15 @@ ------------- We use our [wiki][wiki] for documentation. -If you need further help, feel free to ask on our [forums][forums], and last but not least there's the irc channel [#love on OFTC][irc]. +If you need further help, feel free to ask on our [forums][forums], our [Discord server][discord], or our IRC channel [#love on OFTC][irc]. Compilation ----------- -###Windows +### Windows Follow the instructions at the [megasource][megasource] repository page. -###*nix +### *nix Run `platform/unix/automagic` from the repository root, then run ./configure and make. $ platform/unix/automagic @@ -23,20 +23,20 @@ When using a source release, automagic has already been run, and the first step can be skipped. -###Mac OS X +### macOS Download the required frameworks from [here][dependencies] and place them in `/Library/Frameworks/`. Then use the Xcode project found at `platform/xcode/love.xcodeproj` to build the `love-macosx` target. -###iOS -Download the required libraries from [here][dependencies-ios] and place the `include` and `libraries` folders -into the `platform/xcode/ios` folder. +### iOS +Download the `ios-libraries` zip file corresponding to the LÖVE version being used from [here][dependencies-ios], +unzip it, and place the `include` and `libraries` subfolders into LÖVE's `platform/xcode/ios` folder. Then use the Xcode project found at `platform/xcode/love.xcodeproj` to build the `love-ios` target. See `readme-iOS.rtf` for more information. -###Android +### Android Visit the [Android build repository][android-repository] for build instructions. Repository information @@ -53,7 +53,7 @@ Contributing ------------ -The best places to contribute are through the Bitbucket issue tracker and the official IRC channel. +The best places to contribute are through the Bitbucket issue tracker and the official Discord server or IRC channel. For code contributions, pull requests and patches are welcome. Be sure to read the [source code style guide][codestyle]. Builds @@ -76,7 +76,6 @@ - OpenAL - Lua / LuaJIT / LLVM-lua - FreeType -- PhysicsFS - ModPlug - mpg123 - Vorbisfile @@ -85,9 +84,10 @@ [site]: http://love2d.org [wiki]: http://love2d.org/wiki [forums]: http://love2d.org/forums +[discord]: https://discord.gg/rhUets9 [irc]: irc://irc.oftc.net/love [dependencies]: http://love2d.org/sdk -[dependencies-ios]: https://bitbucket.org/rude/love/downloads/love-0.10.0-ios-libraries.zip +[dependencies-ios]: https://bitbucket.org/rude/love/downloads/ [megasource]: https://bitbucket.org/rude/megasource [builds]: http://love2d.org/builds [stableppa]: https://launchpad.net/~bartbes/+archive/love-stable diff -Nru love-11.1/src/common/android.cpp love-11.3/src/common/android.cpp --- love-11.1/src/common/android.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/android.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -90,6 +90,31 @@ return result; } +bool getSafeArea(int &top, int &left, int &bottom, int &right) +{ + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + jclass clazz(env->GetObjectClass(activity)); + jmethodID methodID = env->GetMethodID(clazz, "initializeSafeArea", "()Z"); + bool hasSafeArea = false; + + if (methodID == nullptr) + // NoSuchMethodException is thrown in case methodID is null + env->ExceptionClear(); + else if ((hasSafeArea = env->CallBooleanMethod(activity, methodID))) + { + top = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaTop", "I")); + left = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaLeft", "I")); + bottom = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaBottom", "I")); + right = env->GetIntField(activity, env->GetFieldID(clazz, "safeAreaRight", "I")); + } + + env->DeleteLocalRef(clazz); + env->DeleteLocalRef(activity); + + return hasSafeArea; +} + const char *getSelectedGameFile() { static const char *path = NULL; @@ -123,14 +148,14 @@ JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); jclass activity = env->FindClass("org/love2d/android/GameActivity"); - jmethodID openURL= env->GetStaticMethodID(activity, "openURL", "(Ljava/lang/String;)V"); + jmethodID openURL = env->GetStaticMethodID(activity, "openURL", "(Ljava/lang/String;)Z"); jstring url_jstring = (jstring) env->NewStringUTF(url.c_str()); - env->CallStaticVoidMethod(activity, openURL, url_jstring); + jboolean result = env->CallStaticBooleanMethod(activity, openURL, url_jstring); env->DeleteLocalRef(url_jstring); env->DeleteLocalRef(activity); - return true; + return result; } void vibrate(double seconds) @@ -241,6 +266,59 @@ return result; } +bool hasRecordingPermission() +{ + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + + jclass clazz(env->GetObjectClass(activity)); + jmethodID methodID = env->GetMethodID(clazz, "hasRecordAudioPermission", "()Z"); + jboolean result = false; + + if (methodID == nullptr) + env->ExceptionClear(); + else + result = env->CallBooleanMethod(activity, methodID); + + env->DeleteLocalRef(activity); + env->DeleteLocalRef(clazz); + + return result; +} + + +void requestRecordingPermission() +{ + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + jclass clazz(env->GetObjectClass(activity)); + jmethodID methodID = env->GetMethodID(clazz, "requestRecordAudioPermission", "()V"); + + if (methodID == nullptr) + env->ExceptionClear(); + else + env->CallVoidMethod(activity, methodID); + + env->DeleteLocalRef(clazz); + env->DeleteLocalRef(activity); +} + +void showRecordingPermissionMissingDialog() +{ + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + jclass clazz(env->GetObjectClass(activity)); + jmethodID methodID = env->GetMethodID(clazz, "showRecordingAudioPermissionMissingDialog", "()V"); + + if (methodID == nullptr) + env->ExceptionClear(); + else + env->CallVoidMethod(activity, methodID); + + env->DeleteLocalRef(clazz); + env->DeleteLocalRef(activity); +} + } // android } // love diff -Nru love-11.1/src/common/android.h love-11.3/src/common/android.h --- love-11.1/src/common/android.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/android.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -45,6 +45,12 @@ double getScreenScale(); /** + * Gets the window safe area, e.g. phone with notch display. + * Returns false if safe area is not set. + **/ +bool getSafeArea(int &top, int &left, int &bottom, int &right); + +/** * Gets the selected love file in the device filesystem. **/ const char *getSelectedGameFile(); @@ -68,6 +74,12 @@ bool hasBackgroundMusic(); +bool hasRecordingPermission(); + +void requestRecordingPermission(); + +void showRecordingPermissionMissingDialog(); + } // android } // love diff -Nru love-11.1/src/common/b64.cpp love-11.3/src/common/b64.cpp --- love-11.1/src/common/b64.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/b64.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/b64.h love-11.3/src/common/b64.h --- love-11.1/src/common/b64.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/b64.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Color.h love-11.3/src/common/Color.h --- love-11.1/src/common/Color.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Color.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -135,18 +135,18 @@ return tmp /= s; } -typedef ColorT Color; +typedef ColorT Color32; typedef ColorT Colorf; -inline Color toColor(Colorf cf) +inline Color32 toColor32(Colorf cf) { - return Color((unsigned char) (cf.r * 255.0f), + return Color32((unsigned char) (cf.r * 255.0f), (unsigned char) (cf.g * 255.0f), (unsigned char) (cf.b * 255.0f), (unsigned char) (cf.a * 255.0f)); } -inline Colorf toColorf(Color c) +inline Colorf toColorf(Color32 c) { return Colorf(c.r / 255.0f, c.g / 255.0f, c.b / 255.0f, c.a / 255.0f); } diff -Nru love-11.1/src/common/config.h love-11.3/src/common/config.h --- love-11.1/src/common/config.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/config.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Data.cpp love-11.3/src/common/Data.cpp --- love-11.1/src/common/Data.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Data.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Data.h love-11.3/src/common/Data.h --- love-11.1/src/common/Data.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Data.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/delay.cpp love-11.3/src/common/delay.cpp --- love-11.1/src/common/delay.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/delay.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/delay.h love-11.3/src/common/delay.h --- love-11.1/src/common/delay.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/delay.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/deprecation.cpp love-11.3/src/common/deprecation.cpp --- love-11.1/src/common/deprecation.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/deprecation.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/deprecation.h love-11.3/src/common/deprecation.h --- love-11.1/src/common/deprecation.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/deprecation.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/EnumMap.h love-11.3/src/common/EnumMap.h --- love-11.1/src/common/EnumMap.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/EnumMap.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Exception.cpp love-11.3/src/common/Exception.cpp --- love-11.1/src/common/Exception.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Exception.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Exception.h love-11.3/src/common/Exception.h --- love-11.1/src/common/Exception.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Exception.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/floattypes.cpp love-11.3/src/common/floattypes.cpp --- love-11.1/src/common/floattypes.cpp 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/common/floattypes.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2006-2019 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "floattypes.h" + +#include +#include + +namespace love +{ + +// Code from ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf + +static bool halfInitialized = false; + +// tables for half -> float conversions +static uint32 mantissatable[2048]; +static uint16 offsettable[64]; +static uint32 exponenttable[64]; + +// tables for float -> half conversions +static uint16 basetable[512]; +static uint8 shifttable[512]; + + +static uint32 convertMantissa(uint32 i) +{ + uint32 m = i << 13; // Zero pad mantissa bits + uint32 e = 0; // Zero exponent + + while (!(m & 0x00800000)) // While not normalized + { + e -= 0x00800000; // Decrement exponent (1<<23) + m <<= 1; // Shift mantissa + } + + m &= ~(0x00800000); // Clear leading 1 bit + e += 0x38800000; // Adjust bias ((127-14)<<23) + + return m | e; // Return combined number +} + +void float16Init() +{ + if (halfInitialized) + return; + + halfInitialized = true; + + + // tables for float16 -> float32 conversions. + + mantissatable[0] = 0; + + for (uint32 i = 1; i < 1024; i++) + mantissatable[i] = convertMantissa(i); + + for (uint32 i = 1024; i < 2048; i++) + mantissatable[i] = 0x38000000 + ((i - 1024) << 13); + + exponenttable[0] = 0; + exponenttable[32] = 0x80000000; + + for (uint32 i = 0; i < 31; i++) + exponenttable[i] = i << 23; + + for (uint32 i = 33; i < 63; i++) + exponenttable[i] = 0x80000000 + ((i - 32) << 23); + + exponenttable[31] = 0x47800000; + exponenttable[63] = 0xC7800000; + + for (int i = 0; i < 64; i++) + { + if (i == 0 || i == 32) + offsettable[i] = 0; + else + offsettable[i] = 1024; + } + + + // tables for float32 -> float16 conversions. + + for (uint32 i = 0; i < 256; i++) + { + int e = (int) i - 127; + + if (e < -24) // Very small numbers map to zero + { + basetable[i | 0x000] = 0x0000; + basetable[i | 0x100] = 0x8000; + shifttable[i | 0x000] = 24; + shifttable[i | 0x100] = 24; + } + else if (e < -14) // Small numbers map to denorms + { + basetable[i | 0x000] = (0x0400 >> (-e - 14)); + basetable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000; + shifttable[i | 0x000] = -e - 1; + shifttable[i | 0x100] = -e - 1; + } + else if (e <= 15) // Normal numbers just lose precision + { + basetable[i | 0x000] = ((e + 15) << 10); + basetable[i | 0x100] = ((e + 15) << 10) | 0x8000; + shifttable[i | 0x000] = 13; + shifttable[i | 0x100] = 13; + } + else if (e < 128) // Large numbers map to Infinity + { + basetable[i | 0x000] = 0x7C00; + basetable[i | 0x100] = 0xFC00; + shifttable[i | 0x000] = 24; + shifttable[i | 0x100] = 24; + } + else // Infinity and NaN's stay Infinity and NaN's + { + basetable[i | 0x000] = 0x7C00; + basetable[i | 0x100] = 0xFC00; + shifttable[i | 0x000] = 13; + shifttable[i | 0x100] = 13; + } + } +} + +static inline uint32 asuint32(float f) +{ + union { float f; uint32 u; } conv; + conv.f = f; + return conv.u; +} + +static inline float asfloat32(uint32 u) +{ + union { float f; uint32 u; } conv; + conv.u = u; + return conv.f; +} + +float float16to32(float16 f) +{ + return asfloat32(mantissatable[offsettable[f >> 10] + (f & 0x3FF)] + exponenttable[f >> 10]); +} + +float16 float32to16(float f) +{ + uint32 u = asuint32(f); + return basetable[(u >> 23) & 0x1FF] + ((u & 0x007FFFFF) >> shifttable[(u >> 23) & 0x1FF]); +} + +// Adapted from https://stackoverflow.com/questions/41532085/how-to-pack-unpack-11-and-10-bit-floats-in-javascript-for-webgl2 + +float float11to32(float11 f) +{ + uint16 exponent = f >> 6; + uint16 mantissa = f & 0x3F; + + if (exponent == 0) + return mantissa == 0 ? 0 : powf(2.0f, -14.0f) * (mantissa / 64.0f); + + if (exponent < 31) + return powf(2.0f, exponent - 15) * (1.0f + mantissa / 64.0f); + + return mantissa == 0 ? std::numeric_limits::infinity() : std::numeric_limits::quiet_NaN(); +} + +float11 float32to11(float f) +{ + const uint16 EXPONENT_BITS = 0x1F; + const uint16 EXPONENT_SHIFT = 6; + const uint16 EXPONENT_BIAS = 15; + const uint16 MANTISSA_BITS = 0x3F; + const uint16 MANTISSA_SHIFT = (23 - EXPONENT_SHIFT); + const uint16 MAX_EXPONENT = (EXPONENT_BITS << EXPONENT_SHIFT); + + uint32 u = asuint32(f); + + if (u & 0x80000000) + return 0; // Negative values go to 0. + + // Map exponent to the range [-127,128] + int32 exponent = (int32)((u >> 23) & 0xFF) - 127; + uint32 mantissa = u & 0x007FFFFF; + + if (exponent > 15) // Infinity or NaN + return MAX_EXPONENT | (exponent == 128 ? (mantissa & MANTISSA_BITS) : 0); + else if (exponent <= -15) + return 0; + + exponent += EXPONENT_BIAS; + + return ((uint16)exponent << EXPONENT_SHIFT) | (mantissa >> MANTISSA_SHIFT); +} + +float float10to32(float10 f) +{ + uint16 exponent = f >> 5; + uint16 mantissa = f & 0x1F; + + if (exponent == 0) + return mantissa == 0 ? 0 : powf(2.0f, -14.0f) * (mantissa / 32.0f); + + if (exponent < 31) + return powf(2.0f, exponent - 15) * (1.0f + mantissa / 32.0f); + + return mantissa == 0 ? std::numeric_limits::infinity() : std::numeric_limits::quiet_NaN(); +} + +float10 float32to10(float f) +{ + const uint16 EXPONENT_BITS = 0x1F; + const uint16 EXPONENT_SHIFT = 5; + const uint16 EXPONENT_BIAS = 15; + const uint16 MANTISSA_BITS = 0x1F; + const uint16 MANTISSA_SHIFT = (23 - EXPONENT_SHIFT); + const uint16 MAX_EXPONENT = (EXPONENT_BITS << EXPONENT_SHIFT); + + uint32 u = asuint32(f); + + if (u & 0x80000000) + return 0; // Negative values go to 0. + + // Map exponent to the range [-127,128] + int32 exponent = (int32)((u >> 23) & 0xFF) - 127; + uint32 mantissa = u & 0x007FFFFF; + + if (exponent > 15) // Infinity or NaN + return MAX_EXPONENT | (exponent == 128 ? (mantissa & MANTISSA_BITS) : 0); + else if (exponent <= -15) + return 0; + + exponent += EXPONENT_BIAS; + + return ((uint16)exponent << EXPONENT_SHIFT) | (mantissa >> MANTISSA_SHIFT); +} + +} // love diff -Nru love-11.1/src/common/floattypes.h love-11.3/src/common/floattypes.h --- love-11.1/src/common/floattypes.h 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/common/floattypes.h 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2006-2019 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#pragma once + +#include "int.h" + +namespace love +{ + +typedef uint16 float16; +typedef uint16 float11; +typedef uint16 float10; + +void float16Init(); + +float float16to32(float16 f); +float16 float32to16(float f); + +float float11to32(float11 f); +float11 float32to11(float f); + +float float10to32(float10 f); +float10 float32to10(float f); + +} // love diff -Nru love-11.1/src/common/halffloat.cpp love-11.3/src/common/halffloat.cpp --- love-11.1/src/common/halffloat.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/halffloat.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -/** - * Copyright (c) 2006-2018 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#include "halffloat.h" - -namespace love -{ - -// Code from ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf - -static bool initialized = false; - -// tables for half -> float conversions -static uint32 mantissatable[2048]; -static uint16 offsettable[64]; -static uint32 exponenttable[64]; - -// tables for float -> half conversions -static uint16 basetable[512]; -static uint8 shifttable[512]; - - -static uint32 convertMantissa(uint32 i) -{ - uint32 m = i << 13; // Zero pad mantissa bits - uint32 e = 0; // Zero exponent - - while (!(m & 0x00800000)) // While not normalized - { - e -= 0x00800000; // Decrement exponent (1<<23) - m <<= 1; // Shift mantissa - } - - m &= ~(0x00800000); // Clear leading 1 bit - e += 0x38800000; // Adjust bias ((127-14)<<23) - - return m | e; // Return combined number -} - -void halfInit() -{ - if (initialized) - return; - - initialized = true; - - - // tables for half -> float conversions. - - mantissatable[0] = 0; - - for (uint32 i = 1; i < 1024; i++) - mantissatable[i] = convertMantissa(i); - - for (uint32 i = 1024; i < 2048; i++) - mantissatable[i] = 0x38000000 + ((i - 1024) << 13); - - exponenttable[0] = 0; - exponenttable[32] = 0x80000000; - - for (uint32 i = 0; i < 31; i++) - exponenttable[i] = i << 23; - - for (uint32 i = 33; i < 63; i++) - exponenttable[i] = 0x80000000 + ((i - 32) << 23); - - exponenttable[31] = 0x47800000; - exponenttable[63] = 0xC7800000; - - for (int i = 0; i < 64; i++) - { - if (i == 0 || i == 32) - offsettable[i] = 0; - else - offsettable[i] = 1024; - } - - - // tables for float -> half conversions. - - for (uint32 i = 0; i < 256; i++) - { - int e = (int) i - 127; - - if (e < -24) // Very small numbers map to zero - { - basetable[i | 0x000] = 0x0000; - basetable[i | 0x100] = 0x8000; - shifttable[i | 0x000] = 24; - shifttable[i | 0x100] = 24; - } - else if (e < -14) // Small numbers map to denorms - { - basetable[i | 0x000] = (0x0400 >> (-e - 14)); - basetable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000; - shifttable[i | 0x000] = -e - 1; - shifttable[i | 0x100] = -e - 1; - } - else if (e <= 15) // Normal numbers just lose precision - { - basetable[i | 0x000] = ((e + 15) << 10); - basetable[i | 0x100] = ((e + 15) << 10) | 0x8000; - shifttable[i | 0x000] = 13; - shifttable[i | 0x100] = 13; - } - else if (e < 128) // Large numbers map to Infinity - { - basetable[i | 0x000] = 0x7C00; - basetable[i | 0x100] = 0xFC00; - shifttable[i | 0x000] = 24; - shifttable[i | 0x100] = 24; - } - else // Infinity and NaN's stay Infinity and NaN's - { - basetable[i | 0x000] = 0x7C00; - basetable[i | 0x100] = 0xFC00; - shifttable[i | 0x000] = 13; - shifttable[i | 0x100] = 13; - } - } -} - -float halfToFloat(half h) -{ - union { float f; uint32 i; } conv; - - conv.i = mantissatable[offsettable[h >> 10] + (h & 0x3FF)] + exponenttable[h >> 10]; - return conv.f; -} - -half floatToHalf(float f) -{ - union { float f; uint32 i; } conv; - conv.f = f; - - return basetable[(conv.i >> 23) & 0x1FF] + ((conv.i & 0x007FFFFF) >> shifttable[(conv.i >> 23) & 0x1FF]); -} - -} // love diff -Nru love-11.1/src/common/halffloat.h love-11.3/src/common/halffloat.h --- love-11.1/src/common/halffloat.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/halffloat.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2006-2018 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#ifndef LOVE_HALF_FLOAT_H -#define LOVE_HALF_FLOAT_H - -#include "int.h" - -namespace love -{ - -typedef uint16 half; - -void halfInit(); - -float halfToFloat(half h); -half floatToHalf(float f); - -} // love - -#endif // LOVE_HALF_FLOAT_H diff -Nru love-11.1/src/common/int.h love-11.3/src/common/int.h --- love-11.1/src/common/int.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/int.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/ios.h love-11.3/src/common/ios.h --- love-11.1/src/common/ios.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/ios.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,12 @@ #ifdef LOVE_IOS +#include "common/math.h" + #include +struct SDL_Window; + namespace love { namespace ios @@ -67,13 +71,19 @@ /** * Enable mix mode (e.g. with background music apps) and playback with a muted device. **/ -void setAudioMixWithOthers(bool mixEnabled); +bool setAudioMixWithOthers(bool mixEnabled); /** * Returns whether another application is playing audio. **/ bool hasBackgroundMusic(); +/** + * Gets the area in the window that is safe for UI to render to (not covered by + * the status bar, notch, etc.) + **/ +Rect getSafeArea(SDL_Window *window); + } // ios } // love diff -Nru love-11.1/src/common/macosx.h love-11.3/src/common/macosx.h --- love-11.1/src/common/macosx.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/macosx.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/macosx.mm love-11.3/src/common/macosx.mm --- love-11.1/src/common/macosx.mm 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/macosx.mm 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/math.h love-11.3/src/common/math.h --- love-11.1/src/common/math.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/math.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Matrix.cpp love-11.3/src/common/Matrix.cpp --- love-11.1/src/common/Matrix.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Matrix.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -29,6 +29,10 @@ #include #endif +#if defined(LOVE_SIMD_NEON) +#include +#endif + namespace love { @@ -43,9 +47,6 @@ void Matrix4::multiply(const Matrix4 &a, const Matrix4 &b, float t[16]) { - // NOTE: in my testing with ARM NEON instructions (on an iPhone 6 with arm64) - // it performed slightly worse than the regular add/multiply code. Further - // investigation would be useful. #if defined(LOVE_SIMD_SSE) // We can't guarantee 16-bit alignment (e.g. for heap-allocated Matrix4 @@ -70,6 +71,38 @@ _mm_storeu_ps(&t[4*i], col); } +#elif defined(LOVE_SIMD_NEON) + + float32x4_t cola1 = vld1q_f32(&a.e[0]); + float32x4_t cola2 = vld1q_f32(&a.e[4]); + float32x4_t cola3 = vld1q_f32(&a.e[8]); + float32x4_t cola4 = vld1q_f32(&a.e[12]); + + float32x4_t col1 = vmulq_n_f32(cola1, b.e[0]); + col1 = vmlaq_n_f32(col1, cola2, b.e[1]); + col1 = vmlaq_n_f32(col1, cola3, b.e[2]); + col1 = vmlaq_n_f32(col1, cola4, b.e[3]); + + float32x4_t col2 = vmulq_n_f32(cola1, b.e[4]); + col2 = vmlaq_n_f32(col2, cola2, b.e[5]); + col2 = vmlaq_n_f32(col2, cola3, b.e[6]); + col2 = vmlaq_n_f32(col2, cola4, b.e[7]); + + float32x4_t col3 = vmulq_n_f32(cola1, b.e[8]); + col3 = vmlaq_n_f32(col3, cola2, b.e[9]); + col3 = vmlaq_n_f32(col3, cola3, b.e[10]); + col3 = vmlaq_n_f32(col3, cola4, b.e[11]); + + float32x4_t col4 = vmulq_n_f32(cola1, b.e[12]); + col4 = vmlaq_n_f32(col4, cola2, b.e[13]); + col4 = vmlaq_n_f32(col4, cola3, b.e[14]); + col4 = vmlaq_n_f32(col4, cola4, b.e[15]); + + vst1q_f32(&t[0], col1); + vst1q_f32(&t[4], col2); + vst1q_f32(&t[8], col3); + vst1q_f32(&t[12], col4); + #else t[0] = (a.e[0]*b.e[0]) + (a.e[4]*b.e[1]) + (a.e[8]*b.e[2]) + (a.e[12]*b.e[3]); diff -Nru love-11.1/src/common/Matrix.h love-11.3/src/common/Matrix.h --- love-11.1/src/common/Matrix.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Matrix.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Memoizer.cpp love-11.3/src/common/Memoizer.cpp --- love-11.1/src/common/Memoizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Memoizer.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2006-2018 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#include "Memoizer.h" - -#include - -namespace love -{ - -static std::unordered_map objectMap; - -void Memoizer::add(void *key, void *val) -{ - objectMap[key] = val; -} - -void Memoizer::remove(void *key) -{ - objectMap.erase(key); -} - -void *Memoizer::find(void *key) -{ - auto it = objectMap.find(key); - - if (it != objectMap.end()) - return it->second; - else - return nullptr; -} - -} // love diff -Nru love-11.1/src/common/Memoizer.h love-11.3/src/common/Memoizer.h --- love-11.1/src/common/Memoizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Memoizer.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2006-2018 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#ifndef LOVE_MEMOIZER_H -#define LOVE_MEMOIZER_H - -namespace love -{ - -class Memoizer -{ -public: - - static void add(void *key, void *val); - static void remove(void *key); - static void *find(void *key); - -}; // Memoizer - -} // love - -#endif // LOVE_MEMOIZER_H diff -Nru love-11.1/src/common/memory.cpp love-11.3/src/common/memory.cpp --- love-11.1/src/common/memory.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/memory.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/memory.h love-11.3/src/common/memory.h --- love-11.1/src/common/memory.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/memory.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Module.cpp love-11.3/src/common/Module.cpp --- love-11.1/src/common/Module.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Module.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Module.h love-11.3/src/common/Module.h --- love-11.1/src/common/Module.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Module.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Object.cpp love-11.3/src/common/Object.cpp --- love-11.1/src/common/Object.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Object.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Object.h love-11.3/src/common/Object.h --- love-11.1/src/common/Object.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Object.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Optional.h love-11.3/src/common/Optional.h --- love-11.1/src/common/Optional.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Optional.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,23 +27,23 @@ template struct Optional { - bool hasValue; T value; + bool hasValue; Optional() - : hasValue(false) - , value(T()) + : value(T()) + , hasValue(false) {} Optional(T val) - : hasValue(true) - , value(val) + : value(val) + , hasValue(true) {} void set(T val) { - hasValue = true; value = val; + hasValue = true; } }; diff -Nru love-11.1/src/common/pixelformat.cpp love-11.3/src/common/pixelformat.cpp --- love-11.1/src/common/pixelformat.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/pixelformat.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -175,5 +175,37 @@ return 0; } } + +int getPixelFormatColorComponents(PixelFormat format) +{ + switch (format) + { + case PIXELFORMAT_R8: + case PIXELFORMAT_R16: + case PIXELFORMAT_R16F: + case PIXELFORMAT_R32F: + return 1; + case PIXELFORMAT_RG8: + case PIXELFORMAT_RG16: + case PIXELFORMAT_RG16F: + case PIXELFORMAT_RG32F: + case PIXELFORMAT_LA8: + return 2; + case PIXELFORMAT_RGB565: + case PIXELFORMAT_RG11B10F: + return 3; + case PIXELFORMAT_RGBA8: + case PIXELFORMAT_sRGBA8: + case PIXELFORMAT_RGBA16: + case PIXELFORMAT_RGBA16F: + case PIXELFORMAT_RGBA32F: + case PIXELFORMAT_RGBA4: + case PIXELFORMAT_RGB5A1: + case PIXELFORMAT_RGB10A2: + return 4; + default: + return 0; + } +} } // love diff -Nru love-11.1/src/common/pixelformat.h love-11.3/src/common/pixelformat.h --- love-11.1/src/common/pixelformat.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/pixelformat.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -51,11 +51,11 @@ PIXELFORMAT_LA8, // Same as RG8, but accessed as (L, L, L, A) // packed formats - PIXELFORMAT_RGBA4, - PIXELFORMAT_RGB5A1, - PIXELFORMAT_RGB565, - PIXELFORMAT_RGB10A2, - PIXELFORMAT_RG11B10F, + PIXELFORMAT_RGBA4, // LSB->MSB: [a, b, g, r] + PIXELFORMAT_RGB5A1, // LSB->MSB: [a, b, g, r] + PIXELFORMAT_RGB565, // LSB->MSB: [b, g, r] + PIXELFORMAT_RGB10A2, // LSB->MSB: [r, g, b, a] + PIXELFORMAT_RG11B10F, // LSB->MSB: [r, g, b] // depth/stencil formats PIXELFORMAT_STENCIL8, @@ -135,4 +135,9 @@ **/ size_t getPixelFormatSize(PixelFormat format); +/** + * Gets the number of color components in the given pixel format. + **/ +int getPixelFormatColorComponents(PixelFormat format); + } // love diff -Nru love-11.1/src/common/Reference.cpp love-11.3/src/common/Reference.cpp --- love-11.1/src/common/Reference.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Reference.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -19,6 +19,7 @@ **/ #include "Reference.h" +#include "runtime.h" namespace love { diff -Nru love-11.1/src/common/Reference.h love-11.3/src/common/Reference.h --- love-11.1/src/common/Reference.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Reference.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -21,8 +21,7 @@ #ifndef LOVE_REFERENCE_H #define LOVE_REFERENCE_H -// LOVE -#include "runtime.h" +struct lua_State; namespace love { diff -Nru love-11.1/src/common/runtime.cpp love-11.3/src/common/runtime.cpp --- love-11.1/src/common/runtime.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/runtime.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -31,8 +31,17 @@ #include #include #include +#include +#include #include +// VS2013 doesn't support alignof +#if defined(_MSC_VER) && _MSC_VER <= 1800 +#define LOVE_ALIGNOF(x) __alignof(x) +#else +#define LOVE_ALIGNOF(x) alignof(x) +#endif + namespace love { @@ -84,6 +93,38 @@ return 1; } +// For use with the love object pointer -> Proxy pointer registry. +// Using the pointer directly via lightuserdata would be ideal, but LuaJIT +// cannot use lightuserdata with more than 47 bits whereas some newer arm64 +// architectures allow pointers which use more than that. +static lua_Number luax_computeloveobjectkey(lua_State *L, love::Object *object) +{ + // love objects should be allocated on the heap, and thus are subject + // to the alignment rules of operator new / malloc. Lua numbers (doubles) + // can store all possible integers up to 2^53. We can store pointers that + // use more than 53 bits if their alignment is guaranteed to be more than 1. + // For example an alignment requirement of 8 means we can shift the + // pointer's bits by 3. + const size_t minalign = LOVE_ALIGNOF(std::max_align_t); + uintptr_t key = (uintptr_t) object; + + if ((key & (minalign - 1)) != 0) + { + luaL_error(L, "Cannot push love object to Lua: unexpected alignment " + "(pointer is %p but alignment should be %d)", object, minalign); + } + + static const size_t shift = (size_t) log2(LOVE_ALIGNOF(std::max_align_t)); + + key >>= shift; + + // Make sure our key isn't larger than 2^53. + if (key > 0x20000000000000ULL) + luaL_error(L, "Cannot push love object to Lua: pointer value %p is too large", object); + + return (lua_Number) key; +} + static int w__release(lua_State *L) { Proxy *p = (Proxy *) lua_touserdata(L, 1); @@ -100,7 +141,8 @@ if (lua_istable(L, -1)) { // loveobjects[object] = nil - lua_pushlightuserdata(L, object); + lua_Number objectkey = luax_computeloveobjectkey(L, object); + lua_pushnumber(L, objectkey); lua_pushnil(L); lua_settable(L, -3); } @@ -209,6 +251,13 @@ lua_pushlstring(L, str.data(), str.size()); } +void luax_pushpointerasstring(lua_State *L, const void *pointer) +{ + char str[sizeof(void *)]; + memcpy(str, &pointer, sizeof(void *)); + lua_pushlstring(L, str, sizeof(void *)); +} + bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue) { lua_getfield(L, table_index, key); @@ -241,7 +290,7 @@ { lua_getfield(L, table_index, key); - int retval; + double retval; if (!lua_isnumber(L, -1)) retval = defaultValue; else @@ -452,7 +501,7 @@ return 0; } -void luax_gettypemetatable(lua_State *L, love::Type &type) +void luax_gettypemetatable(lua_State *L, const love::Type &type) { const char *name = type.getName(); lua_getfield(L, LUA_REGISTRYINDEX, name); @@ -550,14 +599,16 @@ luax_getregistry(L, REGISTRY_OBJECTS); // The table might not exist - it should be insisted in luax_register_type. - if (!lua_istable(L, -1)) + if (lua_isnoneornil(L, -1)) { lua_pop(L, 1); return luax_rawnewtype(L, type, object); } + lua_Number objectkey = luax_computeloveobjectkey(L, object); + // Get the value of loveobjects[object] on the stack. - lua_pushlightuserdata(L, object); + lua_pushnumber(L, objectkey); lua_gettable(L, -2); // If the Proxy userdata isn't in the instantiated types table yet, add it. @@ -567,7 +618,7 @@ luax_rawnewtype(L, type, object); - lua_pushlightuserdata(L, object); + lua_pushnumber(L, objectkey); lua_pushvalue(L, -2); // loveobjects[object] = Proxy. @@ -623,7 +674,7 @@ return 0; } -int luax_convobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn) +int luax_convobj(lua_State *L, const int idxs[], int n, const char *mod, const char *fn) { luax_getfunction(L, mod, fn); for (int i = 0; i < n; i++) @@ -638,6 +689,12 @@ return 0; } +int luax_convobj(lua_State *L, const std::vector& idxs, const char *module, const char *function) +{ + const int *idxPtr = idxs.size() > 0 ? &idxs[0] : nullptr; + return luax_convobj(L, idxPtr, (int) idxs.size(), module, function); +} + int luax_pconvobj(lua_State *L, int idx, const char *mod, const char *fn) { // Convert string to a file. @@ -649,7 +706,7 @@ return ret; } -int luax_pconvobj(lua_State *L, int idxs[], int n, const char *mod, const char *fn) +int luax_pconvobj(lua_State *L, const int idxs[], int n, const char *mod, const char *fn) { luax_getfunction(L, mod, fn); for (int i = 0; i < n; i++) @@ -662,6 +719,12 @@ return ret; } +int luax_pconvobj(lua_State *L, const std::vector& idxs, const char *module, const char *function) +{ + const int *idxPtr = idxs.size() > 0 ? &idxs[0] : nullptr; + return luax_pconvobj(L, idxPtr, (int) idxs.size(), module, function); +} + int luax_insist(lua_State *L, int idx, const char *k) { // Convert to absolute index if necessary. @@ -874,9 +937,39 @@ } } +void luax_runwrapper(lua_State *L, const char *filedata, size_t datalen, const char *filename, const love::Type &type, void *ffifuncs) +{ + luax_gettypemetatable(L, type); + + // Load and execute ImageData.lua, sending the metatable and the ffi + // functions struct pointer as arguments. + if (lua_istable(L, -1)) + { + luaL_loadbuffer(L, filedata, datalen, filename); + lua_pushvalue(L, -2); + if (ffifuncs != nullptr) + luax_pushpointerasstring(L, ffifuncs); + else + lua_pushnil(L); + lua_call(L, 2, 0); + } + + // Pop the metatable. + lua_pop(L, 1); +} + Type *luax_type(lua_State *L, int idx) { return Type::byName(luaL_checkstring(L, idx)); } +int luax_resume(lua_State *L, int nargs) +{ +#if LUA_VERSION_NUM >= 502 + return lua_resume(L, nullptr, nargs); +#else + return lua_resume(L, nargs); +#endif +} + } // love diff -Nru love-11.1/src/common/runtime.h love-11.3/src/common/runtime.h --- love-11.1/src/common/runtime.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/runtime.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -177,6 +177,14 @@ **/ void luax_pushstring(lua_State *L, const std::string &str); +/** + * Pushes a pointer onto the stack as a string (i.e. a new string with a length + * of 4 or 8 will be created, containing the given address in its bytes). + * This is a workaround for lua_pushlightuserdata not working on systems which + * use more than the lower 47 bits of address space, when LuaJIT is used. + **/ +void luax_pushpointerasstring(lua_State *L, const void *pointer); + bool luax_boolflag(lua_State *L, int table_index, const char *key, bool defaultValue); int luax_intflag(lua_State *L, int table_index, const char *key, int defaultValue); @@ -291,7 +299,7 @@ /** * Pushes the metatable of the specified type onto the stack. **/ -void luax_gettypemetatable(lua_State *L, love::Type &type); +void luax_gettypemetatable(lua_State *L, const love::Type &type); /** * Do a table.insert from C @@ -389,11 +397,13 @@ * @param module The module in the love table. * @param function The function in the module. **/ -int luax_convobj(lua_State *L, int idxs[], int n, const char *module, const char *function); +int luax_convobj(lua_State *L, const int idxs[], int n, const char *module, const char *function); +int luax_convobj(lua_State *L, const std::vector& idxs, const char *module, const char *function); // pcall versions of the above int luax_pconvobj(lua_State *L, int idx, const char *module, const char *function); -int luax_pconvobj(lua_State *L, int idxs[], int n, const char *module, const char *function); +int luax_pconvobj(lua_State *L, const int idxs[], int n, const char *module, const char *function); +int luax_pconvobj(lua_State *L, const std::vector& idxs, const char *module, const char *function); /** * 'Insist' that a table 'k' exists in the table at idx. Insistence involves that the @@ -496,6 +506,8 @@ } } +void luax_runwrapper(lua_State *L, const char *filedata, size_t datalen, const char *filename, const love::Type &type, void *ffifuncs); + /** * Calls luax_objlen/lua_rawlen depending on version **/ @@ -543,6 +555,15 @@ } template +T *luax_ffi_checktype(Proxy *p, const love::Type &type = T::type) +{ + // FIXME: We need better type-checking... + if (p == nullptr || p->object == nullptr || p->type == nullptr || !p->type->isa(type)) + return nullptr; + return (T *) p->object; +} + +template T *luax_getmodule(lua_State *L, const love::Type &type) { const char *name = type.getName(); @@ -676,6 +697,12 @@ return 0; } +/** + * Compatibility shim for lua_resume + * Exported because it's used in the launcher + **/ +LOVE_EXPORT int luax_resume(lua_State *L, int nargs); + } // love #endif // LOVE_RUNTIME_H diff -Nru love-11.1/src/common/StringMap.cpp love-11.3/src/common/StringMap.cpp --- love-11.1/src/common/StringMap.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/StringMap.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -22,4 +22,3 @@ // See the header template class std::vector; -template decltype(std::vector().emplace_back("")) std::vector::emplace_back(const char *const&); diff -Nru love-11.1/src/common/StringMap.h love-11.3/src/common/StringMap.h --- love-11.1/src/common/StringMap.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/StringMap.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,6 @@ // getNames(), we end up with multiple copies in the object files. This // declaration means we only emit it once (in StringMap.cpp). extern template class std::vector; -extern template decltype(std::vector().emplace_back("")) std::vector::emplace_back(const char *const&); namespace love { diff -Nru love-11.1/src/common/types.cpp love-11.3/src/common/types.cpp --- love-11.1/src/common/types.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/types.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/types.h love-11.3/src/common/types.h --- love-11.1/src/common/types.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/types.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/utf8.cpp love-11.3/src/common/utf8.cpp --- love-11.1/src/common/utf8.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/utf8.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/utf8.h love-11.3/src/common/utf8.h --- love-11.1/src/common/utf8.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/utf8.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Variant.cpp love-11.3/src/common/Variant.cpp --- love-11.1/src/common/Variant.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Variant.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -58,21 +58,26 @@ data.number = number; } -Variant::Variant(const char *string, size_t len) +Variant::Variant(const char *str, size_t len) { if (len <= MAX_SMALL_STRING_LENGTH) { type = SMALLSTRING; - memcpy(data.smallstring.str, string, len); + memcpy(data.smallstring.str, str, len); data.smallstring.len = (uint8) len; } else { type = STRING; - data.string = new SharedString(string, len); + data.string = new SharedString(str, len); } } +Variant::Variant(const std::string &str) + : Variant(str.c_str(), str.length()) +{ +} + Variant::Variant(void *lightuserdata) : type(LUSERDATA) { @@ -181,12 +186,13 @@ case LUA_TTABLE: { bool success = true; - std::unique_ptr> tableSetPtr; + std::set topTableSet; std::vector> *table = new std::vector>(); - // If we had no tables argument, allocate one now, and store it in our unique_ptr + // We can use a pointer to a stack-allocated variable because it's + // never used after the stack-allocated variable is destroyed. if (tableSet == nullptr) - tableSetPtr.reset(tableSet = new std::set); + tableSet = &topTableSet; // Now make sure this table wasn't already serialised const void *tablePointer = lua_topointer(L, n); diff -Nru love-11.1/src/common/Variant.h love-11.3/src/common/Variant.h --- love-11.1/src/common/Variant.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Variant.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,7 @@ #include "common/int.h" #include +#include #include #include @@ -36,6 +37,8 @@ { public: + static const int MAX_SMALL_STRING_LENGTH = 15; + enum Type { UNKNOWN = 0, @@ -49,26 +52,6 @@ TABLE }; - Variant(); - Variant(bool boolean); - Variant(double number); - Variant(const char *string, size_t len); - Variant(void *lightuserdata); - Variant(love::Type *type, love::Object *object); - Variant(std::vector> *table); - Variant(const Variant &v); - Variant(Variant &&v); - ~Variant(); - - Variant &operator = (const Variant &v); - - Type getType() const { return type; } - - static Variant fromLua(lua_State *L, int n, std::set *tableSet = nullptr); - void toLua(lua_State *L) const; - -private: - class SharedString : public love::Object { public: @@ -77,6 +60,7 @@ : len(len) { str = new char[len+1]; + str[len] = '\0'; memcpy(str, string, len); } virtual ~SharedString() { delete[] str; } @@ -99,10 +83,6 @@ std::vector> *table; }; - static const int MAX_SMALL_STRING_LENGTH = 15; - - Type type; - union Data { bool boolean; @@ -116,7 +96,32 @@ char str[MAX_SMALL_STRING_LENGTH]; uint8 len; } smallstring; - } data; + }; + + Variant(); + Variant(bool boolean); + Variant(double number); + Variant(const char *str, size_t len); + Variant(const std::string &str); + Variant(void *lightuserdata); + Variant(love::Type *type, love::Object *object); + Variant(std::vector> *table); + Variant(const Variant &v); + Variant(Variant &&v); + ~Variant(); + + Variant &operator = (const Variant &v); + + Type getType() const { return type; } + const Data &getData() const { return data; } + + static Variant fromLua(lua_State *L, int n, std::set *tableSet = nullptr); + void toLua(lua_State *L) const; + +private: + + Type type; + Data data; }; // Variant } // love diff -Nru love-11.1/src/common/Vector.cpp love-11.3/src/common/Vector.cpp --- love-11.1/src/common/Vector.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Vector.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/common/Vector.h love-11.3/src/common/Vector.h --- love-11.1/src/common/Vector.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/Vector.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ namespace love { +// All math operators are component-wise. struct Vector2 { float x, y; @@ -43,80 +44,42 @@ : x(v.x), y(v.y) {} - /** - * Gets the length of the Vector. - **/ float getLength() const; float getLengthSquare() const; /** * Normalizes the Vector. * @param length Desired length of the vector. - * @return The old length of the Vector. **/ - float normalize(float length = 1.0); + void normalize(float length = 1.0f); /** * Gets a vector perpendicular to the Vector. * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) - * @return A normal to the Vector. **/ Vector2 getNormal() const; /** * Gets a vector perpendicular to the Vector. * To get the true (normalized) normal, use v.getNormal(1.0f / v.getLength()) - * @param scale factor to apply. - * @return A normal to the Vector. **/ Vector2 getNormal(float scale) const; static inline float dot(const Vector2 &a, const Vector2 &b); static inline float cross(const Vector2 &a, const Vector2 &b); - /** - * Adds a Vector to this Vector. - **/ Vector2 operator + (const Vector2 &v) const; - - /** - * Substracts a Vector from this Vector. - **/ Vector2 operator - (const Vector2 &v) const; - /** - * Component-wise multiplies the Vector by a scalar. - **/ Vector2 operator * (float s) const; - - /** - * Component-wise divides the Vector by a scalar. - **/ Vector2 operator / (float s) const; - /** - * Component-wise negates the Vector. - **/ Vector2 operator - () const; - /** - * Adds a Vector to this Vector, and also saves changes in the first Vector. - **/ void operator += (const Vector2 &v); - - /** - * Subtracts a Vector to this Vector, and also saves changes in the first Vector. - **/ void operator -= (const Vector2 &v); - /** - * Resizes the Vector, and also saves changes in the first Vector. - **/ void operator *= (float s); - - /** - * Resizes the Vector, and also saves changes in the first Vector. - **/ void operator /= (float s); bool operator == (const Vector2 &v) const; @@ -125,6 +88,7 @@ }; // Vector2 +// All math operators are component-wise. struct Vector3 { float x, y, z; @@ -137,69 +101,34 @@ : x(x), y(y), z(z) {} - Vector3(const Vector2 &v) - : x(v.x), y(v.y), z(0.0f) + Vector3(const Vector2 &v, float z = 0.0f) + : x(v.x), y(v.y), z(z) {} - /** - * Gets the length of the Vector. - **/ float getLength() const; float getLengthSquare() const; /** * Normalizes the Vector. * @param length Desired length of the vector. - * @return The old length of the Vector. **/ - float normalize(float length = 1.0); + void normalize(float length = 1.0); static inline float dot(const Vector3 &a, const Vector3 &b); static inline Vector3 cross(const Vector3 &a, const Vector3 &b); - /** - * Adds a Vector to this Vector. - **/ Vector3 operator + (const Vector3 &v) const; - - /** - * Substracts a Vector from this Vector. - **/ Vector3 operator - (const Vector3 &v) const; - /** - * Component-wise multiplies the Vector by a scalar. - **/ Vector3 operator * (float s) const; - - /** - * Component-wise divides the Vector by a scalar. - **/ Vector3 operator / (float s) const; - /** - * Component-wise negates the Vector. - **/ Vector3 operator - () const; - /** - * Adds a Vector to this Vector, and also saves changes in the first Vector. - **/ void operator += (const Vector3 &v); - - /** - * Subtracts a Vector to this Vector, and also saves changes in the first Vector. - **/ void operator -= (const Vector3 &v); - /** - * Resizes the Vector, and also saves changes in the first Vector. - **/ void operator *= (float s); - - /** - * Resizes the Vector, and also saves changes in the first Vector. - **/ void operator /= (float s); bool operator == (const Vector3 &v) const; @@ -208,6 +137,58 @@ }; // Vector3 +// All math operators are component-wise. +struct Vector4 +{ + float x, y, z, w; + + Vector4() + : x(0.0f), y(0.0f), z(0.0f), w(0.0f) + {} + + Vector4(float x, float y, float z, float w) + : x(x), y(y), z(z), w(w) + {} + + Vector4(const Vector2 &v, float z = 0.0f, float w = 0.0f) + : x(v.x), y(v.y), z(z), w(w) + {} + + Vector4(const Vector3 &v, float w = 0.0f) + : x(v.x), y(v.y), z(v.z), w(w) + {} + + float getLength() const; + float getLengthSquare() const; + + /** + * Normalizes the Vector. + * @param length Desired length of the vector. + **/ + void normalize(float length = 1.0); + + static inline float dot(const Vector4 &a, const Vector4 &b); + + Vector4 operator + (const Vector4 &v) const; + Vector4 operator - (const Vector4 &v) const; + + Vector4 operator * (float s) const; + Vector4 operator / (float s) const; + + Vector4 operator - () const; + + void operator += (const Vector4 &v); + void operator -= (const Vector4 &v); + + void operator *= (float s); + void operator /= (float s); + + bool operator == (const Vector4 &v) const; + bool operator != (const Vector4 &v) const; + +}; // Vector4 + + inline float Vector2::getLength() const { return sqrtf(x*x + y*y); @@ -238,14 +219,15 @@ return a.x * b.y - a.y * b.x; } -inline float Vector2::normalize(float length) +inline void Vector2::normalize(float length) { float length_current = getLength(); - if (length_current > 0) - (*this) *= length / length_current; - - return length_current; + { + float m = length / length_current; + x *= m; + y *= m; + } } inline Vector2 Vector2::operator + (const Vector2 &v) const @@ -330,14 +312,16 @@ return Vector3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); } -inline float Vector3::normalize(float length) +inline void Vector3::normalize(float length) { float length_current = getLength(); - if (length_current > 0) - (*this) *= length / length_current; - - return length_current; + { + float m = length / length_current; + x *= m; + y *= m; + z *= m; + } } inline Vector3 Vector3::operator + (const Vector3 &v) const @@ -405,6 +389,104 @@ return x != v.x || y != v.y || z != v.z; } + +inline float Vector4::getLength() const +{ + return sqrtf(x*x + y*y + z*z + w*w); +} + +inline float Vector4::getLengthSquare() const +{ + return x*x + y*y + z*z + w*w; +} + +inline float Vector4::dot(const Vector4 &a, const Vector4 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +inline void Vector4::normalize(float length) +{ + float length_current = getLength(); + if (length_current > 0) + { + float m = length / length_current; + x *= m; + y *= m; + z *= m; + w *= m; + } +} + +inline Vector4 Vector4::operator + (const Vector4 &v) const +{ + return Vector4(x + v.x, y + v.y, z + v.z, w + v.w); +} + +inline Vector4 Vector4::operator - (const Vector4 &v) const +{ + return Vector4(x - v.x, y - v.y, z - v.z, w - v.w); +} + +inline Vector4 Vector4::operator * (float s) const +{ + return Vector4(x*s, y*s, z*s, w*s); +} + +inline Vector4 Vector4::operator / (float s) const +{ + float invs = 1.0f / s; + return Vector4(x*invs, y*invs, z*invs, w*invs); +} + +inline Vector4 Vector4::operator - () const +{ + return Vector4(-x, -y, -z, -w); +} + +inline void Vector4::operator += (const Vector4 &v) +{ + x += v.x; + y += v.y; + z += v.z; + w += v.w; +} + +inline void Vector4::operator -= (const Vector4 &v) +{ + x -= v.x; + y -= v.y; + z -= v.z; + w -= v.w; +} + +inline void Vector4::operator *= (float s) +{ + x *= s; + y *= s; + z *= s; + w *= s; +} + +inline void Vector4::operator /= (float s) +{ + float invs = 1.0f / s; + x *= invs; + y *= invs; + z *= invs; + w *= invs; +} + +inline bool Vector4::operator == (const Vector4 &v) const +{ + return x == v.x && y == v.y && z == v.z && w == v.w; +} + +inline bool Vector4::operator != (const Vector4 &v) const +{ + return x != v.x || y != v.y || z != v.z || w != v.w; +} + } //love #endif// LOVE_VECTOR_H diff -Nru love-11.1/src/common/version.h love-11.3/src/common/version.h --- love-11.1/src/common/version.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/common/version.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,12 +25,12 @@ { // Version stuff. -#define LOVE_VERSION_STRING "11.1" +#define LOVE_VERSION_STRING "11.3" static const int VERSION_MAJOR = 11; -static const int VERSION_MINOR = 1; +static const int VERSION_MINOR = 3; static const int VERSION_REV = 0; static const char *VERSION = LOVE_VERSION_STRING; -static const char *VERSION_COMPATIBILITY[] = { VERSION, "11.0", 0 }; +static const char *VERSION_COMPATIBILITY[] = { VERSION, "11.0", "11.1", "11.2", 0 }; static const char *VERSION_CODENAME = "Mysterious Mysteries"; } // love diff -Nru love-11.1/src/libraries/ddsparse/ddsinfo.h love-11.3/src/libraries/ddsparse/ddsinfo.h --- love-11.1/src/libraries/ddsparse/ddsinfo.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/ddsparse/ddsinfo.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,7 @@ /** * Simple DDS data parser for compressed 2D textures. * - * Copyright (c) 2013-2017 Alex Szpakowski + * Copyright (c) 2013-2019 Alex Szpakowski * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -41,7 +41,8 @@ DDPF_FOURCC = 0x000004, DDPF_RGB = 0x000040, DDPF_YUV = 0x000200, - DDPF_LUMINANCE = 0x020000 + DDPF_LUMINANCE = 0x020000, + DDPF_BUMPDUDV = 0x080000, }; enum D3D10ResourceDimension diff -Nru love-11.1/src/libraries/ddsparse/ddsparse.cpp love-11.3/src/libraries/ddsparse/ddsparse.cpp --- love-11.1/src/libraries/ddsparse/ddsparse.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/ddsparse/ddsparse.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,7 @@ /** * Simple DDS data parser for compressed 2D textures. * - * Copyright (c) 2013-2017 Alex Szpakowski + * Copyright (c) 2013-2019 Alex Szpakowski * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -33,101 +33,347 @@ // Creates a packed uint representation of a FourCC code. #define MakeFourCC(a, b, c, d) ((uint32_t) (((d)<<24) | ((c)<<16) | ((b)<<8) | (a))) -// Translate the old DDS format to our own. -static Format parseDDSFormat(const DDSPixelFormat &fmt) +#define ISBITMASK(r,g,b,a) (ddpf.rBitMask == r && ddpf.gBitMask == g && ddpf.bBitMask == b && ddpf.aBitMask == a) + +// Function adapted from DirectXTex: +// https://github.com/microsoft/DirectXTex/blob/master/DDSTextureLoader/DDSTextureLoader.cpp#L623 +static DXGIFormat getDXGIFormat(const DDSPixelFormat& ddpf) { - if ((fmt.flags & DDPF_FOURCC) == 0) - return FORMAT_UNKNOWN; + if (ddpf.flags & DDPF_RGB) + { + // Note that sRGB formats are written using the "DX10" extended header + + switch (ddpf.rgbBitCount) + { + case 32: + if (ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000)) + return DXGI_FORMAT_R8G8B8A8_UNORM; + + if (ISBITMASK(0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000)) + return DXGI_FORMAT_B8G8R8A8_UNORM; + + if (ISBITMASK(0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000)) + return DXGI_FORMAT_B8G8R8X8_UNORM; - Format f = FORMAT_UNKNOWN; + // No DXGI format maps to ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0x00000000) aka D3DFMT_X8B8G8R8 - switch (fmt.fourCC) + // Note that many common DDS reader/writers (including D3DX) swap the + // the RED/BLUE masks for 10:10:10:2 formats. We assume + // below that the 'backwards' header mask is being used since it is most + // likely written by D3DX. The more robust solution is to use the 'DX10' + // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly + + // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data + if (ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000)) + return DXGI_FORMAT_R10G10B10A2_UNORM; + + // No DXGI format maps to ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) aka D3DFMT_A2R10G10B10 + + if (ISBITMASK(0x0000ffff, 0xffff0000, 0x00000000, 0x00000000)) + return DXGI_FORMAT_R16G16_UNORM; + + if (ISBITMASK(0xffffffff, 0x00000000, 0x00000000, 0x00000000)) + // Only 32-bit color channel format in D3D9 was R32F + return DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114 + break; + + case 24: + // No 24bpp DXGI formats aka D3DFMT_R8G8B8 + break; + + case 16: + if (ISBITMASK(0x7c00, 0x03e0, 0x001f, 0x8000)) + return DXGI_FORMAT_B5G5R5A1_UNORM; + + if (ISBITMASK(0xf800, 0x07e0, 0x001f, 0x0000)) + return DXGI_FORMAT_B5G6R5_UNORM; + + // No DXGI format maps to ISBITMASK(0x7c00,0x03e0,0x001f,0x0000) aka D3DFMT_X1R5G5B5 + + // No DXGI format maps to ISBITMASK(0x0f00,0x00f0,0x000f,0x0000) aka D3DFMT_X4R4G4B4 + + // No 3:3:2, 3:3:2:8, or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_R3G3B2, D3DFMT_P8, D3DFMT_A8P8, etc. + break; + } + } + else if (ddpf.flags & DDPF_LUMINANCE) { - case MakeFourCC('D','X','T','1'): - f = FORMAT_DXT1; - break; - case MakeFourCC('D','X','T','3'): - f = FORMAT_DXT3; - break; - case MakeFourCC('D','X','T','5'): - f = FORMAT_DXT5; - break; - case MakeFourCC('A','T','I','1'): - case MakeFourCC('B','C','4','U'): - f = FORMAT_BC4; - break; - case MakeFourCC('B','C','4','S'): - f = FORMAT_BC4s; - break; - case MakeFourCC('A','T','I','2'): - case MakeFourCC('B','C','5','U'): - f = FORMAT_BC5; - break; - case MakeFourCC('B','C','5','S'): - f = FORMAT_BC5s; - break; - default: - break; + if (ddpf.rgbBitCount == 8) + { + if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x00000000)) + return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension + + // No DXGI format maps to ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4 + + if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00)) + return DXGI_FORMAT_R8G8_UNORM; // Some DDS writers assume the bitcount should be 8 instead of 16 + } + + if (ddpf.rgbBitCount == 16) + { + if (ISBITMASK(0x0000ffff, 0x00000000, 0x00000000, 0x00000000)) + return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension + + if (ISBITMASK(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00)) + return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension + } } + else if (ddpf.flags & DDPF_ALPHA) + { + if (ddpf.rgbBitCount == 8) + return DXGI_FORMAT_A8_UNORM; + } + else if (ddpf.flags & DDPF_BUMPDUDV) + { + if (ddpf.rgbBitCount == 16) + { + if (ISBITMASK(0x00ff, 0xff00, 0x0000, 0x0000)) + return DXGI_FORMAT_R8G8_SNORM; // D3DX10/11 writes this out as DX10 extension + } + + if (ddpf.rgbBitCount == 32) + { + if (ISBITMASK(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000)) + return DXGI_FORMAT_R8G8B8A8_SNORM; // D3DX10/11 writes this out as DX10 extension + + if (ISBITMASK(0x0000ffff, 0xffff0000, 0x00000000, 0x00000000)) + return DXGI_FORMAT_R16G16_SNORM; // D3DX10/11 writes this out as DX10 extension + + // No DXGI format maps to ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000) aka D3DFMT_A2W10V10U10 + } + } + else if (ddpf.flags & DDPF_FOURCC) + { + switch (ddpf.fourCC) + { + case MakeFourCC('D','X','T','1'): + return DXGI_FORMAT_BC1_UNORM; + + case MakeFourCC('D','X','T','3'): + return DXGI_FORMAT_BC2_UNORM; + + case MakeFourCC('D','X','T','5'): + return DXGI_FORMAT_BC3_UNORM; + + // While pre-multiplied alpha isn't directly supported by the DXGI formats, + // they are basically the same as these BC formats so they can be mapped + case MakeFourCC('D','X','T','2'): + return DXGI_FORMAT_BC2_UNORM; + + case MakeFourCC('D','X','T','4'): + return DXGI_FORMAT_BC3_UNORM; + + case MakeFourCC('A','T','I','1'): + return DXGI_FORMAT_BC4_UNORM; + + case MakeFourCC('B','C','4','U'): + return DXGI_FORMAT_BC4_UNORM; + + case MakeFourCC('B','C','4','S'): + return DXGI_FORMAT_BC4_SNORM; + + case MakeFourCC('A','T','I','2'): + return DXGI_FORMAT_BC5_UNORM; + + case MakeFourCC('B','C','5','U'): + return DXGI_FORMAT_BC5_UNORM; + + case MakeFourCC('B','C','5','S'): + return DXGI_FORMAT_BC5_SNORM; - return f; + // BC6H and BC7 are written using the "DX10" extended header + + case MakeFourCC('R','G','B','G'): + return DXGI_FORMAT_R8G8_B8G8_UNORM; + + case MakeFourCC('G','R','G','B'): + return DXGI_FORMAT_G8R8_G8B8_UNORM; + + // Check for D3DFORMAT enums being set here + case 36: // D3DFMT_A16B16G16R16 + return DXGI_FORMAT_R16G16B16A16_UNORM; + + case 110: // D3DFMT_Q16W16V16U16 + return DXGI_FORMAT_R16G16B16A16_SNORM; + + case 111: // D3DFMT_R16F + return DXGI_FORMAT_R16_FLOAT; + + case 112: // D3DFMT_G16R16F + return DXGI_FORMAT_R16G16_FLOAT; + + case 113: // D3DFMT_A16B16G16R16F + return DXGI_FORMAT_R16G16B16A16_FLOAT; + + case 114: // D3DFMT_R32F + return DXGI_FORMAT_R32_FLOAT; + + case 115: // D3DFMT_G32R32F + return DXGI_FORMAT_R32G32_FLOAT; + + case 116: // D3DFMT_A32B32G32R32F + return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + + return DXGI_FORMAT_UNKNOWN; } -// Translate the new DX10 formats to our own. -static Format parseDX10Format(DXGIFormat fmt) +static size_t getBitsPerPixel(DXGIFormat fmt) { - Format f = FORMAT_UNKNOWN; - switch (fmt) { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return 128; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return 96; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 64; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return 32; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return 16; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return 8; + + case DXGI_FORMAT_R1_UNORM: + return 1; + case DXGI_FORMAT_BC1_TYPELESS: case DXGI_FORMAT_BC1_UNORM: case DXGI_FORMAT_BC1_UNORM_SRGB: - f = FORMAT_DXT1; - break; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return 4; + case DXGI_FORMAT_BC2_TYPELESS: case DXGI_FORMAT_BC2_UNORM: case DXGI_FORMAT_BC2_UNORM_SRGB: - f = FORMAT_DXT3; - break; case DXGI_FORMAT_BC3_TYPELESS: case DXGI_FORMAT_BC3_UNORM: case DXGI_FORMAT_BC3_UNORM_SRGB: - f = FORMAT_DXT5; - break; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 8; + + default: + return 0; + } +} + +static bool isBlockCompressed(DXGIFormat fmt) +{ + switch (fmt) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: case DXGI_FORMAT_BC4_TYPELESS: case DXGI_FORMAT_BC4_UNORM: - f = FORMAT_BC4; - break; case DXGI_FORMAT_BC4_SNORM: - f = FORMAT_BC4s; - break; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: case DXGI_FORMAT_BC5_TYPELESS: case DXGI_FORMAT_BC5_UNORM: - f = FORMAT_BC5; - break; case DXGI_FORMAT_BC5_SNORM: - f = FORMAT_BC5s; - break; case DXGI_FORMAT_BC6H_TYPELESS: case DXGI_FORMAT_BC6H_UF16: - f = FORMAT_BC6H; - break; case DXGI_FORMAT_BC6H_SF16: - f = FORMAT_BC6Hs; - break; case DXGI_FORMAT_BC7_TYPELESS: case DXGI_FORMAT_BC7_UNORM: - f = FORMAT_BC7; - break; case DXGI_FORMAT_BC7_UNORM_SRGB: - f = FORMAT_BC7srgb; - break; + return true; default: - break; + return false; } - - return f; } bool isDDS(const void *data, size_t dataSize) @@ -147,7 +393,6 @@ DDSHeader *header = (DDSHeader *) &readData[offset]; - // Verify header to validate DDS data. if (header->size != sizeof(DDSHeader) || header->format.size != sizeof(DDSPixelFormat)) return false; @@ -165,10 +410,10 @@ return true; } -bool isCompressedDDS(const void *data, size_t dataSize) +DXGIFormat getDDSPixelFormat(const void *data, size_t dataSize) { if (!isDDS(data, dataSize)) - return false; + return DXGI_FORMAT_UNKNOWN; const uint8_t *readData = (const uint8_t *) data; ptrdiff_t offset = sizeof(uint32_t); @@ -180,14 +425,20 @@ if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0'))) { DDSHeader10 *header10 = (DDSHeader10 *) &readData[offset]; - return parseDX10Format(header10->dxgiFormat) != FORMAT_UNKNOWN; + return header10->dxgiFormat; } - return parseDDSFormat(header->format) != FORMAT_UNKNOWN; + return getDXGIFormat(header->format); +} + +bool isCompressedDDS(const void *data, size_t dataSize) +{ + DXGIFormat format = getDDSPixelFormat(data, dataSize); + return format != DXGI_FORMAT_UNKNOWN && isBlockCompressed(format); } Parser::Parser(const void *data, size_t dataSize) - : format(FORMAT_UNKNOWN) + : format(DXGI_FORMAT_UNKNOWN) { parseData(data, dataSize); } @@ -199,7 +450,7 @@ } Parser::Parser() - : format(FORMAT_UNKNOWN) + : format(DXGI_FORMAT_UNKNOWN) { } @@ -215,7 +466,7 @@ { } -Format Parser::getFormat() const +DXGIFormat Parser::getFormat() const { return format; } @@ -233,42 +484,78 @@ return texData.size(); } -size_t Parser::parseImageSize(Format fmt, int width, int height) const +size_t Parser::parseImageSize(DXGIFormat fmt, int width, int height) const { - size_t numBlocksWide = 0; - size_t numBlocksHigh = 0; - size_t numBytesPerBlock = 0; + size_t bytes = 0; + size_t bytesPerBlock = 0; + + bool packed = false; + bool blockCompressed = false; switch (fmt) { - case FORMAT_DXT1: - case FORMAT_BC4: - case FORMAT_BC4s: - numBytesPerBlock = 8; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + blockCompressed = true; + bytesPerBlock = 8; + break; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + blockCompressed = true; + bytesPerBlock = 16; break; - case FORMAT_DXT3: - case FORMAT_DXT5: - case FORMAT_BC5s: - case FORMAT_BC5: - case FORMAT_BC6H: - case FORMAT_BC7: - case FORMAT_BC7srgb: - numBytesPerBlock = 16; + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + packed = true; + bytesPerBlock = 4; break; default: break; } - if (width > 0) - numBlocksWide = std::max(1, (width + 3) / 4); - - if (height > 0) - numBlocksHigh = std::max(1, (height + 3) / 4); + if (packed) + { + size_t rowBytes = (((size_t) width + 1u) >> 1) * bytesPerBlock; + bytes = rowBytes * height; + } + else if (blockCompressed) + { + size_t numBlocksWide = width > 0 ? std::max(1, (width + 3) / 4) : 0; + size_t numBlocksHigh = height > 0 ? std::max(1, (height + 3) / 4) : 0; + bytes = numBlocksWide * bytesPerBlock * numBlocksHigh; + } + else + { + size_t bpp = getBitsPerPixel(fmt); + if (bpp == 0) + return 0; + + // Round up to the nearest byte. + size_t rowBytes = ((size_t) width * bpp + 7u) / 8u; + bytes = rowBytes * height; + } - return numBlocksWide * numBytesPerBlock * numBlocksHigh; + return bytes; } -bool Parser::parseTexData(const uint8_t *data, size_t dataSize, Format fmt, int w, int h, int mips) +bool Parser::parseTexData(const uint8_t *data, size_t dataSize, DXGIFormat fmt, int w, int h, int mips) { size_t offset = 0; std::vector newTexData; @@ -313,7 +600,6 @@ DDSHeader *header = (DDSHeader *) &readData[offset]; offset += sizeof(DDSHeader); - // Check for DX10 extension. if ((header->format.flags & DDPF_FOURCC) && (header->format.fourCC == MakeFourCC('D','X','1','0'))) { @@ -334,16 +620,14 @@ if (header10->arraySize > 1) return false; - format = parseDX10Format(header10->dxgiFormat); + format = header10->dxgiFormat; } else - format = parseDDSFormat(header->format); + format = getDXGIFormat(header->format); - - if (format == FORMAT_UNKNOWN) + if (format == DXGI_FORMAT_UNKNOWN) return false; - int w = header->width; int h = header->height; diff -Nru love-11.1/src/libraries/ddsparse/ddsparse.h love-11.3/src/libraries/ddsparse/ddsparse.h --- love-11.1/src/libraries/ddsparse/ddsparse.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/ddsparse/ddsparse.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,7 @@ /** * Simple DDS data parser for compressed 2D textures. * - * Copyright (c) 2013-2017 Alex Szpakowski + * Copyright (c) 2013-2019 Alex Szpakowski * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -28,37 +28,18 @@ #include -namespace dds -{ +#include "ddsinfo.h" -// Supported DDS formats. -// Formats with an 's' suffix have signed data. -enum Format +namespace dds { - FORMAT_DXT1, - FORMAT_DXT3, - FORMAT_DXT5, - FORMAT_BC4, - FORMAT_BC4s, - FORMAT_BC5, - FORMAT_BC5s, - FORMAT_BC6H, - FORMAT_BC6Hs, - FORMAT_BC7, - FORMAT_BC7srgb, // sRGB color space. - FORMAT_UNKNOWN -}; // Represents a single mipmap level of a texture. struct Image { - int width; - int height; - size_t dataSize; - const uint8_t *data; - - Image() : width(0), height(0), dataSize(0), data(0) - {} + int width = 0; + int height = 0; + size_t dataSize = 0; + const uint8_t *data = nullptr; }; /** @@ -79,6 +60,8 @@ **/ bool isCompressedDDS(const void *data, size_t dataSize); +dxinfo::DXGIFormat getDDSPixelFormat(const void *data, size_t dataSize); + class Parser { public: @@ -101,7 +84,7 @@ /** * Gets the format of this texture. **/ - Format getFormat() const; + dxinfo::DXGIFormat getFormat() const; /** * Gets the data of this texture at a mipmap level. Mipmap level 0 @@ -121,12 +104,12 @@ private: - size_t parseImageSize(Format fmt, int width, int height) const; - bool parseTexData(const uint8_t *data, size_t dataSize, Format fmt, int w, int h, int mips); + size_t parseImageSize(dxinfo::DXGIFormat fmt, int width, int height) const; + bool parseTexData(const uint8_t *data, size_t dataSize, dxinfo::DXGIFormat fmt, int w, int h, int mips); bool parseData(const void *data, size_t dataSize); std::vector texData; - Format format; + dxinfo::DXGIFormat format; }; // Parser diff -Nru love-11.1/src/libraries/dr_flac/dr_flac.h love-11.3/src/libraries/dr_flac/dr_flac.h --- love-11.1/src/libraries/dr_flac/dr_flac.h 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/libraries/dr_flac/dr_flac.h 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,8930 @@ +/* +FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. +dr_flac - v0.11.9 - 2019-06-16 + +David Reid - mackron@gmail.com +*/ + +/* +USAGE +===== +dr_flac is a single-file library. To use it, do something like the following in one .c file. + #define DR_FLAC_IMPLEMENTATION + #include "dr_flac.h" + +You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, +do something like the following: + + drflac* pFlac = drflac_open_file("MySong.flac"); + if (pFlac == NULL) { + // Failed to open FLAC file + } + + drflac_int32* pSamples = malloc(pFlac->totalPCMFrameCount * pFlac->channels * sizeof(drflac_int32)); + drflac_uint64 numberOfInterleavedSamplesActuallyRead = drflac_read_pcm_frames_s32(pFlac, pFlac->totalPCMFrameCount, pSamples); + +The drflac object represents the decoder. It is a transparent type so all the information you need, such as the number of +channels and the bits per sample, should be directly accessible - just make sure you don't change their values. Samples are +always output as interleaved signed 32-bit PCM. In the example above a native FLAC stream was opened, however dr_flac has +seamless support for Ogg encapsulated FLAC streams as well. + +You do not need to decode the entire stream in one go - you just specify how many samples you'd like at any given time and +the decoder will give you as many samples as it can, up to the amount requested. Later on when you need the next batch of +samples, just call it again. Example: + + while (drflac_read_pcm_frames_s32(pFlac, chunkSizeInPCMFrames, pChunkSamples) > 0) { + do_something(); + } + +You can seek to a specific sample with drflac_seek_to_sample(). The given sample is based on interleaving. So for example, +if you were to seek to the sample at index 0 in a stereo stream, you'll be seeking to the first sample of the left channel. +The sample at index 1 will be the first sample of the right channel. The sample at index 2 will be the second sample of the +left channel, etc. + + +If you just want to quickly decode an entire FLAC file in one go you can do something like this: + + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int32* pSampleData = drflac_open_file_and_read_pcm_frames_s32("MySong.flac", &channels, &sampleRate, &totalPCMFrameCount); + if (pSampleData == NULL) { + // Failed to open and decode FLAC file. + } + + ... + + drflac_free(pSampleData); + + +You can read samples as signed 16-bit integer and 32-bit floating-point PCM with the *_s16() and *_f32() family of APIs +respectively, but note that these should be considered lossy. + + +If you need access to metadata (album art, etc.), use drflac_open_with_metadata(), drflac_open_file_with_metdata() or +drflac_open_memory_with_metadata(). The rationale for keeping these APIs separate is that they're slightly slower than the +normal versions and also just a little bit harder to use. + +dr_flac reports metadata to the application through the use of a callback, and every metadata block is reported before +drflac_open_with_metdata() returns. + + +The main opening APIs (drflac_open(), etc.) will fail if the header is not present. The presents a problem in certain +scenarios such as broadcast style streams like internet radio where the header may not be present because the user has +started playback mid-stream. To handle this, use the relaxed APIs: drflac_open_relaxed() and drflac_open_with_metadata_relaxed(). + +It is not recommended to use these APIs for file based streams because a missing header would usually indicate a +corrupted or perverse file. In addition, these APIs can take a long time to initialize because they may need to spend +a lot of time finding the first frame. + + + +OPTIONS +======= +#define these options before including this file. + +#define DR_FLAC_NO_STDIO + Disable drflac_open_file() and family. + +#define DR_FLAC_NO_OGG + Disables support for Ogg/FLAC streams. + +#define DR_FLAC_BUFFER_SIZE + Defines the size of the internal buffer to store data from onRead(). This buffer is used to reduce the number of calls + back to the client for more data. Larger values means more memory, but better performance. My tests show diminishing + returns after about 4KB (which is the default). Consider reducing this if you have a very efficient implementation of + onRead(), or increase it if it's very inefficient. Must be a multiple of 8. + +#define DR_FLAC_NO_CRC + Disables CRC checks. This will offer a performance boost when CRC is unnecessary. + +#define DR_FLAC_NO_SIMD + Disables SIMD optimizations (SSE on x86/x64 architectures). Use this if you are having compatibility issues with your + compiler. + + + +QUICK NOTES +=========== +- dr_flac does not currently support changing the sample rate nor channel count mid stream. +- Audio data is output as signed 32-bit PCM, regardless of the bits per sample the FLAC stream is encoded as. +- This has not been tested on big-endian architectures. +- dr_flac is not thread-safe, but its APIs can be called from any thread so long as you do your own synchronization. +- When using Ogg encapsulation, a corrupted metadata block will result in drflac_open_with_metadata() and drflac_open() + returning inconsistent samples. +*/ + +#ifndef dr_flac_h +#define dr_flac_h + +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +typedef signed char drflac_int8; +typedef unsigned char drflac_uint8; +typedef signed short drflac_int16; +typedef unsigned short drflac_uint16; +typedef signed int drflac_int32; +typedef unsigned int drflac_uint32; +typedef signed __int64 drflac_int64; +typedef unsigned __int64 drflac_uint64; +#else +#include +typedef int8_t drflac_int8; +typedef uint8_t drflac_uint8; +typedef int16_t drflac_int16; +typedef uint16_t drflac_uint16; +typedef int32_t drflac_int32; +typedef uint32_t drflac_uint32; +typedef int64_t drflac_int64; +typedef uint64_t drflac_uint64; +#endif +typedef drflac_uint8 drflac_bool8; +typedef drflac_uint32 drflac_bool32; +#define DRFLAC_TRUE 1 +#define DRFLAC_FALSE 0 + +#if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */ + #define DRFLAC_DEPRECATED __declspec(deprecated) +#elif (defined(__GNUC__) && __GNUC__ >= 4) /* GCC 4 */ + #define DRFLAC_DEPRECATED __attribute__((deprecated)) +#elif defined(__has_feature) /* Clang */ + #if __has_feature(attribute_deprecated) + #define DRFLAC_DEPRECATED __attribute__((deprecated)) + #else + #define DRFLAC_DEPRECATED + #endif +#else + #define DRFLAC_DEPRECATED +#endif + +/* +As data is read from the client it is placed into an internal buffer for fast access. This controls the +size of that buffer. Larger values means more speed, but also more memory. In my testing there is diminishing +returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8. +*/ +#ifndef DR_FLAC_BUFFER_SIZE +#define DR_FLAC_BUFFER_SIZE 4096 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Check if we can enable 64-bit optimizations. */ +#if defined(_WIN64) || defined(_LP64) || defined(__LP64__) +#define DRFLAC_64BIT +#endif + +#ifdef DRFLAC_64BIT +typedef drflac_uint64 drflac_cache_t; +#else +typedef drflac_uint32 drflac_cache_t; +#endif + +/* The various metadata block types. */ +#define DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO 0 +#define DRFLAC_METADATA_BLOCK_TYPE_PADDING 1 +#define DRFLAC_METADATA_BLOCK_TYPE_APPLICATION 2 +#define DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE 3 +#define DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT 4 +#define DRFLAC_METADATA_BLOCK_TYPE_CUESHEET 5 +#define DRFLAC_METADATA_BLOCK_TYPE_PICTURE 6 +#define DRFLAC_METADATA_BLOCK_TYPE_INVALID 127 + +/* The various picture types specified in the PICTURE block. */ +#define DRFLAC_PICTURE_TYPE_OTHER 0 +#define DRFLAC_PICTURE_TYPE_FILE_ICON 1 +#define DRFLAC_PICTURE_TYPE_OTHER_FILE_ICON 2 +#define DRFLAC_PICTURE_TYPE_COVER_FRONT 3 +#define DRFLAC_PICTURE_TYPE_COVER_BACK 4 +#define DRFLAC_PICTURE_TYPE_LEAFLET_PAGE 5 +#define DRFLAC_PICTURE_TYPE_MEDIA 6 +#define DRFLAC_PICTURE_TYPE_LEAD_ARTIST 7 +#define DRFLAC_PICTURE_TYPE_ARTIST 8 +#define DRFLAC_PICTURE_TYPE_CONDUCTOR 9 +#define DRFLAC_PICTURE_TYPE_BAND 10 +#define DRFLAC_PICTURE_TYPE_COMPOSER 11 +#define DRFLAC_PICTURE_TYPE_LYRICIST 12 +#define DRFLAC_PICTURE_TYPE_RECORDING_LOCATION 13 +#define DRFLAC_PICTURE_TYPE_DURING_RECORDING 14 +#define DRFLAC_PICTURE_TYPE_DURING_PERFORMANCE 15 +#define DRFLAC_PICTURE_TYPE_SCREEN_CAPTURE 16 +#define DRFLAC_PICTURE_TYPE_BRIGHT_COLORED_FISH 17 +#define DRFLAC_PICTURE_TYPE_ILLUSTRATION 18 +#define DRFLAC_PICTURE_TYPE_BAND_LOGOTYPE 19 +#define DRFLAC_PICTURE_TYPE_PUBLISHER_LOGOTYPE 20 + +typedef enum +{ + drflac_container_native, + drflac_container_ogg, + drflac_container_unknown +} drflac_container; + +typedef enum +{ + drflac_seek_origin_start, + drflac_seek_origin_current +} drflac_seek_origin; + +/* Packing is important on this structure because we map this directly to the raw data within the SEEKTABLE metadata block. */ +#pragma pack(2) +typedef struct +{ + drflac_uint64 firstSample; + drflac_uint64 frameOffset; /* The offset from the first byte of the header of the first frame. */ + drflac_uint16 sampleCount; +} drflac_seekpoint; +#pragma pack() + +typedef struct +{ + drflac_uint16 minBlockSize; + drflac_uint16 maxBlockSize; + drflac_uint32 minFrameSize; + drflac_uint32 maxFrameSize; + drflac_uint32 sampleRate; + drflac_uint8 channels; + drflac_uint8 bitsPerSample; + drflac_uint64 totalSampleCount; + drflac_uint8 md5[16]; +} drflac_streaminfo; + +typedef struct +{ + /* The metadata type. Use this to know how to interpret the data below. */ + drflac_uint32 type; + + /* + A pointer to the raw data. This points to a temporary buffer so don't hold on to it. It's best to + not modify the contents of this buffer. Use the structures below for more meaningful and structured + information about the metadata. It's possible for this to be null. + */ + const void* pRawData; + + /* The size in bytes of the block and the buffer pointed to by pRawData if it's non-NULL. */ + drflac_uint32 rawDataSize; + + union + { + drflac_streaminfo streaminfo; + + struct + { + int unused; + } padding; + + struct + { + drflac_uint32 id; + const void* pData; + drflac_uint32 dataSize; + } application; + + struct + { + drflac_uint32 seekpointCount; + const drflac_seekpoint* pSeekpoints; + } seektable; + + struct + { + drflac_uint32 vendorLength; + const char* vendor; + drflac_uint32 commentCount; + const void* pComments; + } vorbis_comment; + + struct + { + char catalog[128]; + drflac_uint64 leadInSampleCount; + drflac_bool32 isCD; + drflac_uint8 trackCount; + const void* pTrackData; + } cuesheet; + + struct + { + drflac_uint32 type; + drflac_uint32 mimeLength; + const char* mime; + drflac_uint32 descriptionLength; + const char* description; + drflac_uint32 width; + drflac_uint32 height; + drflac_uint32 colorDepth; + drflac_uint32 indexColorCount; + drflac_uint32 pictureDataSize; + const drflac_uint8* pPictureData; + } picture; + } data; +} drflac_metadata; + + +/* +Callback for when data needs to be read from the client. + +pUserData [in] The user data that was passed to drflac_open() and family. +pBufferOut [out] The output buffer. +bytesToRead [in] The number of bytes to read. + +Returns the number of bytes actually read. + +A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until +either the entire bytesToRead is filled or you have reached the end of the stream. +*/ +typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead); + +/* +Callback for when data needs to be seeked. + +pUserData [in] The user data that was passed to drflac_open() and family. +offset [in] The number of bytes to move, relative to the origin. Will never be negative. +origin [in] The origin of the seek - the current position or the start of the stream. + +Returns whether or not the seek was successful. + +The offset will never be negative. Whether or not it is relative to the beginning or current position is determined +by the "origin" parameter which will be either drflac_seek_origin_start or drflac_seek_origin_current. +*/ +typedef drflac_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin); + +/* +Callback for when a metadata block is read. + +pUserData [in] The user data that was passed to drflac_open() and family. +pMetadata [in] A pointer to a structure containing the data of the metadata block. + +Use pMetadata->type to determine which metadata block is being handled and how to read the data. +*/ +typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata); + + +/* Structure for internal use. Only used for decoders opened with drflac_open_memory. */ +typedef struct +{ + const drflac_uint8* data; + size_t dataSize; + size_t currentReadPos; +} drflac__memory_stream; + +/* Structure for internal use. Used for bit streaming. */ +typedef struct +{ + /* The function to call when more data needs to be read. */ + drflac_read_proc onRead; + + /* The function to call when the current read position needs to be moved. */ + drflac_seek_proc onSeek; + + /* The user data to pass around to onRead and onSeek. */ + void* pUserData; + + + /* + The number of unaligned bytes in the L2 cache. This will always be 0 until the end of the stream is hit. At the end of the + stream there will be a number of bytes that don't cleanly fit in an L1 cache line, so we use this variable to know whether + or not the bistreamer needs to run on a slower path to read those last bytes. This will never be more than sizeof(drflac_cache_t). + */ + size_t unalignedByteCount; + + /* The content of the unaligned bytes. */ + drflac_cache_t unalignedCache; + + /* The index of the next valid cache line in the "L2" cache. */ + drflac_uint32 nextL2Line; + + /* The number of bits that have been consumed by the cache. This is used to determine how many valid bits are remaining. */ + drflac_uint32 consumedBits; + + /* + The cached data which was most recently read from the client. There are two levels of cache. Data flows as such: + Client -> L2 -> L1. The L2 -> L1 movement is aligned and runs on a fast path in just a few instructions. + */ + drflac_cache_t cacheL2[DR_FLAC_BUFFER_SIZE/sizeof(drflac_cache_t)]; + drflac_cache_t cache; + + /* + CRC-16. This is updated whenever bits are read from the bit stream. Manually set this to 0 to reset the CRC. For FLAC, this + is reset to 0 at the beginning of each frame. + */ + drflac_uint16 crc16; + drflac_cache_t crc16Cache; /* A cache for optimizing CRC calculations. This is filled when when the L1 cache is reloaded. */ + drflac_uint32 crc16CacheIgnoredBytes; /* The number of bytes to ignore when updating the CRC-16 from the CRC-16 cache. */ +} drflac_bs; + +typedef struct +{ + /* The type of the subframe: SUBFRAME_CONSTANT, SUBFRAME_VERBATIM, SUBFRAME_FIXED or SUBFRAME_LPC. */ + drflac_uint8 subframeType; + + /* The number of wasted bits per sample as specified by the sub-frame header. */ + drflac_uint8 wastedBitsPerSample; + + /* The order to use for the prediction stage for SUBFRAME_FIXED and SUBFRAME_LPC. */ + drflac_uint8 lpcOrder; + + /* + The number of bits per sample for this subframe. This is not always equal to the current frame's bit per sample because + an extra bit is required for side channels when interchannel decorrelation is being used. + */ + drflac_uint32 bitsPerSample; + + /* + A pointer to the buffer containing the decoded samples in the subframe. This pointer is an offset from drflac::pExtraData. Note that + it's a signed 32-bit integer for each value. + */ + drflac_int32* pDecodedSamples; +} drflac_subframe; + +typedef struct +{ + /* + If the stream uses variable block sizes, this will be set to the index of the first sample. If fixed block sizes are used, this will + always be set to 0. + */ + drflac_uint64 sampleNumber; + + /* If the stream uses fixed block sizes, this will be set to the frame number. If variable block sizes are used, this will always be 0. */ + drflac_uint32 frameNumber; + + /* The sample rate of this frame. */ + drflac_uint32 sampleRate; + + /* The number of samples in each sub-frame within this frame. */ + drflac_uint16 blockSize; + + /* + The channel assignment of this frame. This is not always set to the channel count. If interchannel decorrelation is being used this + will be set to DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE, DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE or DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE. + */ + drflac_uint8 channelAssignment; + + /* The number of bits per sample within this frame. */ + drflac_uint8 bitsPerSample; + + /* The frame's CRC. */ + drflac_uint8 crc8; +} drflac_frame_header; + +typedef struct +{ + /* The header. */ + drflac_frame_header header; + + /* + The number of samples left to be read in this frame. This is initially set to the block size multiplied by the channel count. As samples + are read, this will be decremented. When it reaches 0, the decoder will see this frame as fully consumed and load the next frame. + */ + drflac_uint32 samplesRemaining; + + /* The list of sub-frames within the frame. There is one sub-frame for each channel, and there's a maximum of 8 channels. */ + drflac_subframe subframes[8]; +} drflac_frame; + +typedef struct +{ + /* The function to call when a metadata block is read. */ + drflac_meta_proc onMeta; + + /* The user data posted to the metadata callback function. */ + void* pUserDataMD; + + + /* The sample rate. Will be set to something like 44100. */ + drflac_uint32 sampleRate; + + /* + The number of channels. This will be set to 1 for monaural streams, 2 for stereo, etc. Maximum 8. This is set based on the + value specified in the STREAMINFO block. + */ + drflac_uint8 channels; + + /* The bits per sample. Will be set to something like 16, 24, etc. */ + drflac_uint8 bitsPerSample; + + /* The maximum block size, in samples. This number represents the number of samples in each channel (not combined). */ + drflac_uint16 maxBlockSize; + + /* + The total number of samples making up the stream. This includes every channel. For example, if the stream has 2 channels, + with each channel having a total of 4096, this value will be set to 2*4096 = 8192. Can be 0 in which case it's still a + valid stream, but just means the total sample count is unknown. Likely the case with streams like internet radio. + */ + drflac_uint64 totalSampleCount; + drflac_uint64 totalPCMFrameCount; /* <-- Equal to totalSampleCount / channels. */ + + + /* The container type. This is set based on whether or not the decoder was opened from a native or Ogg stream. */ + drflac_container container; + + /* The number of seekpoints in the seektable. */ + drflac_uint32 seekpointCount; + + + /* Information about the frame the decoder is currently sitting on. */ + drflac_frame currentFrame; + + /* The index of the sample the decoder is currently sitting on. This is only used for seeking. */ + drflac_uint64 currentSample; + + /* The position of the first frame in the stream. This is only ever used for seeking. */ + drflac_uint64 firstFramePos; + + + /* A hack to avoid a malloc() when opening a decoder with drflac_open_memory(). */ + drflac__memory_stream memoryStream; + + + /* A pointer to the decoded sample data. This is an offset of pExtraData. */ + drflac_int32* pDecodedSamples; + + /* A pointer to the seek table. This is an offset of pExtraData, or NULL if there is no seek table. */ + drflac_seekpoint* pSeekpoints; + + /* Internal use only. Only used with Ogg containers. Points to a drflac_oggbs object. This is an offset of pExtraData. */ + void* _oggbs; + + /* The bit streamer. The raw FLAC data is fed through this object. */ + drflac_bs bs; + + /* Variable length extra data. We attach this to the end of the object so we can avoid unnecessary mallocs. */ + drflac_uint8 pExtraData[1]; +} drflac; + + +/* +Opens a FLAC decoder. + +onRead [in] The function to call when data needs to be read from the client. +onSeek [in] The function to call when the read position of the client data needs to move. +pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek. + +Returns a pointer to an object representing the decoder. + +Close the decoder with drflac_close(). + +This function will automatically detect whether or not you are attempting to open a native or Ogg encapsulated +FLAC, both of which should work seamlessly without any manual intervention. Ogg encapsulation also works with +multiplexed streams which basically means it can play FLAC encoded audio tracks in videos. + +This is the lowest level function for opening a FLAC stream. You can also use drflac_open_file() and drflac_open_memory() +to open the stream from a file or from a block of memory respectively. + +The STREAMINFO block must be present for this to succeed. Use drflac_open_relaxed() to open a FLAC stream where +the header may not be present. + +See also: drflac_open_file(), drflac_open_memory(), drflac_open_with_metadata(), drflac_close() +*/ +drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData); + +/* +The same as drflac_open(), except attempts to open the stream even when a header block is not present. + +Because the header is not necessarily available, the caller must explicitly define the container (Native or Ogg). Do +not set this to drflac_container_unknown - that is for internal use only. + +Opening in relaxed mode will continue reading data from onRead until it finds a valid frame. If a frame is never +found it will continue forever. To abort, force your onRead callback to return 0, which dr_flac will use as an +indicator that the end of the stream was found. +*/ +drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData); + +/* +Opens a FLAC decoder and notifies the caller of the metadata chunks (album art, etc.). + +onRead [in] The function to call when data needs to be read from the client. +onSeek [in] The function to call when the read position of the client data needs to move. +onMeta [in] The function to call for every metadata block. +pUserData [in, optional] A pointer to application defined data that will be passed to onRead, onSeek and onMeta. + +Returns a pointer to an object representing the decoder. + +Close the decoder with drflac_close(). + +This is slower than drflac_open(), so avoid this one if you don't need metadata. Internally, this will do a DRFLAC_MALLOC() +and DRFLAC_FREE() for every metadata block except for STREAMINFO and PADDING blocks. + +The caller is notified of the metadata via the onMeta callback. All metadata blocks will be handled before the function +returns. + +The STREAMINFO block must be present for this to succeed. Use drflac_open_with_metadata_relaxed() to open a FLAC +stream where the header may not be present. + +Note that this will behave inconsistently with drflac_open() if the stream is an Ogg encapsulated stream and a metadata +block is corrupted. This is due to the way the Ogg stream recovers from corrupted pages. When drflac_open_with_metadata() +is being used, the open routine will try to read the contents of the metadata block, whereas drflac_open() will simply +seek past it (for the sake of efficiency). This inconsistency can result in different samples being returned depending on +whether or not the stream is being opened with metadata. + +See also: drflac_open_file_with_metadata(), drflac_open_memory_with_metadata(), drflac_open(), drflac_close() +*/ +drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData); + +/* +The same as drflac_open_with_metadata(), except attempts to open the stream even when a header block is not present. + +See also: drflac_open_with_metadata(), drflac_open_relaxed() +*/ +drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData); + +/* +Closes the given FLAC decoder. + +pFlac [in] The decoder to close. + +This will destroy the decoder object. +*/ +void drflac_close(drflac* pFlac); + + +/* +Reads sample data from the given FLAC decoder, output as interleaved signed 32-bit PCM. + +pFlac [in] The decoder. +framesToRead [in] The number of PCM frames to read. +pBufferOut [out, optional] A pointer to the buffer that will receive the decoded samples. + +Returns the number of PCM frames actually read. + +pBufferOut can be null, in which case the call will act as a seek, and the return value will be the number of frames +seeked. +*/ +drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut); + +/* +Same as drflac_read_pcm_frames_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit. + +Note that this is lossy for streams where the bits per sample is larger than 16. +*/ +drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut); + +/* +Same as drflac_read_pcm_frames_s32(), except outputs samples as 32-bit floating-point PCM. + +Note that this should be considered lossy due to the nature of floating point numbers not being able to exactly +represent every possible number. +*/ +drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut); + +/* +Seeks to the PCM frame at the given index. + +pFlac [in] The decoder. +pcmFrameIndex [in] The index of the PCM frame to seek to. See notes below. + +Returns DRFLAC_TRUE if successful; DRFLAC_FALSE otherwise. +*/ +drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex); + + + +#ifndef DR_FLAC_NO_STDIO +/* +Opens a FLAC decoder from the file at the given path. + +filename [in] The path of the file to open, either absolute or relative to the current directory. + +Returns a pointer to an object representing the decoder. + +Close the decoder with drflac_close(). + +This will hold a handle to the file until the decoder is closed with drflac_close(). Some platforms will restrict the +number of files a process can have open at any given time, so keep this mind if you have many decoders open at the +same time. + +See also: drflac_open(), drflac_open_file_with_metadata(), drflac_close() +*/ +drflac* drflac_open_file(const char* filename); + +/* +Opens a FLAC decoder from the file at the given path and notifies the caller of the metadata chunks (album art, etc.) + +Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled. +*/ +drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData); +#endif + +/* +Opens a FLAC decoder from a pre-allocated block of memory + +This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for +the lifetime of the decoder. +*/ +drflac* drflac_open_memory(const void* data, size_t dataSize); + +/* +Opens a FLAC decoder from a pre-allocated block of memory and notifies the caller of the metadata chunks (album art, etc.) + +Look at the documentation for drflac_open_with_metadata() for more information on how metadata is handled. +*/ +drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drflac_meta_proc onMeta, void* pUserData); + + + +/* High Level APIs */ + +/* +Opens a FLAC stream from the given callbacks and fully decodes it in a single operation. The return value is a +pointer to the sample data as interleaved signed 32-bit PCM. The returned data must be freed with DRFLAC_FREE(). + +Sometimes a FLAC file won't keep track of the total sample count. In this situation the function will continuously +read samples into a dynamically sized buffer on the heap until no samples are left. + +Do not call this function on a broadcast type of stream (like internet radio streams and whatnot). +*/ +drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Same as drflac_open_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */ +drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Same as drflac_open_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */ +float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +#ifndef DR_FLAC_NO_STDIO +/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a file. */ +drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */ +drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Same as drflac_open_file_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */ +float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); +#endif + +/* Same as drflac_open_and_read_pcm_frames_s32() except opens the decoder from a block of memory. */ +drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns signed 16-bit integer samples. */ +drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Same as drflac_open_memory_and_read_pcm_frames_s32(), except returns 32-bit floating-point samples. */ +float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount); + +/* Frees memory that was allocated internally by dr_flac. */ +void drflac_free(void* p); + + +/* Structure representing an iterator for vorbis comments in a VORBIS_COMMENT metadata block. */ +typedef struct +{ + drflac_uint32 countRemaining; + const char* pRunningData; +} drflac_vorbis_comment_iterator; + +/* +Initializes a vorbis comment iterator. This can be used for iterating over the vorbis comments in a VORBIS_COMMENT +metadata block. +*/ +void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments); + +/* +Goes to the next vorbis comment in the given iterator. If null is returned it means there are no more comments. The +returned string is NOT null terminated. +*/ +const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut); + + +/* Structure representing an iterator for cuesheet tracks in a CUESHEET metadata block. */ +typedef struct +{ + drflac_uint32 countRemaining; + const char* pRunningData; +} drflac_cuesheet_track_iterator; + +/* Packing is important on this structure because we map this directly to the raw data within the CUESHEET metadata block. */ +#pragma pack(4) +typedef struct +{ + drflac_uint64 offset; + drflac_uint8 index; + drflac_uint8 reserved[3]; +} drflac_cuesheet_track_index; +#pragma pack() + +typedef struct +{ + drflac_uint64 offset; + drflac_uint8 trackNumber; + char ISRC[12]; + drflac_bool8 isAudio; + drflac_bool8 preEmphasis; + drflac_uint8 indexCount; + const drflac_cuesheet_track_index* pIndexPoints; +} drflac_cuesheet_track; + +/* +Initializes a cuesheet track iterator. This can be used for iterating over the cuesheet tracks in a CUESHEET metadata +block. +*/ +void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData); + +/* Goes to the next cuesheet track in the given iterator. If DRFLAC_FALSE is returned it means there are no more comments. */ +drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack); + + +/* Deprecated APIs */ +DRFLAC_DEPRECATED drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* pBufferOut); /* Use drflac_read_pcm_frames_s32() instead. */ +DRFLAC_DEPRECATED drflac_uint64 drflac_read_s16(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int16* pBufferOut); /* Use drflac_read_pcm_frames_s16() instead. */ +DRFLAC_DEPRECATED drflac_uint64 drflac_read_f32(drflac* pFlac, drflac_uint64 samplesToRead, float* pBufferOut); /* Use drflac_read_pcm_frames_f32() instead. */ +DRFLAC_DEPRECATED drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex); /* Use drflac_seek_to_pcm_frame() instead. */ +DRFLAC_DEPRECATED drflac_int32* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_and_read_pcm_frames_s32(). */ +DRFLAC_DEPRECATED drflac_int16* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_and_read_pcm_frames_s16(). */ +DRFLAC_DEPRECATED float* drflac_open_and_decode_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_and_read_pcm_frames_f32(). */ +DRFLAC_DEPRECATED drflac_int32* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_file_and_read_pcm_frames_s32(). */ +DRFLAC_DEPRECATED drflac_int16* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_file_and_read_pcm_frames_s16(). */ +DRFLAC_DEPRECATED float* drflac_open_and_decode_file_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_file_and_read_pcm_frames_f32(). */ +DRFLAC_DEPRECATED drflac_int32* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_memory_and_read_pcm_frames_s32(). */ +DRFLAC_DEPRECATED drflac_int16* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_memory_and_read_pcm_frames_s16(). */ +DRFLAC_DEPRECATED float* drflac_open_and_decode_memory_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalSampleCount); /* Use drflac_open_memory_and_read_pcm_frames_f32(). */ + +#ifdef __cplusplus +} +#endif +#endif /* dr_flac_h */ + + +/************************************************************************************************************************************************************ + ************************************************************************************************************************************************************ + + IMPLEMENTATION + + ************************************************************************************************************************************************************ + ************************************************************************************************************************************************************/ +#ifdef DR_FLAC_IMPLEMENTATION + +/* Disable some annoying warnings. */ +#if defined(__GNUC__) + #pragma GCC diagnostic push + #if __GNUC__ >= 7 + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" + #endif +#endif + +#ifdef __linux__ + #ifndef _BSD_SOURCE + #define _BSD_SOURCE + #endif + #ifndef __USE_BSD + #define __USE_BSD + #endif + #include +#endif + +#include +#include + +#ifdef _MSC_VER +#define DRFLAC_INLINE __forceinline +#else +#ifdef __GNUC__ +#define DRFLAC_INLINE __inline__ __attribute__((always_inline)) +#else +#define DRFLAC_INLINE +#endif +#endif + +/* CPU architecture. */ +#if defined(__x86_64__) || defined(_M_X64) + #define DRFLAC_X64 +#elif defined(__i386) || defined(_M_IX86) + #define DRFLAC_X86 +#elif defined(__arm__) || defined(_M_ARM) + #define DRFLAC_ARM +#endif + +/* Intrinsics Support */ +#if !defined(DR_FLAC_NO_SIMD) + #if defined(DRFLAC_X64) || defined(DRFLAC_X86) + #if defined(_MSC_VER) && !defined(__clang__) + /* MSVC. */ + #if _MSC_VER >= 1400 && !defined(DRFLAC_NO_SSE2) /* 2005 */ + #define DRFLAC_SUPPORT_SSE2 + #endif + #if _MSC_VER >= 1600 && !defined(DRFLAC_NO_SSE41) /* 2010 */ + #define DRFLAC_SUPPORT_SSE41 + #endif + #else + /* Assume GNUC-style. */ + #if defined(__SSE2__) && !defined(DRFLAC_NO_SSE2) + #define DRFLAC_SUPPORT_SSE2 + #endif + #if defined(__SSE4_1__) && !defined(DRFLAC_NO_SSE41) + #define DRFLAC_SUPPORT_SSE41 + #endif + #endif + + /* If at this point we still haven't determined compiler support for the intrinsics just fall back to __has_include. */ + #if !defined(__GNUC__) && !defined(__clang__) && defined(__has_include) + #if !defined(DRFLAC_SUPPORT_SSE2) && !defined(DRFLAC_NO_SSE2) && __has_include() + #define DRFLAC_SUPPORT_SSE2 + #endif + #if !defined(DRFLAC_SUPPORT_SSE41) && !defined(DRFLAC_NO_SSE41) && __has_include() + #define DRFLAC_SUPPORT_SSE41 + #endif + #endif + + #if defined(DRFLAC_SUPPORT_SSE41) + #include + #elif defined(DRFLAC_SUPPORT_SSE2) + #include + #endif + #endif + + #if defined(DRFLAC_ARM) + #if !defined(DRFLAC_NO_NEON) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)) + #define DRFLAC_SUPPORT_NEON + #endif + + /* Fall back to looking for the #include file. */ + #if !defined(__GNUC__) && !defined(__clang__) && defined(__has_include) + #if !defined(DRFLAC_SUPPORT_NEON) && !defined(DRFLAC_NO_NEON) && __has_include() + #define DRFLAC_SUPPORT_NEON + #endif + #endif + + #if defined(DRFLAC_SUPPORT_NEON) + #include + #endif + #endif +#endif + +/* Compile-time CPU feature support. */ +#if !defined(DR_FLAC_NO_SIMD) && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) + #if defined(_MSC_VER) && !defined(__clang__) + #if _MSC_VER >= 1400 + #include + static void drflac__cpuid(int info[4], int fid) + { + __cpuid(info, fid); + } + #else + #define DRFLAC_NO_CPUID + #endif + #else + #if defined(__GNUC__) || defined(__clang__) + static void drflac__cpuid(int info[4], int fid) + { + /* + It looks like the -fPIC option uses the ebx register which GCC complains about. We can work around this by just using a different register, the + specific register of which I'm letting the compiler decide on. The "k" prefix is used to specify a 32-bit register. The {...} syntax is for + supporting different assembly dialects. + + What's basically happening is that we're saving and restoring the ebx register manually. + */ + #if defined(DRFLAC_X86) && defined(__PIC__) + __asm__ __volatile__ ( + "xchg{l} {%%}ebx, %k1;" + "cpuid;" + "xchg{l} {%%}ebx, %k1;" + : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0) + ); + #else + __asm__ __volatile__ ( + "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0) + ); + #endif + } + #else + #define DRFLAC_NO_CPUID + #endif + #endif +#else + #define DRFLAC_NO_CPUID +#endif + +static DRFLAC_INLINE drflac_bool32 drflac_has_sse2() +{ +#if defined(DRFLAC_SUPPORT_SSE2) + #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE2) + #if defined(DRFLAC_X64) + return DRFLAC_TRUE; /* 64-bit targets always support SSE2. */ + #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__) + return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE2 code we can assume support. */ + #else + #if defined(DRFLAC_NO_CPUID) + return DRFLAC_FALSE; + #else + int info[4]; + drflac__cpuid(info, 1); + return (info[3] & (1 << 26)) != 0; + #endif + #endif + #else + return DRFLAC_FALSE; /* SSE2 is only supported on x86 and x64 architectures. */ + #endif +#else + return DRFLAC_FALSE; /* No compiler support. */ +#endif +} + +static DRFLAC_INLINE drflac_bool32 drflac_has_sse41() +{ +#if defined(DRFLAC_SUPPORT_SSE41) + #if (defined(DRFLAC_X64) || defined(DRFLAC_X86)) && !defined(DRFLAC_NO_SSE41) + #if defined(DRFLAC_X64) + return DRFLAC_TRUE; /* 64-bit targets always support SSE4.1. */ + #elif (defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE4_1__) + return DRFLAC_TRUE; /* If the compiler is allowed to freely generate SSE41 code we can assume support. */ + #else + #if defined(DRFLAC_NO_CPUID) + return DRFLAC_FALSE; + #else + int info[4]; + drflac__cpuid(info, 1); + return (info[2] & (1 << 19)) != 0; + #endif + #endif + #else + return DRFLAC_FALSE; /* SSE41 is only supported on x86 and x64 architectures. */ + #endif +#else + return DRFLAC_FALSE; /* No compiler support. */ +#endif +} + + +#if defined(_MSC_VER) && _MSC_VER >= 1500 && (defined(DRFLAC_X86) || defined(DRFLAC_X64)) + #define DRFLAC_HAS_LZCNT_INTRINSIC +#elif (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) + #define DRFLAC_HAS_LZCNT_INTRINSIC +#elif defined(__clang__) + #if __has_builtin(__builtin_clzll) || __has_builtin(__builtin_clzl) + #define DRFLAC_HAS_LZCNT_INTRINSIC + #endif +#endif + +#if defined(_MSC_VER) && _MSC_VER >= 1300 + #define DRFLAC_HAS_BYTESWAP16_INTRINSIC + #define DRFLAC_HAS_BYTESWAP32_INTRINSIC + #define DRFLAC_HAS_BYTESWAP64_INTRINSIC +#elif defined(__clang__) + #if __has_builtin(__builtin_bswap16) + #define DRFLAC_HAS_BYTESWAP16_INTRINSIC + #endif + #if __has_builtin(__builtin_bswap32) + #define DRFLAC_HAS_BYTESWAP32_INTRINSIC + #endif + #if __has_builtin(__builtin_bswap64) + #define DRFLAC_HAS_BYTESWAP64_INTRINSIC + #endif +#elif defined(__GNUC__) + #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define DRFLAC_HAS_BYTESWAP32_INTRINSIC + #define DRFLAC_HAS_BYTESWAP64_INTRINSIC + #endif + #if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) + #define DRFLAC_HAS_BYTESWAP16_INTRINSIC + #endif +#endif + + +/* Standard library stuff. */ +#ifndef DRFLAC_ASSERT +#include +#define DRFLAC_ASSERT(expression) assert(expression) +#endif +#ifndef DRFLAC_MALLOC +#define DRFLAC_MALLOC(sz) malloc((sz)) +#endif +#ifndef DRFLAC_REALLOC +#define DRFLAC_REALLOC(p, sz) realloc((p), (sz)) +#endif +#ifndef DRFLAC_FREE +#define DRFLAC_FREE(p) free((p)) +#endif +#ifndef DRFLAC_COPY_MEMORY +#define DRFLAC_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) +#endif +#ifndef DRFLAC_ZERO_MEMORY +#define DRFLAC_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) +#endif + +#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */ + +typedef drflac_int32 drflac_result; +#define DRFLAC_SUCCESS 0 +#define DRFLAC_ERROR -1 /* A generic error. */ +#define DRFLAC_INVALID_ARGS -2 +#define DRFLAC_END_OF_STREAM -128 +#define DRFLAC_CRC_MISMATCH -129 + +#define DRFLAC_SUBFRAME_CONSTANT 0 +#define DRFLAC_SUBFRAME_VERBATIM 1 +#define DRFLAC_SUBFRAME_FIXED 8 +#define DRFLAC_SUBFRAME_LPC 32 +#define DRFLAC_SUBFRAME_RESERVED 255 + +#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE 0 +#define DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2 1 + +#define DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT 0 +#define DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE 8 +#define DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE 9 +#define DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE 10 + +/* +Keeps track of the number of leading samples for each sub-frame. This is required because the SSE pipeline will occasionally +reference excess prior samples. +*/ +#define DRFLAC_LEADING_SAMPLES 32 + + +#define drflac_align(x, a) ((((x) + (a) - 1) / (a)) * (a)) +#define drflac_assert DRFLAC_ASSERT +#define drflac_copy_memory DRFLAC_COPY_MEMORY +#define drflac_zero_memory DRFLAC_ZERO_MEMORY + + +/* CPU caps. */ +static drflac_bool32 drflac__gIsLZCNTSupported = DRFLAC_FALSE; +#ifndef DRFLAC_NO_CPUID +/* +I've had a bug report that Clang's ThreadSanitizer presents a warning in this function. Having reviewed this, this does +actually make sense. However, since CPU caps should never differ for a running process, I don't think the trade off of +complicating internal API's by passing around CPU caps versus just disabling the warnings is worthwhile. I'm therefore +just going to disable these warnings. +*/ +#if defined(__has_feature) + #if __has_feature(thread_sanitizer) + #define DRFLAC_NO_THREAD_SANITIZE __attribute__((no_sanitize("thread"))) + #else + #define DRFLAC_NO_THREAD_SANITIZE + #endif +#else + #define DRFLAC_NO_THREAD_SANITIZE +#endif +static drflac_bool32 drflac__gIsSSE2Supported = DRFLAC_FALSE; +static drflac_bool32 drflac__gIsSSE41Supported = DRFLAC_FALSE; +DRFLAC_NO_THREAD_SANITIZE static void drflac__init_cpu_caps() +{ + static drflac_bool32 isCPUCapsInitialized = DRFLAC_FALSE; + + if (!isCPUCapsInitialized) { + int info[4] = {0}; + + /* LZCNT */ + drflac__cpuid(info, 0x80000001); + drflac__gIsLZCNTSupported = (info[2] & (1 << 5)) != 0; + + /* SSE2 */ + drflac__gIsSSE2Supported = drflac_has_sse2(); + + /* SSE4.1 */ + drflac__gIsSSE41Supported = drflac_has_sse41(); + + /* Initialized. */ + isCPUCapsInitialized = DRFLAC_TRUE; + } +} +#endif + + +/* Endian Management */ +static DRFLAC_INLINE drflac_bool32 drflac__is_little_endian() +{ +#if defined(DRFLAC_X86) || defined(DRFLAC_X64) + return DRFLAC_TRUE; +#elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN + return DRFLAC_TRUE; +#else + int n = 1; + return (*(char*)&n) == 1; +#endif +} + +static DRFLAC_INLINE drflac_uint16 drflac__swap_endian_uint16(drflac_uint16 n) +{ +#ifdef DRFLAC_HAS_BYTESWAP16_INTRINSIC + #if defined(_MSC_VER) + return _byteswap_ushort(n); + #elif defined(__GNUC__) || defined(__clang__) + return __builtin_bswap16(n); + #else + #error "This compiler does not support the byte swap intrinsic." + #endif +#else + return ((n & 0xFF00) >> 8) | + ((n & 0x00FF) << 8); +#endif +} + +static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n) +{ +#ifdef DRFLAC_HAS_BYTESWAP32_INTRINSIC + #if defined(_MSC_VER) + return _byteswap_ulong(n); + #elif defined(__GNUC__) || defined(__clang__) + return __builtin_bswap32(n); + #else + #error "This compiler does not support the byte swap intrinsic." + #endif +#else + return ((n & 0xFF000000) >> 24) | + ((n & 0x00FF0000) >> 8) | + ((n & 0x0000FF00) << 8) | + ((n & 0x000000FF) << 24); +#endif +} + +static DRFLAC_INLINE drflac_uint64 drflac__swap_endian_uint64(drflac_uint64 n) +{ +#ifdef DRFLAC_HAS_BYTESWAP64_INTRINSIC + #if defined(_MSC_VER) + return _byteswap_uint64(n); + #elif defined(__GNUC__) || defined(__clang__) + return __builtin_bswap64(n); + #else + #error "This compiler does not support the byte swap intrinsic." + #endif +#else + return ((n & (drflac_uint64)0xFF00000000000000) >> 56) | + ((n & (drflac_uint64)0x00FF000000000000) >> 40) | + ((n & (drflac_uint64)0x0000FF0000000000) >> 24) | + ((n & (drflac_uint64)0x000000FF00000000) >> 8) | + ((n & (drflac_uint64)0x00000000FF000000) << 8) | + ((n & (drflac_uint64)0x0000000000FF0000) << 24) | + ((n & (drflac_uint64)0x000000000000FF00) << 40) | + ((n & (drflac_uint64)0x00000000000000FF) << 56); +#endif +} + + +static DRFLAC_INLINE drflac_uint16 drflac__be2host_16(drflac_uint16 n) +{ + if (drflac__is_little_endian()) { + return drflac__swap_endian_uint16(n); + } + + return n; +} + +static DRFLAC_INLINE drflac_uint32 drflac__be2host_32(drflac_uint32 n) +{ + if (drflac__is_little_endian()) { + return drflac__swap_endian_uint32(n); + } + + return n; +} + +static DRFLAC_INLINE drflac_uint64 drflac__be2host_64(drflac_uint64 n) +{ + if (drflac__is_little_endian()) { + return drflac__swap_endian_uint64(n); + } + + return n; +} + + +static DRFLAC_INLINE drflac_uint32 drflac__le2host_32(drflac_uint32 n) +{ + if (!drflac__is_little_endian()) { + return drflac__swap_endian_uint32(n); + } + + return n; +} + + +static DRFLAC_INLINE drflac_uint32 drflac__unsynchsafe_32(drflac_uint32 n) +{ + drflac_uint32 result = 0; + result |= (n & 0x7F000000) >> 3; + result |= (n & 0x007F0000) >> 2; + result |= (n & 0x00007F00) >> 1; + result |= (n & 0x0000007F) >> 0; + + return result; +} + + + +/* The CRC code below is based on this document: http://zlib.net/crc_v3.txt */ +static drflac_uint8 drflac__crc8_table[] = { + 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, + 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, + 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, + 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, + 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, + 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, + 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, + 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, + 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, + 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, + 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, + 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, + 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, + 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, + 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, + 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 +}; + +static drflac_uint16 drflac__crc16_table[] = { + 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, + 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, + 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, + 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, + 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, + 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, + 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, + 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, + 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, + 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, + 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, + 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, + 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, + 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, + 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, + 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, + 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, + 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, + 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, + 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, + 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, + 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, + 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, + 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, + 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 +}; + +static DRFLAC_INLINE drflac_uint8 drflac_crc8_byte(drflac_uint8 crc, drflac_uint8 data) +{ + return drflac__crc8_table[crc ^ data]; +} + +static DRFLAC_INLINE drflac_uint8 drflac_crc8(drflac_uint8 crc, drflac_uint32 data, drflac_uint32 count) +{ +#ifdef DR_FLAC_NO_CRC + (void)crc; + (void)data; + (void)count; + return 0; +#else +#if 0 + /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc8(crc, 0, 8);") */ + drflac_uint8 p = 0x07; + for (int i = count-1; i >= 0; --i) { + drflac_uint8 bit = (data & (1 << i)) >> i; + if (crc & 0x80) { + crc = ((crc << 1) | bit) ^ p; + } else { + crc = ((crc << 1) | bit); + } + } + return crc; +#else + drflac_uint32 wholeBytes; + drflac_uint32 leftoverBits; + drflac_uint64 leftoverDataMask; + + static drflac_uint64 leftoverDataMaskTable[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F + }; + + drflac_assert(count <= 32); + + wholeBytes = count >> 3; + leftoverBits = count - (wholeBytes*8); + leftoverDataMask = leftoverDataMaskTable[leftoverBits]; + + switch (wholeBytes) { + case 4: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits))); + case 3: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits))); + case 2: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits))); + case 1: crc = drflac_crc8_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits))); + case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc8_table[(crc >> (8 - leftoverBits)) ^ (data & leftoverDataMask)]; + } + return crc; +#endif +#endif +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16_byte(drflac_uint16 crc, drflac_uint8 data) +{ + return (crc << 8) ^ drflac__crc16_table[(drflac_uint8)(crc >> 8) ^ data]; +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16_bytes(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 byteCount) +{ + switch (byteCount) + { +#ifdef DRFLAC_64BIT + case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 56) & 0xFF)); + case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 48) & 0xFF)); + case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 40) & 0xFF)); + case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 32) & 0xFF)); +#endif + case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 24) & 0xFF)); + case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 16) & 0xFF)); + case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 8) & 0xFF)); + case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data >> 0) & 0xFF)); + } + + return crc; +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16__32bit(drflac_uint16 crc, drflac_uint32 data, drflac_uint32 count) +{ +#ifdef DR_FLAC_NO_CRC + (void)crc; + (void)data; + (void)count; + return 0; +#else +#if 0 + /* REFERENCE (use of this implementation requires an explicit flush by doing "drflac_crc16(crc, 0, 16);") */ + drflac_uint16 p = 0x8005; + for (int i = count-1; i >= 0; --i) { + drflac_uint16 bit = (data & (1ULL << i)) >> i; + if (r & 0x8000) { + r = ((r << 1) | bit) ^ p; + } else { + r = ((r << 1) | bit); + } + } + + return crc; +#else + drflac_uint32 wholeBytes; + drflac_uint32 leftoverBits; + drflac_uint64 leftoverDataMask; + + static drflac_uint64 leftoverDataMaskTable[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F + }; + + drflac_assert(count <= 64); + + wholeBytes = count >> 3; + leftoverBits = count - (wholeBytes*8); + leftoverDataMask = leftoverDataMaskTable[leftoverBits]; + + switch (wholeBytes) { + default: + case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0xFF000000UL << leftoverBits)) >> (24 + leftoverBits))); + case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x00FF0000UL << leftoverBits)) >> (16 + leftoverBits))); + case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x0000FF00UL << leftoverBits)) >> ( 8 + leftoverBits))); + case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (0x000000FFUL << leftoverBits)) >> ( 0 + leftoverBits))); + case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)]; + } + return crc; +#endif +#endif +} + +static DRFLAC_INLINE drflac_uint16 drflac_crc16__64bit(drflac_uint16 crc, drflac_uint64 data, drflac_uint32 count) +{ +#ifdef DR_FLAC_NO_CRC + (void)crc; + (void)data; + (void)count; + return 0; +#else + drflac_uint32 wholeBytes; + drflac_uint32 leftoverBits; + drflac_uint64 leftoverDataMask; + + static drflac_uint64 leftoverDataMaskTable[8] = { + 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F + }; + + drflac_assert(count <= 64); + + wholeBytes = count >> 3; + leftoverBits = count - (wholeBytes*8); + leftoverDataMask = leftoverDataMaskTable[leftoverBits]; + + switch (wholeBytes) { + default: + case 8: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 << 32) << leftoverBits)) >> (56 + leftoverBits))); /* Weird "<< 32" bitshift is required for C89 because it doesn't support 64-bit constants. Should be optimized out by a good compiler. */ + case 7: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 << 32) << leftoverBits)) >> (48 + leftoverBits))); + case 6: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 << 32) << leftoverBits)) >> (40 + leftoverBits))); + case 5: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF << 32) << leftoverBits)) >> (32 + leftoverBits))); + case 4: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0xFF000000 ) << leftoverBits)) >> (24 + leftoverBits))); + case 3: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x00FF0000 ) << leftoverBits)) >> (16 + leftoverBits))); + case 2: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x0000FF00 ) << leftoverBits)) >> ( 8 + leftoverBits))); + case 1: crc = drflac_crc16_byte(crc, (drflac_uint8)((data & (((drflac_uint64)0x000000FF ) << leftoverBits)) >> ( 0 + leftoverBits))); + case 0: if (leftoverBits > 0) crc = (crc << leftoverBits) ^ drflac__crc16_table[(crc >> (16 - leftoverBits)) ^ (data & leftoverDataMask)]; + } + return crc; +#endif +} + + +static DRFLAC_INLINE drflac_uint16 drflac_crc16(drflac_uint16 crc, drflac_cache_t data, drflac_uint32 count) +{ +#ifdef DRFLAC_64BIT + return drflac_crc16__64bit(crc, data, count); +#else + return drflac_crc16__32bit(crc, data, count); +#endif +} + + +#ifdef DRFLAC_64BIT +#define drflac__be2host__cache_line drflac__be2host_64 +#else +#define drflac__be2host__cache_line drflac__be2host_32 +#endif + +/* +BIT READING ATTEMPT #2 + +This uses a 32- or 64-bit bit-shifted cache - as bits are read, the cache is shifted such that the first valid bit is sitting +on the most significant bit. It uses the notion of an L1 and L2 cache (borrowed from CPU architecture), where the L1 cache +is a 32- or 64-bit unsigned integer (depending on whether or not a 32- or 64-bit build is being compiled) and the L2 is an +array of "cache lines", with each cache line being the same size as the L1. The L2 is a buffer of about 4KB and is where data +from onRead() is read into. +*/ +#define DRFLAC_CACHE_L1_SIZE_BYTES(bs) (sizeof((bs)->cache)) +#define DRFLAC_CACHE_L1_SIZE_BITS(bs) (sizeof((bs)->cache)*8) +#define DRFLAC_CACHE_L1_BITS_REMAINING(bs) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (bs)->consumedBits) +#define DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount) (~((~(drflac_cache_t)0) >> (_bitCount))) +#define DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SIZE_BITS(bs) - (_bitCount)) +#define DRFLAC_CACHE_L1_SELECT(bs, _bitCount) (((bs)->cache) & DRFLAC_CACHE_L1_SELECTION_MASK(_bitCount)) +#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, _bitCount) (DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount))) +#define DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, _bitCount)(DRFLAC_CACHE_L1_SELECT((bs), (_bitCount)) >> (DRFLAC_CACHE_L1_SELECTION_SHIFT((bs), (_bitCount)) & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1))) +#define DRFLAC_CACHE_L2_SIZE_BYTES(bs) (sizeof((bs)->cacheL2)) +#define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0])) +#define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line) + + +#ifndef DR_FLAC_NO_CRC +static DRFLAC_INLINE void drflac__reset_crc16(drflac_bs* bs) +{ + bs->crc16 = 0; + bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3; +} + +static DRFLAC_INLINE void drflac__update_crc16(drflac_bs* bs) +{ + bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache, DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bs->crc16CacheIgnoredBytes); + bs->crc16CacheIgnoredBytes = 0; +} + +static DRFLAC_INLINE drflac_uint16 drflac__flush_crc16(drflac_bs* bs) +{ + /* We should never be flushing in a situation where we are not aligned on a byte boundary. */ + drflac_assert((DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7) == 0); + + /* + The bits that were read from the L1 cache need to be accumulated. The number of bytes needing to be accumulated is determined + by the number of bits that have been consumed. + */ + if (DRFLAC_CACHE_L1_BITS_REMAINING(bs) == 0) { + drflac__update_crc16(bs); + } else { + /* We only accumulate the consumed bits. */ + bs->crc16 = drflac_crc16_bytes(bs->crc16, bs->crc16Cache >> DRFLAC_CACHE_L1_BITS_REMAINING(bs), (bs->consumedBits >> 3) - bs->crc16CacheIgnoredBytes); + + /* + The bits that we just accumulated should never be accumulated again. We need to keep track of how many bytes were accumulated + so we can handle that later. + */ + bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3; + } + + return bs->crc16; +} +#endif + +static DRFLAC_INLINE drflac_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) +{ + size_t bytesRead; + size_t alignedL1LineCount; + + /* Fast path. Try loading straight from L2. */ + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + bs->cache = bs->cacheL2[bs->nextL2Line++]; + return DRFLAC_TRUE; + } + + /* + If we get here it means we've run out of data in the L2 cache. We'll need to fetch more from the client, if there's + any left. + */ + if (bs->unalignedByteCount > 0) { + return DRFLAC_FALSE; /* If we have any unaligned bytes it means there's no more aligned bytes left in the client. */ + } + + bytesRead = bs->onRead(bs->pUserData, bs->cacheL2, DRFLAC_CACHE_L2_SIZE_BYTES(bs)); + + bs->nextL2Line = 0; + if (bytesRead == DRFLAC_CACHE_L2_SIZE_BYTES(bs)) { + bs->cache = bs->cacheL2[bs->nextL2Line++]; + return DRFLAC_TRUE; + } + + + /* + If we get here it means we were unable to retrieve enough data to fill the entire L2 cache. It probably + means we've just reached the end of the file. We need to move the valid data down to the end of the buffer + and adjust the index of the next line accordingly. Also keep in mind that the L2 cache must be aligned to + the size of the L1 so we'll need to seek backwards by any misaligned bytes. + */ + alignedL1LineCount = bytesRead / DRFLAC_CACHE_L1_SIZE_BYTES(bs); + + /* We need to keep track of any unaligned bytes for later use. */ + bs->unalignedByteCount = bytesRead - (alignedL1LineCount * DRFLAC_CACHE_L1_SIZE_BYTES(bs)); + if (bs->unalignedByteCount > 0) { + bs->unalignedCache = bs->cacheL2[alignedL1LineCount]; + } + + if (alignedL1LineCount > 0) { + size_t offset = DRFLAC_CACHE_L2_LINE_COUNT(bs) - alignedL1LineCount; + size_t i; + for (i = alignedL1LineCount; i > 0; --i) { + bs->cacheL2[i-1 + offset] = bs->cacheL2[i-1]; + } + + bs->nextL2Line = (drflac_uint32)offset; + bs->cache = bs->cacheL2[bs->nextL2Line++]; + return DRFLAC_TRUE; + } else { + /* If we get into this branch it means we weren't able to load any L1-aligned data. */ + bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs); + return DRFLAC_FALSE; + } +} + +static drflac_bool32 drflac__reload_cache(drflac_bs* bs) +{ + size_t bytesRead; + +#ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); +#endif + + /* Fast path. Try just moving the next value in the L2 cache to the L1 cache. */ + if (drflac__reload_l1_cache_from_l2(bs)) { + bs->cache = drflac__be2host__cache_line(bs->cache); + bs->consumedBits = 0; +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs->cache; +#endif + return DRFLAC_TRUE; + } + + /* Slow path. */ + + /* + If we get here it means we have failed to load the L1 cache from the L2. Likely we've just reached the end of the stream and the last + few bytes did not meet the alignment requirements for the L2 cache. In this case we need to fall back to a slower path and read the + data from the unaligned cache. + */ + bytesRead = bs->unalignedByteCount; + if (bytesRead == 0) { + bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- The stream has been exhausted, so marked the bits as consumed. */ + return DRFLAC_FALSE; + } + + drflac_assert(bytesRead < DRFLAC_CACHE_L1_SIZE_BYTES(bs)); + bs->consumedBits = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BYTES(bs) - bytesRead) * 8; + + bs->cache = drflac__be2host__cache_line(bs->unalignedCache); + bs->cache &= DRFLAC_CACHE_L1_SELECTION_MASK(DRFLAC_CACHE_L1_BITS_REMAINING(bs)); /* <-- Make sure the consumed bits are always set to zero. Other parts of the library depend on this property. */ + bs->unalignedByteCount = 0; /* <-- At this point the unaligned bytes have been moved into the cache and we thus have no more unaligned bytes. */ + +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs->cache >> bs->consumedBits; + bs->crc16CacheIgnoredBytes = bs->consumedBits >> 3; +#endif + return DRFLAC_TRUE; +} + +static void drflac__reset_cache(drflac_bs* bs) +{ + bs->nextL2Line = DRFLAC_CACHE_L2_LINE_COUNT(bs); /* <-- This clears the L2 cache. */ + bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); /* <-- This clears the L1 cache. */ + bs->cache = 0; + bs->unalignedByteCount = 0; /* <-- This clears the trailing unaligned bytes. */ + bs->unalignedCache = 0; + +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = 0; + bs->crc16CacheIgnoredBytes = 0; +#endif +} + + +static DRFLAC_INLINE drflac_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, drflac_uint32* pResultOut) +{ + drflac_assert(bs != NULL); + drflac_assert(pResultOut != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 32); + + if (bs->consumedBits == DRFLAC_CACHE_L1_SIZE_BITS(bs)) { + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + } + + if (bitCount <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) { + /* + If we want to load all 32-bits from a 32-bit cache we need to do it slightly differently because we can't do + a 32-bit shift on a 32-bit integer. This will never be the case on 64-bit caches, so we can have a slightly + more optimal solution for this. + */ +#ifdef DRFLAC_64BIT + *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount); + bs->consumedBits += bitCount; + bs->cache <<= bitCount; +#else + if (bitCount < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { + *pResultOut = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCount); + bs->consumedBits += bitCount; + bs->cache <<= bitCount; + } else { + /* Cannot shift by 32-bits, so need to do it differently. */ + *pResultOut = (drflac_uint32)bs->cache; + bs->consumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs); + bs->cache = 0; + } +#endif + + return DRFLAC_TRUE; + } else { + /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */ + drflac_uint32 bitCountHi = DRFLAC_CACHE_L1_BITS_REMAINING(bs); + drflac_uint32 bitCountLo = bitCount - bitCountHi; + drflac_uint32 resultHi = (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountHi); + + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + *pResultOut = (resultHi << bitCountLo) | (drflac_uint32)DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, bitCountLo); + bs->consumedBits += bitCountLo; + bs->cache <<= bitCountLo; + return DRFLAC_TRUE; + } +} + +static drflac_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, drflac_int32* pResult) +{ + drflac_uint32 result; + drflac_uint32 signbit; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 32); + + if (!drflac__read_uint32(bs, bitCount, &result)) { + return DRFLAC_FALSE; + } + + signbit = ((result >> (bitCount-1)) & 0x01); + result |= (~signbit + 1) << bitCount; + + *pResult = (drflac_int32)result; + return DRFLAC_TRUE; +} + +#ifdef DRFLAC_64BIT +static drflac_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, drflac_uint64* pResultOut) +{ + drflac_uint32 resultHi; + drflac_uint32 resultLo; + + drflac_assert(bitCount <= 64); + drflac_assert(bitCount > 32); + + if (!drflac__read_uint32(bs, bitCount - 32, &resultHi)) { + return DRFLAC_FALSE; + } + + if (!drflac__read_uint32(bs, 32, &resultLo)) { + return DRFLAC_FALSE; + } + + *pResultOut = (((drflac_uint64)resultHi) << 32) | ((drflac_uint64)resultLo); + return DRFLAC_TRUE; +} +#endif + +/* Function below is unused, but leaving it here in case I need to quickly add it again. */ +#if 0 +static drflac_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, drflac_int64* pResultOut) +{ + drflac_uint64 result; + drflac_uint64 signbit; + + drflac_assert(bitCount <= 64); + + if (!drflac__read_uint64(bs, bitCount, &result)) { + return DRFLAC_FALSE; + } + + signbit = ((result >> (bitCount-1)) & 0x01); + result |= (~signbit + 1) << bitCount; + + *pResultOut = (drflac_int64)result; + return DRFLAC_TRUE; +} +#endif + +static drflac_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, drflac_uint16* pResult) +{ + drflac_uint32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 16); + + if (!drflac__read_uint32(bs, bitCount, &result)) { + return DRFLAC_FALSE; + } + + *pResult = (drflac_uint16)result; + return DRFLAC_TRUE; +} + +#if 0 +static drflac_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, drflac_int16* pResult) +{ + drflac_int32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 16); + + if (!drflac__read_int32(bs, bitCount, &result)) { + return DRFLAC_FALSE; + } + + *pResult = (drflac_int16)result; + return DRFLAC_TRUE; +} +#endif + +static drflac_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, drflac_uint8* pResult) +{ + drflac_uint32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 8); + + if (!drflac__read_uint32(bs, bitCount, &result)) { + return DRFLAC_FALSE; + } + + *pResult = (drflac_uint8)result; + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, drflac_int8* pResult) +{ + drflac_int32 result; + + drflac_assert(bs != NULL); + drflac_assert(pResult != NULL); + drflac_assert(bitCount > 0); + drflac_assert(bitCount <= 8); + + if (!drflac__read_int32(bs, bitCount, &result)) { + return DRFLAC_FALSE; + } + + *pResult = (drflac_int8)result; + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) +{ + if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) { + bs->consumedBits += (drflac_uint32)bitsToSeek; + bs->cache <<= bitsToSeek; + return DRFLAC_TRUE; + } else { + /* It straddles the cached data. This function isn't called too frequently so I'm favouring simplicity here. */ + bitsToSeek -= DRFLAC_CACHE_L1_BITS_REMAINING(bs); + bs->consumedBits += DRFLAC_CACHE_L1_BITS_REMAINING(bs); + bs->cache = 0; + + /* Simple case. Seek in groups of the same number as bits that fit within a cache line. */ +#ifdef DRFLAC_64BIT + while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) { + drflac_uint64 bin; + if (!drflac__read_uint64(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) { + return DRFLAC_FALSE; + } + bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs); + } +#else + while (bitsToSeek >= DRFLAC_CACHE_L1_SIZE_BITS(bs)) { + drflac_uint32 bin; + if (!drflac__read_uint32(bs, DRFLAC_CACHE_L1_SIZE_BITS(bs), &bin)) { + return DRFLAC_FALSE; + } + bitsToSeek -= DRFLAC_CACHE_L1_SIZE_BITS(bs); + } +#endif + + /* Whole leftover bytes. */ + while (bitsToSeek >= 8) { + drflac_uint8 bin; + if (!drflac__read_uint8(bs, 8, &bin)) { + return DRFLAC_FALSE; + } + bitsToSeek -= 8; + } + + /* Leftover bits. */ + if (bitsToSeek > 0) { + drflac_uint8 bin; + if (!drflac__read_uint8(bs, (drflac_uint32)bitsToSeek, &bin)) { + return DRFLAC_FALSE; + } + bitsToSeek = 0; /* <-- Necessary for the assert below. */ + } + + drflac_assert(bitsToSeek == 0); + return DRFLAC_TRUE; + } +} + + +/* This function moves the bit streamer to the first bit after the sync code (bit 15 of the of the frame header). It will also update the CRC-16. */ +static drflac_bool32 drflac__find_and_seek_to_next_sync_code(drflac_bs* bs) +{ + drflac_assert(bs != NULL); + + /* + The sync code is always aligned to 8 bits. This is convenient for us because it means we can do byte-aligned movements. The first + thing to do is align to the next byte. + */ + if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) { + return DRFLAC_FALSE; + } + + for (;;) { + drflac_uint8 hi; + +#ifndef DR_FLAC_NO_CRC + drflac__reset_crc16(bs); +#endif + + if (!drflac__read_uint8(bs, 8, &hi)) { + return DRFLAC_FALSE; + } + + if (hi == 0xFF) { + drflac_uint8 lo; + if (!drflac__read_uint8(bs, 6, &lo)) { + return DRFLAC_FALSE; + } + + if (lo == 0x3E) { + return DRFLAC_TRUE; + } else { + if (!drflac__seek_bits(bs, DRFLAC_CACHE_L1_BITS_REMAINING(bs) & 7)) { + return DRFLAC_FALSE; + } + } + } + } + + /* Should never get here. */ + /*return DRFLAC_FALSE;*/ +} + + +#if !defined(DR_FLAC_NO_SIMD) && defined(DRFLAC_HAS_LZCNT_INTRINSIC) +#define DRFLAC_IMPLEMENT_CLZ_LZCNT +#endif +#if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(DRFLAC_X64) || defined(DRFLAC_X86)) +#define DRFLAC_IMPLEMENT_CLZ_MSVC +#endif + +static DRFLAC_INLINE drflac_uint32 drflac__clz_software(drflac_cache_t x) +{ + drflac_uint32 n; + static drflac_uint32 clz_table_4[] = { + 0, + 4, + 3, 3, + 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + + if (x == 0) { + return sizeof(x)*8; + } + + n = clz_table_4[x >> (sizeof(x)*8 - 4)]; + if (n == 0) { +#ifdef DRFLAC_64BIT + if ((x & ((drflac_uint64)0xFFFFFFFF << 32)) == 0) { n = 32; x <<= 32; } + if ((x & ((drflac_uint64)0xFFFF0000 << 32)) == 0) { n += 16; x <<= 16; } + if ((x & ((drflac_uint64)0xFF000000 << 32)) == 0) { n += 8; x <<= 8; } + if ((x & ((drflac_uint64)0xF0000000 << 32)) == 0) { n += 4; x <<= 4; } +#else + if ((x & 0xFFFF0000) == 0) { n = 16; x <<= 16; } + if ((x & 0xFF000000) == 0) { n += 8; x <<= 8; } + if ((x & 0xF0000000) == 0) { n += 4; x <<= 4; } +#endif + n += clz_table_4[x >> (sizeof(x)*8 - 4)]; + } + + return n - 1; +} + +#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT +static DRFLAC_INLINE drflac_bool32 drflac__is_lzcnt_supported() +{ + /* If the compiler itself does not support the intrinsic then we'll need to return false. */ +#ifdef DRFLAC_HAS_LZCNT_INTRINSIC + return drflac__gIsLZCNTSupported; +#else + return DRFLAC_FALSE; +#endif +} + +static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x) +{ +#if defined(_MSC_VER) && !defined(__clang__) + #ifdef DRFLAC_64BIT + return (drflac_uint32)__lzcnt64(x); + #else + return (drflac_uint32)__lzcnt(x); + #endif +#else + #if defined(__GNUC__) || defined(__clang__) + if (x == 0) { + return sizeof(x)*8; + } + #ifdef DRFLAC_64BIT + return (drflac_uint32)__builtin_clzll((drflac_uint64)x); + #else + return (drflac_uint32)__builtin_clzl((drflac_uint32)x); + #endif + #else + /* Unsupported compiler. */ + #error "This compiler does not support the lzcnt intrinsic." + #endif +#endif +} +#endif + +#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC +#include /* For BitScanReverse(). */ + +static DRFLAC_INLINE drflac_uint32 drflac__clz_msvc(drflac_cache_t x) +{ + drflac_uint32 n; + + if (x == 0) { + return sizeof(x)*8; + } + +#ifdef DRFLAC_64BIT + _BitScanReverse64((unsigned long*)&n, x); +#else + _BitScanReverse((unsigned long*)&n, x); +#endif + return sizeof(x)*8 - n - 1; +} +#endif + +static DRFLAC_INLINE drflac_uint32 drflac__clz(drflac_cache_t x) +{ +#ifdef DRFLAC_IMPLEMENT_CLZ_LZCNT + if (drflac__is_lzcnt_supported()) { + return drflac__clz_lzcnt(x); + } else +#endif + { +#ifdef DRFLAC_IMPLEMENT_CLZ_MSVC + return drflac__clz_msvc(x); +#else + return drflac__clz_software(x); +#endif + } +} + + +static DRFLAC_INLINE drflac_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut) +{ + drflac_uint32 zeroCounter = 0; + drflac_uint32 setBitOffsetPlus1; + + while (bs->cache == 0) { + zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs); + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + } + + setBitOffsetPlus1 = drflac__clz(bs->cache); + setBitOffsetPlus1 += 1; + + bs->consumedBits += setBitOffsetPlus1; + bs->cache <<= setBitOffsetPlus1; + + *pOffsetOut = zeroCounter + setBitOffsetPlus1 - 1; + return DRFLAC_TRUE; +} + + + +static drflac_bool32 drflac__seek_to_byte(drflac_bs* bs, drflac_uint64 offsetFromStart) +{ + drflac_assert(bs != NULL); + drflac_assert(offsetFromStart > 0); + + /* + Seeking from the start is not quite as trivial as it sounds because the onSeek callback takes a signed 32-bit integer (which + is intentional because it simplifies the implementation of the onSeek callbacks), however offsetFromStart is unsigned 64-bit. + To resolve we just need to do an initial seek from the start, and then a series of offset seeks to make up the remainder. + */ + if (offsetFromStart > 0x7FFFFFFF) { + drflac_uint64 bytesRemaining = offsetFromStart; + if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) { + return DRFLAC_FALSE; + } + bytesRemaining -= 0x7FFFFFFF; + + while (bytesRemaining > 0x7FFFFFFF) { + if (!bs->onSeek(bs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + bytesRemaining -= 0x7FFFFFFF; + } + + if (bytesRemaining > 0) { + if (!bs->onSeek(bs->pUserData, (int)bytesRemaining, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + } + } else { + if (!bs->onSeek(bs->pUserData, (int)offsetFromStart, drflac_seek_origin_start)) { + return DRFLAC_FALSE; + } + } + + /* The cache should be reset to force a reload of fresh data from the client. */ + drflac__reset_cache(bs); + return DRFLAC_TRUE; +} + + +static drflac_result drflac__read_utf8_coded_number(drflac_bs* bs, drflac_uint64* pNumberOut, drflac_uint8* pCRCOut) +{ + drflac_uint8 crc; + drflac_uint64 result; + unsigned char utf8[7] = {0}; + int byteCount; + int i; + + drflac_assert(bs != NULL); + drflac_assert(pNumberOut != NULL); + drflac_assert(pCRCOut != NULL); + + crc = *pCRCOut; + + if (!drflac__read_uint8(bs, 8, utf8)) { + *pNumberOut = 0; + return DRFLAC_END_OF_STREAM; + } + crc = drflac_crc8(crc, utf8[0], 8); + + if ((utf8[0] & 0x80) == 0) { + *pNumberOut = utf8[0]; + *pCRCOut = crc; + return DRFLAC_SUCCESS; + } + + byteCount = 1; + if ((utf8[0] & 0xE0) == 0xC0) { + byteCount = 2; + } else if ((utf8[0] & 0xF0) == 0xE0) { + byteCount = 3; + } else if ((utf8[0] & 0xF8) == 0xF0) { + byteCount = 4; + } else if ((utf8[0] & 0xFC) == 0xF8) { + byteCount = 5; + } else if ((utf8[0] & 0xFE) == 0xFC) { + byteCount = 6; + } else if ((utf8[0] & 0xFF) == 0xFE) { + byteCount = 7; + } else { + *pNumberOut = 0; + return DRFLAC_CRC_MISMATCH; /* Bad UTF-8 encoding. */ + } + + /* Read extra bytes. */ + drflac_assert(byteCount > 1); + + result = (drflac_uint64)(utf8[0] & (0xFF >> (byteCount + 1))); + for (i = 1; i < byteCount; ++i) { + if (!drflac__read_uint8(bs, 8, utf8 + i)) { + *pNumberOut = 0; + return DRFLAC_END_OF_STREAM; + } + crc = drflac_crc8(crc, utf8[i], 8); + + result = (result << 6) | (utf8[i] & 0x3F); + } + + *pNumberOut = result; + *pCRCOut = crc; + return DRFLAC_SUCCESS; +} + + + +/* +The next two functions are responsible for calculating the prediction. + +When the bits per sample is >16 we need to use 64-bit integer arithmetic because otherwise we'll run out of precision. It's +safe to assume this will be slower on 32-bit platforms so we use a more optimal solution when the bits per sample is <=16. +*/ +static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_32(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + drflac_int32 prediction = 0; + + drflac_assert(order <= 32); + + /* 32-bit version. */ + + /* VC++ optimizes this to a single jmp. I've not yet verified this for other compilers. */ + switch (order) + { + case 32: prediction += coefficients[31] * pDecodedSamples[-32]; + case 31: prediction += coefficients[30] * pDecodedSamples[-31]; + case 30: prediction += coefficients[29] * pDecodedSamples[-30]; + case 29: prediction += coefficients[28] * pDecodedSamples[-29]; + case 28: prediction += coefficients[27] * pDecodedSamples[-28]; + case 27: prediction += coefficients[26] * pDecodedSamples[-27]; + case 26: prediction += coefficients[25] * pDecodedSamples[-26]; + case 25: prediction += coefficients[24] * pDecodedSamples[-25]; + case 24: prediction += coefficients[23] * pDecodedSamples[-24]; + case 23: prediction += coefficients[22] * pDecodedSamples[-23]; + case 22: prediction += coefficients[21] * pDecodedSamples[-22]; + case 21: prediction += coefficients[20] * pDecodedSamples[-21]; + case 20: prediction += coefficients[19] * pDecodedSamples[-20]; + case 19: prediction += coefficients[18] * pDecodedSamples[-19]; + case 18: prediction += coefficients[17] * pDecodedSamples[-18]; + case 17: prediction += coefficients[16] * pDecodedSamples[-17]; + case 16: prediction += coefficients[15] * pDecodedSamples[-16]; + case 15: prediction += coefficients[14] * pDecodedSamples[-15]; + case 14: prediction += coefficients[13] * pDecodedSamples[-14]; + case 13: prediction += coefficients[12] * pDecodedSamples[-13]; + case 12: prediction += coefficients[11] * pDecodedSamples[-12]; + case 11: prediction += coefficients[10] * pDecodedSamples[-11]; + case 10: prediction += coefficients[ 9] * pDecodedSamples[-10]; + case 9: prediction += coefficients[ 8] * pDecodedSamples[- 9]; + case 8: prediction += coefficients[ 7] * pDecodedSamples[- 8]; + case 7: prediction += coefficients[ 6] * pDecodedSamples[- 7]; + case 6: prediction += coefficients[ 5] * pDecodedSamples[- 6]; + case 5: prediction += coefficients[ 4] * pDecodedSamples[- 5]; + case 4: prediction += coefficients[ 3] * pDecodedSamples[- 4]; + case 3: prediction += coefficients[ 2] * pDecodedSamples[- 3]; + case 2: prediction += coefficients[ 1] * pDecodedSamples[- 2]; + case 1: prediction += coefficients[ 0] * pDecodedSamples[- 1]; + } + + return (drflac_int32)(prediction >> shift); +} + +static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + drflac_int64 prediction; + + drflac_assert(order <= 32); + + /* 64-bit version. */ + + /* This method is faster on the 32-bit build when compiling with VC++. See note below. */ +#ifndef DRFLAC_64BIT + if (order == 8) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + } + else if (order == 7) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + } + else if (order == 3) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + } + else if (order == 6) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + } + else if (order == 5) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + } + else if (order == 4) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + } + else if (order == 12) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12]; + } + else if (order == 2) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + } + else if (order == 1) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + } + else if (order == 10) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + } + else if (order == 9) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + } + else if (order == 11) + { + prediction = coefficients[0] * (drflac_int64)pDecodedSamples[-1]; + prediction += coefficients[1] * (drflac_int64)pDecodedSamples[-2]; + prediction += coefficients[2] * (drflac_int64)pDecodedSamples[-3]; + prediction += coefficients[3] * (drflac_int64)pDecodedSamples[-4]; + prediction += coefficients[4] * (drflac_int64)pDecodedSamples[-5]; + prediction += coefficients[5] * (drflac_int64)pDecodedSamples[-6]; + prediction += coefficients[6] * (drflac_int64)pDecodedSamples[-7]; + prediction += coefficients[7] * (drflac_int64)pDecodedSamples[-8]; + prediction += coefficients[8] * (drflac_int64)pDecodedSamples[-9]; + prediction += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + } + else + { + int j; + + prediction = 0; + for (j = 0; j < (int)order; ++j) { + prediction += coefficients[j] * (drflac_int64)pDecodedSamples[-j-1]; + } + } +#endif + + /* + VC++ optimizes this to a single jmp instruction, but only the 64-bit build. The 32-bit build generates less efficient code for some + reason. The ugly version above is faster so we'll just switch between the two depending on the target platform. + */ +#ifdef DRFLAC_64BIT + prediction = 0; + switch (order) + { + case 32: prediction += coefficients[31] * (drflac_int64)pDecodedSamples[-32]; + case 31: prediction += coefficients[30] * (drflac_int64)pDecodedSamples[-31]; + case 30: prediction += coefficients[29] * (drflac_int64)pDecodedSamples[-30]; + case 29: prediction += coefficients[28] * (drflac_int64)pDecodedSamples[-29]; + case 28: prediction += coefficients[27] * (drflac_int64)pDecodedSamples[-28]; + case 27: prediction += coefficients[26] * (drflac_int64)pDecodedSamples[-27]; + case 26: prediction += coefficients[25] * (drflac_int64)pDecodedSamples[-26]; + case 25: prediction += coefficients[24] * (drflac_int64)pDecodedSamples[-25]; + case 24: prediction += coefficients[23] * (drflac_int64)pDecodedSamples[-24]; + case 23: prediction += coefficients[22] * (drflac_int64)pDecodedSamples[-23]; + case 22: prediction += coefficients[21] * (drflac_int64)pDecodedSamples[-22]; + case 21: prediction += coefficients[20] * (drflac_int64)pDecodedSamples[-21]; + case 20: prediction += coefficients[19] * (drflac_int64)pDecodedSamples[-20]; + case 19: prediction += coefficients[18] * (drflac_int64)pDecodedSamples[-19]; + case 18: prediction += coefficients[17] * (drflac_int64)pDecodedSamples[-18]; + case 17: prediction += coefficients[16] * (drflac_int64)pDecodedSamples[-17]; + case 16: prediction += coefficients[15] * (drflac_int64)pDecodedSamples[-16]; + case 15: prediction += coefficients[14] * (drflac_int64)pDecodedSamples[-15]; + case 14: prediction += coefficients[13] * (drflac_int64)pDecodedSamples[-14]; + case 13: prediction += coefficients[12] * (drflac_int64)pDecodedSamples[-13]; + case 12: prediction += coefficients[11] * (drflac_int64)pDecodedSamples[-12]; + case 11: prediction += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + case 10: prediction += coefficients[ 9] * (drflac_int64)pDecodedSamples[-10]; + case 9: prediction += coefficients[ 8] * (drflac_int64)pDecodedSamples[- 9]; + case 8: prediction += coefficients[ 7] * (drflac_int64)pDecodedSamples[- 8]; + case 7: prediction += coefficients[ 6] * (drflac_int64)pDecodedSamples[- 7]; + case 6: prediction += coefficients[ 5] * (drflac_int64)pDecodedSamples[- 6]; + case 5: prediction += coefficients[ 4] * (drflac_int64)pDecodedSamples[- 5]; + case 4: prediction += coefficients[ 3] * (drflac_int64)pDecodedSamples[- 4]; + case 3: prediction += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3]; + case 2: prediction += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2]; + case 1: prediction += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1]; + } +#endif + + return (drflac_int32)(prediction >> shift); +} + +static DRFLAC_INLINE void drflac__calculate_prediction_64_x4(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, const drflac_uint32 riceParamParts[4], drflac_int32* pDecodedSamples) +{ + drflac_int64 prediction0 = 0; + drflac_int64 prediction1 = 0; + drflac_int64 prediction2 = 0; + drflac_int64 prediction3 = 0; + + drflac_assert(order <= 32); + + switch (order) + { + case 32: + prediction0 += coefficients[31] * (drflac_int64)pDecodedSamples[-32]; + prediction1 += coefficients[31] * (drflac_int64)pDecodedSamples[-31]; + prediction2 += coefficients[31] * (drflac_int64)pDecodedSamples[-30]; + prediction3 += coefficients[31] * (drflac_int64)pDecodedSamples[-29]; + case 31: + prediction0 += coefficients[30] * (drflac_int64)pDecodedSamples[-31]; + prediction1 += coefficients[30] * (drflac_int64)pDecodedSamples[-30]; + prediction2 += coefficients[30] * (drflac_int64)pDecodedSamples[-29]; + prediction3 += coefficients[30] * (drflac_int64)pDecodedSamples[-28]; + case 30: + prediction0 += coefficients[29] * (drflac_int64)pDecodedSamples[-30]; + prediction1 += coefficients[29] * (drflac_int64)pDecodedSamples[-29]; + prediction2 += coefficients[29] * (drflac_int64)pDecodedSamples[-28]; + prediction3 += coefficients[29] * (drflac_int64)pDecodedSamples[-27]; + case 29: + prediction0 += coefficients[28] * (drflac_int64)pDecodedSamples[-29]; + prediction1 += coefficients[28] * (drflac_int64)pDecodedSamples[-28]; + prediction2 += coefficients[28] * (drflac_int64)pDecodedSamples[-27]; + prediction3 += coefficients[28] * (drflac_int64)pDecodedSamples[-26]; + case 28: + prediction0 += coefficients[27] * (drflac_int64)pDecodedSamples[-28]; + prediction1 += coefficients[27] * (drflac_int64)pDecodedSamples[-27]; + prediction2 += coefficients[27] * (drflac_int64)pDecodedSamples[-26]; + prediction3 += coefficients[27] * (drflac_int64)pDecodedSamples[-25]; + case 27: + prediction0 += coefficients[26] * (drflac_int64)pDecodedSamples[-27]; + prediction1 += coefficients[26] * (drflac_int64)pDecodedSamples[-26]; + prediction2 += coefficients[26] * (drflac_int64)pDecodedSamples[-25]; + prediction3 += coefficients[26] * (drflac_int64)pDecodedSamples[-24]; + case 26: + prediction0 += coefficients[25] * (drflac_int64)pDecodedSamples[-26]; + prediction1 += coefficients[25] * (drflac_int64)pDecodedSamples[-25]; + prediction2 += coefficients[25] * (drflac_int64)pDecodedSamples[-24]; + prediction3 += coefficients[25] * (drflac_int64)pDecodedSamples[-23]; + case 25: + prediction0 += coefficients[24] * (drflac_int64)pDecodedSamples[-25]; + prediction1 += coefficients[24] * (drflac_int64)pDecodedSamples[-24]; + prediction2 += coefficients[24] * (drflac_int64)pDecodedSamples[-23]; + prediction3 += coefficients[24] * (drflac_int64)pDecodedSamples[-22]; + case 24: + prediction0 += coefficients[23] * (drflac_int64)pDecodedSamples[-24]; + prediction1 += coefficients[23] * (drflac_int64)pDecodedSamples[-23]; + prediction2 += coefficients[23] * (drflac_int64)pDecodedSamples[-22]; + prediction3 += coefficients[23] * (drflac_int64)pDecodedSamples[-21]; + case 23: + prediction0 += coefficients[22] * (drflac_int64)pDecodedSamples[-23]; + prediction1 += coefficients[22] * (drflac_int64)pDecodedSamples[-22]; + prediction2 += coefficients[22] * (drflac_int64)pDecodedSamples[-21]; + prediction3 += coefficients[22] * (drflac_int64)pDecodedSamples[-20]; + case 22: + prediction0 += coefficients[21] * (drflac_int64)pDecodedSamples[-22]; + prediction1 += coefficients[21] * (drflac_int64)pDecodedSamples[-21]; + prediction2 += coefficients[21] * (drflac_int64)pDecodedSamples[-20]; + prediction3 += coefficients[21] * (drflac_int64)pDecodedSamples[-19]; + case 21: + prediction0 += coefficients[20] * (drflac_int64)pDecodedSamples[-21]; + prediction1 += coefficients[20] * (drflac_int64)pDecodedSamples[-20]; + prediction2 += coefficients[20] * (drflac_int64)pDecodedSamples[-19]; + prediction3 += coefficients[20] * (drflac_int64)pDecodedSamples[-18]; + case 20: + prediction0 += coefficients[19] * (drflac_int64)pDecodedSamples[-20]; + prediction1 += coefficients[19] * (drflac_int64)pDecodedSamples[-19]; + prediction2 += coefficients[19] * (drflac_int64)pDecodedSamples[-18]; + prediction3 += coefficients[19] * (drflac_int64)pDecodedSamples[-17]; + case 19: + prediction0 += coefficients[18] * (drflac_int64)pDecodedSamples[-19]; + prediction1 += coefficients[18] * (drflac_int64)pDecodedSamples[-18]; + prediction2 += coefficients[18] * (drflac_int64)pDecodedSamples[-17]; + prediction3 += coefficients[18] * (drflac_int64)pDecodedSamples[-16]; + case 18: + prediction0 += coefficients[17] * (drflac_int64)pDecodedSamples[-18]; + prediction1 += coefficients[17] * (drflac_int64)pDecodedSamples[-17]; + prediction2 += coefficients[17] * (drflac_int64)pDecodedSamples[-16]; + prediction3 += coefficients[17] * (drflac_int64)pDecodedSamples[-15]; + case 17: + prediction0 += coefficients[16] * (drflac_int64)pDecodedSamples[-17]; + prediction1 += coefficients[16] * (drflac_int64)pDecodedSamples[-16]; + prediction2 += coefficients[16] * (drflac_int64)pDecodedSamples[-15]; + prediction3 += coefficients[16] * (drflac_int64)pDecodedSamples[-14]; + + case 16: + prediction0 += coefficients[15] * (drflac_int64)pDecodedSamples[-16]; + prediction1 += coefficients[15] * (drflac_int64)pDecodedSamples[-15]; + prediction2 += coefficients[15] * (drflac_int64)pDecodedSamples[-14]; + prediction3 += coefficients[15] * (drflac_int64)pDecodedSamples[-13]; + case 15: + prediction0 += coefficients[14] * (drflac_int64)pDecodedSamples[-15]; + prediction1 += coefficients[14] * (drflac_int64)pDecodedSamples[-14]; + prediction2 += coefficients[14] * (drflac_int64)pDecodedSamples[-13]; + prediction3 += coefficients[14] * (drflac_int64)pDecodedSamples[-12]; + case 14: + prediction0 += coefficients[13] * (drflac_int64)pDecodedSamples[-14]; + prediction1 += coefficients[13] * (drflac_int64)pDecodedSamples[-13]; + prediction2 += coefficients[13] * (drflac_int64)pDecodedSamples[-12]; + prediction3 += coefficients[13] * (drflac_int64)pDecodedSamples[-11]; + case 13: + prediction0 += coefficients[12] * (drflac_int64)pDecodedSamples[-13]; + prediction1 += coefficients[12] * (drflac_int64)pDecodedSamples[-12]; + prediction2 += coefficients[12] * (drflac_int64)pDecodedSamples[-11]; + prediction3 += coefficients[12] * (drflac_int64)pDecodedSamples[-10]; + case 12: + prediction0 += coefficients[11] * (drflac_int64)pDecodedSamples[-12]; + prediction1 += coefficients[11] * (drflac_int64)pDecodedSamples[-11]; + prediction2 += coefficients[11] * (drflac_int64)pDecodedSamples[-10]; + prediction3 += coefficients[11] * (drflac_int64)pDecodedSamples[- 9]; + case 11: + prediction0 += coefficients[10] * (drflac_int64)pDecodedSamples[-11]; + prediction1 += coefficients[10] * (drflac_int64)pDecodedSamples[-10]; + prediction2 += coefficients[10] * (drflac_int64)pDecodedSamples[- 9]; + prediction3 += coefficients[10] * (drflac_int64)pDecodedSamples[- 8]; + case 10: + prediction0 += coefficients[9] * (drflac_int64)pDecodedSamples[-10]; + prediction1 += coefficients[9] * (drflac_int64)pDecodedSamples[- 9]; + prediction2 += coefficients[9] * (drflac_int64)pDecodedSamples[- 8]; + prediction3 += coefficients[9] * (drflac_int64)pDecodedSamples[- 7]; + case 9: + prediction0 += coefficients[8] * (drflac_int64)pDecodedSamples[- 9]; + prediction1 += coefficients[8] * (drflac_int64)pDecodedSamples[- 8]; + prediction2 += coefficients[8] * (drflac_int64)pDecodedSamples[- 7]; + prediction3 += coefficients[8] * (drflac_int64)pDecodedSamples[- 6]; + case 8: + prediction0 += coefficients[7] * (drflac_int64)pDecodedSamples[- 8]; + prediction1 += coefficients[7] * (drflac_int64)pDecodedSamples[- 7]; + prediction2 += coefficients[7] * (drflac_int64)pDecodedSamples[- 6]; + prediction3 += coefficients[7] * (drflac_int64)pDecodedSamples[- 5]; + case 7: + prediction0 += coefficients[6] * (drflac_int64)pDecodedSamples[- 7]; + prediction1 += coefficients[6] * (drflac_int64)pDecodedSamples[- 6]; + prediction2 += coefficients[6] * (drflac_int64)pDecodedSamples[- 5]; + prediction3 += coefficients[6] * (drflac_int64)pDecodedSamples[- 4]; + case 6: + prediction0 += coefficients[5] * (drflac_int64)pDecodedSamples[- 6]; + prediction1 += coefficients[5] * (drflac_int64)pDecodedSamples[- 5]; + prediction2 += coefficients[5] * (drflac_int64)pDecodedSamples[- 4]; + prediction3 += coefficients[5] * (drflac_int64)pDecodedSamples[- 3]; + case 5: + prediction0 += coefficients[4] * (drflac_int64)pDecodedSamples[- 5]; + prediction1 += coefficients[4] * (drflac_int64)pDecodedSamples[- 4]; + prediction2 += coefficients[4] * (drflac_int64)pDecodedSamples[- 3]; + prediction3 += coefficients[4] * (drflac_int64)pDecodedSamples[- 2]; + case 4: + prediction0 += coefficients[3] * (drflac_int64)pDecodedSamples[- 4]; + prediction1 += coefficients[3] * (drflac_int64)pDecodedSamples[- 3]; + prediction2 += coefficients[3] * (drflac_int64)pDecodedSamples[- 2]; + prediction3 += coefficients[3] * (drflac_int64)pDecodedSamples[- 1]; + order = 3; + } + + switch (order) + { + case 3: prediction0 += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 3]; + case 2: prediction0 += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 2]; + case 1: prediction0 += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1]; + } + pDecodedSamples[0] = riceParamParts[0] + (drflac_int32)(prediction0 >> shift); + + switch (order) + { + case 3: prediction1 += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 2]; + case 2: prediction1 += coefficients[ 1] * (drflac_int64)pDecodedSamples[- 1]; + case 1: prediction1 += coefficients[ 0] * (drflac_int64)pDecodedSamples[ 0]; + } + pDecodedSamples[1] = riceParamParts[1] + (drflac_int32)(prediction1 >> shift); + + switch (order) + { + case 3: prediction2 += coefficients[ 2] * (drflac_int64)pDecodedSamples[- 1]; + case 2: prediction2 += coefficients[ 1] * (drflac_int64)pDecodedSamples[ 0]; + case 1: prediction2 += coefficients[ 0] * (drflac_int64)pDecodedSamples[ 1]; + } + pDecodedSamples[2] = riceParamParts[2] + (drflac_int32)(prediction2 >> shift); + + switch (order) + { + case 3: prediction3 += coefficients[ 2] * (drflac_int64)pDecodedSamples[ 0]; + case 2: prediction3 += coefficients[ 1] * (drflac_int64)pDecodedSamples[ 1]; + case 1: prediction3 += coefficients[ 0] * (drflac_int64)pDecodedSamples[ 2]; + } + pDecodedSamples[3] = riceParamParts[3] + (drflac_int32)(prediction3 >> shift); +} + +#if defined(DRFLAC_SUPPORT_SSE41) +static DRFLAC_INLINE drflac_int32 drflac__calculate_prediction_64__sse41(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + __m128i prediction = _mm_setzero_si128(); + + drflac_assert(order <= 32); + + switch (order) + { + case 32: + case 31: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[31], 0, coefficients[30]), _mm_set_epi32(0, pDecodedSamples[-32], 0, pDecodedSamples[-31]))); + case 30: + case 29: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[29], 0, coefficients[28]), _mm_set_epi32(0, pDecodedSamples[-30], 0, pDecodedSamples[-29]))); + case 28: + case 27: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[27], 0, coefficients[26]), _mm_set_epi32(0, pDecodedSamples[-28], 0, pDecodedSamples[-27]))); + case 26: + case 25: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[25], 0, coefficients[24]), _mm_set_epi32(0, pDecodedSamples[-26], 0, pDecodedSamples[-25]))); + case 24: + case 23: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[23], 0, coefficients[22]), _mm_set_epi32(0, pDecodedSamples[-24], 0, pDecodedSamples[-23]))); + case 22: + case 21: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[21], 0, coefficients[20]), _mm_set_epi32(0, pDecodedSamples[-22], 0, pDecodedSamples[-21]))); + case 20: + case 19: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[19], 0, coefficients[18]), _mm_set_epi32(0, pDecodedSamples[-20], 0, pDecodedSamples[-19]))); + case 18: + case 17: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[17], 0, coefficients[16]), _mm_set_epi32(0, pDecodedSamples[-18], 0, pDecodedSamples[-17]))); + case 16: + case 15: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[15], 0, coefficients[14]), _mm_set_epi32(0, pDecodedSamples[-16], 0, pDecodedSamples[-15]))); + case 14: + case 13: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[13], 0, coefficients[12]), _mm_set_epi32(0, pDecodedSamples[-14], 0, pDecodedSamples[-13]))); + case 12: + case 11: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[11], 0, coefficients[10]), _mm_set_epi32(0, pDecodedSamples[-12], 0, pDecodedSamples[-11]))); + case 10: + case 9: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 9], 0, coefficients[ 8]), _mm_set_epi32(0, pDecodedSamples[-10], 0, pDecodedSamples[- 9]))); + case 8: + case 7: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 7], 0, coefficients[ 6]), _mm_set_epi32(0, pDecodedSamples[- 8], 0, pDecodedSamples[- 7]))); + case 6: + case 5: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 5], 0, coefficients[ 4]), _mm_set_epi32(0, pDecodedSamples[- 6], 0, pDecodedSamples[- 5]))); + case 4: + case 3: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 3], 0, coefficients[ 2]), _mm_set_epi32(0, pDecodedSamples[- 4], 0, pDecodedSamples[- 3]))); + case 2: + case 1: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 1], 0, coefficients[ 0]), _mm_set_epi32(0, pDecodedSamples[- 2], 0, pDecodedSamples[- 1]))); + } + + return (drflac_int32)(( + ((drflac_uint64*)&prediction)[0] + + ((drflac_uint64*)&prediction)[1]) >> shift); +} + +static DRFLAC_INLINE void drflac__calculate_prediction_64_x2__sse41(drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, const drflac_uint32 riceParamParts[4], drflac_int32* pDecodedSamples) +{ + __m128i prediction = _mm_setzero_si128(); + drflac_int64 predictions[2] = {0, 0}; + + drflac_assert(order <= 32); + + switch (order) + { + case 32: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[31], 0, coefficients[31]), _mm_set_epi32(0, pDecodedSamples[-31], 0, pDecodedSamples[-32]))); + case 31: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[30], 0, coefficients[30]), _mm_set_epi32(0, pDecodedSamples[-30], 0, pDecodedSamples[-31]))); + case 30: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[29], 0, coefficients[29]), _mm_set_epi32(0, pDecodedSamples[-29], 0, pDecodedSamples[-30]))); + case 29: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[28], 0, coefficients[28]), _mm_set_epi32(0, pDecodedSamples[-28], 0, pDecodedSamples[-29]))); + case 28: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[27], 0, coefficients[27]), _mm_set_epi32(0, pDecodedSamples[-27], 0, pDecodedSamples[-28]))); + case 27: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[26], 0, coefficients[26]), _mm_set_epi32(0, pDecodedSamples[-26], 0, pDecodedSamples[-27]))); + case 26: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[25], 0, coefficients[25]), _mm_set_epi32(0, pDecodedSamples[-25], 0, pDecodedSamples[-26]))); + case 25: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[24], 0, coefficients[24]), _mm_set_epi32(0, pDecodedSamples[-24], 0, pDecodedSamples[-25]))); + case 24: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[23], 0, coefficients[23]), _mm_set_epi32(0, pDecodedSamples[-23], 0, pDecodedSamples[-24]))); + case 23: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[22], 0, coefficients[22]), _mm_set_epi32(0, pDecodedSamples[-22], 0, pDecodedSamples[-23]))); + case 22: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[21], 0, coefficients[21]), _mm_set_epi32(0, pDecodedSamples[-21], 0, pDecodedSamples[-22]))); + case 21: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[20], 0, coefficients[20]), _mm_set_epi32(0, pDecodedSamples[-20], 0, pDecodedSamples[-21]))); + case 20: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[19], 0, coefficients[19]), _mm_set_epi32(0, pDecodedSamples[-19], 0, pDecodedSamples[-20]))); + case 19: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[18], 0, coefficients[18]), _mm_set_epi32(0, pDecodedSamples[-18], 0, pDecodedSamples[-19]))); + case 18: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[17], 0, coefficients[17]), _mm_set_epi32(0, pDecodedSamples[-17], 0, pDecodedSamples[-18]))); + case 17: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[16], 0, coefficients[16]), _mm_set_epi32(0, pDecodedSamples[-16], 0, pDecodedSamples[-17]))); + case 16: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[15], 0, coefficients[15]), _mm_set_epi32(0, pDecodedSamples[-15], 0, pDecodedSamples[-16]))); + case 15: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[14], 0, coefficients[14]), _mm_set_epi32(0, pDecodedSamples[-14], 0, pDecodedSamples[-15]))); + case 14: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[13], 0, coefficients[13]), _mm_set_epi32(0, pDecodedSamples[-13], 0, pDecodedSamples[-14]))); + case 13: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[12], 0, coefficients[12]), _mm_set_epi32(0, pDecodedSamples[-12], 0, pDecodedSamples[-13]))); + case 12: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[11], 0, coefficients[11]), _mm_set_epi32(0, pDecodedSamples[-11], 0, pDecodedSamples[-12]))); + case 11: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[10], 0, coefficients[10]), _mm_set_epi32(0, pDecodedSamples[-10], 0, pDecodedSamples[-11]))); + case 10: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 9], 0, coefficients[ 9]), _mm_set_epi32(0, pDecodedSamples[- 9], 0, pDecodedSamples[-10]))); + case 9: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 8], 0, coefficients[ 8]), _mm_set_epi32(0, pDecodedSamples[- 8], 0, pDecodedSamples[- 9]))); + case 8: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 7], 0, coefficients[ 7]), _mm_set_epi32(0, pDecodedSamples[- 7], 0, pDecodedSamples[- 8]))); + case 7: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 6], 0, coefficients[ 6]), _mm_set_epi32(0, pDecodedSamples[- 6], 0, pDecodedSamples[- 7]))); + case 6: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 5], 0, coefficients[ 5]), _mm_set_epi32(0, pDecodedSamples[- 5], 0, pDecodedSamples[- 6]))); + case 5: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 4], 0, coefficients[ 4]), _mm_set_epi32(0, pDecodedSamples[- 4], 0, pDecodedSamples[- 5]))); + case 4: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 3], 0, coefficients[ 3]), _mm_set_epi32(0, pDecodedSamples[- 3], 0, pDecodedSamples[- 4]))); + case 3: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 2], 0, coefficients[ 2]), _mm_set_epi32(0, pDecodedSamples[- 2], 0, pDecodedSamples[- 3]))); + case 2: prediction = _mm_add_epi64(prediction, _mm_mul_epi32(_mm_set_epi32(0, coefficients[ 1], 0, coefficients[ 1]), _mm_set_epi32(0, pDecodedSamples[- 1], 0, pDecodedSamples[- 2]))); + order = 1; + } + + _mm_storeu_si128((__m128i*)predictions, prediction); + + switch (order) + { + case 1: predictions[0] += coefficients[ 0] * (drflac_int64)pDecodedSamples[- 1]; + } + pDecodedSamples[0] = riceParamParts[0] + (drflac_int32)(predictions[0] >> shift); + + switch (order) + { + case 1: predictions[1] += coefficients[ 0] * (drflac_int64)pDecodedSamples[ 0]; + } + pDecodedSamples[1] = riceParamParts[1] + (drflac_int32)(predictions[1] >> shift); +} + + +static DRFLAC_INLINE __m128i drflac__mm_not_si128(__m128i a) +{ + return _mm_xor_si128(a, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())); +} + +static DRFLAC_INLINE __m128i drflac__mm_slide1_epi32(__m128i a, __m128i b) +{ + /* a3a2a1a0/b3b2b1b0 -> a2a1a0b3 */ + + /* Result = a2a1a0b3 */ + __m128i b3a3b2a2 = _mm_unpackhi_epi32(a, b); + __m128i a2b3a2b3 = _mm_shuffle_epi32(b3a3b2a2, _MM_SHUFFLE(0, 3, 0, 3)); + __m128i a1a2a0b3 = _mm_unpacklo_epi32(a2b3a2b3, a); + __m128i a2a1a0b3 = _mm_shuffle_epi32(a1a2a0b3, _MM_SHUFFLE(2, 3, 1, 0)); + return a2a1a0b3; +} + +static DRFLAC_INLINE __m128i drflac__mm_slide2_epi32(__m128i a, __m128i b) +{ + /* Result = a1a0b3b2 */ + __m128i b1b0b3b2 = _mm_shuffle_epi32(b, _MM_SHUFFLE(1, 0, 3, 2)); + __m128i a1b3a0b2 = _mm_unpacklo_epi32(b1b0b3b2, a); + __m128i a1a0b3b2 = _mm_shuffle_epi32(a1b3a0b2, _MM_SHUFFLE(3, 1, 2, 0)); + return a1a0b3b2; +} + +static DRFLAC_INLINE __m128i drflac__mm_slide3_epi32(__m128i a, __m128i b) +{ + /* Result = a0b3b2b1 */ + __m128i b1a1b0a0 = _mm_unpacklo_epi32(a, b); + __m128i a0b1a0b1 = _mm_shuffle_epi32(b1a1b0a0, _MM_SHUFFLE(0, 3, 0, 3)); + __m128i b3a0b2b1 = _mm_unpackhi_epi32(a0b1a0b1, b); + __m128i a0b3b2b1 = _mm_shuffle_epi32(b3a0b2b1, _MM_SHUFFLE(2, 3, 1, 0)); + return a0b3b2b1; +} + +static DRFLAC_INLINE void drflac__calculate_prediction_32_x4__sse41(drflac_uint32 order, drflac_int32 shift, const __m128i* coefficients128, const __m128i riceParamParts128, drflac_int32* pDecodedSamples) +{ + drflac_assert(order <= 32); + + /* I don't think this is as efficient as it could be. More work needs to be done on this. */ + if (order > 0) { + drflac_int32 predictions[4]; + drflac_uint32 riceParamParts[4]; + + __m128i s_09_10_11_12 = _mm_loadu_si128((const __m128i*)(pDecodedSamples - 12)); + __m128i s_05_06_07_08 = _mm_loadu_si128((const __m128i*)(pDecodedSamples - 8)); + __m128i s_01_02_03_04 = _mm_loadu_si128((const __m128i*)(pDecodedSamples - 4)); + + __m128i prediction = _mm_setzero_si128(); + + /* + The idea with this switch is to do do a single jump based on the value of "order". In my test library, "order" is never larger than 12, so + I have decided to do a less optimal, but simpler solution in the order > 12 case. + */ + switch (order) + { + case 32: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[31], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 32)))); + case 31: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[30], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 31)))); + case 30: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[29], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 30)))); + case 29: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[28], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 29)))); + case 28: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[27], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 28)))); + case 27: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[26], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 27)))); + case 26: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[25], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 26)))); + case 25: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[24], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 25)))); + case 24: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[23], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 24)))); + case 23: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[22], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 23)))); + case 22: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[21], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 22)))); + case 21: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[20], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 21)))); + case 20: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[19], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 20)))); + case 19: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[18], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 19)))); + case 18: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[17], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 18)))); + case 17: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[16], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 17)))); + case 16: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[15], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 16)))); + case 15: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[14], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 15)))); + case 14: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[13], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 14)))); + case 13: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[12], _mm_loadu_si128((const __m128i*)(pDecodedSamples - 13)))); + + case 12: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[11], s_09_10_11_12)); + case 11: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[10], drflac__mm_slide3_epi32(s_05_06_07_08, s_09_10_11_12))); + case 10: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 9], drflac__mm_slide2_epi32(s_05_06_07_08, s_09_10_11_12))); + case 9: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 8], drflac__mm_slide1_epi32(s_05_06_07_08, s_09_10_11_12))); + case 8: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 7], s_05_06_07_08)); + case 7: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 6], drflac__mm_slide3_epi32(s_01_02_03_04, s_05_06_07_08))); + case 6: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 5], drflac__mm_slide2_epi32(s_01_02_03_04, s_05_06_07_08))); + case 5: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 4], drflac__mm_slide1_epi32(s_01_02_03_04, s_05_06_07_08))); + case 4: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 3], s_01_02_03_04)); order = 3; /* <-- Don't forget to set order to 3 here! */ + case 3: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 2], drflac__mm_slide3_epi32(_mm_setzero_si128(), s_01_02_03_04))); + case 2: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 1], drflac__mm_slide2_epi32(_mm_setzero_si128(), s_01_02_03_04))); + case 1: prediction = _mm_add_epi32(prediction, _mm_mullo_epi32(coefficients128[ 0], drflac__mm_slide1_epi32(_mm_setzero_si128(), s_01_02_03_04))); + } + + _mm_storeu_si128((__m128i*)predictions, prediction); + _mm_storeu_si128((__m128i*)riceParamParts, riceParamParts128); + + predictions[0] = riceParamParts[0] + (predictions[0] >> shift); + + switch (order) + { + case 3: predictions[3] += ((const drflac_int32*)&coefficients128[ 2])[0] * predictions[ 0]; + case 2: predictions[2] += ((const drflac_int32*)&coefficients128[ 1])[0] * predictions[ 0]; + case 1: predictions[1] += ((const drflac_int32*)&coefficients128[ 0])[0] * predictions[ 0]; + } + predictions[1] = riceParamParts[1] + (predictions[1] >> shift); + + switch (order) + { + case 3: + case 2: predictions[3] += ((const drflac_int32*)&coefficients128[ 1])[0] * predictions[ 1]; + case 1: predictions[2] += ((const drflac_int32*)&coefficients128[ 0])[0] * predictions[ 1]; + } + predictions[2] = riceParamParts[2] + (predictions[2] >> shift); + + switch (order) + { + case 3: + case 2: + case 1: predictions[3] += ((const drflac_int32*)&coefficients128[ 0])[0] * predictions[ 2]; + } + predictions[3] = riceParamParts[3] + (predictions[3] >> shift); + + pDecodedSamples[0] = predictions[0]; + pDecodedSamples[1] = predictions[1]; + pDecodedSamples[2] = predictions[2]; + pDecodedSamples[3] = predictions[3]; + } else { + _mm_storeu_si128((__m128i*)pDecodedSamples, riceParamParts128); + } +} +#endif + +#if 0 +/* +Reference implementation for reading and decoding samples with residual. This is intentionally left unoptimized for the +sake of readability and should only be used as a reference. +*/ +static drflac_bool32 drflac__decode_samples_with_residual__rice__reference(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + drflac_uint32 i; + + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(pSamplesOut != NULL); + + for (i = 0; i < count; ++i) { + drflac_uint32 zeroCounter = 0; + for (;;) { + drflac_uint8 bit; + if (!drflac__read_uint8(bs, 1, &bit)) { + return DRFLAC_FALSE; + } + + if (bit == 0) { + zeroCounter += 1; + } else { + break; + } + } + + drflac_uint32 decodedRice; + if (riceParam > 0) { + if (!drflac__read_uint32(bs, riceParam, &decodedRice)) { + return DRFLAC_FALSE; + } + } else { + decodedRice = 0; + } + + decodedRice |= (zeroCounter << riceParam); + if ((decodedRice & 0x01)) { + decodedRice = ~(decodedRice >> 1); + } else { + decodedRice = (decodedRice >> 1); + } + + + if (bitsPerSample > 16) { + pSamplesOut[i] = decodedRice + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i); + } else { + pSamplesOut[i] = decodedRice + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i); + } + } + + return DRFLAC_TRUE; +} +#endif + +#if 0 +static drflac_bool32 drflac__read_rice_parts__reference(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut) +{ + drflac_uint32 zeroCounter = 0; + drflac_uint32 decodedRice; + + for (;;) { + drflac_uint8 bit; + if (!drflac__read_uint8(bs, 1, &bit)) { + return DRFLAC_FALSE; + } + + if (bit == 0) { + zeroCounter += 1; + } else { + break; + } + } + + if (riceParam > 0) { + if (!drflac__read_uint32(bs, riceParam, &decodedRice)) { + return DRFLAC_FALSE; + } + } else { + decodedRice = 0; + } + + *pZeroCounterOut = zeroCounter; + *pRiceParamPartOut = decodedRice; + return DRFLAC_TRUE; +} +#endif + +#if 0 +static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut) +{ + drflac_cache_t riceParamMask; + drflac_uint32 zeroCounter; + drflac_uint32 setBitOffsetPlus1; + drflac_uint32 riceParamPart; + drflac_uint32 riceLength; + + drflac_assert(riceParam > 0); /* <-- riceParam should never be 0. drflac__read_rice_parts__param_equals_zero() should be used instead for this case. */ + + riceParamMask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParam); + + zeroCounter = 0; + while (bs->cache == 0) { + zeroCounter += (drflac_uint32)DRFLAC_CACHE_L1_BITS_REMAINING(bs); + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + } + + setBitOffsetPlus1 = drflac__clz(bs->cache); + zeroCounter += setBitOffsetPlus1; + setBitOffsetPlus1 += 1; + + riceLength = setBitOffsetPlus1 + riceParam; + if (riceLength < DRFLAC_CACHE_L1_BITS_REMAINING(bs)) { + riceParamPart = (drflac_uint32)((bs->cache & (riceParamMask >> setBitOffsetPlus1)) >> DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceLength)); + + bs->consumedBits += riceLength; + bs->cache <<= riceLength; + } else { + drflac_uint32 bitCountLo; + drflac_cache_t resultHi; + + bs->consumedBits += riceLength; + bs->cache <<= setBitOffsetPlus1 & (DRFLAC_CACHE_L1_SIZE_BITS(bs)-1); /* <-- Equivalent to "if (setBitOffsetPlus1 < DRFLAC_CACHE_L1_SIZE_BITS(bs)) { bs->cache <<= setBitOffsetPlus1; }" */ + + /* It straddles the cached data. It will never cover more than the next chunk. We just read the number in two parts and combine them. */ + bitCountLo = bs->consumedBits - DRFLAC_CACHE_L1_SIZE_BITS(bs); + resultHi = DRFLAC_CACHE_L1_SELECT_AND_SHIFT(bs, riceParam); /* <-- Use DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE() if ever this function allows riceParam=0. */ + + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { +#ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); +#endif + bs->cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs->consumedBits = 0; +#ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs->cache; +#endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + } + + riceParamPart = (drflac_uint32)(resultHi | DRFLAC_CACHE_L1_SELECT_AND_SHIFT_SAFE(bs, bitCountLo)); + + bs->consumedBits += bitCountLo; + bs->cache <<= bitCountLo; + } + + pZeroCounterOut[0] = zeroCounter; + pRiceParamPartOut[0] = riceParamPart; + + return DRFLAC_TRUE; +} +#endif + +static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x1(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut) +{ + drflac_uint32 riceParamPlus1 = riceParam + 1; + /*drflac_cache_t riceParamPlus1Mask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/ + drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1); + drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1; + + /* + The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have + no idea how this will work in practice... + */ + drflac_cache_t bs_cache = bs->cache; + drflac_uint32 bs_consumedBits = bs->consumedBits; + + /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */ + drflac_uint32 lzcount = drflac__clz(bs_cache); + if (lzcount < sizeof(bs_cache)*8) { + pZeroCounterOut[0] = lzcount; + + /* + It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting + this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled + outside of this function at a higher level. + */ + extract_rice_param_part: + bs_cache <<= lzcount; + bs_consumedBits += lzcount; + + if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) { + /* Getting here means the rice parameter part is wholly contained within the current cache line. */ + pRiceParamPartOut[0] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift); + bs_cache <<= riceParamPlus1; + bs_consumedBits += riceParamPlus1; + } else { + drflac_uint32 riceParamPartHi; + drflac_uint32 riceParamPartLo; + drflac_uint32 riceParamPartLoBitCount; + + /* + Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache + line, reload the cache, and then combine it with the head of the next cache line. + */ + + /* Grab the high part of the rice parameter part. */ + riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift); + + /* Before reloading the cache we need to grab the size in bits of the low part. */ + riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits; + drflac_assert(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32); + + /* Now reload the cache. */ + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + #ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); + #endif + bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs_consumedBits = riceParamPartLoBitCount; + #ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs_cache; + #endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + bs_cache = bs->cache; + bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount; + } + + /* We should now have enough information to construct the rice parameter part. */ + riceParamPartLo = (drflac_uint32)(bs_cache >> (DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPartLoBitCount))); + pRiceParamPartOut[0] = riceParamPartHi | riceParamPartLo; + + bs_cache <<= riceParamPartLoBitCount; + } + } else { + /* + Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call + to drflac__clz() and we need to reload the cache. + */ + drflac_uint32 zeroCounter = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs_consumedBits); + for (;;) { + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + #ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); + #endif + bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs_consumedBits = 0; + #ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs_cache; + #endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + bs_cache = bs->cache; + bs_consumedBits = bs->consumedBits; + } + + lzcount = drflac__clz(bs_cache); + zeroCounter += lzcount; + + if (lzcount < sizeof(bs_cache)*8) { + break; + } + } + + pZeroCounterOut[0] = zeroCounter; + goto extract_rice_param_part; + } + + /* Make sure the cache is restored at the end of it all. */ + bs->cache = bs_cache; + bs->consumedBits = bs_consumedBits; + + return DRFLAC_TRUE; +} + +static DRFLAC_INLINE drflac_bool32 drflac__read_rice_parts_x4(drflac_bs* bs, drflac_uint8 riceParam, drflac_uint32* pZeroCounterOut, drflac_uint32* pRiceParamPartOut) +{ + drflac_uint32 riceParamPlus1 = riceParam + 1; + /*drflac_cache_t riceParamPlus1Mask = DRFLAC_CACHE_L1_SELECTION_MASK(riceParamPlus1);*/ + drflac_uint32 riceParamPlus1Shift = DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPlus1); + drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1; + + /* + The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have + no idea how this will work in practice... + */ + drflac_cache_t bs_cache = bs->cache; + drflac_uint32 bs_consumedBits = bs->consumedBits; + + /* + What this is doing is trying to efficiently extract 4 rice parts at a time, the idea being that we can exploit certain properties + to our advantage to make things more efficient. + */ + int i; + for (i = 0; i < 4; ++i) { + /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */ + drflac_uint32 lzcount = drflac__clz(bs_cache); + if (lzcount < sizeof(bs_cache)*8) { + pZeroCounterOut[i] = lzcount; + + /* + It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting + this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled + outside of this function at a higher level. + */ + extract_rice_param_part: + bs_cache <<= lzcount; + bs_consumedBits += lzcount; + + if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) { + /* Getting here means the rice parameter part is wholly contained within the current cache line. */ + pRiceParamPartOut[i] = (drflac_uint32)(bs_cache >> riceParamPlus1Shift); + bs_cache <<= riceParamPlus1; + bs_consumedBits += riceParamPlus1; + } else { + drflac_uint32 riceParamPartHi; + drflac_uint32 riceParamPartLo; + drflac_uint32 riceParamPartLoBitCount; + + /* + Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache + line, reload the cache, and then combine it with the head of the next cache line. + */ + + /* Grab the high part of the rice parameter part. */ + riceParamPartHi = (drflac_uint32)(bs_cache >> riceParamPlus1Shift); + + /* Before reloading the cache we need to grab the size in bits of the low part. */ + riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits; + + /* Now reload the cache. */ + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + #ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); + #endif + bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs_consumedBits = riceParamPartLoBitCount; + #ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs_cache; + #endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + bs_cache = bs->cache; + bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount; + } + + /* We should now have enough information to construct the rice parameter part. */ + riceParamPartLo = (drflac_uint32)(bs_cache >> (DRFLAC_CACHE_L1_SELECTION_SHIFT(bs, riceParamPartLoBitCount))); + pRiceParamPartOut[i] = riceParamPartHi | riceParamPartLo; + + bs_cache <<= riceParamPartLoBitCount; + } + } else { + /* + Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call + to drflac__clz() and we need to reload the cache. + */ + drflac_uint32 zeroCounter = (drflac_uint32)(DRFLAC_CACHE_L1_SIZE_BITS(bs) - bs_consumedBits); + for (;;) { + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + #ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); + #endif + bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs_consumedBits = 0; + #ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs_cache; + #endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + bs_cache = bs->cache; + bs_consumedBits = bs->consumedBits; + } + + lzcount = drflac__clz(bs_cache); + zeroCounter += lzcount; + + if (lzcount < sizeof(bs_cache)*8) { + break; + } + } + + pZeroCounterOut[i] = zeroCounter; + goto extract_rice_param_part; + } + } + + /* Make sure the cache is restored at the end of it all. */ + bs->cache = bs_cache; + bs->consumedBits = bs_consumedBits; + + return DRFLAC_TRUE; +} + +static DRFLAC_INLINE drflac_bool32 drflac__seek_rice_parts(drflac_bs* bs, drflac_uint8 riceParam) +{ + drflac_uint32 riceParamPlus1 = riceParam + 1; + drflac_uint32 riceParamPlus1MaxConsumedBits = DRFLAC_CACHE_L1_SIZE_BITS(bs) - riceParamPlus1; + + /* + The idea here is to use local variables for the cache in an attempt to encourage the compiler to store them in registers. I have + no idea how this will work in practice... + */ + drflac_cache_t bs_cache = bs->cache; + drflac_uint32 bs_consumedBits = bs->consumedBits; + + /* The first thing to do is find the first unset bit. Most likely a bit will be set in the current cache line. */ + drflac_uint32 lzcount = drflac__clz(bs_cache); + if (lzcount < sizeof(bs_cache)*8) { + /* + It is most likely that the riceParam part (which comes after the zero counter) is also on this cache line. When extracting + this, we include the set bit from the unary coded part because it simplifies cache management. This bit will be handled + outside of this function at a higher level. + */ + extract_rice_param_part: + bs_cache <<= lzcount; + bs_consumedBits += lzcount; + + if (bs_consumedBits <= riceParamPlus1MaxConsumedBits) { + /* Getting here means the rice parameter part is wholly contained within the current cache line. */ + bs_cache <<= riceParamPlus1; + bs_consumedBits += riceParamPlus1; + } else { + /* + Getting here means the rice parameter part straddles the cache line. We need to read from the tail of the current cache + line, reload the cache, and then combine it with the head of the next cache line. + */ + + /* Before reloading the cache we need to grab the size in bits of the low part. */ + drflac_uint32 riceParamPartLoBitCount = bs_consumedBits - riceParamPlus1MaxConsumedBits; + drflac_assert(riceParamPartLoBitCount > 0 && riceParamPartLoBitCount < 32); + + /* Now reload the cache. */ + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + #ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); + #endif + bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs_consumedBits = riceParamPartLoBitCount; + #ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs_cache; + #endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + bs_cache = bs->cache; + bs_consumedBits = bs->consumedBits + riceParamPartLoBitCount; + } + + bs_cache <<= riceParamPartLoBitCount; + } + } else { + /* + Getting here means there are no bits set on the cache line. This is a less optimal case because we just wasted a call + to drflac__clz() and we need to reload the cache. + */ + for (;;) { + if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { + #ifndef DR_FLAC_NO_CRC + drflac__update_crc16(bs); + #endif + bs_cache = drflac__be2host__cache_line(bs->cacheL2[bs->nextL2Line++]); + bs_consumedBits = 0; + #ifndef DR_FLAC_NO_CRC + bs->crc16Cache = bs_cache; + #endif + } else { + /* Slow path. We need to fetch more data from the client. */ + if (!drflac__reload_cache(bs)) { + return DRFLAC_FALSE; + } + + bs_cache = bs->cache; + bs_consumedBits = bs->consumedBits; + } + + lzcount = drflac__clz(bs_cache); + if (lzcount < sizeof(bs_cache)*8) { + break; + } + } + + goto extract_rice_param_part; + } + + /* Make sure the cache is restored at the end of it all. */ + bs->cache = bs_cache; + bs->consumedBits = bs_consumedBits; + + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__decode_samples_with_residual__rice__scalar(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF}; + drflac_uint32 zeroCountPart0; + drflac_uint32 zeroCountPart1; + drflac_uint32 zeroCountPart2; + drflac_uint32 zeroCountPart3; + drflac_uint32 riceParamPart0; + drflac_uint32 riceParamPart1; + drflac_uint32 riceParamPart2; + drflac_uint32 riceParamPart3; + drflac_uint32 riceParamMask; + const drflac_int32* pSamplesOutEnd; + drflac_uint32 i; + + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(pSamplesOut != NULL); + + riceParamMask = ~((~0UL) << riceParam); + pSamplesOutEnd = pSamplesOut + ((count >> 2) << 2); + + if (bitsPerSample >= 24) { + while (pSamplesOut < pSamplesOutEnd) { + /* + Rice extraction. It's faster to do this one at a time against local variables than it is to use the x4 version + against an array. Not sure why, but perhaps it's making more efficient use of registers? + */ + if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) { + return DRFLAC_FALSE; + } + + riceParamPart0 &= riceParamMask; + riceParamPart1 &= riceParamMask; + riceParamPart2 &= riceParamMask; + riceParamPart3 &= riceParamMask; + + riceParamPart0 |= (zeroCountPart0 << riceParam); + riceParamPart1 |= (zeroCountPart1 << riceParam); + riceParamPart2 |= (zeroCountPart2 << riceParam); + riceParamPart3 |= (zeroCountPart3 << riceParam); + + riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01]; + riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01]; + riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01]; + riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01]; + + pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0); + pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 1); + pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 2); + pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 3); + + pSamplesOut += 4; + } + } else { + while (pSamplesOut < pSamplesOutEnd) { + if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart1, &riceParamPart1) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart2, &riceParamPart2) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart3, &riceParamPart3)) { + return DRFLAC_FALSE; + } + + riceParamPart0 &= riceParamMask; + riceParamPart1 &= riceParamMask; + riceParamPart2 &= riceParamMask; + riceParamPart3 &= riceParamMask; + + riceParamPart0 |= (zeroCountPart0 << riceParam); + riceParamPart1 |= (zeroCountPart1 << riceParam); + riceParamPart2 |= (zeroCountPart2 << riceParam); + riceParamPart3 |= (zeroCountPart3 << riceParam); + + riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01]; + riceParamPart1 = (riceParamPart1 >> 1) ^ t[riceParamPart1 & 0x01]; + riceParamPart2 = (riceParamPart2 >> 1) ^ t[riceParamPart2 & 0x01]; + riceParamPart3 = (riceParamPart3 >> 1) ^ t[riceParamPart3 & 0x01]; + + pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0); + pSamplesOut[1] = riceParamPart1 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 1); + pSamplesOut[2] = riceParamPart2 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 2); + pSamplesOut[3] = riceParamPart3 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 3); + + pSamplesOut += 4; + } + } + + i = ((count >> 2) << 2); + while (i < count) { + /* Rice extraction. */ + if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountPart0, &riceParamPart0)) { + return DRFLAC_FALSE; + } + + /* Rice reconstruction. */ + riceParamPart0 &= riceParamMask; + riceParamPart0 |= (zeroCountPart0 << riceParam); + riceParamPart0 = (riceParamPart0 >> 1) ^ t[riceParamPart0 & 0x01]; + /*riceParamPart0 = (riceParamPart0 >> 1) ^ (~(riceParamPart0 & 0x01) + 1);*/ + + /* Sample reconstruction. */ + if (bitsPerSample >= 24) { + pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0); + } else { + pSamplesOut[0] = riceParamPart0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0); + } + + i += 1; + pSamplesOut += 1; + } + + return DRFLAC_TRUE; +} + +#if defined(DRFLAC_SUPPORT_SSE41) +static drflac_bool32 drflac__decode_samples_with_residual__rice__sse41(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + static drflac_uint32 t[2] = {0x00000000, 0xFFFFFFFF}; + + /*drflac_uint32 zeroCountParts[4];*/ + /*drflac_uint32 riceParamParts[4];*/ + + drflac_uint32 zeroCountParts0; + drflac_uint32 zeroCountParts1; + drflac_uint32 zeroCountParts2; + drflac_uint32 zeroCountParts3; + drflac_uint32 riceParamParts0; + drflac_uint32 riceParamParts1; + drflac_uint32 riceParamParts2; + drflac_uint32 riceParamParts3; + drflac_uint32 riceParamMask; + const drflac_int32* pSamplesOutEnd; + __m128i riceParamMask128; + __m128i one; + drflac_uint32 i; + + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(pSamplesOut != NULL); + + riceParamMask = ~((~0UL) << riceParam); + riceParamMask128 = _mm_set1_epi32(riceParamMask); + one = _mm_set1_epi32(0x01); + + pSamplesOutEnd = pSamplesOut + ((count >> 2) << 2); + + if (bitsPerSample >= 24) { + while (pSamplesOut < pSamplesOutEnd) { + __m128i zeroCountPart128; + __m128i riceParamPart128; + drflac_uint32 riceParamParts[4]; + + /* Rice extraction. */ + if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) { + return DRFLAC_FALSE; + } + + zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0); + riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0); + + riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128); + riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam)); + riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_mullo_epi32(_mm_and_si128(riceParamPart128, one), _mm_set1_epi32(0xFFFFFFFF))); /* <-- Only supported from SSE4.1 */ + /*riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_add_epi32(drflac__mm_not_si128(_mm_and_si128(riceParamPart128, one)), one));*/ /* <-- SSE2 compatible */ + + _mm_storeu_si128((__m128i*)riceParamParts, riceParamPart128); + + #if defined(DRFLAC_64BIT) + /* The scalar implementation seems to be faster on 64-bit in my testing. */ + drflac__calculate_prediction_64_x4(order, shift, coefficients, riceParamParts, pSamplesOut); + #else + pSamplesOut[0] = riceParamParts[0] + drflac__calculate_prediction_64__sse41(order, shift, coefficients, pSamplesOut + 0); + pSamplesOut[1] = riceParamParts[1] + drflac__calculate_prediction_64__sse41(order, shift, coefficients, pSamplesOut + 1); + pSamplesOut[2] = riceParamParts[2] + drflac__calculate_prediction_64__sse41(order, shift, coefficients, pSamplesOut + 2); + pSamplesOut[3] = riceParamParts[3] + drflac__calculate_prediction_64__sse41(order, shift, coefficients, pSamplesOut + 3); + #endif + + pSamplesOut += 4; + } + } else { + drflac_int32 coefficientsUnaligned[32*4 + 4] = {0}; + drflac_int32* coefficients128 = (drflac_int32*)(((size_t)coefficientsUnaligned + 15) & ~15); + + for (i = 0; i < order; ++i) { + coefficients128[i*4+0] = coefficients[i]; + coefficients128[i*4+1] = coefficients[i]; + coefficients128[i*4+2] = coefficients[i]; + coefficients128[i*4+3] = coefficients[i]; + } + + while (pSamplesOut < pSamplesOutEnd) { + __m128i zeroCountPart128; + __m128i riceParamPart128; + /*drflac_int32 riceParamParts[4];*/ + + /* Rice extraction. */ +#if 1 + if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts1, &riceParamParts1) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts2, &riceParamParts2) || + !drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts3, &riceParamParts3)) { + return DRFLAC_FALSE; + } + + zeroCountPart128 = _mm_set_epi32(zeroCountParts3, zeroCountParts2, zeroCountParts1, zeroCountParts0); + riceParamPart128 = _mm_set_epi32(riceParamParts3, riceParamParts2, riceParamParts1, riceParamParts0); +#else + if (!drflac__read_rice_parts_x4(bs, riceParam, zeroCountParts, riceParamParts)) { + return DRFLAC_FALSE; + } + + zeroCountPart128 = _mm_set_epi32(zeroCountParts[3], zeroCountParts[2], zeroCountParts[1], zeroCountParts[0]); + riceParamPart128 = _mm_set_epi32(riceParamParts[3], riceParamParts[2], riceParamParts[1], riceParamParts[0]); +#endif + + riceParamPart128 = _mm_and_si128(riceParamPart128, riceParamMask128); + riceParamPart128 = _mm_or_si128(riceParamPart128, _mm_slli_epi32(zeroCountPart128, riceParam)); + riceParamPart128 = _mm_xor_si128(_mm_srli_epi32(riceParamPart128, 1), _mm_mullo_epi32(_mm_and_si128(riceParamPart128, one), _mm_set1_epi32(0xFFFFFFFF))); + +#if 1 + drflac__calculate_prediction_32_x4__sse41(order, shift, (const __m128i*)coefficients128, riceParamPart128, pSamplesOut); +#else + _mm_storeu_si128((__m128i*)riceParamParts, riceParamPart128); + + pSamplesOut[0] = riceParamParts[0] + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0); + pSamplesOut[1] = riceParamParts[1] + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 1); + pSamplesOut[2] = riceParamParts[2] + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 2); + pSamplesOut[3] = riceParamParts[3] + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 3); +#endif + + pSamplesOut += 4; + } + } + + + i = ((count >> 2) << 2); + while (i < count) { + /* Rice extraction. */ + if (!drflac__read_rice_parts_x1(bs, riceParam, &zeroCountParts0, &riceParamParts0)) { + return DRFLAC_FALSE; + } + + /* Rice reconstruction. */ + riceParamParts0 &= riceParamMask; + riceParamParts0 |= (zeroCountParts0 << riceParam); + riceParamParts0 = (riceParamParts0 >> 1) ^ t[riceParamParts0 & 0x01]; + + /* Sample reconstruction. */ + if (bitsPerSample >= 24) { + pSamplesOut[0] = riceParamParts0 + drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + 0); + } else { + pSamplesOut[0] = riceParamParts0 + drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + 0); + } + + i += 1; + pSamplesOut += 1; + } + + return DRFLAC_TRUE; +} +#endif + +static drflac_bool32 drflac__decode_samples_with_residual__rice(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 riceParam, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ +#if defined(DRFLAC_SUPPORT_SSE41) + if (drflac__gIsSSE41Supported) { + return drflac__decode_samples_with_residual__rice__sse41(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut); + } else +#endif + { + /* Scalar fallback. */ + #if 0 + return drflac__decode_samples_with_residual__rice__reference(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut); + #else + return drflac__decode_samples_with_residual__rice__scalar(bs, bitsPerSample, count, riceParam, order, shift, coefficients, pSamplesOut); + #endif + } +} + +/* Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes. */ +static drflac_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, drflac_uint32 count, drflac_uint8 riceParam) +{ + drflac_uint32 i; + + drflac_assert(bs != NULL); + drflac_assert(count > 0); + + for (i = 0; i < count; ++i) { + if (!drflac__seek_rice_parts(bs, riceParam)) { + return DRFLAC_FALSE; + } + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 count, drflac_uint8 unencodedBitsPerSample, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pSamplesOut) +{ + drflac_uint32 i; + + drflac_assert(bs != NULL); + drflac_assert(count > 0); + drflac_assert(unencodedBitsPerSample <= 31); /* <-- unencodedBitsPerSample is a 5 bit number, so cannot exceed 31. */ + drflac_assert(pSamplesOut != NULL); + + for (i = 0; i < count; ++i) { + if (unencodedBitsPerSample > 0) { + if (!drflac__read_int32(bs, unencodedBitsPerSample, pSamplesOut + i)) { + return DRFLAC_FALSE; + } + } else { + pSamplesOut[i] = 0; + } + + if (bitsPerSample > 16) { + pSamplesOut[i] += drflac__calculate_prediction_64(order, shift, coefficients, pSamplesOut + i); + } else { + pSamplesOut[i] += drflac__calculate_prediction_32(order, shift, coefficients, pSamplesOut + i); + } + } + + return DRFLAC_TRUE; +} + + +/* +Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called +when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be ignored. The + and parameters are used to determine how many residual values need to be decoded. +*/ +static drflac_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, drflac_uint32 bitsPerSample, drflac_uint32 blockSize, drflac_uint32 order, drflac_int32 shift, const drflac_int32* coefficients, drflac_int32* pDecodedSamples) +{ + drflac_uint8 residualMethod; + drflac_uint8 partitionOrder; + drflac_uint32 samplesInPartition; + drflac_uint32 partitionsRemaining; + + drflac_assert(bs != NULL); + drflac_assert(blockSize != 0); + drflac_assert(pDecodedSamples != NULL); /* <-- Should we allow NULL, in which case we just seek past the residual rather than do a full decode? */ + + if (!drflac__read_uint8(bs, 2, &residualMethod)) { + return DRFLAC_FALSE; + } + + if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) { + return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */ + } + + /* Ignore the first values. */ + pDecodedSamples += order; + + if (!drflac__read_uint8(bs, 4, &partitionOrder)) { + return DRFLAC_FALSE; + } + + /* + From the FLAC spec: + The Rice partition order in a Rice-coded residual section must be less than or equal to 8. + */ + if (partitionOrder > 8) { + return DRFLAC_FALSE; + } + + /* Validation check. */ + if ((blockSize / (1 << partitionOrder)) <= order) { + return DRFLAC_FALSE; + } + + samplesInPartition = (blockSize / (1 << partitionOrder)) - order; + partitionsRemaining = (1 << partitionOrder); + for (;;) { + drflac_uint8 riceParam = 0; + if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) { + if (!drflac__read_uint8(bs, 4, &riceParam)) { + return DRFLAC_FALSE; + } + if (riceParam == 15) { + riceParam = 0xFF; + } + } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) { + if (!drflac__read_uint8(bs, 5, &riceParam)) { + return DRFLAC_FALSE; + } + if (riceParam == 31) { + riceParam = 0xFF; + } + } + + if (riceParam != 0xFF) { + if (!drflac__decode_samples_with_residual__rice(bs, bitsPerSample, samplesInPartition, riceParam, order, shift, coefficients, pDecodedSamples)) { + return DRFLAC_FALSE; + } + } else { + unsigned char unencodedBitsPerSample = 0; + if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) { + return DRFLAC_FALSE; + } + + if (!drflac__decode_samples_with_residual__unencoded(bs, bitsPerSample, samplesInPartition, unencodedBitsPerSample, order, shift, coefficients, pDecodedSamples)) { + return DRFLAC_FALSE; + } + } + + pDecodedSamples += samplesInPartition; + + if (partitionsRemaining == 1) { + break; + } + + partitionsRemaining -= 1; + + if (partitionOrder != 0) { + samplesInPartition = blockSize / (1 << partitionOrder); + } + } + + return DRFLAC_TRUE; +} + +/* +Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called +when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be set to 0. The + and parameters are used to determine how many residual values need to be decoded. +*/ +static drflac_bool32 drflac__read_and_seek_residual(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 order) +{ + drflac_uint8 residualMethod; + drflac_uint8 partitionOrder; + drflac_uint32 samplesInPartition; + drflac_uint32 partitionsRemaining; + + drflac_assert(bs != NULL); + drflac_assert(blockSize != 0); + + if (!drflac__read_uint8(bs, 2, &residualMethod)) { + return DRFLAC_FALSE; + } + + if (residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE && residualMethod != DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) { + return DRFLAC_FALSE; /* Unknown or unsupported residual coding method. */ + } + + if (!drflac__read_uint8(bs, 4, &partitionOrder)) { + return DRFLAC_FALSE; + } + + /* + From the FLAC spec: + The Rice partition order in a Rice-coded residual section must be less than or equal to 8. + */ + if (partitionOrder > 8) { + return DRFLAC_FALSE; + } + + /* Validation check. */ + if ((blockSize / (1 << partitionOrder)) <= order) { + return DRFLAC_FALSE; + } + + samplesInPartition = (blockSize / (1 << partitionOrder)) - order; + partitionsRemaining = (1 << partitionOrder); + for (;;) + { + drflac_uint8 riceParam = 0; + if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE) { + if (!drflac__read_uint8(bs, 4, &riceParam)) { + return DRFLAC_FALSE; + } + if (riceParam == 15) { + riceParam = 0xFF; + } + } else if (residualMethod == DRFLAC_RESIDUAL_CODING_METHOD_PARTITIONED_RICE2) { + if (!drflac__read_uint8(bs, 5, &riceParam)) { + return DRFLAC_FALSE; + } + if (riceParam == 31) { + riceParam = 0xFF; + } + } + + if (riceParam != 0xFF) { + if (!drflac__read_and_seek_residual__rice(bs, samplesInPartition, riceParam)) { + return DRFLAC_FALSE; + } + } else { + unsigned char unencodedBitsPerSample = 0; + if (!drflac__read_uint8(bs, 5, &unencodedBitsPerSample)) { + return DRFLAC_FALSE; + } + + if (!drflac__seek_bits(bs, unencodedBitsPerSample * samplesInPartition)) { + return DRFLAC_FALSE; + } + } + + + if (partitionsRemaining == 1) { + break; + } + + partitionsRemaining -= 1; + samplesInPartition = blockSize / (1 << partitionOrder); + } + + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__decode_samples__constant(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_int32* pDecodedSamples) +{ + drflac_uint32 i; + + /* Only a single sample needs to be decoded here. */ + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) { + return DRFLAC_FALSE; + } + + /* + We don't really need to expand this, but it does simplify the process of reading samples. If this becomes a performance issue (unlikely) + we'll want to look at a more efficient way. + */ + for (i = 0; i < blockSize; ++i) { + pDecodedSamples[i] = sample; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_int32* pDecodedSamples) +{ + drflac_uint32 i; + + for (i = 0; i < blockSize; ++i) { + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) { + return DRFLAC_FALSE; + } + + pDecodedSamples[i] = sample; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples__fixed(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples) +{ + drflac_uint32 i; + + static drflac_int32 lpcCoefficientsTable[5][4] = { + {0, 0, 0, 0}, + {1, 0, 0, 0}, + {2, -1, 0, 0}, + {3, -3, 1, 0}, + {4, -6, 4, -1} + }; + + /* Warm up samples and coefficients. */ + for (i = 0; i < lpcOrder; ++i) { + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) { + return DRFLAC_FALSE; + } + + pDecodedSamples[i] = sample; + } + + if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, 0, lpcCoefficientsTable[lpcOrder], pDecodedSamples)) { + return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_samples__lpc(drflac_bs* bs, drflac_uint32 blockSize, drflac_uint32 bitsPerSample, drflac_uint8 lpcOrder, drflac_int32* pDecodedSamples) +{ + drflac_uint8 i; + drflac_uint8 lpcPrecision; + drflac_int8 lpcShift; + drflac_int32 coefficients[32]; + + /* Warm up samples. */ + for (i = 0; i < lpcOrder; ++i) { + drflac_int32 sample; + if (!drflac__read_int32(bs, bitsPerSample, &sample)) { + return DRFLAC_FALSE; + } + + pDecodedSamples[i] = sample; + } + + if (!drflac__read_uint8(bs, 4, &lpcPrecision)) { + return DRFLAC_FALSE; + } + if (lpcPrecision == 15) { + return DRFLAC_FALSE; /* Invalid. */ + } + lpcPrecision += 1; + + if (!drflac__read_int8(bs, 5, &lpcShift)) { + return DRFLAC_FALSE; + } + + drflac_zero_memory(coefficients, sizeof(coefficients)); + for (i = 0; i < lpcOrder; ++i) { + if (!drflac__read_int32(bs, lpcPrecision, coefficients + i)) { + return DRFLAC_FALSE; + } + } + + if (!drflac__decode_samples_with_residual(bs, bitsPerSample, blockSize, lpcOrder, lpcShift, coefficients, pDecodedSamples)) { + return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + + +static drflac_bool32 drflac__read_next_flac_frame_header(drflac_bs* bs, drflac_uint8 streaminfoBitsPerSample, drflac_frame_header* header) +{ + const drflac_uint32 sampleRateTable[12] = {0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000}; + const drflac_uint8 bitsPerSampleTable[8] = {0, 8, 12, (drflac_uint8)-1, 16, 20, 24, (drflac_uint8)-1}; /* -1 = reserved. */ + + drflac_assert(bs != NULL); + drflac_assert(header != NULL); + + /* Keep looping until we find a valid sync code. */ + for (;;) { + drflac_uint8 crc8 = 0xCE; /* 0xCE = drflac_crc8(0, 0x3FFE, 14); */ + drflac_uint8 reserved = 0; + drflac_uint8 blockingStrategy = 0; + drflac_uint8 blockSize = 0; + drflac_uint8 sampleRate = 0; + drflac_uint8 channelAssignment = 0; + drflac_uint8 bitsPerSample = 0; + drflac_bool32 isVariableBlockSize; + + if (!drflac__find_and_seek_to_next_sync_code(bs)) { + return DRFLAC_FALSE; + } + + if (!drflac__read_uint8(bs, 1, &reserved)) { + return DRFLAC_FALSE; + } + if (reserved == 1) { + continue; + } + crc8 = drflac_crc8(crc8, reserved, 1); + + if (!drflac__read_uint8(bs, 1, &blockingStrategy)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, blockingStrategy, 1); + + if (!drflac__read_uint8(bs, 4, &blockSize)) { + return DRFLAC_FALSE; + } + if (blockSize == 0) { + continue; + } + crc8 = drflac_crc8(crc8, blockSize, 4); + + if (!drflac__read_uint8(bs, 4, &sampleRate)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, sampleRate, 4); + + if (!drflac__read_uint8(bs, 4, &channelAssignment)) { + return DRFLAC_FALSE; + } + if (channelAssignment > 10) { + continue; + } + crc8 = drflac_crc8(crc8, channelAssignment, 4); + + if (!drflac__read_uint8(bs, 3, &bitsPerSample)) { + return DRFLAC_FALSE; + } + if (bitsPerSample == 3 || bitsPerSample == 7) { + continue; + } + crc8 = drflac_crc8(crc8, bitsPerSample, 3); + + + if (!drflac__read_uint8(bs, 1, &reserved)) { + return DRFLAC_FALSE; + } + if (reserved == 1) { + continue; + } + crc8 = drflac_crc8(crc8, reserved, 1); + + + isVariableBlockSize = blockingStrategy == 1; + if (isVariableBlockSize) { + drflac_uint64 sampleNumber; + drflac_result result = drflac__read_utf8_coded_number(bs, &sampleNumber, &crc8); + if (result != DRFLAC_SUCCESS) { + if (result == DRFLAC_END_OF_STREAM) { + return DRFLAC_FALSE; + } else { + continue; + } + } + header->frameNumber = 0; + header->sampleNumber = sampleNumber; + } else { + drflac_uint64 frameNumber = 0; + drflac_result result = drflac__read_utf8_coded_number(bs, &frameNumber, &crc8); + if (result != DRFLAC_SUCCESS) { + if (result == DRFLAC_END_OF_STREAM) { + return DRFLAC_FALSE; + } else { + continue; + } + } + header->frameNumber = (drflac_uint32)frameNumber; /* <-- Safe cast. */ + header->sampleNumber = 0; + } + + + if (blockSize == 1) { + header->blockSize = 192; + } else if (blockSize >= 2 && blockSize <= 5) { + header->blockSize = 576 * (1 << (blockSize - 2)); + } else if (blockSize == 6) { + if (!drflac__read_uint16(bs, 8, &header->blockSize)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, header->blockSize, 8); + header->blockSize += 1; + } else if (blockSize == 7) { + if (!drflac__read_uint16(bs, 16, &header->blockSize)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, header->blockSize, 16); + header->blockSize += 1; + } else { + header->blockSize = 256 * (1 << (blockSize - 8)); + } + + + if (sampleRate <= 11) { + header->sampleRate = sampleRateTable[sampleRate]; + } else if (sampleRate == 12) { + if (!drflac__read_uint32(bs, 8, &header->sampleRate)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, header->sampleRate, 8); + header->sampleRate *= 1000; + } else if (sampleRate == 13) { + if (!drflac__read_uint32(bs, 16, &header->sampleRate)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, header->sampleRate, 16); + } else if (sampleRate == 14) { + if (!drflac__read_uint32(bs, 16, &header->sampleRate)) { + return DRFLAC_FALSE; + } + crc8 = drflac_crc8(crc8, header->sampleRate, 16); + header->sampleRate *= 10; + } else { + continue; /* Invalid. Assume an invalid block. */ + } + + + header->channelAssignment = channelAssignment; + + header->bitsPerSample = bitsPerSampleTable[bitsPerSample]; + if (header->bitsPerSample == 0) { + header->bitsPerSample = streaminfoBitsPerSample; + } + + if (!drflac__read_uint8(bs, 8, &header->crc8)) { + return DRFLAC_FALSE; + } + +#ifndef DR_FLAC_NO_CRC + if (header->crc8 != crc8) { + continue; /* CRC mismatch. Loop back to the top and find the next sync code. */ + } +#endif + return DRFLAC_TRUE; + } +} + +static drflac_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe) +{ + drflac_uint8 header; + int type; + + if (!drflac__read_uint8(bs, 8, &header)) { + return DRFLAC_FALSE; + } + + /* First bit should always be 0. */ + if ((header & 0x80) != 0) { + return DRFLAC_FALSE; + } + + type = (header & 0x7E) >> 1; + if (type == 0) { + pSubframe->subframeType = DRFLAC_SUBFRAME_CONSTANT; + } else if (type == 1) { + pSubframe->subframeType = DRFLAC_SUBFRAME_VERBATIM; + } else { + if ((type & 0x20) != 0) { + pSubframe->subframeType = DRFLAC_SUBFRAME_LPC; + pSubframe->lpcOrder = (type & 0x1F) + 1; + } else if ((type & 0x08) != 0) { + pSubframe->subframeType = DRFLAC_SUBFRAME_FIXED; + pSubframe->lpcOrder = (type & 0x07); + if (pSubframe->lpcOrder > 4) { + pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED; + pSubframe->lpcOrder = 0; + } + } else { + pSubframe->subframeType = DRFLAC_SUBFRAME_RESERVED; + } + } + + if (pSubframe->subframeType == DRFLAC_SUBFRAME_RESERVED) { + return DRFLAC_FALSE; + } + + /* Wasted bits per sample. */ + pSubframe->wastedBitsPerSample = 0; + if ((header & 0x01) == 1) { + unsigned int wastedBitsPerSample; + if (!drflac__seek_past_next_set_bit(bs, &wastedBitsPerSample)) { + return DRFLAC_FALSE; + } + pSubframe->wastedBitsPerSample = (unsigned char)wastedBitsPerSample + 1; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, drflac_int32* pDecodedSamplesOut) +{ + drflac_subframe* pSubframe; + + drflac_assert(bs != NULL); + drflac_assert(frame != NULL); + + pSubframe = frame->subframes + subframeIndex; + if (!drflac__read_subframe_header(bs, pSubframe)) { + return DRFLAC_FALSE; + } + + /* Side channels require an extra bit per sample. Took a while to figure that one out... */ + pSubframe->bitsPerSample = frame->header.bitsPerSample; + if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) { + pSubframe->bitsPerSample += 1; + } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) { + pSubframe->bitsPerSample += 1; + } + + /* Need to handle wasted bits per sample. */ + if (pSubframe->wastedBitsPerSample >= pSubframe->bitsPerSample) { + return DRFLAC_FALSE; + } + pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample; + pSubframe->pDecodedSamples = pDecodedSamplesOut; + + switch (pSubframe->subframeType) + { + case DRFLAC_SUBFRAME_CONSTANT: + { + drflac__decode_samples__constant(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->pDecodedSamples); + } break; + + case DRFLAC_SUBFRAME_VERBATIM: + { + drflac__decode_samples__verbatim(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->pDecodedSamples); + } break; + + case DRFLAC_SUBFRAME_FIXED: + { + drflac__decode_samples__fixed(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->lpcOrder, pSubframe->pDecodedSamples); + } break; + + case DRFLAC_SUBFRAME_LPC: + { + drflac__decode_samples__lpc(bs, frame->header.blockSize, pSubframe->bitsPerSample, pSubframe->lpcOrder, pSubframe->pDecodedSamples); + } break; + + default: return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + +static drflac_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex) +{ + drflac_subframe* pSubframe; + + drflac_assert(bs != NULL); + drflac_assert(frame != NULL); + + pSubframe = frame->subframes + subframeIndex; + if (!drflac__read_subframe_header(bs, pSubframe)) { + return DRFLAC_FALSE; + } + + /* Side channels require an extra bit per sample. Took a while to figure that one out... */ + pSubframe->bitsPerSample = frame->header.bitsPerSample; + if ((frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE || frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE) && subframeIndex == 1) { + pSubframe->bitsPerSample += 1; + } else if (frame->header.channelAssignment == DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE && subframeIndex == 0) { + pSubframe->bitsPerSample += 1; + } + + /* Need to handle wasted bits per sample. */ + if (pSubframe->wastedBitsPerSample >= pSubframe->bitsPerSample) { + return DRFLAC_FALSE; + } + pSubframe->bitsPerSample -= pSubframe->wastedBitsPerSample; + pSubframe->pDecodedSamples = NULL; + + switch (pSubframe->subframeType) + { + case DRFLAC_SUBFRAME_CONSTANT: + { + if (!drflac__seek_bits(bs, pSubframe->bitsPerSample)) { + return DRFLAC_FALSE; + } + } break; + + case DRFLAC_SUBFRAME_VERBATIM: + { + unsigned int bitsToSeek = frame->header.blockSize * pSubframe->bitsPerSample; + if (!drflac__seek_bits(bs, bitsToSeek)) { + return DRFLAC_FALSE; + } + } break; + + case DRFLAC_SUBFRAME_FIXED: + { + unsigned int bitsToSeek = pSubframe->lpcOrder * pSubframe->bitsPerSample; + if (!drflac__seek_bits(bs, bitsToSeek)) { + return DRFLAC_FALSE; + } + + if (!drflac__read_and_seek_residual(bs, frame->header.blockSize, pSubframe->lpcOrder)) { + return DRFLAC_FALSE; + } + } break; + + case DRFLAC_SUBFRAME_LPC: + { + unsigned char lpcPrecision; + + unsigned int bitsToSeek = pSubframe->lpcOrder * pSubframe->bitsPerSample; + if (!drflac__seek_bits(bs, bitsToSeek)) { + return DRFLAC_FALSE; + } + + if (!drflac__read_uint8(bs, 4, &lpcPrecision)) { + return DRFLAC_FALSE; + } + if (lpcPrecision == 15) { + return DRFLAC_FALSE; /* Invalid. */ + } + lpcPrecision += 1; + + + bitsToSeek = (pSubframe->lpcOrder * lpcPrecision) + 5; /* +5 for shift. */ + if (!drflac__seek_bits(bs, bitsToSeek)) { + return DRFLAC_FALSE; + } + + if (!drflac__read_and_seek_residual(bs, frame->header.blockSize, pSubframe->lpcOrder)) { + return DRFLAC_FALSE; + } + } break; + + default: return DRFLAC_FALSE; + } + + return DRFLAC_TRUE; +} + + +static DRFLAC_INLINE drflac_uint8 drflac__get_channel_count_from_channel_assignment(drflac_int8 channelAssignment) +{ + drflac_uint8 lookup[] = {1, 2, 3, 4, 5, 6, 7, 8, 2, 2, 2}; + + drflac_assert(channelAssignment <= 10); + return lookup[channelAssignment]; +} + +static drflac_result drflac__decode_flac_frame(drflac* pFlac) +{ + int channelCount; + int i; + drflac_uint8 paddingSizeInBits; + drflac_uint16 desiredCRC16; +#ifndef DR_FLAC_NO_CRC + drflac_uint16 actualCRC16; +#endif + + /* This function should be called while the stream is sitting on the first byte after the frame header. */ + drflac_zero_memory(pFlac->currentFrame.subframes, sizeof(pFlac->currentFrame.subframes)); + + /* The frame block size must never be larger than the maximum block size defined by the FLAC stream. */ + if (pFlac->currentFrame.header.blockSize > pFlac->maxBlockSize) { + return DRFLAC_ERROR; + } + + /* The number of channels in the frame must match the channel count from the STREAMINFO block. */ + channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + if (channelCount != (int)pFlac->channels) { + return DRFLAC_ERROR; + } + + for (i = 0; i < channelCount; ++i) { + if (!drflac__decode_subframe(&pFlac->bs, &pFlac->currentFrame, i, pFlac->pDecodedSamples + ((pFlac->currentFrame.header.blockSize+DRFLAC_LEADING_SAMPLES) * i) + DRFLAC_LEADING_SAMPLES)) { + return DRFLAC_ERROR; + } + } + + paddingSizeInBits = DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7; + if (paddingSizeInBits > 0) { + drflac_uint8 padding = 0; + if (!drflac__read_uint8(&pFlac->bs, paddingSizeInBits, &padding)) { + return DRFLAC_END_OF_STREAM; + } + } + +#ifndef DR_FLAC_NO_CRC + actualCRC16 = drflac__flush_crc16(&pFlac->bs); +#endif + if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) { + return DRFLAC_END_OF_STREAM; + } + +#ifndef DR_FLAC_NO_CRC + if (actualCRC16 != desiredCRC16) { + return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */ + } +#endif + + pFlac->currentFrame.samplesRemaining = pFlac->currentFrame.header.blockSize * channelCount; + + return DRFLAC_SUCCESS; +} + +static drflac_result drflac__seek_flac_frame(drflac* pFlac) +{ + int channelCount; + int i; + drflac_uint16 desiredCRC16; +#ifndef DR_FLAC_NO_CRC + drflac_uint16 actualCRC16; +#endif + + channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + for (i = 0; i < channelCount; ++i) { + if (!drflac__seek_subframe(&pFlac->bs, &pFlac->currentFrame, i)) { + return DRFLAC_ERROR; + } + } + + /* Padding. */ + if (!drflac__seek_bits(&pFlac->bs, DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7)) { + return DRFLAC_ERROR; + } + + /* CRC. */ +#ifndef DR_FLAC_NO_CRC + actualCRC16 = drflac__flush_crc16(&pFlac->bs); +#endif + if (!drflac__read_uint16(&pFlac->bs, 16, &desiredCRC16)) { + return DRFLAC_END_OF_STREAM; + } + +#ifndef DR_FLAC_NO_CRC + if (actualCRC16 != desiredCRC16) { + return DRFLAC_CRC_MISMATCH; /* CRC mismatch. */ + } +#endif + + return DRFLAC_SUCCESS; +} + +static drflac_bool32 drflac__read_and_decode_next_flac_frame(drflac* pFlac) +{ + drflac_assert(pFlac != NULL); + + for (;;) { + drflac_result result; + + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + + result = drflac__decode_flac_frame(pFlac); + if (result != DRFLAC_SUCCESS) { + if (result == DRFLAC_CRC_MISMATCH) { + continue; /* CRC mismatch. Skip to the next frame. */ + } else { + return DRFLAC_FALSE; + } + } + + return DRFLAC_TRUE; + } +} + + +static void drflac__get_current_frame_sample_range(drflac* pFlac, drflac_uint64* pFirstSampleInFrameOut, drflac_uint64* pLastSampleInFrameOut) +{ + unsigned int channelCount; + drflac_uint64 firstSampleInFrame; + drflac_uint64 lastSampleInFrame; + + drflac_assert(pFlac != NULL); + + channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + + firstSampleInFrame = pFlac->currentFrame.header.sampleNumber*channelCount; + if (firstSampleInFrame == 0) { + firstSampleInFrame = pFlac->currentFrame.header.frameNumber * pFlac->maxBlockSize*channelCount; + } + + lastSampleInFrame = firstSampleInFrame + (pFlac->currentFrame.header.blockSize*channelCount); + if (lastSampleInFrame > 0) { + lastSampleInFrame -= 1; /* Needs to be zero based. */ + } + + if (pFirstSampleInFrameOut) { + *pFirstSampleInFrameOut = firstSampleInFrame; + } + if (pLastSampleInFrameOut) { + *pLastSampleInFrameOut = lastSampleInFrame; + } +} + +/* This function will be replacing drflac__get_current_frame_sample_range(), but it's not currently used so I have commented it out to silence a compiler warning. */ +#if 0 +static void drflac__get_pcm_frame_range_of_current_flac_frame(drflac* pFlac, drflac_uint64* pFirstPCMFrame, drflac_uint64* pLastPCMFrame) +{ + drflac_uint64 firstPCMFrame; + drflac_uint64 lastPCMFrame; + + drflac_assert(pFlac != NULL); + + firstPCMFrame = pFlac->currentFrame.header.sampleNumber; + if (firstPCMFrame == 0) { + firstPCMFrame = pFlac->currentFrame.header.frameNumber * pFlac->maxBlockSize; + } + + lastPCMFrame = firstPCMFrame + (pFlac->currentFrame.header.blockSize); + if (lastPCMFrame > 0) { + lastPCMFrame -= 1; /* Needs to be zero based. */ + } + + if (pFirstPCMFrame) { + *pFirstPCMFrame = firstPCMFrame; + } + if (pLastPCMFrame) { + *pLastPCMFrame = lastPCMFrame; + } +} +#endif + +static drflac_bool32 drflac__seek_to_first_frame(drflac* pFlac) +{ + drflac_bool32 result; + + drflac_assert(pFlac != NULL); + + result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos); + + drflac_zero_memory(&pFlac->currentFrame, sizeof(pFlac->currentFrame)); + pFlac->currentSample = 0; + + return result; +} + +static DRFLAC_INLINE drflac_result drflac__seek_to_next_flac_frame(drflac* pFlac) +{ + /* This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. */ + drflac_assert(pFlac != NULL); + return drflac__seek_flac_frame(pFlac); +} + +drflac_uint64 drflac__seek_forward_by_samples(drflac* pFlac, drflac_uint64 samplesToRead) +{ + drflac_uint64 samplesRead = 0; + while (samplesToRead > 0) { + if (pFlac->currentFrame.samplesRemaining == 0) { + if (!drflac__read_and_decode_next_flac_frame(pFlac)) { + break; /* Couldn't read the next frame, so just break from the loop and return. */ + } + } else { + if (pFlac->currentFrame.samplesRemaining > samplesToRead) { + samplesRead += samplesToRead; + pFlac->currentFrame.samplesRemaining -= (drflac_uint32)samplesToRead; /* <-- Safe cast. Will always be < currentFrame.samplesRemaining < 65536. */ + samplesToRead = 0; + } else { + samplesRead += pFlac->currentFrame.samplesRemaining; + samplesToRead -= pFlac->currentFrame.samplesRemaining; + pFlac->currentFrame.samplesRemaining = 0; + } + } + } + + pFlac->currentSample += samplesRead; + return samplesRead; +} + +drflac_uint64 drflac__seek_forward_by_pcm_frames(drflac* pFlac, drflac_uint64 pcmFramesToSeek) +{ + return drflac__seek_forward_by_samples(pFlac, pcmFramesToSeek*pFlac->channels); +} + +static drflac_bool32 drflac__seek_to_sample__brute_force(drflac* pFlac, drflac_uint64 sampleIndex) +{ + drflac_bool32 isMidFrame = DRFLAC_FALSE; + drflac_uint64 runningSampleCount; + + drflac_assert(pFlac != NULL); + + /* If we are seeking forward we start from the current position. Otherwise we need to start all the way from the start of the file. */ + if (sampleIndex >= pFlac->currentSample) { + /* Seeking forward. Need to seek from the current position. */ + runningSampleCount = pFlac->currentSample; + + /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */ + if (pFlac->currentSample == 0 && pFlac->currentFrame.samplesRemaining == 0) { + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + } else { + isMidFrame = DRFLAC_TRUE; + } + } else { + /* Seeking backwards. Need to seek from the start of the file. */ + runningSampleCount = 0; + + /* Move back to the start. */ + if (!drflac__seek_to_first_frame(pFlac)) { + return DRFLAC_FALSE; + } + + /* Decode the first frame in preparation for sample-exact seeking below. */ + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + } + + /* + We need to as quickly as possible find the frame that contains the target sample. To do this, we iterate over each frame and inspect its + header. If based on the header we can determine that the frame contains the sample, we do a full decode of that frame. + */ + for (;;) { + drflac_uint64 sampleCountInThisFrame; + drflac_uint64 firstSampleInFrame = 0; + drflac_uint64 lastSampleInFrame = 0; + + drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame); + + sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1; + if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) { + /* + The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend + it never existed and keep iterating. + */ + drflac_uint64 samplesToDecode = sampleIndex - runningSampleCount; + + if (!isMidFrame) { + drflac_result result = drflac__decode_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */ + return drflac__seek_forward_by_samples(pFlac, samplesToDecode) == samplesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */ + } else { + if (result == DRFLAC_CRC_MISMATCH) { + goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */ + } else { + return DRFLAC_FALSE; + } + } + } else { + /* We started seeking mid-frame which means we need to skip the frame decoding part. */ + return drflac__seek_forward_by_samples(pFlac, samplesToDecode) == samplesToDecode; + } + } else { + /* + It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this + frame never existed and leave the running sample count untouched. + */ + if (!isMidFrame) { + drflac_result result = drflac__seek_to_next_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + runningSampleCount += sampleCountInThisFrame; + } else { + if (result == DRFLAC_CRC_MISMATCH) { + goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */ + } else { + return DRFLAC_FALSE; + } + } + } else { + /* + We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with + drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header. + */ + runningSampleCount += pFlac->currentFrame.samplesRemaining; + pFlac->currentFrame.samplesRemaining = 0; + isMidFrame = DRFLAC_FALSE; + } + } + + next_iteration: + /* Grab the next frame in preparation for the next iteration. */ + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + } +} + + +static drflac_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, drflac_uint64 sampleIndex) +{ + drflac_uint32 iClosestSeekpoint = 0; + drflac_bool32 isMidFrame = DRFLAC_FALSE; + drflac_uint64 runningSampleCount; + drflac_uint32 iSeekpoint; + + drflac_assert(pFlac != NULL); + + if (pFlac->pSeekpoints == NULL || pFlac->seekpointCount == 0) { + return DRFLAC_FALSE; + } + + for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) { + if (pFlac->pSeekpoints[iSeekpoint].firstSample*pFlac->channels >= sampleIndex) { + break; + } + + iClosestSeekpoint = iSeekpoint; + } + + /* + At this point we should have found the seekpoint closest to our sample. If we are seeking forward and the closest seekpoint is _before_ the current sample, we + just seek forward from where we are. Otherwise we start seeking from the seekpoint's first sample. + */ + if ((sampleIndex >= pFlac->currentSample) && (pFlac->pSeekpoints[iClosestSeekpoint].firstSample*pFlac->channels <= pFlac->currentSample)) { + /* Optimized case. Just seek forward from where we are. */ + runningSampleCount = pFlac->currentSample; + + /* The frame header for the first frame may not yet have been read. We need to do that if necessary. */ + if (pFlac->currentSample == 0 && pFlac->currentFrame.samplesRemaining == 0) { + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + } else { + isMidFrame = DRFLAC_TRUE; + } + } else { + /* Slower case. Seek to the start of the seekpoint and then seek forward from there. */ + runningSampleCount = pFlac->pSeekpoints[iClosestSeekpoint].firstSample*pFlac->channels; + + if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos + pFlac->pSeekpoints[iClosestSeekpoint].frameOffset)) { + return DRFLAC_FALSE; + } + + /* Grab the frame the seekpoint is sitting on in preparation for the sample-exact seeking below. */ + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + } + + for (;;) { + drflac_uint64 sampleCountInThisFrame; + drflac_uint64 firstSampleInFrame = 0; + drflac_uint64 lastSampleInFrame = 0; + drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame); + + sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1; + if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) { + /* + The sample should be in this frame. We need to fully decode it, but if it's an invalid frame (a CRC mismatch) we need to pretend + it never existed and keep iterating. + */ + drflac_uint64 samplesToDecode = sampleIndex - runningSampleCount; + + if (!isMidFrame) { + drflac_result result = drflac__decode_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */ + return drflac__seek_forward_by_samples(pFlac, samplesToDecode) == samplesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */ + } else { + if (result == DRFLAC_CRC_MISMATCH) { + goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */ + } else { + return DRFLAC_FALSE; + } + } + } else { + /* We started seeking mid-frame which means we need to skip the frame decoding part. */ + return drflac__seek_forward_by_samples(pFlac, samplesToDecode) == samplesToDecode; + } + } else { + /* + It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this + frame never existed and leave the running sample count untouched. + */ + if (!isMidFrame) { + drflac_result result = drflac__seek_to_next_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + runningSampleCount += sampleCountInThisFrame; + } else { + if (result == DRFLAC_CRC_MISMATCH) { + goto next_iteration; /* CRC mismatch. Pretend this frame never existed. */ + } else { + return DRFLAC_FALSE; + } + } + } else { + /* + We started seeking mid-frame which means we need to seek by reading to the end of the frame instead of with + drflac__seek_to_next_flac_frame() which only works if the decoder is sitting on the byte just after the frame header. + */ + runningSampleCount += pFlac->currentFrame.samplesRemaining; + pFlac->currentFrame.samplesRemaining = 0; + isMidFrame = DRFLAC_FALSE; + } + } + + next_iteration: + /* Grab the next frame in preparation for the next iteration. */ + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + } +} + + +#ifndef DR_FLAC_NO_OGG +typedef struct +{ + drflac_uint8 capturePattern[4]; /* Should be "OggS" */ + drflac_uint8 structureVersion; /* Always 0. */ + drflac_uint8 headerType; + drflac_uint64 granulePosition; + drflac_uint32 serialNumber; + drflac_uint32 sequenceNumber; + drflac_uint32 checksum; + drflac_uint8 segmentCount; + drflac_uint8 segmentTable[255]; +} drflac_ogg_page_header; +#endif + +typedef struct +{ + drflac_read_proc onRead; + drflac_seek_proc onSeek; + drflac_meta_proc onMeta; + drflac_container container; + void* pUserData; + void* pUserDataMD; + drflac_uint32 sampleRate; + drflac_uint8 channels; + drflac_uint8 bitsPerSample; + drflac_uint64 totalSampleCount; + drflac_uint16 maxBlockSize; + drflac_uint64 runningFilePos; + drflac_bool32 hasStreamInfoBlock; + drflac_bool32 hasMetadataBlocks; + drflac_bs bs; /* <-- A bit streamer is required for loading data during initialization. */ + drflac_frame_header firstFrameHeader; /* <-- The header of the first frame that was read during relaxed initalization. Only set if there is no STREAMINFO block. */ + +#ifndef DR_FLAC_NO_OGG + drflac_uint32 oggSerial; + drflac_uint64 oggFirstBytePos; + drflac_ogg_page_header oggBosHeader; +#endif +} drflac_init_info; + +static DRFLAC_INLINE void drflac__decode_block_header(drflac_uint32 blockHeader, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize) +{ + blockHeader = drflac__be2host_32(blockHeader); + *isLastBlock = (blockHeader & 0x80000000UL) >> 31; + *blockType = (blockHeader & 0x7F000000UL) >> 24; + *blockSize = (blockHeader & 0x00FFFFFFUL); +} + +static DRFLAC_INLINE drflac_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, drflac_uint8* isLastBlock, drflac_uint8* blockType, drflac_uint32* blockSize) +{ + drflac_uint32 blockHeader; + if (onRead(pUserData, &blockHeader, 4) != 4) { + return DRFLAC_FALSE; + } + + drflac__decode_block_header(blockHeader, isLastBlock, blockType, blockSize); + return DRFLAC_TRUE; +} + +drflac_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo) +{ + drflac_uint32 blockSizes; + drflac_uint64 frameSizes = 0; + drflac_uint64 importantProps; + drflac_uint8 md5[16]; + + /* min/max block size. */ + if (onRead(pUserData, &blockSizes, 4) != 4) { + return DRFLAC_FALSE; + } + + /* min/max frame size. */ + if (onRead(pUserData, &frameSizes, 6) != 6) { + return DRFLAC_FALSE; + } + + /* Sample rate, channels, bits per sample and total sample count. */ + if (onRead(pUserData, &importantProps, 8) != 8) { + return DRFLAC_FALSE; + } + + /* MD5 */ + if (onRead(pUserData, md5, sizeof(md5)) != sizeof(md5)) { + return DRFLAC_FALSE; + } + + blockSizes = drflac__be2host_32(blockSizes); + frameSizes = drflac__be2host_64(frameSizes); + importantProps = drflac__be2host_64(importantProps); + + pStreamInfo->minBlockSize = (blockSizes & 0xFFFF0000) >> 16; + pStreamInfo->maxBlockSize = (blockSizes & 0x0000FFFF); + pStreamInfo->minFrameSize = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 24)) >> 40); + pStreamInfo->maxFrameSize = (drflac_uint32)((frameSizes & (((drflac_uint64)0x00FFFFFF << 16) << 0)) >> 16); + pStreamInfo->sampleRate = (drflac_uint32)((importantProps & (((drflac_uint64)0x000FFFFF << 16) << 28)) >> 44); + pStreamInfo->channels = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000000E << 16) << 24)) >> 41) + 1; + pStreamInfo->bitsPerSample = (drflac_uint8 )((importantProps & (((drflac_uint64)0x0000001F << 16) << 20)) >> 36) + 1; + pStreamInfo->totalSampleCount = ((importantProps & ((((drflac_uint64)0x0000000F << 16) << 16) | 0xFFFFFFFF))) * pStreamInfo->channels; + drflac_copy_memory(pStreamInfo->md5, md5, sizeof(md5)); + + return DRFLAC_TRUE; +} + +drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_uint64* pFirstFramePos, drflac_uint64* pSeektablePos, drflac_uint32* pSeektableSize) +{ + /* + We want to keep track of the byte position in the stream of the seektable. At the time of calling this function we know that + we'll be sitting on byte 42. + */ + drflac_uint64 runningFilePos = 42; + drflac_uint64 seektablePos = 0; + drflac_uint32 seektableSize = 0; + + for (;;) { + drflac_metadata metadata; + drflac_uint8 isLastBlock = 0; + drflac_uint8 blockType; + drflac_uint32 blockSize; + if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) { + return DRFLAC_FALSE; + } + runningFilePos += 4; + + metadata.type = blockType; + metadata.pRawData = NULL; + metadata.rawDataSize = 0; + + switch (blockType) + { + case DRFLAC_METADATA_BLOCK_TYPE_APPLICATION: + { + if (blockSize < 4) { + return DRFLAC_FALSE; + } + + if (onMeta) { + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) { + return DRFLAC_FALSE; + } + + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + metadata.data.application.id = drflac__be2host_32(*(drflac_uint32*)pRawData); + metadata.data.application.pData = (const void*)((drflac_uint8*)pRawData + sizeof(drflac_uint32)); + metadata.data.application.dataSize = blockSize - sizeof(drflac_uint32); + onMeta(pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_SEEKTABLE: + { + seektablePos = runningFilePos; + seektableSize = blockSize; + + if (onMeta) { + drflac_uint32 iSeekpoint; + void* pRawData; + + pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) { + return DRFLAC_FALSE; + } + + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + metadata.data.seektable.seekpointCount = blockSize/sizeof(drflac_seekpoint); + metadata.data.seektable.pSeekpoints = (const drflac_seekpoint*)pRawData; + + /* Endian swap. */ + for (iSeekpoint = 0; iSeekpoint < metadata.data.seektable.seekpointCount; ++iSeekpoint) { + drflac_seekpoint* pSeekpoint = (drflac_seekpoint*)pRawData + iSeekpoint; + pSeekpoint->firstSample = drflac__be2host_64(pSeekpoint->firstSample); + pSeekpoint->frameOffset = drflac__be2host_64(pSeekpoint->frameOffset); + pSeekpoint->sampleCount = drflac__be2host_16(pSeekpoint->sampleCount); + } + + onMeta(pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_VORBIS_COMMENT: + { + if (blockSize < 8) { + return DRFLAC_FALSE; + } + + if (onMeta) { + void* pRawData; + const char* pRunningData; + const char* pRunningDataEnd; + drflac_uint32 i; + + pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) { + return DRFLAC_FALSE; + } + + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + + pRunningData = (const char*)pRawData; + pRunningDataEnd = (const char*)pRawData + blockSize; + + metadata.data.vorbis_comment.vendorLength = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + + /* Need space for the rest of the block */ + if ((pRunningDataEnd - pRunningData) - 4 < (drflac_int64)metadata.data.vorbis_comment.vendorLength) { /* <-- Note the order of operations to avoid overflow to a valid value */ + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + metadata.data.vorbis_comment.vendor = pRunningData; pRunningData += metadata.data.vorbis_comment.vendorLength; + metadata.data.vorbis_comment.commentCount = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + + /* Need space for 'commentCount' comments after the block, which at minimum is a drflac_uint32 per comment */ + if ((pRunningDataEnd - pRunningData) / sizeof(drflac_uint32) < metadata.data.vorbis_comment.commentCount) { /* <-- Note the order of operations to avoid overflow to a valid value */ + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + metadata.data.vorbis_comment.pComments = pRunningData; + + /* Check that the comments section is valid before passing it to the callback */ + for (i = 0; i < metadata.data.vorbis_comment.commentCount; ++i) { + drflac_uint32 commentLength; + + if (pRunningDataEnd - pRunningData < 4) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + commentLength = drflac__le2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + if (pRunningDataEnd - pRunningData < (drflac_int64)commentLength) { /* <-- Note the order of operations to avoid overflow to a valid value */ + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + pRunningData += commentLength; + } + + onMeta(pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_CUESHEET: + { + if (blockSize < 396) { + return DRFLAC_FALSE; + } + + if (onMeta) { + void* pRawData; + const char* pRunningData; + const char* pRunningDataEnd; + drflac_uint8 iTrack; + drflac_uint8 iIndex; + + pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) { + return DRFLAC_FALSE; + } + + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + + pRunningData = (const char*)pRawData; + pRunningDataEnd = (const char*)pRawData + blockSize; + + drflac_copy_memory(metadata.data.cuesheet.catalog, pRunningData, 128); pRunningData += 128; + metadata.data.cuesheet.leadInSampleCount = drflac__be2host_64(*(const drflac_uint64*)pRunningData); pRunningData += 8; + metadata.data.cuesheet.isCD = (pRunningData[0] & 0x80) != 0; pRunningData += 259; + metadata.data.cuesheet.trackCount = pRunningData[0]; pRunningData += 1; + metadata.data.cuesheet.pTrackData = pRunningData; + + /* Check that the cuesheet tracks are valid before passing it to the callback */ + for (iTrack = 0; iTrack < metadata.data.cuesheet.trackCount; ++iTrack) { + drflac_uint8 indexCount; + drflac_uint32 indexPointSize; + + if (pRunningDataEnd - pRunningData < 36) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + /* Skip to the index point count */ + pRunningData += 35; + indexCount = pRunningData[0]; pRunningData += 1; + indexPointSize = indexCount * sizeof(drflac_cuesheet_track_index); + if (pRunningDataEnd - pRunningData < (drflac_int64)indexPointSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + /* Endian swap. */ + for (iIndex = 0; iIndex < indexCount; ++iIndex) { + drflac_cuesheet_track_index* pTrack = (drflac_cuesheet_track_index*)pRunningData; + pRunningData += sizeof(drflac_cuesheet_track_index); + pTrack->offset = drflac__be2host_64(pTrack->offset); + } + } + + onMeta(pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_PICTURE: + { + if (blockSize < 32) { + return DRFLAC_FALSE; + } + + if (onMeta) { + void* pRawData; + const char* pRunningData; + const char* pRunningDataEnd; + + pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) { + return DRFLAC_FALSE; + } + + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + + pRunningData = (const char*)pRawData; + pRunningDataEnd = (const char*)pRawData + blockSize; + + metadata.data.picture.type = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.mimeLength = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + + /* Need space for the rest of the block */ + if ((pRunningDataEnd - pRunningData) - 24 < (drflac_int64)metadata.data.picture.mimeLength) { /* <-- Note the order of operations to avoid overflow to a valid value */ + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength; + metadata.data.picture.descriptionLength = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + + /* Need space for the rest of the block */ + if ((pRunningDataEnd - pRunningData) - 20 < (drflac_int64)metadata.data.picture.descriptionLength) { /* <-- Note the order of operations to avoid overflow to a valid value */ + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength; + metadata.data.picture.width = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.height = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.colorDepth = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.indexColorCount = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.pictureDataSize = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + metadata.data.picture.pPictureData = (const drflac_uint8*)pRunningData; + + /* Need space for the picture after the block */ + if (pRunningDataEnd - pRunningData < (drflac_int64)metadata.data.picture.pictureDataSize) { /* <-- Note the order of operations to avoid overflow to a valid value */ + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + onMeta(pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_PADDING: + { + if (onMeta) { + metadata.data.padding.unused = 0; + + /* Padding doesn't have anything meaningful in it, so just skip over it, but make sure the caller is aware of it by firing the callback. */ + if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) { + isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */ + } else { + onMeta(pUserDataMD, &metadata); + } + } + } break; + + case DRFLAC_METADATA_BLOCK_TYPE_INVALID: + { + /* Invalid chunk. Just skip over this one. */ + if (onMeta) { + if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) { + isLastBlock = DRFLAC_TRUE; /* An error occurred while seeking. Attempt to recover by treating this as the last block which will in turn terminate the loop. */ + } + } + } break; + + default: + { + /* + It's an unknown chunk, but not necessarily invalid. There's a chance more metadata blocks might be defined later on, so we + can at the very least report the chunk to the application and let it look at the raw data. + */ + if (onMeta) { + void* pRawData = DRFLAC_MALLOC(blockSize); + if (pRawData == NULL) { + return DRFLAC_FALSE; + } + + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + DRFLAC_FREE(pRawData); + return DRFLAC_FALSE; + } + + metadata.pRawData = pRawData; + metadata.rawDataSize = blockSize; + onMeta(pUserDataMD, &metadata); + + DRFLAC_FREE(pRawData); + } + } break; + } + + /* If we're not handling metadata, just skip over the block. If we are, it will have been handled earlier in the switch statement above. */ + if (onMeta == NULL && blockSize > 0) { + if (!onSeek(pUserData, blockSize, drflac_seek_origin_current)) { + isLastBlock = DRFLAC_TRUE; + } + } + + runningFilePos += blockSize; + if (isLastBlock) { + break; + } + } + + *pSeektablePos = seektablePos; + *pSeektableSize = seektableSize; + *pFirstFramePos = runningFilePos; + + return DRFLAC_TRUE; +} + +drflac_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed) +{ + /* Pre Condition: The bit stream should be sitting just past the 4-byte id header. */ + + drflac_uint8 isLastBlock; + drflac_uint8 blockType; + drflac_uint32 blockSize; + + (void)onSeek; + + pInit->container = drflac_container_native; + + /* The first metadata block should be the STREAMINFO block. */ + if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) { + return DRFLAC_FALSE; + } + + if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) { + if (!relaxed) { + /* We're opening in strict mode and the first block is not the STREAMINFO block. Error. */ + return DRFLAC_FALSE; + } else { + /* + Relaxed mode. To open from here we need to just find the first frame and set the sample rate, etc. to whatever is defined + for that frame. + */ + pInit->hasStreamInfoBlock = DRFLAC_FALSE; + pInit->hasMetadataBlocks = DRFLAC_FALSE; + + if (!drflac__read_next_flac_frame_header(&pInit->bs, 0, &pInit->firstFrameHeader)) { + return DRFLAC_FALSE; /* Couldn't find a frame. */ + } + + if (pInit->firstFrameHeader.bitsPerSample == 0) { + return DRFLAC_FALSE; /* Failed to initialize because the first frame depends on the STREAMINFO block, which does not exist. */ + } + + pInit->sampleRate = pInit->firstFrameHeader.sampleRate; + pInit->channels = drflac__get_channel_count_from_channel_assignment(pInit->firstFrameHeader.channelAssignment); + pInit->bitsPerSample = pInit->firstFrameHeader.bitsPerSample; + pInit->maxBlockSize = 65535; /* <-- See notes here: https://xiph.org/flac/format.html#metadata_block_streaminfo */ + return DRFLAC_TRUE; + } + } else { + drflac_streaminfo streaminfo; + if (!drflac__read_streaminfo(onRead, pUserData, &streaminfo)) { + return DRFLAC_FALSE; + } + + pInit->hasStreamInfoBlock = DRFLAC_TRUE; + pInit->sampleRate = streaminfo.sampleRate; + pInit->channels = streaminfo.channels; + pInit->bitsPerSample = streaminfo.bitsPerSample; + pInit->totalSampleCount = streaminfo.totalSampleCount; + pInit->maxBlockSize = streaminfo.maxBlockSize; /* Don't care about the min block size - only the max (used for determining the size of the memory allocation). */ + pInit->hasMetadataBlocks = !isLastBlock; + + if (onMeta) { + drflac_metadata metadata; + metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO; + metadata.pRawData = NULL; + metadata.rawDataSize = 0; + metadata.data.streaminfo = streaminfo; + onMeta(pUserDataMD, &metadata); + } + + return DRFLAC_TRUE; + } +} + +#ifndef DR_FLAC_NO_OGG +#define DRFLAC_OGG_MAX_PAGE_SIZE 65307 +#define DRFLAC_OGG_CAPTURE_PATTERN_CRC32 1605413199 /* CRC-32 of "OggS". */ + +typedef enum +{ + drflac_ogg_recover_on_crc_mismatch, + drflac_ogg_fail_on_crc_mismatch +} drflac_ogg_crc_mismatch_recovery; + +#ifndef DR_FLAC_NO_CRC +static drflac_uint32 drflac__crc32_table[] = { + 0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L, + 0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L, + 0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L, + 0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL, + 0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L, + 0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L, + 0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L, + 0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL, + 0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L, + 0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L, + 0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L, + 0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL, + 0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L, + 0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L, + 0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L, + 0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL, + 0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL, + 0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L, + 0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L, + 0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL, + 0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL, + 0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L, + 0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L, + 0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL, + 0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL, + 0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L, + 0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L, + 0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL, + 0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL, + 0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L, + 0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L, + 0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL, + 0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L, + 0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL, + 0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL, + 0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L, + 0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L, + 0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL, + 0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL, + 0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L, + 0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L, + 0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL, + 0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL, + 0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L, + 0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L, + 0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL, + 0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL, + 0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L, + 0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L, + 0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL, + 0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L, + 0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L, + 0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L, + 0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL, + 0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L, + 0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L, + 0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L, + 0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL, + 0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L, + 0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L, + 0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L, + 0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL, + 0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L, + 0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L +}; +#endif + +static DRFLAC_INLINE drflac_uint32 drflac_crc32_byte(drflac_uint32 crc32, drflac_uint8 data) +{ +#ifndef DR_FLAC_NO_CRC + return (crc32 << 8) ^ drflac__crc32_table[(drflac_uint8)((crc32 >> 24) & 0xFF) ^ data]; +#else + (void)data; + return crc32; +#endif +} + +#if 0 +static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint32(drflac_uint32 crc32, drflac_uint32 data) +{ + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 24) & 0xFF)); + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 16) & 0xFF)); + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 8) & 0xFF)); + crc32 = drflac_crc32_byte(crc32, (drflac_uint8)((data >> 0) & 0xFF)); + return crc32; +} + +static DRFLAC_INLINE drflac_uint32 drflac_crc32_uint64(drflac_uint32 crc32, drflac_uint64 data) +{ + crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 32) & 0xFFFFFFFF)); + crc32 = drflac_crc32_uint32(crc32, (drflac_uint32)((data >> 0) & 0xFFFFFFFF)); + return crc32; +} +#endif + +static DRFLAC_INLINE drflac_uint32 drflac_crc32_buffer(drflac_uint32 crc32, drflac_uint8* pData, drflac_uint32 dataSize) +{ + /* This can be optimized. */ + drflac_uint32 i; + for (i = 0; i < dataSize; ++i) { + crc32 = drflac_crc32_byte(crc32, pData[i]); + } + return crc32; +} + + +static DRFLAC_INLINE drflac_bool32 drflac_ogg__is_capture_pattern(drflac_uint8 pattern[4]) +{ + return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S'; +} + +static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_header_size(drflac_ogg_page_header* pHeader) +{ + return 27 + pHeader->segmentCount; +} + +static DRFLAC_INLINE drflac_uint32 drflac_ogg__get_page_body_size(drflac_ogg_page_header* pHeader) +{ + drflac_uint32 pageBodySize = 0; + int i; + + for (i = 0; i < pHeader->segmentCount; ++i) { + pageBodySize += pHeader->segmentTable[i]; + } + + return pageBodySize; +} + +drflac_result drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32) +{ + drflac_uint8 data[23]; + drflac_uint32 i; + + drflac_assert(*pCRC32 == DRFLAC_OGG_CAPTURE_PATTERN_CRC32); + + if (onRead(pUserData, data, 23) != 23) { + return DRFLAC_END_OF_STREAM; + } + *pBytesRead += 23; + + pHeader->structureVersion = data[0]; + pHeader->headerType = data[1]; + drflac_copy_memory(&pHeader->granulePosition, &data[ 2], 8); + drflac_copy_memory(&pHeader->serialNumber, &data[10], 4); + drflac_copy_memory(&pHeader->sequenceNumber, &data[14], 4); + drflac_copy_memory(&pHeader->checksum, &data[18], 4); + pHeader->segmentCount = data[22]; + + /* Calculate the CRC. Note that for the calculation the checksum part of the page needs to be set to 0. */ + data[18] = 0; + data[19] = 0; + data[20] = 0; + data[21] = 0; + + for (i = 0; i < 23; ++i) { + *pCRC32 = drflac_crc32_byte(*pCRC32, data[i]); + } + + + if (onRead(pUserData, pHeader->segmentTable, pHeader->segmentCount) != pHeader->segmentCount) { + return DRFLAC_END_OF_STREAM; + } + *pBytesRead += pHeader->segmentCount; + + for (i = 0; i < pHeader->segmentCount; ++i) { + *pCRC32 = drflac_crc32_byte(*pCRC32, pHeader->segmentTable[i]); + } + + return DRFLAC_SUCCESS; +} + +drflac_result drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, drflac_uint32* pBytesRead, drflac_uint32* pCRC32) +{ + drflac_uint8 id[4]; + + *pBytesRead = 0; + + if (onRead(pUserData, id, 4) != 4) { + return DRFLAC_END_OF_STREAM; + } + *pBytesRead += 4; + + /* We need to read byte-by-byte until we find the OggS capture pattern. */ + for (;;) { + if (drflac_ogg__is_capture_pattern(id)) { + drflac_result result; + + *pCRC32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32; + + result = drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, pHeader, pBytesRead, pCRC32); + if (result == DRFLAC_SUCCESS) { + return DRFLAC_SUCCESS; + } else { + if (result == DRFLAC_CRC_MISMATCH) { + continue; + } else { + return result; + } + } + } else { + /* The first 4 bytes did not equal the capture pattern. Read the next byte and try again. */ + id[0] = id[1]; + id[1] = id[2]; + id[2] = id[3]; + if (onRead(pUserData, &id[3], 1) != 1) { + return DRFLAC_END_OF_STREAM; + } + *pBytesRead += 1; + } + } +} + + +/* +The main part of the Ogg encapsulation is the conversion from the physical Ogg bitstream to the native FLAC bitstream. It works +in three general stages: Ogg Physical Bitstream -> Ogg/FLAC Logical Bitstream -> FLAC Native Bitstream. dr_flac is designed +in such a way that the core sections assume everything is delivered in native format. Therefore, for each encapsulation type +dr_flac is supporting there needs to be a layer sitting on top of the onRead and onSeek callbacks that ensures the bits read from +the physical Ogg bitstream are converted and delivered in native FLAC format. +*/ +typedef struct +{ + drflac_read_proc onRead; /* The original onRead callback from drflac_open() and family. */ + drflac_seek_proc onSeek; /* The original onSeek callback from drflac_open() and family. */ + void* pUserData; /* The user data passed on onRead and onSeek. This is the user data that was passed on drflac_open() and family. */ + drflac_uint64 currentBytePos; /* The position of the byte we are sitting on in the physical byte stream. Used for efficient seeking. */ + drflac_uint64 firstBytePos; /* The position of the first byte in the physical bitstream. Points to the start of the "OggS" identifier of the FLAC bos page. */ + drflac_uint32 serialNumber; /* The serial number of the FLAC audio pages. This is determined by the initial header page that was read during initialization. */ + drflac_ogg_page_header bosPageHeader; /* Used for seeking. */ + drflac_ogg_page_header currentPageHeader; + drflac_uint32 bytesRemainingInPage; + drflac_uint32 pageDataSize; + drflac_uint8 pageData[DRFLAC_OGG_MAX_PAGE_SIZE]; +} drflac_oggbs; /* oggbs = Ogg Bitstream */ + +static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, size_t bytesToRead) +{ + size_t bytesActuallyRead = oggbs->onRead(oggbs->pUserData, bufferOut, bytesToRead); + oggbs->currentBytePos += bytesActuallyRead; + + return bytesActuallyRead; +} + +static drflac_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, drflac_uint64 offset, drflac_seek_origin origin) +{ + if (origin == drflac_seek_origin_start) { + if (offset <= 0x7FFFFFFF) { + if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_start)) { + return DRFLAC_FALSE; + } + oggbs->currentBytePos = offset; + + return DRFLAC_TRUE; + } else { + if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_start)) { + return DRFLAC_FALSE; + } + oggbs->currentBytePos = offset; + + return drflac_oggbs__seek_physical(oggbs, offset - 0x7FFFFFFF, drflac_seek_origin_current); + } + } else { + while (offset > 0x7FFFFFFF) { + if (!oggbs->onSeek(oggbs->pUserData, 0x7FFFFFFF, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + oggbs->currentBytePos += 0x7FFFFFFF; + offset -= 0x7FFFFFFF; + } + + if (!oggbs->onSeek(oggbs->pUserData, (int)offset, drflac_seek_origin_current)) { /* <-- Safe cast thanks to the loop above. */ + return DRFLAC_FALSE; + } + oggbs->currentBytePos += offset; + + return DRFLAC_TRUE; + } +} + +static drflac_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs, drflac_ogg_crc_mismatch_recovery recoveryMethod) +{ + drflac_ogg_page_header header; + for (;;) { + drflac_uint32 crc32 = 0; + drflac_uint32 bytesRead; + drflac_uint32 pageBodySize; +#ifndef DR_FLAC_NO_CRC + drflac_uint32 actualCRC32; +#endif + + if (drflac_ogg__read_page_header(oggbs->onRead, oggbs->pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) { + return DRFLAC_FALSE; + } + oggbs->currentBytePos += bytesRead; + + pageBodySize = drflac_ogg__get_page_body_size(&header); + if (pageBodySize > DRFLAC_OGG_MAX_PAGE_SIZE) { + continue; /* Invalid page size. Assume it's corrupted and just move to the next page. */ + } + + if (header.serialNumber != oggbs->serialNumber) { + /* It's not a FLAC page. Skip it. */ + if (pageBodySize > 0 && !drflac_oggbs__seek_physical(oggbs, pageBodySize, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + continue; + } + + + /* We need to read the entire page and then do a CRC check on it. If there's a CRC mismatch we need to skip this page. */ + if (drflac_oggbs__read_physical(oggbs, oggbs->pageData, pageBodySize) != pageBodySize) { + return DRFLAC_FALSE; + } + oggbs->pageDataSize = pageBodySize; + +#ifndef DR_FLAC_NO_CRC + actualCRC32 = drflac_crc32_buffer(crc32, oggbs->pageData, oggbs->pageDataSize); + if (actualCRC32 != header.checksum) { + if (recoveryMethod == drflac_ogg_recover_on_crc_mismatch) { + continue; /* CRC mismatch. Skip this page. */ + } else { + /* + Even though we are failing on a CRC mismatch, we still want our stream to be in a good state. Therefore we + go to the next valid page to ensure we're in a good state, but return false to let the caller know that the + seek did not fully complete. + */ + drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch); + return DRFLAC_FALSE; + } + } +#else + (void)recoveryMethod; /* <-- Silence a warning. */ +#endif + + oggbs->currentPageHeader = header; + oggbs->bytesRemainingInPage = pageBodySize; + return DRFLAC_TRUE; + } +} + +/* Function below is unused at the moment, but I might be re-adding it later. */ +#if 0 +static drflac_uint8 drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, drflac_uint8* pBytesRemainingInSeg) +{ + drflac_uint32 bytesConsumedInPage = drflac_ogg__get_page_body_size(&oggbs->currentPageHeader) - oggbs->bytesRemainingInPage; + drflac_uint8 iSeg = 0; + drflac_uint32 iByte = 0; + while (iByte < bytesConsumedInPage) { + drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg]; + if (iByte + segmentSize > bytesConsumedInPage) { + break; + } else { + iSeg += 1; + iByte += segmentSize; + } + } + + *pBytesRemainingInSeg = oggbs->currentPageHeader.segmentTable[iSeg] - (drflac_uint8)(bytesConsumedInPage - iByte); + return iSeg; +} + +static drflac_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) +{ + /* The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. */ + for (;;) { + drflac_bool32 atEndOfPage = DRFLAC_FALSE; + + drflac_uint8 bytesRemainingInSeg; + drflac_uint8 iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg); + + drflac_uint32 bytesToEndOfPacketOrPage = bytesRemainingInSeg; + for (drflac_uint8 iSeg = iFirstSeg; iSeg < oggbs->currentPageHeader.segmentCount; ++iSeg) { + drflac_uint8 segmentSize = oggbs->currentPageHeader.segmentTable[iSeg]; + if (segmentSize < 255) { + if (iSeg == oggbs->currentPageHeader.segmentCount-1) { + atEndOfPage = DRFLAC_TRUE; + } + + break; + } + + bytesToEndOfPacketOrPage += segmentSize; + } + + /* + At this point we will have found either the packet or the end of the page. If were at the end of the page we'll + want to load the next page and keep searching for the end of the packet. + */ + drflac_oggbs__seek_physical(oggbs, bytesToEndOfPacketOrPage, drflac_seek_origin_current); + oggbs->bytesRemainingInPage -= bytesToEndOfPacketOrPage; + + if (atEndOfPage) { + /* + We're potentially at the next packet, but we need to check the next page first to be sure because the packet may + straddle pages. + */ + if (!drflac_oggbs__goto_next_page(oggbs)) { + return DRFLAC_FALSE; + } + + /* If it's a fresh packet it most likely means we're at the next packet. */ + if ((oggbs->currentPageHeader.headerType & 0x01) == 0) { + return DRFLAC_TRUE; + } + } else { + /* We're at the next packet. */ + return DRFLAC_TRUE; + } + } +} + +static drflac_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs) +{ + /* The bitstream should be sitting on the first byte just after the header of the frame. */ + + /* What we're actually doing here is seeking to the start of the next packet. */ + return drflac_oggbs__seek_to_next_packet(oggbs); +} +#endif + +static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + drflac_oggbs* oggbs = (drflac_oggbs*)pUserData; + drflac_uint8* pRunningBufferOut = (drflac_uint8*)bufferOut; + size_t bytesRead = 0; + + drflac_assert(oggbs != NULL); + drflac_assert(pRunningBufferOut != NULL); + + /* Reading is done page-by-page. If we've run out of bytes in the page we need to move to the next one. */ + while (bytesRead < bytesToRead) { + size_t bytesRemainingToRead = bytesToRead - bytesRead; + + if (oggbs->bytesRemainingInPage >= bytesRemainingToRead) { + drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), bytesRemainingToRead); + bytesRead += bytesRemainingToRead; + oggbs->bytesRemainingInPage -= (drflac_uint32)bytesRemainingToRead; + break; + } + + /* If we get here it means some of the requested data is contained in the next pages. */ + if (oggbs->bytesRemainingInPage > 0) { + drflac_copy_memory(pRunningBufferOut, oggbs->pageData + (oggbs->pageDataSize - oggbs->bytesRemainingInPage), oggbs->bytesRemainingInPage); + bytesRead += oggbs->bytesRemainingInPage; + pRunningBufferOut += oggbs->bytesRemainingInPage; + oggbs->bytesRemainingInPage = 0; + } + + drflac_assert(bytesRemainingToRead > 0); + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) { + break; /* Failed to go to the next page. Might have simply hit the end of the stream. */ + } + } + + return bytesRead; +} + +static drflac_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin) +{ + drflac_oggbs* oggbs = (drflac_oggbs*)pUserData; + int bytesSeeked = 0; + + drflac_assert(oggbs != NULL); + drflac_assert(offset >= 0); /* <-- Never seek backwards. */ + + /* Seeking is always forward which makes things a lot simpler. */ + if (origin == drflac_seek_origin_start) { + if (!drflac_oggbs__seek_physical(oggbs, (int)oggbs->firstBytePos, drflac_seek_origin_start)) { + return DRFLAC_FALSE; + } + + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) { + return DRFLAC_FALSE; + } + + return drflac__on_seek_ogg(pUserData, offset, drflac_seek_origin_current); + } + + drflac_assert(origin == drflac_seek_origin_current); + + while (bytesSeeked < offset) { + int bytesRemainingToSeek = offset - bytesSeeked; + drflac_assert(bytesRemainingToSeek >= 0); + + if (oggbs->bytesRemainingInPage >= (size_t)bytesRemainingToSeek) { + bytesSeeked += bytesRemainingToSeek; + oggbs->bytesRemainingInPage -= bytesRemainingToSeek; + break; + } + + /* If we get here it means some of the requested data is contained in the next pages. */ + if (oggbs->bytesRemainingInPage > 0) { + bytesSeeked += (int)oggbs->bytesRemainingInPage; + oggbs->bytesRemainingInPage = 0; + } + + drflac_assert(bytesRemainingToSeek > 0); + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_fail_on_crc_mismatch)) { + /* Failed to go to the next page. We either hit the end of the stream or had a CRC mismatch. */ + return DRFLAC_FALSE; + } + } + + return DRFLAC_TRUE; +} + +drflac_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex) +{ + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + drflac_uint64 originalBytePos; + drflac_uint64 runningGranulePosition; + drflac_uint64 runningFrameBytePos; + drflac_uint64 runningSampleCount; + + drflac_assert(oggbs != NULL); + + originalBytePos = oggbs->currentBytePos; /* For recovery. */ + + /* First seek to the first frame. */ + if (!drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos)) { + return DRFLAC_FALSE; + } + oggbs->bytesRemainingInPage = 0; + + runningGranulePosition = 0; + runningFrameBytePos = oggbs->currentBytePos; /* <-- Points to the OggS identifier. */ + for (;;) { + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) { + drflac_oggbs__seek_physical(oggbs, originalBytePos, drflac_seek_origin_start); + return DRFLAC_FALSE; /* Never did find that sample... */ + } + + runningFrameBytePos = oggbs->currentBytePos - drflac_ogg__get_page_header_size(&oggbs->currentPageHeader) - oggbs->pageDataSize; + if (oggbs->currentPageHeader.granulePosition*pFlac->channels >= sampleIndex) { + break; /* The sample is somewhere in the previous page. */ + } + + /* + At this point we know the sample is not in the previous page. It could possibly be in this page. For simplicity we + disregard any pages that do not begin a fresh packet. + */ + if ((oggbs->currentPageHeader.headerType & 0x01) == 0) { /* <-- Is it a fresh page? */ + if (oggbs->currentPageHeader.segmentTable[0] >= 2) { + drflac_uint8 firstBytesInPage[2]; + firstBytesInPage[0] = oggbs->pageData[0]; + firstBytesInPage[1] = oggbs->pageData[1]; + + if ((firstBytesInPage[0] == 0xFF) && (firstBytesInPage[1] & 0xFC) == 0xF8) { /* <-- Does the page begin with a frame's sync code? */ + runningGranulePosition = oggbs->currentPageHeader.granulePosition*pFlac->channels; + } + + continue; + } + } + } + + /* + We found the page that that is closest to the sample, so now we need to find it. The first thing to do is seek to the + start of that page. In the loop above we checked that it was a fresh page which means this page is also the start of + a new frame. This property means that after we've seeked to the page we can immediately start looping over frames until + we find the one containing the target sample. + */ + if (!drflac_oggbs__seek_physical(oggbs, runningFrameBytePos, drflac_seek_origin_start)) { + return DRFLAC_FALSE; + } + if (!drflac_oggbs__goto_next_page(oggbs, drflac_ogg_recover_on_crc_mismatch)) { + return DRFLAC_FALSE; + } + + /* + At this point we'll be sitting on the first byte of the frame header of the first frame in the page. We just keep + looping over these frames until we find the one containing the sample we're after. + */ + runningSampleCount = runningGranulePosition; + for (;;) { + /* + There are two ways to find the sample and seek past irrelevant frames: + 1) Use the native FLAC decoder. + 2) Use Ogg's framing system. + + Both of these options have their own pros and cons. Using the native FLAC decoder is slower because it needs to + do a full decode of the frame. Using Ogg's framing system is faster, but more complicated and involves some code + duplication for the decoding of frame headers. + + Another thing to consider is that using the Ogg framing system will perform direct seeking of the physical Ogg + bitstream. This is important to consider because it means we cannot read data from the drflac_bs object using the + standard drflac__*() APIs because that will read in extra data for its own internal caching which in turn breaks + the positioning of the read pointer of the physical Ogg bitstream. Therefore, anything that would normally be read + using the native FLAC decoding APIs, such as drflac__read_next_flac_frame_header(), need to be re-implemented so as to + avoid the use of the drflac_bs object. + + Considering these issues, I have decided to use the slower native FLAC decoding method for the following reasons: + 1) Seeking is already partially accelerated using Ogg's paging system in the code block above. + 2) Seeking in an Ogg encapsulated FLAC stream is probably quite uncommon. + 3) Simplicity. + */ + drflac_uint64 firstSampleInFrame = 0; + drflac_uint64 lastSampleInFrame = 0; + drflac_uint64 sampleCountInThisFrame; + + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + return DRFLAC_FALSE; + } + + drflac__get_current_frame_sample_range(pFlac, &firstSampleInFrame, &lastSampleInFrame); + + sampleCountInThisFrame = (lastSampleInFrame - firstSampleInFrame) + 1; + if (sampleIndex < (runningSampleCount + sampleCountInThisFrame)) { + /* + The sample should be in this frame. We need to fully decode it, however if it's an invalid frame (a CRC mismatch), we need to pretend + it never existed and keep iterating. + */ + drflac_result result = drflac__decode_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + /* The frame is valid. We just need to skip over some samples to ensure it's sample-exact. */ + drflac_uint64 samplesToDecode = (size_t)(sampleIndex - runningSampleCount); /* <-- Safe cast because the maximum number of samples in a frame is 65535. */ + if (samplesToDecode == 0) { + return DRFLAC_TRUE; + } + return drflac__seek_forward_by_samples(pFlac, samplesToDecode) == samplesToDecode; /* <-- If this fails, something bad has happened (it should never fail). */ + } else { + if (result == DRFLAC_CRC_MISMATCH) { + continue; /* CRC mismatch. Pretend this frame never existed. */ + } else { + return DRFLAC_FALSE; + } + } + } else { + /* + It's not in this frame. We need to seek past the frame, but check if there was a CRC mismatch. If so, we pretend this + frame never existed and leave the running sample count untouched. + */ + drflac_result result = drflac__seek_to_next_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + runningSampleCount += sampleCountInThisFrame; + } else { + if (result == DRFLAC_CRC_MISMATCH) { + continue; /* CRC mismatch. Pretend this frame never existed. */ + } else { + return DRFLAC_FALSE; + } + } + } + } +} + + +drflac_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD, drflac_bool32 relaxed) +{ + drflac_ogg_page_header header; + drflac_uint32 crc32 = DRFLAC_OGG_CAPTURE_PATTERN_CRC32; + drflac_uint32 bytesRead = 0; + + /* Pre Condition: The bit stream should be sitting just past the 4-byte OggS capture pattern. */ + (void)relaxed; + + pInit->container = drflac_container_ogg; + pInit->oggFirstBytePos = 0; + + /* + We'll get here if the first 4 bytes of the stream were the OggS capture pattern, however it doesn't necessarily mean the + stream includes FLAC encoded audio. To check for this we need to scan the beginning-of-stream page markers and check if + any match the FLAC specification. Important to keep in mind that the stream may be multiplexed. + */ + if (drflac_ogg__read_page_header_after_capture_pattern(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) { + return DRFLAC_FALSE; + } + pInit->runningFilePos += bytesRead; + + for (;;) { + int pageBodySize; + + /* Break if we're past the beginning of stream page. */ + if ((header.headerType & 0x02) == 0) { + return DRFLAC_FALSE; + } + + /* Check if it's a FLAC header. */ + pageBodySize = drflac_ogg__get_page_body_size(&header); + if (pageBodySize == 51) { /* 51 = the lacing value of the FLAC header packet. */ + /* It could be a FLAC page... */ + drflac_uint32 bytesRemainingInPage = pageBodySize; + drflac_uint8 packetType; + + if (onRead(pUserData, &packetType, 1) != 1) { + return DRFLAC_FALSE; + } + + bytesRemainingInPage -= 1; + if (packetType == 0x7F) { + /* Increasingly more likely to be a FLAC page... */ + drflac_uint8 sig[4]; + if (onRead(pUserData, sig, 4) != 4) { + return DRFLAC_FALSE; + } + + bytesRemainingInPage -= 4; + if (sig[0] == 'F' && sig[1] == 'L' && sig[2] == 'A' && sig[3] == 'C') { + /* Almost certainly a FLAC page... */ + drflac_uint8 mappingVersion[2]; + if (onRead(pUserData, mappingVersion, 2) != 2) { + return DRFLAC_FALSE; + } + + if (mappingVersion[0] != 1) { + return DRFLAC_FALSE; /* Only supporting version 1.x of the Ogg mapping. */ + } + + /* + The next 2 bytes are the non-audio packets, not including this one. We don't care about this because we're going to + be handling it in a generic way based on the serial number and packet types. + */ + if (!onSeek(pUserData, 2, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + + /* Expecting the native FLAC signature "fLaC". */ + if (onRead(pUserData, sig, 4) != 4) { + return DRFLAC_FALSE; + } + + if (sig[0] == 'f' && sig[1] == 'L' && sig[2] == 'a' && sig[3] == 'C') { + /* The remaining data in the page should be the STREAMINFO block. */ + drflac_streaminfo streaminfo; + drflac_uint8 isLastBlock; + drflac_uint8 blockType; + drflac_uint32 blockSize; + if (!drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize)) { + return DRFLAC_FALSE; + } + + if (blockType != DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO || blockSize != 34) { + return DRFLAC_FALSE; /* Invalid block type. First block must be the STREAMINFO block. */ + } + + if (drflac__read_streaminfo(onRead, pUserData, &streaminfo)) { + /* Success! */ + pInit->hasStreamInfoBlock = DRFLAC_TRUE; + pInit->sampleRate = streaminfo.sampleRate; + pInit->channels = streaminfo.channels; + pInit->bitsPerSample = streaminfo.bitsPerSample; + pInit->totalSampleCount = streaminfo.totalSampleCount; + pInit->maxBlockSize = streaminfo.maxBlockSize; + pInit->hasMetadataBlocks = !isLastBlock; + + if (onMeta) { + drflac_metadata metadata; + metadata.type = DRFLAC_METADATA_BLOCK_TYPE_STREAMINFO; + metadata.pRawData = NULL; + metadata.rawDataSize = 0; + metadata.data.streaminfo = streaminfo; + onMeta(pUserDataMD, &metadata); + } + + pInit->runningFilePos += pageBodySize; + pInit->oggFirstBytePos = pInit->runningFilePos - 79; /* Subtracting 79 will place us right on top of the "OggS" identifier of the FLAC bos page. */ + pInit->oggSerial = header.serialNumber; + pInit->oggBosHeader = header; + break; + } else { + /* Failed to read STREAMINFO block. Aww, so close... */ + return DRFLAC_FALSE; + } + } else { + /* Invalid file. */ + return DRFLAC_FALSE; + } + } else { + /* Not a FLAC header. Skip it. */ + if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + } + } else { + /* Not a FLAC header. Seek past the entire page and move on to the next. */ + if (!onSeek(pUserData, bytesRemainingInPage, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + } + } else { + if (!onSeek(pUserData, pageBodySize, drflac_seek_origin_current)) { + return DRFLAC_FALSE; + } + } + + pInit->runningFilePos += pageBodySize; + + + /* Read the header of the next page. */ + if (drflac_ogg__read_page_header(onRead, pUserData, &header, &bytesRead, &crc32) != DRFLAC_SUCCESS) { + return DRFLAC_FALSE; + } + pInit->runningFilePos += bytesRead; + } + + /* + If we get here it means we found a FLAC audio stream. We should be sitting on the first byte of the header of the next page. The next + packets in the FLAC logical stream contain the metadata. The only thing left to do in the initialization phase for Ogg is to create the + Ogg bistream object. + */ + pInit->hasMetadataBlocks = DRFLAC_TRUE; /* <-- Always have at least VORBIS_COMMENT metadata block. */ + return DRFLAC_TRUE; +} +#endif + +drflac_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD) +{ + drflac_bool32 relaxed; + drflac_uint8 id[4]; + + if (pInit == NULL || onRead == NULL || onSeek == NULL) { + return DRFLAC_FALSE; + } + + drflac_zero_memory(pInit, sizeof(*pInit)); + pInit->onRead = onRead; + pInit->onSeek = onSeek; + pInit->onMeta = onMeta; + pInit->container = container; + pInit->pUserData = pUserData; + pInit->pUserDataMD = pUserDataMD; + + pInit->bs.onRead = onRead; + pInit->bs.onSeek = onSeek; + pInit->bs.pUserData = pUserData; + drflac__reset_cache(&pInit->bs); + + + /* If the container is explicitly defined then we can try opening in relaxed mode. */ + relaxed = container != drflac_container_unknown; + + /* Skip over any ID3 tags. */ + for (;;) { + if (onRead(pUserData, id, 4) != 4) { + return DRFLAC_FALSE; /* Ran out of data. */ + } + pInit->runningFilePos += 4; + + if (id[0] == 'I' && id[1] == 'D' && id[2] == '3') { + drflac_uint8 header[6]; + drflac_uint8 flags; + drflac_uint32 headerSize; + + if (onRead(pUserData, header, 6) != 6) { + return DRFLAC_FALSE; /* Ran out of data. */ + } + pInit->runningFilePos += 6; + + flags = header[1]; + + drflac_copy_memory(&headerSize, header+2, 4); + headerSize = drflac__unsynchsafe_32(drflac__be2host_32(headerSize)); + if (flags & 0x10) { + headerSize += 10; + } + + if (!onSeek(pUserData, headerSize, drflac_seek_origin_current)) { + return DRFLAC_FALSE; /* Failed to seek past the tag. */ + } + pInit->runningFilePos += headerSize; + } else { + break; + } + } + + if (id[0] == 'f' && id[1] == 'L' && id[2] == 'a' && id[3] == 'C') { + return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); + } +#ifndef DR_FLAC_NO_OGG + if (id[0] == 'O' && id[1] == 'g' && id[2] == 'g' && id[3] == 'S') { + return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); + } +#endif + + /* If we get here it means we likely don't have a header. Try opening in relaxed mode, if applicable. */ + if (relaxed) { + if (container == drflac_container_native) { + return drflac__init_private__native(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); + } +#ifndef DR_FLAC_NO_OGG + if (container == drflac_container_ogg) { + return drflac__init_private__ogg(pInit, onRead, onSeek, onMeta, pUserData, pUserDataMD, relaxed); + } +#endif + } + + /* Unsupported container. */ + return DRFLAC_FALSE; +} + +void drflac__init_from_info(drflac* pFlac, drflac_init_info* pInit) +{ + drflac_assert(pFlac != NULL); + drflac_assert(pInit != NULL); + + drflac_zero_memory(pFlac, sizeof(*pFlac)); + pFlac->bs = pInit->bs; + pFlac->onMeta = pInit->onMeta; + pFlac->pUserDataMD = pInit->pUserDataMD; + pFlac->maxBlockSize = pInit->maxBlockSize; + pFlac->sampleRate = pInit->sampleRate; + pFlac->channels = (drflac_uint8)pInit->channels; + pFlac->bitsPerSample = (drflac_uint8)pInit->bitsPerSample; + pFlac->totalSampleCount = pInit->totalSampleCount; + pFlac->totalPCMFrameCount = pInit->totalSampleCount / pFlac->channels; + pFlac->container = pInit->container; +} + +drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData, void* pUserDataMD) +{ + drflac_init_info init; + drflac_uint32 allocationSize; + drflac_uint32 wholeSIMDVectorCountPerChannel; + drflac_uint32 decodedSamplesAllocationSize; +#ifndef DR_FLAC_NO_OGG + drflac_uint32 oggbsAllocationSize; + drflac_oggbs oggbs; +#endif + drflac_uint64 firstFramePos; + drflac_uint64 seektablePos; + drflac_uint32 seektableSize; + drflac* pFlac; + +#ifndef DRFLAC_NO_CPUID + /* CPU support first. */ + drflac__init_cpu_caps(); +#endif + + if (!drflac__init_private(&init, onRead, onSeek, onMeta, container, pUserData, pUserDataMD)) { + return NULL; + } + + /* + The size of the allocation for the drflac object needs to be large enough to fit the following: + 1) The main members of the drflac structure + 2) A block of memory large enough to store the decoded samples of the largest frame in the stream + 3) If the container is Ogg, a drflac_oggbs object + + The complicated part of the allocation is making sure there's enough room the decoded samples, taking into consideration + the different SIMD instruction sets. + */ + allocationSize = sizeof(drflac); + + /* + The allocation size for decoded frames depends on the number of 32-bit integers that fit inside the largest SIMD vector + we are supporting. + */ + if (((init.maxBlockSize+DRFLAC_LEADING_SAMPLES) % (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) == 0) { + wholeSIMDVectorCountPerChannel = ((init.maxBlockSize+DRFLAC_LEADING_SAMPLES) / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))); + } else { + wholeSIMDVectorCountPerChannel = ((init.maxBlockSize+DRFLAC_LEADING_SAMPLES) / (DRFLAC_MAX_SIMD_VECTOR_SIZE / sizeof(drflac_int32))) + 1; + } + + decodedSamplesAllocationSize = wholeSIMDVectorCountPerChannel * DRFLAC_MAX_SIMD_VECTOR_SIZE * init.channels; + + allocationSize += decodedSamplesAllocationSize; + allocationSize += DRFLAC_MAX_SIMD_VECTOR_SIZE; /* Allocate extra bytes to ensure we have enough for alignment. */ + +#ifndef DR_FLAC_NO_OGG + /* There's additional data required for Ogg streams. */ + oggbsAllocationSize = 0; + if (init.container == drflac_container_ogg) { + oggbsAllocationSize = sizeof(drflac_oggbs); + allocationSize += oggbsAllocationSize; + } + + drflac_zero_memory(&oggbs, sizeof(oggbs)); + if (init.container == drflac_container_ogg) { + oggbs.onRead = onRead; + oggbs.onSeek = onSeek; + oggbs.pUserData = pUserData; + oggbs.currentBytePos = init.oggFirstBytePos; + oggbs.firstBytePos = init.oggFirstBytePos; + oggbs.serialNumber = init.oggSerial; + oggbs.bosPageHeader = init.oggBosHeader; + oggbs.bytesRemainingInPage = 0; + } +#endif + + /* + This part is a bit awkward. We need to load the seektable so that it can be referenced in-memory, but I want the drflac object to + consist of only a single heap allocation. To this, the size of the seek table needs to be known, which we determine when reading + and decoding the metadata. + */ + firstFramePos = 42; /* <-- We know we are at byte 42 at this point. */ + seektablePos = 0; + seektableSize = 0; + if (init.hasMetadataBlocks) { + drflac_read_proc onReadOverride = onRead; + drflac_seek_proc onSeekOverride = onSeek; + void* pUserDataOverride = pUserData; + +#ifndef DR_FLAC_NO_OGG + if (init.container == drflac_container_ogg) { + onReadOverride = drflac__on_read_ogg; + onSeekOverride = drflac__on_seek_ogg; + pUserDataOverride = (void*)&oggbs; + } +#endif + + if (!drflac__read_and_decode_metadata(onReadOverride, onSeekOverride, onMeta, pUserDataOverride, pUserDataMD, &firstFramePos, &seektablePos, &seektableSize)) { + return NULL; + } + + allocationSize += seektableSize; + } + + + pFlac = (drflac*)DRFLAC_MALLOC(allocationSize); + drflac__init_from_info(pFlac, &init); + pFlac->pDecodedSamples = (drflac_int32*)drflac_align((size_t)pFlac->pExtraData, DRFLAC_MAX_SIMD_VECTOR_SIZE); + +#ifndef DR_FLAC_NO_OGG + if (init.container == drflac_container_ogg) { + drflac_oggbs* pInternalOggbs = (drflac_oggbs*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize + seektableSize); + *pInternalOggbs = oggbs; + + /* The Ogg bistream needs to be layered on top of the original bitstream. */ + pFlac->bs.onRead = drflac__on_read_ogg; + pFlac->bs.onSeek = drflac__on_seek_ogg; + pFlac->bs.pUserData = (void*)pInternalOggbs; + pFlac->_oggbs = (void*)pInternalOggbs; + } +#endif + + pFlac->firstFramePos = firstFramePos; + + /* NOTE: Seektables are not currently compatible with Ogg encapsulation (Ogg has its own accelerated seeking system). I may change this later, so I'm leaving this here for now. */ +#ifndef DR_FLAC_NO_OGG + if (init.container == drflac_container_ogg) + { + pFlac->pSeekpoints = NULL; + pFlac->seekpointCount = 0; + } + else +#endif + { + /* If we have a seektable we need to load it now, making sure we move back to where we were previously. */ + if (seektablePos != 0) { + pFlac->seekpointCount = seektableSize / sizeof(*pFlac->pSeekpoints); + pFlac->pSeekpoints = (drflac_seekpoint*)((drflac_uint8*)pFlac->pDecodedSamples + decodedSamplesAllocationSize); + + /* Seek to the seektable, then just read directly into our seektable buffer. */ + if (pFlac->bs.onSeek(pFlac->bs.pUserData, (int)seektablePos, drflac_seek_origin_start)) { + if (pFlac->bs.onRead(pFlac->bs.pUserData, pFlac->pSeekpoints, seektableSize) == seektableSize) { + /* Endian swap. */ + drflac_uint32 iSeekpoint; + for (iSeekpoint = 0; iSeekpoint < pFlac->seekpointCount; ++iSeekpoint) { + pFlac->pSeekpoints[iSeekpoint].firstSample = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].firstSample); + pFlac->pSeekpoints[iSeekpoint].frameOffset = drflac__be2host_64(pFlac->pSeekpoints[iSeekpoint].frameOffset); + pFlac->pSeekpoints[iSeekpoint].sampleCount = drflac__be2host_16(pFlac->pSeekpoints[iSeekpoint].sampleCount); + } + } else { + /* Failed to read the seektable. Pretend we don't have one. */ + pFlac->pSeekpoints = NULL; + pFlac->seekpointCount = 0; + } + + /* We need to seek back to where we were. If this fails it's a critical error. */ + if (!pFlac->bs.onSeek(pFlac->bs.pUserData, (int)pFlac->firstFramePos, drflac_seek_origin_start)) { + DRFLAC_FREE(pFlac); + return NULL; + } + } else { + /* Failed to seek to the seektable. Ominous sign, but for now we can just pretend we don't have one. */ + pFlac->pSeekpoints = NULL; + pFlac->seekpointCount = 0; + } + } + } + + + /* + If we get here, but don't have a STREAMINFO block, it means we've opened the stream in relaxed mode and need to decode + the first frame. + */ + if (!init.hasStreamInfoBlock) { + pFlac->currentFrame.header = init.firstFrameHeader; + do + { + drflac_result result = drflac__decode_flac_frame(pFlac); + if (result == DRFLAC_SUCCESS) { + break; + } else { + if (result == DRFLAC_CRC_MISMATCH) { + if (!drflac__read_next_flac_frame_header(&pFlac->bs, pFlac->bitsPerSample, &pFlac->currentFrame.header)) { + DRFLAC_FREE(pFlac); + return NULL; + } + continue; + } else { + DRFLAC_FREE(pFlac); + return NULL; + } + } + } while (1); + } + + return pFlac; +} + + + +#ifndef DR_FLAC_NO_STDIO +#include + +static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData); +} + +static drflac_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +{ + drflac_assert(offset >= 0); /* <-- Never seek backwards. */ + + return fseek((FILE*)pUserData, offset, (origin == drflac_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0; +} + +static FILE* drflac__fopen(const char* filename) +{ + FILE* pFile; +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (fopen_s(&pFile, filename, "rb") != 0) { + return NULL; + } +#else + pFile = fopen(filename, "rb"); + if (pFile == NULL) { + return NULL; + } +#endif + + return pFile; +} + + +drflac* drflac_open_file(const char* filename) +{ + drflac* pFlac; + FILE* pFile; + + pFile = drflac__fopen(filename); + if (pFile == NULL) { + return NULL; + } + + pFlac = drflac_open(drflac__on_read_stdio, drflac__on_seek_stdio, (void*)pFile); + if (pFlac == NULL) { + fclose(pFile); + return NULL; + } + + return pFlac; +} + +drflac* drflac_open_file_with_metadata(const char* filename, drflac_meta_proc onMeta, void* pUserData) +{ + drflac* pFlac; + FILE* pFile; + + pFile = drflac__fopen(filename); + if (pFile == NULL) { + return NULL; + } + + pFlac = drflac_open_with_metadata_private(drflac__on_read_stdio, drflac__on_seek_stdio, onMeta, drflac_container_unknown, (void*)pFile, pUserData); + if (pFlac == NULL) { + fclose(pFile); + return pFlac; + } + + return pFlac; +} +#endif /* DR_FLAC_NO_STDIO */ + +static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t bytesToRead) +{ + drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData; + size_t bytesRemaining; + + drflac_assert(memoryStream != NULL); + drflac_assert(memoryStream->dataSize >= memoryStream->currentReadPos); + + bytesRemaining = memoryStream->dataSize - memoryStream->currentReadPos; + if (bytesToRead > bytesRemaining) { + bytesToRead = bytesRemaining; + } + + if (bytesToRead > 0) { + drflac_copy_memory(bufferOut, memoryStream->data + memoryStream->currentReadPos, bytesToRead); + memoryStream->currentReadPos += bytesToRead; + } + + return bytesToRead; +} + +static drflac_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin) +{ + drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData; + + drflac_assert(memoryStream != NULL); + drflac_assert(offset >= 0); /* <-- Never seek backwards. */ + + if (offset > (drflac_int64)memoryStream->dataSize) { + return DRFLAC_FALSE; + } + + if (origin == drflac_seek_origin_current) { + if (memoryStream->currentReadPos + offset <= memoryStream->dataSize) { + memoryStream->currentReadPos += offset; + } else { + return DRFLAC_FALSE; /* Trying to seek too far forward. */ + } + } else { + if ((drflac_uint32)offset <= memoryStream->dataSize) { + memoryStream->currentReadPos = offset; + } else { + return DRFLAC_FALSE; /* Trying to seek too far forward. */ + } + } + + return DRFLAC_TRUE; +} + +drflac* drflac_open_memory(const void* data, size_t dataSize) +{ + drflac__memory_stream memoryStream; + drflac* pFlac; + + memoryStream.data = (const unsigned char*)data; + memoryStream.dataSize = dataSize; + memoryStream.currentReadPos = 0; + pFlac = drflac_open(drflac__on_read_memory, drflac__on_seek_memory, &memoryStream); + if (pFlac == NULL) { + return NULL; + } + + pFlac->memoryStream = memoryStream; + + /* This is an awful hack... */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + { + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + oggbs->pUserData = &pFlac->memoryStream; + } + else +#endif + { + pFlac->bs.pUserData = &pFlac->memoryStream; + } + + return pFlac; +} + +drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drflac_meta_proc onMeta, void* pUserData) +{ + drflac__memory_stream memoryStream; + drflac* pFlac; + + memoryStream.data = (const unsigned char*)data; + memoryStream.dataSize = dataSize; + memoryStream.currentReadPos = 0; + pFlac = drflac_open_with_metadata_private(drflac__on_read_memory, drflac__on_seek_memory, onMeta, drflac_container_unknown, &memoryStream, pUserData); + if (pFlac == NULL) { + return NULL; + } + + pFlac->memoryStream = memoryStream; + + /* This is an awful hack... */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + { + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + oggbs->pUserData = &pFlac->memoryStream; + } + else +#endif + { + pFlac->bs.pUserData = &pFlac->memoryStream; + } + + return pFlac; +} + + + +drflac* drflac_open(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, NULL, drflac_container_unknown, pUserData, pUserData); +} +drflac* drflac_open_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_container container, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, NULL, container, pUserData, pUserData); +} + +drflac* drflac_open_with_metadata(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, onMeta, drflac_container_unknown, pUserData, pUserData); +} +drflac* drflac_open_with_metadata_relaxed(drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, drflac_container container, void* pUserData) +{ + return drflac_open_with_metadata_private(onRead, onSeek, onMeta, container, pUserData, pUserData); +} + +void drflac_close(drflac* pFlac) +{ + if (pFlac == NULL) { + return; + } + +#ifndef DR_FLAC_NO_STDIO + /* + If we opened the file with drflac_open_file() we will want to close the file handle. We can know whether or not drflac_open_file() + was used by looking at the callbacks. + */ + if (pFlac->bs.onRead == drflac__on_read_stdio) { + fclose((FILE*)pFlac->bs.pUserData); + } + +#ifndef DR_FLAC_NO_OGG + /* Need to clean up Ogg streams a bit differently due to the way the bit streaming is chained. */ + if (pFlac->container == drflac_container_ogg) { + drflac_oggbs* oggbs = (drflac_oggbs*)pFlac->_oggbs; + drflac_assert(pFlac->bs.onRead == drflac__on_read_ogg); + + if (oggbs->onRead == drflac__on_read_stdio) { + fclose((FILE*)oggbs->pUserData); + } + } +#endif +#endif + + DRFLAC_FREE(pFlac); +} + +drflac_uint64 drflac__read_s32__misaligned(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* bufferOut) +{ + unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + drflac_uint64 samplesRead; + + /* We should never be calling this when the number of samples to read is >= the sample count. */ + drflac_assert(samplesToRead < channelCount); + drflac_assert(pFlac->currentFrame.samplesRemaining > 0 && samplesToRead <= pFlac->currentFrame.samplesRemaining); + + samplesRead = 0; + while (samplesToRead > 0) { + drflac_uint64 totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount; + drflac_uint64 samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining; + drflac_uint64 channelIndex = samplesReadFromFrameSoFar % channelCount; + drflac_uint64 nextSampleInFrame = samplesReadFromFrameSoFar / channelCount; + int decodedSample = 0; + + switch (pFlac->currentFrame.header.channelAssignment) + { + case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE: + { + if (channelIndex == 0) { + decodedSample = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + } else { + int side = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + int left = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex - 1].wastedBitsPerSample); + decodedSample = left - side; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE: + { + if (channelIndex == 0) { + int side = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + int right = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 1].wastedBitsPerSample); + decodedSample = side + right; + } else { + decodedSample = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE: + { + int mid; + int side; + if (channelIndex == 0) { + mid = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + side = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 1].wastedBitsPerSample); + + mid = (((unsigned int)mid) << 1) | (side & 0x01); + decodedSample = (mid + side) >> 1; + } else { + mid = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex - 1].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex - 1].wastedBitsPerSample); + side = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + + mid = (((unsigned int)mid) << 1) | (side & 0x01); + decodedSample = (mid - side) >> 1; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT: + default: + { + decodedSample = (int)((drflac_uint32)pFlac->currentFrame.subframes[channelIndex + 0].pDecodedSamples[nextSampleInFrame] << pFlac->currentFrame.subframes[channelIndex + 0].wastedBitsPerSample); + } break; + } + + decodedSample = (int)((drflac_uint32)decodedSample << (32 - pFlac->bitsPerSample)); + + if (bufferOut) { + *bufferOut++ = decodedSample; + } + + samplesRead += 1; + pFlac->currentFrame.samplesRemaining -= 1; + samplesToRead -= 1; + } + + return samplesRead; +} + +drflac_uint64 drflac_read_s32(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int32* bufferOut) +{ + drflac_uint64 samplesRead; + + /* Note that is allowed to be null, in which case this will act like a seek. */ + if (pFlac == NULL || samplesToRead == 0) { + return 0; + } + + if (bufferOut == NULL) { + return drflac__seek_forward_by_samples(pFlac, samplesToRead); + } + + samplesRead = 0; + while (samplesToRead > 0) { + /* If we've run out of samples in this frame, go to the next. */ + if (pFlac->currentFrame.samplesRemaining == 0) { + if (!drflac__read_and_decode_next_flac_frame(pFlac)) { + break; /* Couldn't read the next frame, so just break from the loop and return. */ + } + } else { + /* Here is where we grab the samples and interleave them. */ + unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + drflac_uint64 totalSamplesInFrame = pFlac->currentFrame.header.blockSize * channelCount; + drflac_uint64 samplesReadFromFrameSoFar = totalSamplesInFrame - pFlac->currentFrame.samplesRemaining; + drflac_uint64 misalignedSampleCount = samplesReadFromFrameSoFar % channelCount; + drflac_uint64 alignedSampleCountPerChannel; + drflac_uint64 firstAlignedSampleInFrame; + unsigned int unusedBitsPerSample; + drflac_uint64 alignedSamplesRead; + + if (misalignedSampleCount > 0) { + drflac_uint64 misalignedSamplesRead = drflac__read_s32__misaligned(pFlac, misalignedSampleCount, bufferOut); + samplesRead += misalignedSamplesRead; + samplesReadFromFrameSoFar += misalignedSamplesRead; + bufferOut += misalignedSamplesRead; + samplesToRead -= misalignedSamplesRead; + pFlac->currentSample += misalignedSamplesRead; + } + + + alignedSampleCountPerChannel = samplesToRead / channelCount; + if (alignedSampleCountPerChannel > pFlac->currentFrame.samplesRemaining / channelCount) { + alignedSampleCountPerChannel = pFlac->currentFrame.samplesRemaining / channelCount; + } + + firstAlignedSampleInFrame = samplesReadFromFrameSoFar / channelCount; + unusedBitsPerSample = 32 - pFlac->bitsPerSample; + + switch (pFlac->currentFrame.header.channelAssignment) + { + case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE: + { + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + int left = (int)((drflac_uint32)pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample)); + int side = (int)((drflac_uint32)pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample)); + int right = left - side; + + bufferOut[i*2+0] = left; + bufferOut[i*2+1] = right; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE: + { + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + int side = (int)((drflac_uint32)pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample)); + int right = (int)((drflac_uint32)pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample)); + int left = right + side; + + bufferOut[i*2+0] = left; + bufferOut[i*2+1] = right; + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE: + { + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + int mid = (int)((drflac_uint32)pDecodedSamples0[i] << pFlac->currentFrame.subframes[0].wastedBitsPerSample); + int side = (int)((drflac_uint32)pDecodedSamples1[i] << pFlac->currentFrame.subframes[1].wastedBitsPerSample); + + mid = (((drflac_uint32)mid) << 1) | (side & 0x01); + + bufferOut[i*2+0] = (drflac_int32)((drflac_uint32)((mid + side) >> 1) << (unusedBitsPerSample)); + bufferOut[i*2+1] = (drflac_int32)((drflac_uint32)((mid - side) >> 1) << (unusedBitsPerSample)); + } + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT: + default: + { + if (pFlac->currentFrame.header.channelAssignment == 1) /* 1 = Stereo */ + { + /* Stereo optimized inner loop unroll. */ + drflac_uint64 i; + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + firstAlignedSampleInFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + firstAlignedSampleInFrame; + + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + bufferOut[i*2+0] = (drflac_int32)((drflac_uint32)pDecodedSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample)); + bufferOut[i*2+1] = (drflac_int32)((drflac_uint32)pDecodedSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample)); + } + } + else + { + /* Generic interleaving. */ + drflac_uint64 i; + for (i = 0; i < alignedSampleCountPerChannel; ++i) { + unsigned int j; + for (j = 0; j < channelCount; ++j) { + bufferOut[(i*channelCount)+j] = (drflac_int32)((drflac_uint32)(pFlac->currentFrame.subframes[j].pDecodedSamples[firstAlignedSampleInFrame + i]) << (unusedBitsPerSample + pFlac->currentFrame.subframes[j].wastedBitsPerSample)); + } + } + } + } break; + } + + alignedSamplesRead = alignedSampleCountPerChannel * channelCount; + samplesRead += alignedSamplesRead; + samplesReadFromFrameSoFar += alignedSamplesRead; + bufferOut += alignedSamplesRead; + samplesToRead -= alignedSamplesRead; + pFlac->currentSample += alignedSamplesRead; + pFlac->currentFrame.samplesRemaining -= (unsigned int)alignedSamplesRead; + + + /* At this point we may still have some excess samples left to read. */ + if (samplesToRead > 0 && pFlac->currentFrame.samplesRemaining > 0) { + drflac_uint64 excessSamplesRead = 0; + if (samplesToRead < pFlac->currentFrame.samplesRemaining) { + excessSamplesRead = drflac__read_s32__misaligned(pFlac, samplesToRead, bufferOut); + } else { + excessSamplesRead = drflac__read_s32__misaligned(pFlac, pFlac->currentFrame.samplesRemaining, bufferOut); + } + + samplesRead += excessSamplesRead; + samplesReadFromFrameSoFar += excessSamplesRead; + bufferOut += excessSamplesRead; + samplesToRead -= excessSamplesRead; + pFlac->currentSample += excessSamplesRead; + } + } + } + + return samplesRead; +} + +drflac_uint64 drflac_read_pcm_frames_s32(drflac* pFlac, drflac_uint64 framesToRead, drflac_int32* pBufferOut) +{ +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(push) + #pragma warning(disable:4996) /* was declared deprecated */ +#elif defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + return drflac_read_s32(pFlac, framesToRead*pFlac->channels, pBufferOut) / pFlac->channels; +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(pop) +#elif defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic pop +#endif +} + + +drflac_uint64 drflac_read_s16(drflac* pFlac, drflac_uint64 samplesToRead, drflac_int16* pBufferOut) +{ + /* This reads samples in 2 passes and can probably be optimized. */ + drflac_uint64 totalSamplesRead = 0; + +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(push) + #pragma warning(disable:4996) /* was declared deprecated */ +#elif defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + + while (samplesToRead > 0) { + drflac_uint64 i; + drflac_int32 samples32[4096]; + drflac_uint64 samplesJustRead = drflac_read_s32(pFlac, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) { + break; /* Reached the end. */ + } + + /* s32 -> s16 */ + for (i = 0; i < samplesJustRead; ++i) { + pBufferOut[i] = (drflac_int16)(samples32[i] >> 16); + } + + totalSamplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(pop) +#elif defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic pop +#endif + + return totalSamplesRead; +} + +drflac_uint64 drflac_read_pcm_frames_s16(drflac* pFlac, drflac_uint64 framesToRead, drflac_int16* pBufferOut) +{ + /* This reads samples in 2 passes and can probably be optimized. */ + drflac_uint64 totalPCMFramesRead = 0; + + while (framesToRead > 0) { + drflac_uint64 iFrame; + drflac_int32 samples32[4096]; + drflac_uint64 framesJustRead = drflac_read_pcm_frames_s32(pFlac, (framesToRead > 4096/pFlac->channels) ? 4096/pFlac->channels : framesToRead, samples32); + if (framesJustRead == 0) { + break; /* Reached the end. */ + } + + /* s32 -> s16 */ + for (iFrame = 0; iFrame < framesJustRead; ++iFrame) { + drflac_uint32 iChannel; + for (iChannel = 0; iChannel < pFlac->channels; ++iChannel) { + drflac_uint64 iSample = iFrame*pFlac->channels + iChannel; + pBufferOut[iSample] = (drflac_int16)(samples32[iSample] >> 16); + } + } + + totalPCMFramesRead += framesJustRead; + framesToRead -= framesJustRead; + pBufferOut += framesJustRead * pFlac->channels; + } + + return totalPCMFramesRead; +} + + +drflac_uint64 drflac_read_f32(drflac* pFlac, drflac_uint64 samplesToRead, float* pBufferOut) +{ + /* This reads samples in 2 passes and can probably be optimized. */ + drflac_uint64 totalSamplesRead = 0; + +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(push) + #pragma warning(disable:4996) /* was declared deprecated */ +#elif defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + + while (samplesToRead > 0) { + drflac_uint64 i; + drflac_int32 samples32[4096]; + drflac_uint64 samplesJustRead = drflac_read_s32(pFlac, (samplesToRead > 4096) ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) { + break; /* Reached the end. */ + } + + /* s32 -> f32 */ + for (i = 0; i < samplesJustRead; ++i) { + pBufferOut[i] = (float)(samples32[i] / 2147483648.0); + } + + totalSamplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + +#if defined(_MSC_VER) && !defined(__clang__) + #pragma warning(pop) +#elif defined(__GNUC__) || defined(__clang__) + #pragma GCC diagnostic pop +#endif + + return totalSamplesRead; +} + +#if 0 +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + for (i = 0; i < frameCount; ++i) { + int left = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + int side = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + int right = left - side; + + pOutputSamples[i*2+0] = (float)(left / 2147483648.0); + pOutputSamples[i*2+1] = (float)(right / 2147483648.0); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + drflac_uint64 frameCount4 = frameCount >> 2; + + float factor = 1 / 2147483648.0; + + drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample; + drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample; + for (i = 0; i < frameCount4; ++i) { + drflac_int32 left0 = pInputSamples0[i*4+0] << shift0; + drflac_int32 left1 = pInputSamples0[i*4+1] << shift0; + drflac_int32 left2 = pInputSamples0[i*4+2] << shift0; + drflac_int32 left3 = pInputSamples0[i*4+3] << shift0; + + drflac_int32 side0 = pInputSamples1[i*4+0] << shift1; + drflac_int32 side1 = pInputSamples1[i*4+1] << shift1; + drflac_int32 side2 = pInputSamples1[i*4+2] << shift1; + drflac_int32 side3 = pInputSamples1[i*4+3] << shift1; + + drflac_int32 right0 = left0 - side0; + drflac_int32 right1 = left1 - side1; + drflac_int32 right2 = left2 - side2; + drflac_int32 right3 = left3 - side3; + + pOutputSamples[i*8+0] = left0 * factor; + pOutputSamples[i*8+1] = right0 * factor; + pOutputSamples[i*8+2] = left1 * factor; + pOutputSamples[i*8+3] = right1 * factor; + pOutputSamples[i*8+4] = left2 * factor; + pOutputSamples[i*8+5] = right2 * factor; + pOutputSamples[i*8+6] = left3 * factor; + pOutputSamples[i*8+7] = right3 * factor; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int left = pInputSamples0[i] << shift0; + int side = pInputSamples1[i] << shift1; + int right = left - side; + + pOutputSamples[i*2+0] = (float)(left * factor); + pOutputSamples[i*2+1] = (float)(right * factor); + } +} + +#if defined(DRFLAC_SUPPORT_SSE2) +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 frameCount4; + __m128 factor; + int shift0; + int shift1; + drflac_uint64 i; + + drflac_assert(pFlac->bitsPerSample <= 24); + + frameCount4 = frameCount >> 2; + + factor = _mm_set1_ps(1.0f / 8388608.0f); + shift0 = (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample) - 8; + shift1 = (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample) - 8; + + for (i = 0; i < frameCount4; ++i) { + __m128i inputSample0 = _mm_loadu_si128((const __m128i*)pInputSamples0 + i); + __m128i inputSample1 = _mm_loadu_si128((const __m128i*)pInputSamples1 + i); + + __m128i left = _mm_slli_epi32(inputSample0, shift0); + __m128i side = _mm_slli_epi32(inputSample1, shift1); + __m128i right = _mm_sub_epi32(left, side); + __m128 leftf = _mm_mul_ps(_mm_cvtepi32_ps(left), factor); + __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor); + + pOutputSamples[i*8+0] = ((float*)&leftf)[0]; + pOutputSamples[i*8+1] = ((float*)&rightf)[0]; + pOutputSamples[i*8+2] = ((float*)&leftf)[1]; + pOutputSamples[i*8+3] = ((float*)&rightf)[1]; + pOutputSamples[i*8+4] = ((float*)&leftf)[2]; + pOutputSamples[i*8+5] = ((float*)&rightf)[2]; + pOutputSamples[i*8+6] = ((float*)&leftf)[3]; + pOutputSamples[i*8+7] = ((float*)&rightf)[3]; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int left = pInputSamples0[i] << shift0; + int side = pInputSamples1[i] << shift1; + int right = left - side; + + pOutputSamples[i*2+0] = (float)(left / 8388608.0f); + pOutputSamples[i*2+1] = (float)(right / 8388608.0f); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_left_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ +#if defined(DRFLAC_SUPPORT_SSE2) + if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) { + drflac_read_pcm_frames_f32__decode_left_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); + } else +#endif + { + /* Scalar fallback. */ +#if 0 + drflac_read_pcm_frames_f32__decode_left_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#else + drflac_read_pcm_frames_f32__decode_left_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#endif + } +} + + +#if 0 +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + for (i = 0; i < frameCount; ++i) { + int side = pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + int right = pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + int left = right + side; + + pOutputSamples[i*2+0] = (float)(left / 2147483648.0); + pOutputSamples[i*2+1] = (float)(right / 2147483648.0); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + drflac_uint64 frameCount4 = frameCount >> 2; + + float factor = 1 / 2147483648.0; + + drflac_int32 shift0 = unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample; + drflac_int32 shift1 = unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample; + for (i = 0; i < frameCount4; ++i) { + drflac_int32 side0 = pInputSamples0[i*4+0] << shift0; + drflac_int32 side1 = pInputSamples0[i*4+1] << shift0; + drflac_int32 side2 = pInputSamples0[i*4+2] << shift0; + drflac_int32 side3 = pInputSamples0[i*4+3] << shift0; + + drflac_int32 right0 = pInputSamples1[i*4+0] << shift1; + drflac_int32 right1 = pInputSamples1[i*4+1] << shift1; + drflac_int32 right2 = pInputSamples1[i*4+2] << shift1; + drflac_int32 right3 = pInputSamples1[i*4+3] << shift1; + + drflac_int32 left0 = right0 + side0; + drflac_int32 left1 = right1 + side1; + drflac_int32 left2 = right2 + side2; + drflac_int32 left3 = right3 + side3; + + pOutputSamples[i*8+0] = left0 * factor; + pOutputSamples[i*8+1] = right0 * factor; + pOutputSamples[i*8+2] = left1 * factor; + pOutputSamples[i*8+3] = right1 * factor; + pOutputSamples[i*8+4] = left2 * factor; + pOutputSamples[i*8+5] = right2 * factor; + pOutputSamples[i*8+6] = left3 * factor; + pOutputSamples[i*8+7] = right3 * factor; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int side = pInputSamples0[i] << shift0; + int right = pInputSamples1[i] << shift1; + int left = right + side; + + pOutputSamples[i*2+0] = (float)(left * factor); + pOutputSamples[i*2+1] = (float)(right * factor); + } +} + +#if defined(DRFLAC_SUPPORT_SSE2) +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 frameCount4; + __m128 factor; + int shift0; + int shift1; + drflac_uint64 i; + + drflac_assert(pFlac->bitsPerSample <= 24); + + frameCount4 = frameCount >> 2; + + factor = _mm_set1_ps(1.0f / 8388608.0f); + shift0 = (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample) - 8; + shift1 = (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample) - 8; + + for (i = 0; i < frameCount4; ++i) { + __m128i inputSample0 = _mm_loadu_si128((const __m128i*)pInputSamples0 + i); + __m128i inputSample1 = _mm_loadu_si128((const __m128i*)pInputSamples1 + i); + + __m128i side = _mm_slli_epi32(inputSample0, shift0); + __m128i right = _mm_slli_epi32(inputSample1, shift1); + __m128i left = _mm_add_epi32(right, side); + __m128 leftf = _mm_mul_ps(_mm_cvtepi32_ps(left), factor); + __m128 rightf = _mm_mul_ps(_mm_cvtepi32_ps(right), factor); + + pOutputSamples[i*8+0] = ((float*)&leftf)[0]; + pOutputSamples[i*8+1] = ((float*)&rightf)[0]; + pOutputSamples[i*8+2] = ((float*)&leftf)[1]; + pOutputSamples[i*8+3] = ((float*)&rightf)[1]; + pOutputSamples[i*8+4] = ((float*)&leftf)[2]; + pOutputSamples[i*8+5] = ((float*)&rightf)[2]; + pOutputSamples[i*8+6] = ((float*)&leftf)[3]; + pOutputSamples[i*8+7] = ((float*)&rightf)[3]; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int side = pInputSamples0[i] << shift0; + int right = pInputSamples1[i] << shift1; + int left = right + side; + + pOutputSamples[i*2+0] = (float)(left / 8388608.0f); + pOutputSamples[i*2+1] = (float)(right / 8388608.0f); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_right_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ +#if defined(DRFLAC_SUPPORT_SSE2) + if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) { + drflac_read_pcm_frames_f32__decode_right_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); + } else +#endif + { + /* Scalar fallback. */ +#if 0 + drflac_read_pcm_frames_f32__decode_right_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#else + drflac_read_pcm_frames_f32__decode_right_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#endif + } +} + + +#if 0 +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + for (drflac_uint64 i = 0; i < frameCount; ++i) { + int mid = pInputSamples0[i] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int side = pInputSamples1[i] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + + mid = (((drflac_uint32)mid) << 1) | (side & 0x01); + + pOutputSamples[i*2+0] = (float)((((mid + side) >> 1) << (unusedBitsPerSample)) / 2147483648.0); + pOutputSamples[i*2+1] = (float)((((mid - side) >> 1) << (unusedBitsPerSample)) / 2147483648.0); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + drflac_uint64 frameCount4 = frameCount >> 2; + + float factor = 1 / 2147483648.0; + + int shift = unusedBitsPerSample; + if (shift > 0) { + shift -= 1; + for (i = 0; i < frameCount4; ++i) { + int temp0L; + int temp1L; + int temp2L; + int temp3L; + int temp0R; + int temp1R; + int temp2R; + int temp3R; + + int mid0 = pInputSamples0[i*4+0] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int mid1 = pInputSamples0[i*4+1] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int mid2 = pInputSamples0[i*4+2] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int mid3 = pInputSamples0[i*4+3] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + + int side0 = pInputSamples1[i*4+0] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + int side1 = pInputSamples1[i*4+1] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + int side2 = pInputSamples1[i*4+2] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + int side3 = pInputSamples1[i*4+3] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + + mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01); + mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01); + mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01); + mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01); + + temp0L = ((mid0 + side0) << shift); + temp1L = ((mid1 + side1) << shift); + temp2L = ((mid2 + side2) << shift); + temp3L = ((mid3 + side3) << shift); + + temp0R = ((mid0 - side0) << shift); + temp1R = ((mid1 - side1) << shift); + temp2R = ((mid2 - side2) << shift); + temp3R = ((mid3 - side3) << shift); + + pOutputSamples[i*8+0] = (float)(temp0L * factor); + pOutputSamples[i*8+1] = (float)(temp0R * factor); + pOutputSamples[i*8+2] = (float)(temp1L * factor); + pOutputSamples[i*8+3] = (float)(temp1R * factor); + pOutputSamples[i*8+4] = (float)(temp2L * factor); + pOutputSamples[i*8+5] = (float)(temp2R * factor); + pOutputSamples[i*8+6] = (float)(temp3L * factor); + pOutputSamples[i*8+7] = (float)(temp3R * factor); + } + } else { + for (i = 0; i < frameCount4; ++i) { + int temp0L; + int temp1L; + int temp2L; + int temp3L; + int temp0R; + int temp1R; + int temp2R; + int temp3R; + + int mid0 = pInputSamples0[i*4+0] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int mid1 = pInputSamples0[i*4+1] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int mid2 = pInputSamples0[i*4+2] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int mid3 = pInputSamples0[i*4+3] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + + int side0 = pInputSamples1[i*4+0] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + int side1 = pInputSamples1[i*4+1] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + int side2 = pInputSamples1[i*4+2] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + int side3 = pInputSamples1[i*4+3] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + + mid0 = (((drflac_uint32)mid0) << 1) | (side0 & 0x01); + mid1 = (((drflac_uint32)mid1) << 1) | (side1 & 0x01); + mid2 = (((drflac_uint32)mid2) << 1) | (side2 & 0x01); + mid3 = (((drflac_uint32)mid3) << 1) | (side3 & 0x01); + + temp0L = ((mid0 + side0) >> 1); + temp1L = ((mid1 + side1) >> 1); + temp2L = ((mid2 + side2) >> 1); + temp3L = ((mid3 + side3) >> 1); + + temp0R = ((mid0 - side0) >> 1); + temp1R = ((mid1 - side1) >> 1); + temp2R = ((mid2 - side2) >> 1); + temp3R = ((mid3 - side3) >> 1); + + pOutputSamples[i*8+0] = (float)(temp0L * factor); + pOutputSamples[i*8+1] = (float)(temp0R * factor); + pOutputSamples[i*8+2] = (float)(temp1L * factor); + pOutputSamples[i*8+3] = (float)(temp1R * factor); + pOutputSamples[i*8+4] = (float)(temp2L * factor); + pOutputSamples[i*8+5] = (float)(temp2R * factor); + pOutputSamples[i*8+6] = (float)(temp3L * factor); + pOutputSamples[i*8+7] = (float)(temp3R * factor); + } + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int mid = pInputSamples0[i] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int side = pInputSamples1[i] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + + mid = (((drflac_uint32)mid) << 1) | (side & 0x01); + + pOutputSamples[i*2+0] = (float)((((mid + side) >> 1) << unusedBitsPerSample) * factor); + pOutputSamples[i*2+1] = (float)((((mid - side) >> 1) << unusedBitsPerSample) * factor); + } +} + +#if defined(DRFLAC_SUPPORT_SSE2) +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + drflac_uint64 frameCount4; + float factor; + int shift; + __m128 factor128; + + drflac_assert(pFlac->bitsPerSample <= 24); + + frameCount4 = frameCount >> 2; + + factor = 1.0f / 8388608.0f; + factor128 = _mm_set1_ps(1.0f / 8388608.0f); + + shift = unusedBitsPerSample - 8; + if (shift == 0) { + for (i = 0; i < frameCount4; ++i) { + __m128i tempL; + __m128i tempR; + __m128 leftf; + __m128 rightf; + + __m128i inputSample0 = _mm_loadu_si128((const __m128i*)pInputSamples0 + i); + __m128i inputSample1 = _mm_loadu_si128((const __m128i*)pInputSamples1 + i); + + __m128i mid = _mm_slli_epi32(inputSample0, pFlac->currentFrame.subframes[0].wastedBitsPerSample); + __m128i side = _mm_slli_epi32(inputSample1, pFlac->currentFrame.subframes[1].wastedBitsPerSample); + + mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01))); + + tempL = _mm_add_epi32(mid, side); + tempR = _mm_sub_epi32(mid, side); + + /* Signed bit shift. */ + tempL = _mm_or_si128(_mm_srli_epi32(tempL, 1), _mm_and_si128(tempL, _mm_set1_epi32(0x80000000))); + tempR = _mm_or_si128(_mm_srli_epi32(tempR, 1), _mm_and_si128(tempR, _mm_set1_epi32(0x80000000))); + + leftf = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128); + rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128); + + pOutputSamples[i*8+0] = ((float*)&leftf)[0]; + pOutputSamples[i*8+1] = ((float*)&rightf)[0]; + pOutputSamples[i*8+2] = ((float*)&leftf)[1]; + pOutputSamples[i*8+3] = ((float*)&rightf)[1]; + pOutputSamples[i*8+4] = ((float*)&leftf)[2]; + pOutputSamples[i*8+5] = ((float*)&rightf)[2]; + pOutputSamples[i*8+6] = ((float*)&leftf)[3]; + pOutputSamples[i*8+7] = ((float*)&rightf)[3]; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int mid = pInputSamples0[i] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int side = pInputSamples1[i] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + + mid = (((drflac_uint32)mid) << 1) | (side & 0x01); + + pOutputSamples[i*2+0] = (float)(((mid + side) >> 1) * factor); + pOutputSamples[i*2+1] = (float)(((mid - side) >> 1) * factor); + } + } else { + for (i = 0; i < frameCount4; ++i) { + __m128i inputSample0; + __m128i inputSample1; + __m128i mid; + __m128i side; + __m128i tempL; + __m128i tempR; + __m128 leftf; + __m128 rightf; + + inputSample0 = _mm_loadu_si128((const __m128i*)pInputSamples0 + i); + inputSample1 = _mm_loadu_si128((const __m128i*)pInputSamples1 + i); + + mid = _mm_slli_epi32(inputSample0, pFlac->currentFrame.subframes[0].wastedBitsPerSample); + side = _mm_slli_epi32(inputSample1, pFlac->currentFrame.subframes[1].wastedBitsPerSample); + + mid = _mm_or_si128(_mm_slli_epi32(mid, 1), _mm_and_si128(side, _mm_set1_epi32(0x01))); + + tempL = _mm_slli_epi32(_mm_srli_epi32(_mm_add_epi32(mid, side), 1), shift); + tempR = _mm_slli_epi32(_mm_srli_epi32(_mm_sub_epi32(mid, side), 1), shift); + + leftf = _mm_mul_ps(_mm_cvtepi32_ps(tempL), factor128); + rightf = _mm_mul_ps(_mm_cvtepi32_ps(tempR), factor128); + + pOutputSamples[i*8+0] = ((float*)&leftf)[0]; + pOutputSamples[i*8+1] = ((float*)&rightf)[0]; + pOutputSamples[i*8+2] = ((float*)&leftf)[1]; + pOutputSamples[i*8+3] = ((float*)&rightf)[1]; + pOutputSamples[i*8+4] = ((float*)&leftf)[2]; + pOutputSamples[i*8+5] = ((float*)&rightf)[2]; + pOutputSamples[i*8+6] = ((float*)&leftf)[3]; + pOutputSamples[i*8+7] = ((float*)&rightf)[3]; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + int mid = pInputSamples0[i] << pFlac->currentFrame.subframes[0].wastedBitsPerSample; + int side = pInputSamples1[i] << pFlac->currentFrame.subframes[1].wastedBitsPerSample; + + mid = (((drflac_uint32)mid) << 1) | (side & 0x01); + + pOutputSamples[i*2+0] = (float)((((mid + side) >> 1) << shift) * factor); + pOutputSamples[i*2+1] = (float)((((mid - side) >> 1) << shift) * factor); + } + } +} +#endif + + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_mid_side(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ +#if defined(DRFLAC_SUPPORT_SSE2) + if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) { + drflac_read_pcm_frames_f32__decode_mid_side__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); + } else +#endif + { + /* Scalar fallback. */ +#if 0 + drflac_read_pcm_frames_f32__decode_mid_side__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#else + drflac_read_pcm_frames_f32__decode_mid_side__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#endif + } +} + +#if 0 +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__reference(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + for (drflac_uint64 i = 0; i < frameCount; ++i) { + pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample)) / 2147483648.0); + pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample)) / 2147483648.0); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + drflac_uint64 frameCount4 = frameCount >> 2; + + float factor = 1 / 2147483648.0; + + int shift0 = (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample); + int shift1 = (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample); + + for (i = 0; i < frameCount4; ++i) { + int tempL0 = pInputSamples0[i*4+0] << shift0; + int tempL1 = pInputSamples0[i*4+1] << shift0; + int tempL2 = pInputSamples0[i*4+2] << shift0; + int tempL3 = pInputSamples0[i*4+3] << shift0; + + int tempR0 = pInputSamples1[i*4+0] << shift1; + int tempR1 = pInputSamples1[i*4+1] << shift1; + int tempR2 = pInputSamples1[i*4+2] << shift1; + int tempR3 = pInputSamples1[i*4+3] << shift1; + + pOutputSamples[i*8+0] = (float)(tempL0 * factor); + pOutputSamples[i*8+1] = (float)(tempR0 * factor); + pOutputSamples[i*8+2] = (float)(tempL1 * factor); + pOutputSamples[i*8+3] = (float)(tempR1 * factor); + pOutputSamples[i*8+4] = (float)(tempL2 * factor); + pOutputSamples[i*8+5] = (float)(tempR2 * factor); + pOutputSamples[i*8+6] = (float)(tempL3 * factor); + pOutputSamples[i*8+7] = (float)(tempR3 * factor); + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << shift0) * factor); + pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << shift1) * factor); + } +} + +#if defined(DRFLAC_SUPPORT_SSE2) +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ + drflac_uint64 i; + drflac_uint64 frameCount4 = frameCount >> 2; + + float factor = 1.0f / 8388608.0f; + __m128 factor128 = _mm_set1_ps(1.0f / 8388608.0f); + + int shift0 = (unusedBitsPerSample + pFlac->currentFrame.subframes[0].wastedBitsPerSample) - 8; + int shift1 = (unusedBitsPerSample + pFlac->currentFrame.subframes[1].wastedBitsPerSample) - 8; + + for (i = 0; i < frameCount4; ++i) { + __m128i inputSample0 = _mm_loadu_si128((const __m128i*)pInputSamples0 + i); + __m128i inputSample1 = _mm_loadu_si128((const __m128i*)pInputSamples1 + i); + + __m128i i32L = _mm_slli_epi32(inputSample0, shift0); + __m128i i32R = _mm_slli_epi32(inputSample1, shift1); + + __m128 f32L = _mm_mul_ps(_mm_cvtepi32_ps(i32L), factor128); + __m128 f32R = _mm_mul_ps(_mm_cvtepi32_ps(i32R), factor128); + + pOutputSamples[i*8+0] = ((float*)&f32L)[0]; + pOutputSamples[i*8+1] = ((float*)&f32R)[0]; + pOutputSamples[i*8+2] = ((float*)&f32L)[1]; + pOutputSamples[i*8+3] = ((float*)&f32R)[1]; + pOutputSamples[i*8+4] = ((float*)&f32L)[2]; + pOutputSamples[i*8+5] = ((float*)&f32R)[2]; + pOutputSamples[i*8+6] = ((float*)&f32L)[3]; + pOutputSamples[i*8+7] = ((float*)&f32R)[3]; + } + + for (i = (frameCount4 << 2); i < frameCount; ++i) { + pOutputSamples[i*2+0] = (float)((pInputSamples0[i] << shift0) * factor); + pOutputSamples[i*2+1] = (float)((pInputSamples1[i] << shift1) * factor); + } +} +#endif + +static DRFLAC_INLINE void drflac_read_pcm_frames_f32__decode_independent_stereo(drflac* pFlac, drflac_uint64 frameCount, drflac_int32 unusedBitsPerSample, const drflac_int32* pInputSamples0, const drflac_int32* pInputSamples1, float* pOutputSamples) +{ +#if defined(DRFLAC_SUPPORT_SSE2) + if (drflac__gIsSSE2Supported && pFlac->bitsPerSample <= 24) { + drflac_read_pcm_frames_f32__decode_independent_stereo__sse2(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); + } else +#endif + { + /* Scalar fallback. */ +#if 0 + drflac_read_pcm_frames_f32__decode_independent_stereo__reference(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#else + drflac_read_pcm_frames_f32__decode_independent_stereo__scalar(pFlac, frameCount, unusedBitsPerSample, pInputSamples0, pInputSamples1, pOutputSamples); +#endif + } +} + +drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut) +{ + drflac_uint64 framesRead; + + if (pFlac == NULL || framesToRead == 0) { + return 0; + } + + if (pBufferOut == NULL) { + return drflac__seek_forward_by_pcm_frames(pFlac, framesToRead); + } + + framesRead = 0; + while (framesToRead > 0) { + /* If we've run out of samples in this frame, go to the next. */ + if (pFlac->currentFrame.samplesRemaining == 0) { + if (!drflac__read_and_decode_next_flac_frame(pFlac)) { + break; /* Couldn't read the next frame, so just break from the loop and return. */ + } + } else { + unsigned int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + drflac_uint64 totalFramesInPacket = pFlac->currentFrame.header.blockSize; + drflac_uint64 framesReadFromPacketSoFar = totalFramesInPacket - (pFlac->currentFrame.samplesRemaining/channelCount); + drflac_uint64 iFirstPCMFrame = framesReadFromPacketSoFar; + drflac_int32 unusedBitsPerSample = 32 - pFlac->bitsPerSample; + drflac_uint64 frameCountThisIteration = framesToRead; + drflac_uint64 samplesReadThisIteration; + + if (frameCountThisIteration > pFlac->currentFrame.samplesRemaining / channelCount) { + frameCountThisIteration = pFlac->currentFrame.samplesRemaining / channelCount; + } + + if (channelCount == 2) { + const drflac_int32* pDecodedSamples0 = pFlac->currentFrame.subframes[0].pDecodedSamples + iFirstPCMFrame; + const drflac_int32* pDecodedSamples1 = pFlac->currentFrame.subframes[1].pDecodedSamples + iFirstPCMFrame; + + switch (pFlac->currentFrame.header.channelAssignment) + { + case DRFLAC_CHANNEL_ASSIGNMENT_LEFT_SIDE: + { + drflac_read_pcm_frames_f32__decode_left_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut); + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_RIGHT_SIDE: + { + drflac_read_pcm_frames_f32__decode_right_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut); + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_MID_SIDE: + { + drflac_read_pcm_frames_f32__decode_mid_side(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut); + } break; + + case DRFLAC_CHANNEL_ASSIGNMENT_INDEPENDENT: + default: + { + drflac_read_pcm_frames_f32__decode_independent_stereo(pFlac, frameCountThisIteration, unusedBitsPerSample, pDecodedSamples0, pDecodedSamples1, pBufferOut); + } break; + } + } else { + /* Generic interleaving. */ + drflac_uint64 i; + for (i = 0; i < frameCountThisIteration; ++i) { + unsigned int j; + for (j = 0; j < channelCount; ++j) { + pBufferOut[(i*channelCount)+j] = (float)(((pFlac->currentFrame.subframes[j].pDecodedSamples[iFirstPCMFrame + i]) << (unusedBitsPerSample + pFlac->currentFrame.subframes[j].wastedBitsPerSample)) / 2147483648.0); + } + } + } + + samplesReadThisIteration = frameCountThisIteration * channelCount; + framesRead += frameCountThisIteration; + framesReadFromPacketSoFar += frameCountThisIteration; + pBufferOut += samplesReadThisIteration; + framesToRead -= frameCountThisIteration; + pFlac->currentSample += samplesReadThisIteration; + pFlac->currentFrame.samplesRemaining -= (unsigned int)samplesReadThisIteration; + } + } + + return framesRead; +} + +drflac_bool32 drflac_seek_to_sample(drflac* pFlac, drflac_uint64 sampleIndex) +{ + if (pFlac == NULL) { + return DRFLAC_FALSE; + } + + /* + If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present + when the decoder was opened. + */ + if (pFlac->firstFramePos == 0) { + return DRFLAC_FALSE; + } + + if (sampleIndex == 0) { + pFlac->currentSample = 0; + return drflac__seek_to_first_frame(pFlac); + } else { + drflac_bool32 wasSuccessful = DRFLAC_FALSE; + + /* Clamp the sample to the end. */ + if (sampleIndex >= pFlac->totalSampleCount) { + sampleIndex = pFlac->totalSampleCount - 1; + } + + /* If the target sample and the current sample are in the same frame we just move the position forward. */ + if (sampleIndex > pFlac->currentSample) { + /* Forward. */ + drflac_uint32 offset = (drflac_uint32)(sampleIndex - pFlac->currentSample); + if (pFlac->currentFrame.samplesRemaining > offset) { + pFlac->currentFrame.samplesRemaining -= offset; + pFlac->currentSample = sampleIndex; + return DRFLAC_TRUE; + } + } else { + /* Backward. */ + drflac_uint32 offsetAbs = (drflac_uint32)(pFlac->currentSample - sampleIndex); + drflac_uint32 currentFrameSampleCount = pFlac->currentFrame.header.blockSize * drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + drflac_uint32 currentFrameSamplesConsumed = (drflac_uint32)(currentFrameSampleCount - pFlac->currentFrame.samplesRemaining); + if (currentFrameSamplesConsumed > offsetAbs) { + pFlac->currentFrame.samplesRemaining += offsetAbs; + pFlac->currentSample = sampleIndex; + return DRFLAC_TRUE; + } + } + + /* + Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so + we'll instead use Ogg's natural seeking facility. + */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + { + wasSuccessful = drflac_ogg__seek_to_sample(pFlac, sampleIndex); + } + else +#endif + { + /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */ + wasSuccessful = drflac__seek_to_sample__seek_table(pFlac, sampleIndex); + if (!wasSuccessful) { + wasSuccessful = drflac__seek_to_sample__brute_force(pFlac, sampleIndex); + } + } + + pFlac->currentSample = sampleIndex; + return wasSuccessful; + } +} + +drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex) +{ + if (pFlac == NULL) { + return DRFLAC_FALSE; + } + + /* + If we don't know where the first frame begins then we can't seek. This will happen when the STREAMINFO block was not present + when the decoder was opened. + */ + if (pFlac->firstFramePos == 0) { + return DRFLAC_FALSE; + } + + if (pcmFrameIndex == 0) { + pFlac->currentSample = 0; + return drflac__seek_to_first_frame(pFlac); + } else { + drflac_bool32 wasSuccessful = DRFLAC_FALSE; + + /* Clamp the sample to the end. */ + if (pcmFrameIndex >= pFlac->totalPCMFrameCount) { + pcmFrameIndex = pFlac->totalPCMFrameCount - 1; + } + + /* If the target sample and the current sample are in the same frame we just move the position forward. */ + if (pcmFrameIndex*pFlac->channels > pFlac->currentSample) { + /* Forward. */ + drflac_uint32 offset = (drflac_uint32)(pcmFrameIndex*pFlac->channels - pFlac->currentSample); + if (pFlac->currentFrame.samplesRemaining > offset) { + pFlac->currentFrame.samplesRemaining -= offset; + pFlac->currentSample = pcmFrameIndex*pFlac->channels; + return DRFLAC_TRUE; + } + } else { + /* Backward. */ + drflac_uint32 offsetAbs = (drflac_uint32)(pFlac->currentSample - pcmFrameIndex*pFlac->channels); + drflac_uint32 currentFrameSampleCount = pFlac->currentFrame.header.blockSize * drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); + drflac_uint32 currentFrameSamplesConsumed = (drflac_uint32)(currentFrameSampleCount - pFlac->currentFrame.samplesRemaining); + if (currentFrameSamplesConsumed > offsetAbs) { + pFlac->currentFrame.samplesRemaining += offsetAbs; + pFlac->currentSample = pcmFrameIndex*pFlac->channels; + return DRFLAC_TRUE; + } + } + + /* + Different techniques depending on encapsulation. Using the native FLAC seektable with Ogg encapsulation is a bit awkward so + we'll instead use Ogg's natural seeking facility. + */ +#ifndef DR_FLAC_NO_OGG + if (pFlac->container == drflac_container_ogg) + { + wasSuccessful = drflac_ogg__seek_to_sample(pFlac, pcmFrameIndex*pFlac->channels); + } + else +#endif + { + /* First try seeking via the seek table. If this fails, fall back to a brute force seek which is much slower. */ + wasSuccessful = drflac__seek_to_sample__seek_table(pFlac, pcmFrameIndex*pFlac->channels); + if (!wasSuccessful) { + wasSuccessful = drflac__seek_to_sample__brute_force(pFlac, pcmFrameIndex*pFlac->channels); + } + } + + pFlac->currentSample = pcmFrameIndex*pFlac->channels; + return wasSuccessful; + } +} + + + +/* High Level APIs */ + +#if defined(SIZE_MAX) + #define DRFLAC_SIZE_MAX SIZE_MAX +#else + #if defined(DRFLAC_64BIT) + #define DRFLAC_SIZE_MAX ((drflac_uint64)0xFFFFFFFFFFFFFFFF) + #else + #define DRFLAC_SIZE_MAX 0xFFFFFFFF + #endif +#endif + + +/* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */ +#define DRFLAC_DEFINE_FULL_READ_AND_CLOSE(extension, type) \ +static type* drflac__full_read_and_close_ ## extension (drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut)\ +{ \ + type* pSampleData = NULL; \ + drflac_uint64 totalPCMFrameCount; \ + \ + drflac_assert(pFlac != NULL); \ + \ + totalPCMFrameCount = pFlac->totalPCMFrameCount; \ + \ + if (totalPCMFrameCount == 0) { \ + type buffer[4096]; \ + drflac_uint64 pcmFramesRead; \ + size_t sampleDataBufferSize = sizeof(buffer); \ + \ + pSampleData = (type*)DRFLAC_MALLOC(sampleDataBufferSize); \ + if (pSampleData == NULL) { \ + goto on_error; \ + } \ + \ + while ((pcmFramesRead = (drflac_uint64)drflac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \ + if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \ + type* pNewSampleData; \ + \ + sampleDataBufferSize *= 2; \ + pNewSampleData = (type*)DRFLAC_REALLOC(pSampleData, sampleDataBufferSize); \ + if (pNewSampleData == NULL) { \ + DRFLAC_FREE(pSampleData); \ + goto on_error; \ + } \ + \ + pSampleData = pNewSampleData; \ + } \ + \ + drflac_copy_memory(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \ + totalPCMFrameCount += pcmFramesRead; \ + } \ + \ + /* At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to \ + protect those ears from random noise! */ \ + drflac_zero_memory(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \ + } else { \ + drflac_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \ + if (dataSize > DRFLAC_SIZE_MAX) { \ + goto on_error; /* The decoded data is too big. */ \ + } \ + \ + pSampleData = (type*)DRFLAC_MALLOC((size_t)dataSize); /* <-- Safe cast as per the check above. */ \ + if (pSampleData == NULL) { \ + goto on_error; \ + } \ + \ + totalPCMFrameCount = drflac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \ + } \ + \ + if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \ + if (channelsOut) *channelsOut = pFlac->channels; \ + if (totalPCMFrameCountOut) *totalPCMFrameCountOut = totalPCMFrameCount; \ + \ + drflac_close(pFlac); \ + return pSampleData; \ + \ +on_error: \ + drflac_close(pFlac); \ + return NULL; \ +} + +DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s32, drflac_int32) +DRFLAC_DEFINE_FULL_READ_AND_CLOSE(s16, drflac_int16) +DRFLAC_DEFINE_FULL_READ_AND_CLOSE(f32, float) + +drflac_int32* drflac_open_and_read_pcm_frames_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut) +{ + drflac* pFlac; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalPCMFrameCountOut) { + *totalPCMFrameCountOut = 0; + } + + pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_s32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut); +} + +drflac_int32* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int32* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_and_read_pcm_frames_s32(onRead, onSeek, pUserData, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + + +drflac_int16* drflac_open_and_read_pcm_frames_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut) +{ + drflac* pFlac; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalPCMFrameCountOut) { + *totalPCMFrameCountOut = 0; + } + + pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_s16(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut); +} + +drflac_int16* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int16* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_and_read_pcm_frames_s16(onRead, onSeek, pUserData, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + +float* drflac_open_and_read_pcm_frames_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalPCMFrameCountOut) +{ + drflac* pFlac; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalPCMFrameCountOut) { + *totalPCMFrameCountOut = 0; + } + + pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_f32(pFlac, channelsOut, sampleRateOut, totalPCMFrameCountOut); +} + +float* drflac_open_and_decode_f32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + float* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_and_read_pcm_frames_f32(onRead, onSeek, pUserData, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + +#ifndef DR_FLAC_NO_STDIO +drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount) +{ + drflac* pFlac; + + if (sampleRate) { + *sampleRate = 0; + } + if (channels) { + *channels = 0; + } + if (totalPCMFrameCount) { + *totalPCMFrameCount = 0; + } + + pFlac = drflac_open_file(filename); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount); +} + +drflac_int32* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int32* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_file_and_read_pcm_frames_s32(filename, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + +drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount) +{ + drflac* pFlac; + + if (sampleRate) { + *sampleRate = 0; + } + if (channels) { + *channels = 0; + } + if (totalPCMFrameCount) { + *totalPCMFrameCount = 0; + } + + pFlac = drflac_open_file(filename); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount); +} + +drflac_int16* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int16* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_file_and_read_pcm_frames_s16(filename, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + +float* drflac_open_file_and_read_pcm_frames_f32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount) +{ + drflac* pFlac; + + if (sampleRate) { + *sampleRate = 0; + } + if (channels) { + *channels = 0; + } + if (totalPCMFrameCount) { + *totalPCMFrameCount = 0; + } + + pFlac = drflac_open_file(filename); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount); +} + +float* drflac_open_and_decode_file_f32(const char* filename, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + float* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_file_and_read_pcm_frames_f32(filename, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} +#endif + +drflac_int32* drflac_open_memory_and_read_pcm_frames_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount) +{ + drflac* pFlac; + + if (sampleRate) { + *sampleRate = 0; + } + if (channels) { + *channels = 0; + } + if (totalPCMFrameCount) { + *totalPCMFrameCount = 0; + } + + pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_s32(pFlac, channels, sampleRate, totalPCMFrameCount); +} + +drflac_int32* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int32* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_memory_and_read_pcm_frames_s32(data, dataSize, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + +drflac_int16* drflac_open_memory_and_read_pcm_frames_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount) +{ + drflac* pFlac; + + if (sampleRate) { + *sampleRate = 0; + } + if (channels) { + *channels = 0; + } + if (totalPCMFrameCount) { + *totalPCMFrameCount = 0; + } + + pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_s16(pFlac, channels, sampleRate, totalPCMFrameCount); +} + +drflac_int16* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + drflac_int16* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_memory_and_read_pcm_frames_s16(data, dataSize, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + +float* drflac_open_memory_and_read_pcm_frames_f32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount) +{ + drflac* pFlac; + + if (sampleRate) { + *sampleRate = 0; + } + if (channels) { + *channels = 0; + } + if (totalPCMFrameCount) { + *totalPCMFrameCount = 0; + } + + pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_read_and_close_f32(pFlac, channels, sampleRate, totalPCMFrameCount); +} + +float* drflac_open_and_decode_memory_f32(const void* data, size_t dataSize, unsigned int* channelsOut, unsigned int* sampleRateOut, drflac_uint64* totalSampleCountOut) +{ + unsigned int channels; + unsigned int sampleRate; + drflac_uint64 totalPCMFrameCount; + float* pResult; + + if (channelsOut) { + *channelsOut = 0; + } + if (sampleRateOut) { + *sampleRateOut = 0; + } + if (totalSampleCountOut) { + *totalSampleCountOut = 0; + } + + pResult = drflac_open_memory_and_read_pcm_frames_f32(data, dataSize, &channels, &sampleRate, &totalPCMFrameCount); + if (pResult == NULL) { + return NULL; + } + + if (channelsOut) { + *channelsOut = channels; + } + if (sampleRateOut) { + *sampleRateOut = sampleRate; + } + if (totalSampleCountOut) { + *totalSampleCountOut = totalPCMFrameCount * channels; + } + + return pResult; +} + + +void drflac_free(void* pSampleDataReturnedByOpenAndDecode) +{ + DRFLAC_FREE(pSampleDataReturnedByOpenAndDecode); +} + + + + +void drflac_init_vorbis_comment_iterator(drflac_vorbis_comment_iterator* pIter, drflac_uint32 commentCount, const void* pComments) +{ + if (pIter == NULL) { + return; + } + + pIter->countRemaining = commentCount; + pIter->pRunningData = (const char*)pComments; +} + +const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, drflac_uint32* pCommentLengthOut) +{ + drflac_int32 length; + const char* pComment; + + /* Safety. */ + if (pCommentLengthOut) { + *pCommentLengthOut = 0; + } + + if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) { + return NULL; + } + + length = drflac__le2host_32(*(const drflac_uint32*)pIter->pRunningData); + pIter->pRunningData += 4; + + pComment = pIter->pRunningData; + pIter->pRunningData += length; + pIter->countRemaining -= 1; + + if (pCommentLengthOut) { + *pCommentLengthOut = length; + } + + return pComment; +} + + + + +void drflac_init_cuesheet_track_iterator(drflac_cuesheet_track_iterator* pIter, drflac_uint32 trackCount, const void* pTrackData) +{ + if (pIter == NULL) { + return; + } + + pIter->countRemaining = trackCount; + pIter->pRunningData = (const char*)pTrackData; +} + +drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterator* pIter, drflac_cuesheet_track* pCuesheetTrack) +{ + drflac_cuesheet_track cuesheetTrack; + const char* pRunningData; + drflac_uint64 offsetHi; + drflac_uint64 offsetLo; + + if (pIter == NULL || pIter->countRemaining == 0 || pIter->pRunningData == NULL) { + return DRFLAC_FALSE; + } + + pRunningData = pIter->pRunningData; + + offsetHi = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + offsetLo = drflac__be2host_32(*(const drflac_uint32*)pRunningData); pRunningData += 4; + cuesheetTrack.offset = offsetLo | (offsetHi << 32); + cuesheetTrack.trackNumber = pRunningData[0]; pRunningData += 1; + drflac_copy_memory(cuesheetTrack.ISRC, pRunningData, sizeof(cuesheetTrack.ISRC)); pRunningData += 12; + cuesheetTrack.isAudio = (pRunningData[0] & 0x80) != 0; + cuesheetTrack.preEmphasis = (pRunningData[0] & 0x40) != 0; pRunningData += 14; + cuesheetTrack.indexCount = pRunningData[0]; pRunningData += 1; + cuesheetTrack.pIndexPoints = (const drflac_cuesheet_track_index*)pRunningData; pRunningData += cuesheetTrack.indexCount * sizeof(drflac_cuesheet_track_index); + + pIter->pRunningData = pRunningData; + pIter->countRemaining -= 1; + + if (pCuesheetTrack) { + *pCuesheetTrack = cuesheetTrack; + } + + return DRFLAC_TRUE; +} + +#if defined(__GNUC__) + #pragma GCC diagnostic pop +#endif +#endif /* DR_FLAC_IMPLEMENTATION */ + + +/* +REVISION HISTORY +================ +v0.11.9 - 2019-06-16 + - Silence some ThreadSanitizer warnings. + +v0.11.8 - 2019-05-21 + - Fix warnings. + +v0.11.7 - 2019-05-06 + - C89 fixes. + +v0.11.6 - 2019-05-05 + - Add support for C89. + - Fix a compiler warning when CRC is disabled. + - Change license to choice of public domain or MIT-0. + +v0.11.5 - 2019-04-19 + - Fix a compiler error with GCC. + +v0.11.4 - 2019-04-17 + - Fix some warnings with GCC when compiling with -std=c99. + +v0.11.3 - 2019-04-07 + - Silence warnings with GCC. + +v0.11.2 - 2019-03-10 + - Fix a warning. + +v0.11.1 - 2019-02-17 + - Fix a potential bug with seeking. + +v0.11.0 - 2018-12-16 + - API CHANGE: Deprecated drflac_read_s32(), drflac_read_s16() and drflac_read_f32() and replaced them with + drflac_read_pcm_frames_s32(), drflac_read_pcm_frames_s16() and drflac_read_pcm_frames_f32(). The new APIs take + and return PCM frame counts instead of sample counts. To upgrade you will need to change the input count by + dividing it by the channel count, and then do the same with the return value. + - API_CHANGE: Deprecated drflac_seek_to_sample() and replaced with drflac_seek_to_pcm_frame(). Same rules as + the changes to drflac_read_*() apply. + - API CHANGE: Deprecated drflac_open_and_decode_*() and replaced with drflac_open_*_and_read_*(). Same rules as + the changes to drflac_read_*() apply. + - Optimizations. + +v0.10.0 - 2018-09-11 + - Remove the DR_FLAC_NO_WIN32_IO option and the Win32 file IO functionality. If you need to use Win32 file IO you + need to do it yourself via the callback API. + - Fix the clang build. + - Fix undefined behavior. + - Fix errors with CUESHEET metdata blocks. + - Add an API for iterating over each cuesheet track in the CUESHEET metadata block. This works the same way as the + Vorbis comment API. + - Other miscellaneous bug fixes, mostly relating to invalid FLAC streams. + - Minor optimizations. + +v0.9.11 - 2018-08-29 + - Fix a bug with sample reconstruction. + +v0.9.10 - 2018-08-07 + - Improve 64-bit detection. + +v0.9.9 - 2018-08-05 + - Fix C++ build on older versions of GCC. + +v0.9.8 - 2018-07-24 + - Fix compilation errors. + +v0.9.7 - 2018-07-05 + - Fix a warning. + +v0.9.6 - 2018-06-29 + - Fix some typos. + +v0.9.5 - 2018-06-23 + - Fix some warnings. + +v0.9.4 - 2018-06-14 + - Optimizations to seeking. + - Clean up. + +v0.9.3 - 2018-05-22 + - Bug fix. + +v0.9.2 - 2018-05-12 + - Fix a compilation error due to a missing break statement. + +v0.9.1 - 2018-04-29 + - Fix compilation error with Clang. + +v0.9 - 2018-04-24 + - Fix Clang build. + - Start using major.minor.revision versioning. + +v0.8g - 2018-04-19 + - Fix build on non-x86/x64 architectures. + +v0.8f - 2018-02-02 + - Stop pretending to support changing rate/channels mid stream. + +v0.8e - 2018-02-01 + - Fix a crash when the block size of a frame is larger than the maximum block size defined by the FLAC stream. + - Fix a crash the the Rice partition order is invalid. + +v0.8d - 2017-09-22 + - Add support for decoding streams with ID3 tags. ID3 tags are just skipped. + +v0.8c - 2017-09-07 + - Fix warning on non-x86/x64 architectures. + +v0.8b - 2017-08-19 + - Fix build on non-x86/x64 architectures. + +v0.8a - 2017-08-13 + - A small optimization for the Clang build. + +v0.8 - 2017-08-12 + - API CHANGE: Rename dr_* types to drflac_*. + - Optimizations. This brings dr_flac back to about the same class of efficiency as the reference implementation. + - Add support for custom implementations of malloc(), realloc(), etc. + - Add CRC checking to Ogg encapsulated streams. + - Fix VC++ 6 build. This is only for the C++ compiler. The C compiler is not currently supported. + - Bug fixes. + +v0.7 - 2017-07-23 + - Add support for opening a stream without a header block. To do this, use drflac_open_relaxed() / drflac_open_with_metadata_relaxed(). + +v0.6 - 2017-07-22 + - Add support for recovering from invalid frames. With this change, dr_flac will simply skip over invalid frames as if they + never existed. Frames are checked against their sync code, the CRC-8 of the frame header and the CRC-16 of the whole frame. + +v0.5 - 2017-07-16 + - Fix typos. + - Change drflac_bool* types to unsigned. + - Add CRC checking. This makes dr_flac slower, but can be disabled with #define DR_FLAC_NO_CRC. + +v0.4f - 2017-03-10 + - Fix a couple of bugs with the bitstreaming code. + +v0.4e - 2017-02-17 + - Fix some warnings. + +v0.4d - 2016-12-26 + - Add support for 32-bit floating-point PCM decoding. + - Use drflac_int* and drflac_uint* sized types to improve compiler support. + - Minor improvements to documentation. + +v0.4c - 2016-12-26 + - Add support for signed 16-bit integer PCM decoding. + +v0.4b - 2016-10-23 + - A minor change to drflac_bool8 and drflac_bool32 types. + +v0.4a - 2016-10-11 + - Rename drBool32 to drflac_bool32 for styling consistency. + +v0.4 - 2016-09-29 + - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type. + - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32(). + - API CHANGE: Swap the order of "channels" and "sampleRate" parameters in drflac_open_and_decode*(). Rationale for this is to + keep it consistent with drflac_audio. + +v0.3f - 2016-09-21 + - Fix a warning with GCC. + +v0.3e - 2016-09-18 + - Fixed a bug where GCC 4.3+ was not getting properly identified. + - Fixed a few typos. + - Changed date formats to ISO 8601 (YYYY-MM-DD). + +v0.3d - 2016-06-11 + - Minor clean up. + +v0.3c - 2016-05-28 + - Fixed compilation error. + +v0.3b - 2016-05-16 + - Fixed Linux/GCC build. + - Updated documentation. + +v0.3a - 2016-05-15 + - Minor fixes to documentation. + +v0.3 - 2016-05-11 + - Optimizations. Now at about parity with the reference implementation on 32-bit builds. + - Lots of clean up. + +v0.2b - 2016-05-10 + - Bug fixes. + +v0.2a - 2016-05-10 + - Made drflac_open_and_decode() more robust. + - Removed an unused debugging variable + +v0.2 - 2016-05-09 + - Added support for Ogg encapsulation. + - API CHANGE. Have the onSeek callback take a third argument which specifies whether or not the seek + should be relative to the start or the current position. Also changes the seeking rules such that + seeking offsets will never be negative. + - Have drflac_open_and_decode() fail gracefully if the stream has an unknown total sample count. + +v0.1b - 2016-05-07 + - Properly close the file handle in drflac_open_file() and family when the decoder fails to initialize. + - Removed a stale comment. + +v0.1a - 2016-05-05 + - Minor formatting changes. + - Fixed a warning on the GCC build. + +v0.1 - 2016-05-03 + - Initial versioned release. +*/ + +/* +This software is available as a choice of the following licenses. Choose +whichever you prefer. + +=============================================================================== +ALTERNATIVE 1 - Public Domain (www.unlicense.org) +=============================================================================== +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. + +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 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. + +For more information, please refer to + +=============================================================================== +ALTERNATIVE 2 - MIT No Attribution +=============================================================================== +Copyright 2018 David Reid + +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. + +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. +*/ diff -Nru love-11.1/src/libraries/enet/enet.cpp love-11.3/src/libraries/enet/enet.cpp --- love-11.1/src/libraries/enet/enet.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/enet/enet.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -21,8 +21,18 @@ * THE SOFTWARE. */ +#ifdef _WIN32 +#define NOMINMAX +#endif + #include #include +#include +#include + +#include +#include +#include extern "C" { #define LUA_COMPAT_ALL @@ -101,10 +111,50 @@ return peer_index; } +// VS2013 doesn't support alignof +#if defined(_MSC_VER) && _MSC_VER <= 1800 +#define ENET_ALIGNOF(x) __alignof(x) +#else +#define ENET_ALIGNOF(x) alignof(x) +#endif + +// For use with the enet_peers registry. +// Using the pointer directly via lightuserdata would be ideal, but LuaJIT +// cannot use lightuserdata with more than 47 bits whereas some newer arm64 +// architectures allow pointers which use more than that. +static lua_Number compute_peer_key(lua_State *L, ENetPeer *peer) +{ + // ENet peers are be allocated on the heap in an array. Lua numbers + // (doubles) can store all possible integers up to 2^53. We can store + // pointers that use more than 53 bits if their alignment is guaranteed to + // be more than 1. For example an alignment requirement of 8 means we can + // shift the pointer's bits by 3. + const size_t minalign = std::min(ENET_ALIGNOF(ENetPeer), ENET_ALIGNOF(std::max_align_t)); + uintptr_t key = (uintptr_t) peer; + + if ((key & (minalign - 1)) != 0) + { + luaL_error(L, "Cannot push enet peer to Lua: unexpected alignment " + "(pointer is %p but alignment should be %d)", peer, minalign); + } + + static const size_t shift = (size_t) log2((double) minalign); + + key >>= shift; + + // Make sure our key isn't larger than 2^53. + if (key > 0x20000000000000ULL) + luaL_error(L, "Cannot push enet peer to Lua: pointer value %p is too large", peer); + + return (lua_Number) key; +} + static void push_peer(lua_State *l, ENetPeer *peer) { + lua_Number key = compute_peer_key(l, peer); + // try to find in peer table lua_getfield(l, LUA_REGISTRYINDEX, "enet_peers"); - lua_pushlightuserdata(l, peer); + lua_pushnumber(l, key); lua_gettable(l, -2); if (lua_isnil(l, -1)) { @@ -115,7 +165,7 @@ luaL_getmetatable(l, "enet_peer"); lua_setmetatable(l, -2); - lua_pushlightuserdata(l, peer); + lua_pushnumber(l, key); lua_pushvalue(l, -2); lua_settable(l, -4); diff -Nru love-11.1/src/libraries/enet/lua-enet.h love-11.3/src/libraries/enet/lua-enet.h --- love-11.1/src/libraries/enet/lua-enet.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/enet/lua-enet.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** -* Copyright (c) 2006-2018 LOVE Development Team +* Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/libraries/glslang/glslang/Include/arrays.h love-11.3/src/libraries/glslang/glslang/Include/arrays.h --- love-11.1/src/libraries/glslang/glslang/Include/arrays.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/arrays.h 2019-10-27 13:44:49.000000000 +0000 @@ -41,6 +41,8 @@ #ifndef _ARRAYS_INCLUDED #define _ARRAYS_INCLUDED +#include + namespace glslang { // This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else. @@ -130,10 +132,10 @@ sizes->push_back(pair); } - void push_front(const TSmallArrayVector& newDims) + void push_back(const TSmallArrayVector& newDims) { alloc(); - sizes->insert(sizes->begin(), newDims.sizes->begin(), newDims.sizes->end()); + sizes->insert(sizes->end(), newDims.sizes->begin(), newDims.sizes->end()); } void pop_front() @@ -220,12 +222,13 @@ struct TArraySizes { POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - TArraySizes() : implicitArraySize(1) { } + TArraySizes() : implicitArraySize(1), variablyIndexed(false) { } // For breaking into two non-shared copies, independently modifiable. TArraySizes& operator=(const TArraySizes& from) { implicitArraySize = from.implicitArraySize; + variablyIndexed = from.variablyIndexed; sizes = from.sizes; return *this; @@ -251,11 +254,14 @@ void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); } void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); } void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); } - void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); } + void addInnerSize(TArraySize pair) { + sizes.push_back(pair.size, pair.node); + } + void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); } void changeOuterSize(int s) { sizes.changeFront((unsigned)s); } - int getImplicitSize() const { return (int)implicitArraySize; } - void setImplicitSize(int s) { implicitArraySize = s; } - bool isInnerImplicit() const + int getImplicitSize() const { return implicitArraySize; } + void updateImplicitSize(int s) { implicitArraySize = std::max(implicitArraySize, s); } + bool isInnerUnsized() const { for (int d = 1; d < sizes.size(); ++d) { if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize) @@ -264,7 +270,7 @@ return false; } - bool clearInnerImplicit() + bool clearInnerUnsized() { for (int d = 1; d < sizes.size(); ++d) { if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize) @@ -287,8 +293,8 @@ return sizes.getDimNode(0) != nullptr; } - bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); } - void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); } + bool hasUnsized() const { return getOuterSize() == UnsizedArraySize || isInnerUnsized(); } + bool isSized() const { return getOuterSize() != UnsizedArraySize; } void dereference() { sizes.pop_front(); } void copyDereferenced(const TArraySizes& rhs) { @@ -311,17 +317,23 @@ return true; } - bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; } - bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; } + void setVariablyIndexed() { variablyIndexed = true; } + bool isVariablyIndexed() const { return variablyIndexed; } + + bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; } + bool operator!=(const TArraySizes& rhs) const { return sizes != rhs.sizes; } protected: TSmallArrayVector sizes; TArraySizes(const TArraySizes&); - // for tracking maximum referenced index, before an explicit size is given - // applies only to the outer-most dimension + // For tracking maximum referenced compile-time constant index. + // Applies only to the outer-most dimension. Potentially becomes + // the implicit size of the array, if not variably indexed and + // otherwise legal. int implicitArraySize; + bool variablyIndexed; // true if array is indexed with a non compile-time constant }; } // end namespace glslang diff -Nru love-11.1/src/libraries/glslang/glslang/Include/BaseTypes.h love-11.3/src/libraries/glslang/glslang/Include/BaseTypes.h --- love-11.1/src/libraries/glslang/glslang/Include/BaseTypes.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/BaseTypes.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -46,23 +47,27 @@ EbtVoid, EbtFloat, EbtDouble, -#ifdef AMD_EXTENSIONS EbtFloat16, -#endif + EbtInt8, + EbtUint8, + EbtInt16, + EbtUint16, EbtInt, EbtUint, EbtInt64, EbtUint64, -#ifdef AMD_EXTENSIONS - EbtInt16, - EbtUint16, -#endif EbtBool, EbtAtomicUint, EbtSampler, EbtStruct, EbtBlock, +#ifdef NV_EXTENSIONS + EbtAccStructNV, +#endif + + EbtReference, + // HLSL types that live only temporarily. EbtString, @@ -89,6 +94,14 @@ EvqBuffer, // read/write, shared with app EvqShared, // compute shader's read/write 'shared' qualifier +#ifdef NV_EXTENSIONS + EvqPayloadNV, + EvqPayloadInNV, + EvqHitAttrNV, + EvqCallableDataNV, + EvqCallableDataInNV, +#endif + // parameters EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter @@ -141,6 +154,8 @@ EbvLocalInvocationId, EbvGlobalInvocationId, EbvLocalInvocationIndex, + EbvNumSubgroups, + EbvSubgroupID, EbvSubGroupSize, EbvSubGroupInvocation, EbvSubGroupEqMask, @@ -148,6 +163,13 @@ EbvSubGroupGtMask, EbvSubGroupLeMask, EbvSubGroupLtMask, + EbvSubgroupSize2, + EbvSubgroupInvocation2, + EbvSubgroupEqMask2, + EbvSubgroupGeMask2, + EbvSubgroupGtMask2, + EbvSubgroupLeMask2, + EbvSubgroupLtMask2, EbvVertexId, EbvInstanceId, EbvVertexIndex, @@ -212,6 +234,9 @@ EbvViewIndex, EbvDeviceIndex, + EbvFragSizeEXT, + EbvFragInvocationCountEXT, + #ifdef NV_EXTENSIONS EbvViewportMaskNV, EbvSecondaryPositionNV, @@ -219,6 +244,33 @@ EbvPositionPerViewNV, EbvViewportMaskPerViewNV, EbvFragFullyCoveredNV, + EbvFragmentSizeNV, + EbvInvocationsPerPixelNV, + // raytracing + EbvLaunchIdNV, + EbvLaunchSizeNV, + EbvInstanceCustomIndexNV, + EbvWorldRayOriginNV, + EbvWorldRayDirectionNV, + EbvObjectRayOriginNV, + EbvObjectRayDirectionNV, + EbvRayTminNV, + EbvRayTmaxNV, + EbvHitTNV, + EbvHitKindNV, + EbvObjectToWorldNV, + EbvWorldToObjectNV, + EbvIncomingRayFlagsNV, + EbvBaryCoordNV, + EbvBaryCoordNoPerspNV, + EbvTaskCountNV, + EbvPrimitiveCountNV, + EbvPrimitiveIndicesNV, + EbvClipDistancePerViewNV, + EbvCullDistancePerViewNV, + EbvLayerPerViewNV, + EbvMeshViewCountNV, + EbvMeshViewIndicesNV, #endif // HLSL built-ins that live only temporarily, until they get remapped @@ -265,6 +317,13 @@ case EvqPointCoord: return "gl_PointCoord"; break; case EvqFragColor: return "fragColor"; break; case EvqFragDepth: return "gl_FragDepth"; break; +#ifdef NV_EXTENSIONS + case EvqPayloadNV: return "rayPayloadNV"; break; + case EvqPayloadInNV: return "rayPayloadInNV"; break; + case EvqHitAttrNV: return "hitAttributeNV"; break; + case EvqCallableDataNV: return "callableDataNV"; break; + case EvqCallableDataInNV: return "callableDataInNV"; break; +#endif default: return "unknown qualifier"; } } @@ -350,6 +409,9 @@ case EbvViewIndex: return "ViewIndex"; case EbvDeviceIndex: return "DeviceIndex"; + case EbvFragSizeEXT: return "FragSizeEXT"; + case EbvFragInvocationCountEXT: return "FragInvocationCountEXT"; + #ifdef NV_EXTENSIONS case EbvViewportMaskNV: return "ViewportMaskNV"; case EbvSecondaryPositionNV: return "SecondaryPositionNV"; @@ -357,6 +419,33 @@ case EbvPositionPerViewNV: return "PositionPerViewNV"; case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; case EbvFragFullyCoveredNV: return "FragFullyCoveredNV"; + case EbvFragmentSizeNV: return "FragmentSizeNV"; + case EbvInvocationsPerPixelNV: return "InvocationsPerPixelNV"; + case EbvLaunchIdNV: return "LaunchIdNV"; + case EbvLaunchSizeNV: return "LaunchSizeNV"; + case EbvInstanceCustomIndexNV: return "InstanceCustomIndexNV"; + case EbvWorldRayOriginNV: return "WorldRayOriginNV"; + case EbvWorldRayDirectionNV: return "WorldRayDirectionNV"; + case EbvObjectRayOriginNV: return "ObjectRayOriginNV"; + case EbvObjectRayDirectionNV: return "ObjectRayDirectionNV"; + case EbvRayTminNV: return "ObjectRayTminNV"; + case EbvRayTmaxNV: return "ObjectRayTmaxNV"; + case EbvHitTNV: return "HitTNV"; + case EbvHitKindNV: return "HitKindNV"; + case EbvIncomingRayFlagsNV: return "IncomingRayFlagsNV"; + case EbvObjectToWorldNV: return "ObjectToWorldNV"; + case EbvWorldToObjectNV: return "WorldToObjectNV"; + + case EbvBaryCoordNV: return "BaryCoordNV"; + case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; + case EbvTaskCountNV: return "TaskCountNV"; + case EbvPrimitiveCountNV: return "PrimitiveCountNV"; + case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case EbvClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case EbvCullDistancePerViewNV: return "CullDistancePerViewNV"; + case EbvLayerPerViewNV: return "LayerPerViewNV"; + case EbvMeshViewCountNV: return "MeshViewCountNV"; + case EbvMeshViewIndicesNV: return "MeshViewIndicesNV"; #endif default: return "unknown built-in variable"; } @@ -373,7 +462,7 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { - switch(p) { + switch (p) { case EpqNone: return ""; break; case EpqLow: return "lowp"; break; case EpqMedium: return "mediump"; break; @@ -382,6 +471,75 @@ } } +__inline bool isTypeSignedInt(TBasicType type) +{ + switch (type) { + case EbtInt8: + case EbtInt16: + case EbtInt: + case EbtInt64: + return true; + default: + return false; + } +} + +__inline bool isTypeUnsignedInt(TBasicType type) +{ + switch (type) { + case EbtUint8: + case EbtUint16: + case EbtUint: + case EbtUint64: + return true; + default: + return false; + } +} + +__inline bool isTypeInt(TBasicType type) +{ + return isTypeSignedInt(type) || isTypeUnsignedInt(type); +} + +__inline bool isTypeFloat(TBasicType type) +{ + switch (type) { + case EbtFloat: + case EbtDouble: + case EbtFloat16: + return true; + default: + return false; + } +} + +__inline int getTypeRank(TBasicType type) { + int res = -1; + switch(type) { + case EbtInt8: + case EbtUint8: + res = 0; + break; + case EbtInt16: + case EbtUint16: + res = 1; + break; + case EbtInt: + case EbtUint: + res = 2; + break; + case EbtInt64: + case EbtUint64: + res = 3; + break; + default: + assert(false); + break; + } + return res; +} + } // end namespace glslang #endif // _BASICTYPES_INCLUDED_ diff -Nru love-11.1/src/libraries/glslang/glslang/Include/Common.h love-11.3/src/libraries/glslang/glslang/Include/Common.h --- love-11.1/src/libraries/glslang/glslang/Include/Common.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/Common.h 2019-10-27 13:44:49.000000000 +0000 @@ -37,9 +37,24 @@ #ifndef _COMMON_INCLUDED_ #define _COMMON_INCLUDED_ + +#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700) +#include +namespace std { +template +std::string to_string(const T& val) { + std::ostringstream os; + os << val; + return os.str(); +} +} +#endif + #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API #include + #ifndef snprintf #define snprintf sprintf_s + #endif #define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args)) #elif defined (solaris) #define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args)) @@ -51,31 +66,20 @@ #define UINT_PTR uintptr_t #endif -#if defined(__ANDROID__) || _MSC_VER < 1700 -#include -namespace std { -template -std::string to_string(const T& val) { - std::ostringstream os; - os << val; - return os.str(); -} -} -#endif - #if defined(_MSC_VER) && _MSC_VER < 1800 -inline long long int strtoll (const char* str, char** endptr, int base) -{ - return _strtoi64(str, endptr, base); -} -inline unsigned long long int strtoull (const char* str, char** endptr, int base) -{ - return _strtoui64(str, endptr, base); -} -inline long long int atoll (const char* str) -{ - return strtoll(str, NULL, 10); -} + #include + inline long long int strtoll (const char* str, char** endptr, int base) + { + return _strtoi64(str, endptr, base); + } + inline unsigned long long int strtoull (const char* str, char** endptr, int base) + { + return _strtoui64(str, endptr, base); + } + inline long long int atoll (const char* str) + { + return strtoll(str, NULL, 10); + } #endif #if defined(_MSC_VER) @@ -98,6 +102,7 @@ #include #include #include +#include #include #include "PoolAlloc.h" @@ -155,7 +160,7 @@ return new(memory) TString(s); } -template inline T* NewPoolObject(T) +template inline T* NewPoolObject(T*) { return new(GetThreadPoolAllocator().allocate(sizeof(T))) T; } @@ -225,16 +230,29 @@ #endif struct TSourceLoc { - void init() { name = nullptr; string = 0; line = 0; column = 0; } + void init() + { + name = nullptr; string = 0; line = 0; column = 0; + } void init(int stringNum) { init(); string = stringNum; } // Returns the name if it exists. Otherwise, returns the string number. std::string getStringNameOrNum(bool quoteStringName = true) const { - if (name != nullptr) - return quoteStringName ? ("\"" + std::string(name) + "\"") : name; + if (name != nullptr) { + TString qstr = quoteStringName ? ("\"" + *name + "\"") : *name; + std::string ret_str(qstr.c_str()); + return ret_str; + } return std::to_string((long long)string); } - const char* name; // descriptive name for this string + const char* getFilename() const + { + if (name == nullptr) + return nullptr; + return name->c_str(); + } + const char* getFilenameStr() const { return name == nullptr ? "" : name->c_str(); } + TString* name; // descriptive name for this string, when a textual name is available, otherwise nullptr int string; int line; int column; diff -Nru love-11.1/src/libraries/glslang/glslang/Include/ConstantUnion.h love-11.3/src/libraries/glslang/glslang/Include/ConstantUnion.h --- love-11.1/src/libraries/glslang/glslang/Include/ConstantUnion.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/ConstantUnion.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -37,6 +38,9 @@ #ifndef _CONSTANT_UNION_INCLUDED_ #define _CONSTANT_UNION_INCLUDED_ +#include "../Include/Common.h" +#include "../Include/BaseTypes.h" + namespace glslang { class TConstUnion { @@ -45,6 +49,30 @@ TConstUnion() : iConst(0), type(EbtInt) { } + void setI8Const(signed char i) + { + i8Const = i; + type = EbtInt8; + } + + void setU8Const(unsigned char u) + { + u8Const = u; + type = EbtUint8; + } + + void setI16Const(signed short i) + { + i16Const = i; + type = EbtInt16; + } + + void setU16Const(unsigned short u) + { + u16Const = u; + type = EbtUint16; + } + void setIConst(int i) { iConst = i; @@ -87,6 +115,10 @@ type = EbtString; } + signed char getI8Const() const { return i8Const; } + unsigned char getU8Const() const { return u8Const; } + signed short getI16Const() const { return i16Const; } + unsigned short getU16Const() const { return u16Const; } int getIConst() const { return iConst; } unsigned int getUConst() const { return uConst; } long long getI64Const() const { return i64Const; } @@ -95,6 +127,38 @@ bool getBConst() const { return bConst; } const TString* getSConst() const { return sConst; } + bool operator==(const signed char i) const + { + if (i == i8Const) + return true; + + return false; + } + + bool operator==(const unsigned char u) const + { + if (u == u8Const) + return true; + + return false; + } + + bool operator==(const signed short i) const + { + if (i == i16Const) + return true; + + return false; + } + + bool operator==(const unsigned short u) const + { + if (u == u16Const) + return true; + + return false; + } + bool operator==(const int i) const { if (i == iConst) @@ -149,6 +213,26 @@ return false; switch (type) { + case EbtInt16: + if (constant.i16Const == i16Const) + return true; + + break; + case EbtUint16: + if (constant.u16Const == u16Const) + return true; + + break; + case EbtInt8: + if (constant.i8Const == i8Const) + return true; + + break; + case EbtUint8: + if (constant.u8Const == u8Const) + return true; + + break; case EbtInt: if (constant.iConst == iConst) return true; @@ -186,6 +270,26 @@ return false; } + bool operator!=(const signed char i) const + { + return !operator==(i); + } + + bool operator!=(const unsigned char u) const + { + return !operator==(u); + } + + bool operator!=(const signed short i) const + { + return !operator==(i); + } + + bool operator!=(const unsigned short u) const + { + return !operator==(u); + } + bool operator!=(const int i) const { return !operator==(i); @@ -225,6 +329,26 @@ { assert(type == constant.type); switch (type) { + case EbtInt8: + if (i8Const > constant.i8Const) + return true; + + return false; + case EbtUint8: + if (u8Const > constant.u8Const) + return true; + + return false; + case EbtInt16: + if (i16Const > constant.i16Const) + return true; + + return false; + case EbtUint16: + if (u16Const > constant.u16Const) + return true; + + return false; case EbtInt: if (iConst > constant.iConst) return true; @@ -260,6 +384,26 @@ { assert(type == constant.type); switch (type) { + case EbtInt8: + if (i8Const < constant.i8Const) + return true; + + return false; + case EbtUint8: + if (u8Const < constant.u8Const) + return true; + + return false; + case EbtInt16: + if (i16Const < constant.i16Const) + return true; + + return false; + case EbtUint16: + if (u16Const < constant.u16Const) + return true; + + return false; case EbtInt: if (iConst < constant.iConst) return true; @@ -296,9 +440,13 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; - case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; - case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break; + case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; + case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break; + case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break; + case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break; case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; default: assert(false && "Default missing"); @@ -312,9 +460,13 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; - case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; - case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break; + case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; + case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break; + case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break; + case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break; case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; default: assert(false && "Default missing"); @@ -328,9 +480,13 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; - case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; - case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break; + case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; + case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break; + case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break; + case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; default: assert(false && "Default missing"); @@ -344,9 +500,13 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; - case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; - case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break; + case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break; + case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; + case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; + case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break; + case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break; + case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break; default: assert(false && "Default missing"); } @@ -358,8 +518,64 @@ { TConstUnion returnValue; switch (type) { + case EbtInt8: + switch (constant.type) { + case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break; + case EbtUint8: returnValue.setI8Const(i8Const >> constant.u8Const); break; + case EbtInt16: returnValue.setI8Const(i8Const >> constant.i16Const); break; + case EbtUint16: returnValue.setI8Const(i8Const >> constant.u16Const); break; + case EbtInt: returnValue.setI8Const(i8Const >> constant.iConst); break; + case EbtUint: returnValue.setI8Const(i8Const >> constant.uConst); break; + case EbtInt64: returnValue.setI8Const(i8Const >> constant.i64Const); break; + case EbtUint64: returnValue.setI8Const(i8Const >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint8: + switch (constant.type) { + case EbtInt8: returnValue.setU8Const(u8Const >> constant.i8Const); break; + case EbtUint8: returnValue.setU8Const(u8Const >> constant.u8Const); break; + case EbtInt16: returnValue.setU8Const(u8Const >> constant.i16Const); break; + case EbtUint16: returnValue.setU8Const(u8Const >> constant.u16Const); break; + case EbtInt: returnValue.setU8Const(u8Const >> constant.iConst); break; + case EbtUint: returnValue.setU8Const(u8Const >> constant.uConst); break; + case EbtInt64: returnValue.setU8Const(u8Const >> constant.i64Const); break; + case EbtUint64: returnValue.setU8Const(u8Const >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtInt16: + switch (constant.type) { + case EbtInt8: returnValue.setI16Const(i16Const >> constant.i8Const); break; + case EbtUint8: returnValue.setI16Const(i16Const >> constant.u8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const >> constant.i16Const); break; + case EbtUint16: returnValue.setI16Const(i16Const >> constant.u16Const); break; + case EbtInt: returnValue.setI16Const(i16Const >> constant.iConst); break; + case EbtUint: returnValue.setI16Const(i16Const >> constant.uConst); break; + case EbtInt64: returnValue.setI16Const(i16Const >> constant.i64Const); break; + case EbtUint64: returnValue.setI16Const(i16Const >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint16: + switch (constant.type) { + case EbtInt8: returnValue.setU16Const(u16Const >> constant.i8Const); break; + case EbtUint8: returnValue.setU16Const(u16Const >> constant.u8Const); break; + case EbtInt16: returnValue.setU16Const(u16Const >> constant.i16Const); break; + case EbtUint16: returnValue.setU16Const(u16Const >> constant.u16Const); break; + case EbtInt: returnValue.setU16Const(u16Const >> constant.iConst); break; + case EbtUint: returnValue.setU16Const(u16Const >> constant.uConst); break; + case EbtInt64: returnValue.setU16Const(u16Const >> constant.i64Const); break; + case EbtUint64: returnValue.setU16Const(u16Const >> constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; case EbtInt: switch (constant.type) { + case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break; + case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break; + case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break; + case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break; case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break; @@ -369,6 +585,10 @@ break; case EbtUint: switch (constant.type) { + case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break; + case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break; + case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break; + case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break; case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break; @@ -378,6 +598,10 @@ break; case EbtInt64: switch (constant.type) { + case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break; + case EbtUint8: returnValue.setI64Const(i64Const >> constant.u8Const); break; + case EbtInt16: returnValue.setI64Const(i64Const >> constant.i16Const); break; + case EbtUint16: returnValue.setI64Const(i64Const >> constant.u16Const); break; case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break; case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break; @@ -387,6 +611,10 @@ break; case EbtUint64: switch (constant.type) { + case EbtInt8: returnValue.setU64Const(u64Const >> constant.i8Const); break; + case EbtUint8: returnValue.setU64Const(u64Const >> constant.u8Const); break; + case EbtInt16: returnValue.setU64Const(u64Const >> constant.i16Const); break; + case EbtUint16: returnValue.setU64Const(u64Const >> constant.u16Const); break; case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break; case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break; case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break; @@ -404,8 +632,64 @@ { TConstUnion returnValue; switch (type) { + case EbtInt8: + switch (constant.type) { + case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break; + case EbtUint8: returnValue.setI8Const(i8Const << constant.u8Const); break; + case EbtInt16: returnValue.setI8Const(i8Const << constant.i16Const); break; + case EbtUint16: returnValue.setI8Const(i8Const << constant.u16Const); break; + case EbtInt: returnValue.setI8Const(i8Const << constant.iConst); break; + case EbtUint: returnValue.setI8Const(i8Const << constant.uConst); break; + case EbtInt64: returnValue.setI8Const(i8Const << constant.i64Const); break; + case EbtUint64: returnValue.setI8Const(i8Const << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint8: + switch (constant.type) { + case EbtInt8: returnValue.setU8Const(u8Const << constant.i8Const); break; + case EbtUint8: returnValue.setU8Const(u8Const << constant.u8Const); break; + case EbtInt16: returnValue.setU8Const(u8Const << constant.i16Const); break; + case EbtUint16: returnValue.setU8Const(u8Const << constant.u16Const); break; + case EbtInt: returnValue.setU8Const(u8Const << constant.iConst); break; + case EbtUint: returnValue.setU8Const(u8Const << constant.uConst); break; + case EbtInt64: returnValue.setU8Const(u8Const << constant.i64Const); break; + case EbtUint64: returnValue.setU8Const(u8Const << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtInt16: + switch (constant.type) { + case EbtInt8: returnValue.setI16Const(i16Const << constant.i8Const); break; + case EbtUint8: returnValue.setI16Const(i16Const << constant.u8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const << constant.i16Const); break; + case EbtUint16: returnValue.setI16Const(i16Const << constant.u16Const); break; + case EbtInt: returnValue.setI16Const(i16Const << constant.iConst); break; + case EbtUint: returnValue.setI16Const(i16Const << constant.uConst); break; + case EbtInt64: returnValue.setI16Const(i16Const << constant.i64Const); break; + case EbtUint64: returnValue.setI16Const(i16Const << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; + case EbtUint16: + switch (constant.type) { + case EbtInt8: returnValue.setU16Const(u16Const << constant.i8Const); break; + case EbtUint8: returnValue.setU16Const(u16Const << constant.u8Const); break; + case EbtInt16: returnValue.setU16Const(u16Const << constant.i16Const); break; + case EbtUint16: returnValue.setU16Const(u16Const << constant.u16Const); break; + case EbtInt: returnValue.setU16Const(u16Const << constant.iConst); break; + case EbtUint: returnValue.setU16Const(u16Const << constant.uConst); break; + case EbtInt64: returnValue.setU16Const(u16Const << constant.i64Const); break; + case EbtUint64: returnValue.setU16Const(u16Const << constant.u64Const); break; + default: assert(false && "Default missing"); + } + break; case EbtInt: switch (constant.type) { + case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break; + case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break; + case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break; + case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break; case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; @@ -415,6 +699,10 @@ break; case EbtUint: switch (constant.type) { + case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break; + case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break; + case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break; + case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break; case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; @@ -422,8 +710,12 @@ default: assert(false && "Default missing"); } break; - case EbtInt64: + case EbtInt64: switch (constant.type) { + case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break; + case EbtUint8: returnValue.setI64Const(i64Const << constant.u8Const); break; + case EbtInt16: returnValue.setI64Const(i64Const << constant.i16Const); break; + case EbtUint16: returnValue.setI64Const(i64Const << constant.u16Const); break; case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break; case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break; @@ -433,6 +725,10 @@ break; case EbtUint64: switch (constant.type) { + case EbtInt8: returnValue.setU64Const(u64Const << constant.i8Const); break; + case EbtUint8: returnValue.setU64Const(u64Const << constant.u8Const); break; + case EbtInt16: returnValue.setU64Const(u64Const << constant.i16Const); break; + case EbtUint16: returnValue.setU64Const(u64Const << constant.u16Const); break; case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break; case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break; case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break; @@ -451,8 +747,12 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break; + case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break; + case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break; + case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break; default: assert(false && "Default missing"); @@ -466,8 +766,12 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break; + case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break; + case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break; + case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break; default: assert(false && "Default missing"); @@ -481,8 +785,12 @@ TConstUnion returnValue; assert(type == constant.type); switch (type) { - case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; - case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; + case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break; + case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break; + case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break; + case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break; + case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break; default: assert(false && "Default missing"); @@ -495,8 +803,12 @@ { TConstUnion returnValue; switch (type) { - case EbtInt: returnValue.setIConst(~iConst); break; - case EbtUint: returnValue.setUConst(~uConst); break; + case EbtInt8: returnValue.setI8Const(~i8Const); break; + case EbtUint8: returnValue.setU8Const(~u8Const); break; + case EbtInt16: returnValue.setI16Const(~i16Const); break; + case EbtUint16: returnValue.setU16Const(~u16Const); break; + case EbtInt: returnValue.setIConst(~iConst); break; + case EbtUint: returnValue.setUConst(~uConst); break; case EbtInt64: returnValue.setI64Const(~i64Const); break; case EbtUint64: returnValue.setU64Const(~u64Const); break; default: assert(false && "Default missing"); @@ -533,6 +845,10 @@ private: union { + signed char i8Const; // used for i8vec, scalar int8s + unsigned char u8Const; // used for u8vec, scalar uint8s + signed short i16Const; // used for i16vec, scalar int16s + unsigned short u16Const; // used for u16vec, scalar uint16s int iConst; // used for ivec, scalar ints unsigned int uConst; // used for uvec, scalar uints long long i64Const; // used for i64vec, scalar int64s @@ -594,9 +910,6 @@ if (! unionArray || ! rhs.unionArray) return false; - - if (! unionArray || ! rhs.unionArray) - return false; return *unionArray == *rhs.unionArray; } diff -Nru love-11.1/src/libraries/glslang/glslang/Include/intermediate.h love-11.3/src/libraries/glslang/glslang/Include/intermediate.h --- love-11.1/src/libraries/glslang/glslang/Include/intermediate.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/intermediate.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -46,7 +47,7 @@ #ifndef __INTERMEDIATE_H #define __INTERMEDIATE_H -#if _MSC_VER >= 1900 +#if defined(_MSC_VER) && _MSC_VER >= 1900 #pragma warning(disable : 4464) // relative include path contains '..' #pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted #endif @@ -84,100 +85,195 @@ EOpPreIncrement, EOpPreDecrement, + EOpCopyObject, + + // (u)int* -> bool + EOpConvInt8ToBool, + EOpConvUint8ToBool, + EOpConvInt16ToBool, + EOpConvUint16ToBool, EOpConvIntToBool, EOpConvUintToBool, - EOpConvFloatToBool, - EOpConvDoubleToBool, EOpConvInt64ToBool, EOpConvUint64ToBool, - EOpConvBoolToFloat, - EOpConvIntToFloat, - EOpConvUintToFloat, - EOpConvDoubleToFloat, - EOpConvInt64ToFloat, - EOpConvUint64ToFloat, - EOpConvUintToInt, - EOpConvFloatToInt, + + // float* -> bool + EOpConvFloat16ToBool, + EOpConvFloatToBool, + EOpConvDoubleToBool, + + // bool -> (u)int* + EOpConvBoolToInt8, + EOpConvBoolToUint8, + EOpConvBoolToInt16, + EOpConvBoolToUint16, EOpConvBoolToInt, - EOpConvDoubleToInt, - EOpConvInt64ToInt, - EOpConvUint64ToInt, - EOpConvIntToUint, - EOpConvFloatToUint, EOpConvBoolToUint, - EOpConvDoubleToUint, - EOpConvInt64ToUint, - EOpConvUint64ToUint, - EOpConvIntToDouble, - EOpConvUintToDouble, - EOpConvFloatToDouble, - EOpConvBoolToDouble, - EOpConvInt64ToDouble, - EOpConvUint64ToDouble, EOpConvBoolToInt64, - EOpConvIntToInt64, - EOpConvUintToInt64, - EOpConvFloatToInt64, - EOpConvDoubleToInt64, - EOpConvUint64ToInt64, EOpConvBoolToUint64, + + // bool -> float* + EOpConvBoolToFloat16, + EOpConvBoolToFloat, + EOpConvBoolToDouble, + + // int8_t -> (u)int* + EOpConvInt8ToInt16, + EOpConvInt8ToInt, + EOpConvInt8ToInt64, + EOpConvInt8ToUint8, + EOpConvInt8ToUint16, + EOpConvInt8ToUint, + EOpConvInt8ToUint64, + + // uint8_t -> (u)int* + EOpConvUint8ToInt8, + EOpConvUint8ToInt16, + EOpConvUint8ToInt, + EOpConvUint8ToInt64, + EOpConvUint8ToUint16, + EOpConvUint8ToUint, + EOpConvUint8ToUint64, + + // int8_t -> float* + EOpConvInt8ToFloat16, + EOpConvInt8ToFloat, + EOpConvInt8ToDouble, + + // uint8_t -> float* + EOpConvUint8ToFloat16, + EOpConvUint8ToFloat, + EOpConvUint8ToDouble, + + // int16_t -> (u)int* + EOpConvInt16ToInt8, + EOpConvInt16ToInt, + EOpConvInt16ToInt64, + EOpConvInt16ToUint8, + EOpConvInt16ToUint16, + EOpConvInt16ToUint, + EOpConvInt16ToUint64, + + // uint16_t -> (u)int* + EOpConvUint16ToInt8, + EOpConvUint16ToInt16, + EOpConvUint16ToInt, + EOpConvUint16ToInt64, + EOpConvUint16ToUint8, + EOpConvUint16ToUint, + EOpConvUint16ToUint64, + + // int16_t -> float* + EOpConvInt16ToFloat16, + EOpConvInt16ToFloat, + EOpConvInt16ToDouble, + + // uint16_t -> float* + EOpConvUint16ToFloat16, + EOpConvUint16ToFloat, + EOpConvUint16ToDouble, + + // int32_t -> (u)int* + EOpConvIntToInt8, + EOpConvIntToInt16, + EOpConvIntToInt64, + EOpConvIntToUint8, + EOpConvIntToUint16, + EOpConvIntToUint, EOpConvIntToUint64, + + // uint32_t -> (u)int* + EOpConvUintToInt8, + EOpConvUintToInt16, + EOpConvUintToInt, + EOpConvUintToInt64, + EOpConvUintToUint8, + EOpConvUintToUint16, EOpConvUintToUint64, - EOpConvFloatToUint64, - EOpConvDoubleToUint64, - EOpConvInt64ToUint64, -#ifdef AMD_EXTENSIONS - EOpConvBoolToFloat16, + + // int32_t -> float* EOpConvIntToFloat16, + EOpConvIntToFloat, + EOpConvIntToDouble, + + // uint32_t -> float* EOpConvUintToFloat16, - EOpConvFloatToFloat16, - EOpConvDoubleToFloat16, + EOpConvUintToFloat, + EOpConvUintToDouble, + + // int64_t -> (u)int* + EOpConvInt64ToInt8, + EOpConvInt64ToInt16, + EOpConvInt64ToInt, + EOpConvInt64ToUint8, + EOpConvInt64ToUint16, + EOpConvInt64ToUint, + EOpConvInt64ToUint64, + + // uint64_t -> (u)int* + EOpConvUint64ToInt8, + EOpConvUint64ToInt16, + EOpConvUint64ToInt, + EOpConvUint64ToInt64, + EOpConvUint64ToUint8, + EOpConvUint64ToUint16, + EOpConvUint64ToUint, + + // int64_t -> float* EOpConvInt64ToFloat16, + EOpConvInt64ToFloat, + EOpConvInt64ToDouble, + + // uint64_t -> float* EOpConvUint64ToFloat16, - EOpConvFloat16ToBool, + EOpConvUint64ToFloat, + EOpConvUint64ToDouble, + + // float16_t -> (u)int* + EOpConvFloat16ToInt8, + EOpConvFloat16ToInt16, EOpConvFloat16ToInt, + EOpConvFloat16ToInt64, + EOpConvFloat16ToUint8, + EOpConvFloat16ToUint16, EOpConvFloat16ToUint, + EOpConvFloat16ToUint64, + + // float16_t -> float* EOpConvFloat16ToFloat, EOpConvFloat16ToDouble, - EOpConvFloat16ToInt64, - EOpConvFloat16ToUint64, - EOpConvBoolToInt16, - EOpConvIntToInt16, - EOpConvUintToInt16, + // float -> (u)int* + EOpConvFloatToInt8, EOpConvFloatToInt16, - EOpConvDoubleToInt16, - EOpConvFloat16ToInt16, - EOpConvInt64ToInt16, - EOpConvUint64ToInt16, - EOpConvUint16ToInt16, - EOpConvInt16ToBool, - EOpConvInt16ToInt, - EOpConvInt16ToUint, - EOpConvInt16ToFloat, - EOpConvInt16ToDouble, - EOpConvInt16ToFloat16, - EOpConvInt16ToInt64, - EOpConvInt16ToUint64, - - EOpConvBoolToUint16, - EOpConvIntToUint16, - EOpConvUintToUint16, + EOpConvFloatToInt, + EOpConvFloatToInt64, + EOpConvFloatToUint8, EOpConvFloatToUint16, + EOpConvFloatToUint, + EOpConvFloatToUint64, + + // float -> float* + EOpConvFloatToFloat16, + EOpConvFloatToDouble, + + // float64 _t-> (u)int* + EOpConvDoubleToInt8, + EOpConvDoubleToInt16, + EOpConvDoubleToInt, + EOpConvDoubleToInt64, + EOpConvDoubleToUint8, EOpConvDoubleToUint16, - EOpConvFloat16ToUint16, - EOpConvInt64ToUint16, - EOpConvUint64ToUint16, - EOpConvInt16ToUint16, - EOpConvUint16ToBool, - EOpConvUint16ToInt, - EOpConvUint16ToUint, - EOpConvUint16ToFloat, - EOpConvUint16ToDouble, - EOpConvUint16ToFloat16, - EOpConvUint16ToInt64, - EOpConvUint16ToUint64, -#endif + EOpConvDoubleToUint, + EOpConvDoubleToUint64, + + // float64_t -> float* + EOpConvDoubleToFloat16, + EOpConvDoubleToFloat, + + // uint64_t <-> pointer + EOpConvUint64ToPtr, + EOpConvPtrToUint64, // // binary operations @@ -280,12 +376,10 @@ EOpDoubleBitsToUint64, EOpInt64BitsToDouble, EOpUint64BitsToDouble, -#ifdef AMD_EXTENSIONS EOpFloat16BitsToInt16, EOpFloat16BitsToUint16, EOpInt16BitsToFloat16, EOpUint16BitsToFloat16, -#endif EOpPackSnorm2x16, EOpUnpackSnorm2x16, EOpPackUnorm2x16, @@ -302,7 +396,6 @@ EOpUnpackInt2x32, EOpPackUint2x32, EOpUnpackUint2x32, -#ifdef AMD_EXTENSIONS EOpPackFloat2x16, EOpUnpackFloat2x16, EOpPackInt2x16, @@ -313,7 +406,12 @@ EOpUnpackInt4x16, EOpPackUint4x16, EOpUnpackUint4x16, -#endif + EOpPack16, + EOpPack32, + EOpPack64, + EOpUnpack32, + EOpUnpack16, + EOpUnpack8, EOpLength, EOpDistance, @@ -379,6 +477,90 @@ EOpAllInvocations, EOpAllInvocationsEqual, + EOpSubgroupGuardStart, + EOpSubgroupBarrier, + EOpSubgroupMemoryBarrier, + EOpSubgroupMemoryBarrierBuffer, + EOpSubgroupMemoryBarrierImage, + EOpSubgroupMemoryBarrierShared, // compute only + EOpSubgroupElect, + EOpSubgroupAll, + EOpSubgroupAny, + EOpSubgroupAllEqual, + EOpSubgroupBroadcast, + EOpSubgroupBroadcastFirst, + EOpSubgroupBallot, + EOpSubgroupInverseBallot, + EOpSubgroupBallotBitExtract, + EOpSubgroupBallotBitCount, + EOpSubgroupBallotInclusiveBitCount, + EOpSubgroupBallotExclusiveBitCount, + EOpSubgroupBallotFindLSB, + EOpSubgroupBallotFindMSB, + EOpSubgroupShuffle, + EOpSubgroupShuffleXor, + EOpSubgroupShuffleUp, + EOpSubgroupShuffleDown, + EOpSubgroupAdd, + EOpSubgroupMul, + EOpSubgroupMin, + EOpSubgroupMax, + EOpSubgroupAnd, + EOpSubgroupOr, + EOpSubgroupXor, + EOpSubgroupInclusiveAdd, + EOpSubgroupInclusiveMul, + EOpSubgroupInclusiveMin, + EOpSubgroupInclusiveMax, + EOpSubgroupInclusiveAnd, + EOpSubgroupInclusiveOr, + EOpSubgroupInclusiveXor, + EOpSubgroupExclusiveAdd, + EOpSubgroupExclusiveMul, + EOpSubgroupExclusiveMin, + EOpSubgroupExclusiveMax, + EOpSubgroupExclusiveAnd, + EOpSubgroupExclusiveOr, + EOpSubgroupExclusiveXor, + EOpSubgroupClusteredAdd, + EOpSubgroupClusteredMul, + EOpSubgroupClusteredMin, + EOpSubgroupClusteredMax, + EOpSubgroupClusteredAnd, + EOpSubgroupClusteredOr, + EOpSubgroupClusteredXor, + EOpSubgroupQuadBroadcast, + EOpSubgroupQuadSwapHorizontal, + EOpSubgroupQuadSwapVertical, + EOpSubgroupQuadSwapDiagonal, + +#ifdef NV_EXTENSIONS + EOpSubgroupPartition, + EOpSubgroupPartitionedAdd, + EOpSubgroupPartitionedMul, + EOpSubgroupPartitionedMin, + EOpSubgroupPartitionedMax, + EOpSubgroupPartitionedAnd, + EOpSubgroupPartitionedOr, + EOpSubgroupPartitionedXor, + EOpSubgroupPartitionedInclusiveAdd, + EOpSubgroupPartitionedInclusiveMul, + EOpSubgroupPartitionedInclusiveMin, + EOpSubgroupPartitionedInclusiveMax, + EOpSubgroupPartitionedInclusiveAnd, + EOpSubgroupPartitionedInclusiveOr, + EOpSubgroupPartitionedInclusiveXor, + EOpSubgroupPartitionedExclusiveAdd, + EOpSubgroupPartitionedExclusiveMul, + EOpSubgroupPartitionedExclusiveMin, + EOpSubgroupPartitionedExclusiveMax, + EOpSubgroupPartitionedExclusiveAnd, + EOpSubgroupPartitionedExclusiveOr, + EOpSubgroupPartitionedExclusiveXor, +#endif + + EOpSubgroupGuardStop, + #ifdef AMD_EXTENSIONS EOpMinInvocations, EOpMaxInvocations, @@ -416,6 +598,8 @@ EOpAtomicXor, EOpAtomicExchange, EOpAtomicCompSwap, + EOpAtomicLoad, + EOpAtomicStore, EOpAtomicCounterIncrement, // results in pre-increment value EOpAtomicCounterDecrement, // results in post-decrement value @@ -433,6 +617,10 @@ EOpAny, EOpAll, + EOpCooperativeMatrixLoad, + EOpCooperativeMatrixStore, + EOpCooperativeMatrixMulAdd, + // // Branch // @@ -451,32 +639,36 @@ EOpConstructGuardStart, EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed EOpConstructUint, - EOpConstructInt64, - EOpConstructUint64, -#ifdef AMD_EXTENSIONS + EOpConstructInt8, + EOpConstructUint8, EOpConstructInt16, EOpConstructUint16, -#endif + EOpConstructInt64, + EOpConstructUint64, EOpConstructBool, EOpConstructFloat, EOpConstructDouble, -#ifdef AMD_EXTENSIONS - EOpConstructFloat16, -#endif EOpConstructVec2, EOpConstructVec3, EOpConstructVec4, EOpConstructDVec2, EOpConstructDVec3, EOpConstructDVec4, -#ifdef AMD_EXTENSIONS - EOpConstructF16Vec2, - EOpConstructF16Vec3, - EOpConstructF16Vec4, -#endif EOpConstructBVec2, EOpConstructBVec3, EOpConstructBVec4, + EOpConstructI8Vec2, + EOpConstructI8Vec3, + EOpConstructI8Vec4, + EOpConstructU8Vec2, + EOpConstructU8Vec3, + EOpConstructU8Vec4, + EOpConstructI16Vec2, + EOpConstructI16Vec3, + EOpConstructI16Vec4, + EOpConstructU16Vec2, + EOpConstructU16Vec3, + EOpConstructU16Vec4, EOpConstructIVec2, EOpConstructIVec3, EOpConstructIVec4, @@ -489,14 +681,6 @@ EOpConstructU64Vec2, EOpConstructU64Vec3, EOpConstructU64Vec4, -#ifdef AMD_EXTENSIONS - EOpConstructI16Vec2, - EOpConstructI16Vec3, - EOpConstructI16Vec4, - EOpConstructU16Vec2, - EOpConstructU16Vec3, - EOpConstructU16Vec4, -#endif EOpConstructMat2x2, EOpConstructMat2x3, EOpConstructMat2x4, @@ -542,7 +726,10 @@ EOpConstructBMat4x2, EOpConstructBMat4x3, EOpConstructBMat4x4, -#ifdef AMD_EXTENSIONS + EOpConstructFloat16, + EOpConstructF16Vec2, + EOpConstructF16Vec3, + EOpConstructF16Vec4, EOpConstructF16Mat2x2, EOpConstructF16Mat2x3, EOpConstructF16Mat2x4, @@ -552,9 +739,11 @@ EOpConstructF16Mat4x2, EOpConstructF16Mat4x3, EOpConstructF16Mat4x4, -#endif EOpConstructStruct, EOpConstructTextureSampler, + EOpConstructNonuniform, // expected to be transformed away, not present in final AST + EOpConstructReference, + EOpConstructCooperativeMatrix, EOpConstructGuardEnd, // @@ -581,7 +770,11 @@ // Array operators // - EOpArrayLength, // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well. + // Can apply to arrays, vectors, or matrices. + // Can be decomposed to a constant at compile time, but this does not always happen, + // due to link-time effects. So, consumer can expect either a link-time sized or + // run-time sized array. + EOpArrayLength, // // Image operations @@ -605,6 +798,8 @@ EOpImageAtomicXor, EOpImageAtomicExchange, EOpImageAtomicCompSwap, + EOpImageAtomicLoad, + EOpImageAtomicStore, EOpSubpassLoad, EOpSubpassLoadMS, @@ -682,6 +877,16 @@ #endif EOpSparseTextureGuardEnd, + +#ifdef NV_EXTENSIONS + EOpImageFootprintGuardBegin, + EOpImageSampleFootprintNV, + EOpImageSampleFootprintClampNV, + EOpImageSampleFootprintLodNV, + EOpImageSampleFootprintGradNV, + EOpImageSampleFootprintGradClampNV, + EOpImageFootprintGuardEnd, +#endif EOpSamplingGuardEnd, EOpTextureGuardEnd, @@ -700,6 +905,14 @@ EOpFindLSB, EOpFindMSB, +#ifdef NV_EXTENSIONS + EOpTraceNV, + EOpReportIntersectionNV, + EOpIgnoreIntersectionNV, + EOpTerminateRayNV, + EOpExecuteCallableNV, + EOpWritePackedPrimitiveIndices4x8NV, +#endif // // HLSL operations // @@ -777,6 +990,12 @@ // matrix EOpMatrixSwizzle, // select multiple matrix components (non-column) + + // SM6 wave ops + EOpWaveGetLaneCount, // Will decompose to gl_SubgroupSize. + EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID. + EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()). + EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()). }; class TIntermTraverser; @@ -819,7 +1038,7 @@ virtual glslang::TIntermMethod* getAsMethodNode() { return 0; } virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; } virtual glslang::TIntermBranch* getAsBranchNode() { return 0; } - virtual glslang::TIntermLoop* getAsLoopNode() { return 0; } + virtual glslang::TIntermLoop* getAsLoopNode() { return 0; } virtual const glslang::TIntermTyped* getAsTyped() const { return 0; } virtual const glslang::TIntermOperator* getAsOperator() const { return 0; } @@ -832,7 +1051,7 @@ virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; } virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; } virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; } - virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; } + virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; } virtual ~TIntermNode() { } protected: @@ -886,24 +1105,6 @@ }; // -// Selection control hints -// -enum TSelectionControl { - ESelectionControlNone, - ESelectionControlFlatten, - ESelectionControlDontFlatten, -}; - -// -// Loop control hints -// -enum TLoopControl { - ELoopControlNone, - ELoopControlUnroll, - ELoopControlDontUnroll, -}; - -// // Handle for, do-while, and while loops. // class TIntermLoop : public TIntermNode { @@ -913,26 +1114,68 @@ test(aTest), terminal(aTerminal), first(testFirst), - control(ELoopControlNone) + unroll(false), + dontUnroll(false), + dependency(0), + minIterations(0), + maxIterations(iterationsInfinite), + iterationMultiple(1), + peelCount(0), + partialCount(0) { } - virtual TIntermLoop* getAsLoopNode() { return this; } - virtual const TIntermLoop* getAsLoopNode() const { return this; } + virtual TIntermLoop* getAsLoopNode() { return this; } + virtual const TIntermLoop* getAsLoopNode() const { return this; } virtual void traverse(TIntermTraverser*); TIntermNode* getBody() const { return body; } TIntermTyped* getTest() const { return test; } TIntermTyped* getTerminal() const { return terminal; } bool testFirst() const { return first; } - void setLoopControl(TLoopControl c) { control = c; } - TLoopControl getLoopControl() const { return control; } + void setUnroll() { unroll = true; } + void setDontUnroll() { + dontUnroll = true; + peelCount = 0; + partialCount = 0; + } + bool getUnroll() const { return unroll; } + bool getDontUnroll() const { return dontUnroll; } + + static const unsigned int dependencyInfinite = 0xFFFFFFFF; + static const unsigned int iterationsInfinite = 0xFFFFFFFF; + void setLoopDependency(int d) { dependency = d; } + int getLoopDependency() const { return dependency; } + + void setMinIterations(unsigned int v) { minIterations = v; } + unsigned int getMinIterations() const { return minIterations; } + void setMaxIterations(unsigned int v) { maxIterations = v; } + unsigned int getMaxIterations() const { return maxIterations; } + void setIterationMultiple(unsigned int v) { iterationMultiple = v; } + unsigned int getIterationMultiple() const { return iterationMultiple; } + void setPeelCount(unsigned int v) { + peelCount = v; + dontUnroll = false; + } + unsigned int getPeelCount() const { return peelCount; } + void setPartialCount(unsigned int v) { + partialCount = v; + dontUnroll = false; + } + unsigned int getPartialCount() const { return partialCount; } protected: TIntermNode* body; // code to loop over TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops TIntermTyped* terminal; // exists for for-loops bool first; // true for while and for, not for do-while - TLoopControl control; // loop control hint + bool unroll; // true if unroll requested + bool dontUnroll; // true if request to not unroll + unsigned int dependency; // loop dependency hint; 0 means not set or unknown + unsigned int minIterations; // as per the SPIR-V specification + unsigned int maxIterations; // as per the SPIR-V specification + unsigned int iterationMultiple; // as per the SPIR-V specification + unsigned int peelCount; // as per the SPIR-V specification + unsigned int partialCount; // as per the SPIR-V specification }; // @@ -987,6 +1230,7 @@ constSubtree(nullptr) { name = n; } virtual int getId() const { return id; } + virtual void changeId(int i) { id = i; } virtual const TString& getName() const { return name; } virtual void traverse(TIntermTraverser*); virtual TIntermSymbol* getAsSymbolNode() { return this; } @@ -1066,6 +1310,9 @@ bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; } bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; } +#ifdef NV_EXTENSIONS + bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; } +#endif bool isSparseImage() const { return op == EOpSparseImageLoad; } void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; } @@ -1239,6 +1486,23 @@ cracked.fragMask = true; break; #endif +#ifdef NV_EXTENSIONS + case EOpImageSampleFootprintNV: + break; + case EOpImageSampleFootprintClampNV: + cracked.lodClamp = true; + break; + case EOpImageSampleFootprintLodNV: + cracked.lod = true; + break; + case EOpImageSampleFootprintGradNV: + cracked.grad = true; + break; + case EOpImageSampleFootprintGradClampNV: + cracked.lodClamp = true; + cracked.grad = true; + break; +#endif case EOpSubpassLoad: case EOpSubpassLoadMS: cracked.subpass = true; @@ -1343,22 +1607,35 @@ class TIntermSelection : public TIntermTyped { public: TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) : - TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {} + TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB), + shortCircuit(true), + flatten(false), dontFlatten(false) {} TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) : - TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {} + TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB), + shortCircuit(true), + flatten(false), dontFlatten(false) {} virtual void traverse(TIntermTraverser*); virtual TIntermTyped* getCondition() const { return condition; } virtual TIntermNode* getTrueBlock() const { return trueBlock; } virtual TIntermNode* getFalseBlock() const { return falseBlock; } virtual TIntermSelection* getAsSelectionNode() { return this; } virtual const TIntermSelection* getAsSelectionNode() const { return this; } - void setSelectionControl(TSelectionControl c) { control = c; } - TSelectionControl getSelectionControl() const { return control; } + + void setNoShortCircuit() { shortCircuit = false; } + bool getShortCircuit() const { return shortCircuit; } + + void setFlatten() { flatten = true; } + void setDontFlatten() { dontFlatten = true; } + bool getFlatten() const { return flatten; } + bool getDontFlatten() const { return dontFlatten; } + protected: TIntermTyped* condition; TIntermNode* trueBlock; TIntermNode* falseBlock; - TSelectionControl control; // selection control hint + bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not + bool flatten; // true if flatten requested + bool dontFlatten; // true if requested to not flatten }; // @@ -1369,18 +1646,24 @@ // class TIntermSwitch : public TIntermNode { public: - TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b), control(ESelectionControlNone) { } + TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b), + flatten(false), dontFlatten(false) {} virtual void traverse(TIntermTraverser*); virtual TIntermNode* getCondition() const { return condition; } virtual TIntermAggregate* getBody() const { return body; } virtual TIntermSwitch* getAsSwitchNode() { return this; } virtual const TIntermSwitch* getAsSwitchNode() const { return this; } - void setSelectionControl(TSelectionControl c) { control = c; } - TSelectionControl getSelectionControl() const { return control; } + + void setFlatten() { flatten = true; } + void setDontFlatten() { dontFlatten = true; } + bool getFlatten() const { return flatten; } + bool getDontFlatten() const { return dontFlatten; } + protected: TIntermTyped* condition; TIntermAggregate* body; - TSelectionControl control; // selection control hint + bool flatten; // true if flatten requested + bool dontFlatten; // true if requested to not flatten }; enum TVisit diff -Nru love-11.1/src/libraries/glslang/glslang/Include/PoolAlloc.h love-11.3/src/libraries/glslang/glslang/Include/PoolAlloc.h --- love-11.1/src/libraries/glslang/glslang/Include/PoolAlloc.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/PoolAlloc.h 2019-10-27 13:44:49.000000000 +0000 @@ -281,8 +281,6 @@ pool_allocator(TPoolAllocator& a) : allocator(a) { } pool_allocator(const pool_allocator& p) : allocator(p.allocator) { } - pool_allocator& operator=(const pool_allocator&) { return *this; } - template pool_allocator(const pool_allocator& p) : allocator(p.getAllocator()) { } @@ -310,6 +308,7 @@ TPoolAllocator& getAllocator() const { return allocator; } protected: + pool_allocator& operator=(const pool_allocator&) { return *this; } TPoolAllocator& allocator; }; diff -Nru love-11.1/src/libraries/glslang/glslang/Include/ResourceLimits.h love-11.3/src/libraries/glslang/glslang/Include/ResourceLimits.h --- love-11.1/src/libraries/glslang/glslang/Include/ResourceLimits.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/ResourceLimits.h 2019-10-27 13:44:49.000000000 +0000 @@ -133,6 +133,15 @@ int maxCullDistances; int maxCombinedClipAndCullDistances; int maxSamples; + int maxMeshOutputVerticesNV; + int maxMeshOutputPrimitivesNV; + int maxMeshWorkGroupSizeX_NV; + int maxMeshWorkGroupSizeY_NV; + int maxMeshWorkGroupSizeZ_NV; + int maxTaskWorkGroupSizeX_NV; + int maxTaskWorkGroupSizeY_NV; + int maxTaskWorkGroupSizeZ_NV; + int maxMeshViewCountNV; TLimits limits; }; diff -Nru love-11.1/src/libraries/glslang/glslang/Include/revision.h love-11.3/src/libraries/glslang/glslang/Include/revision.h --- love-11.1/src/libraries/glslang/glslang/Include/revision.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/revision.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,3 @@ // This header is generated by the make-revision script. -// For the version, it uses the latest git tag followed by the number of commits. -// For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "Overload400-PrecQual.2000" -#define GLSLANG_DATE "12-Apr-2017" +#define GLSLANG_PATCH_LEVEL 3226 diff -Nru love-11.1/src/libraries/glslang/glslang/Include/Types.h love-11.3/src/libraries/glslang/glslang/Include/Types.h --- love-11.1/src/libraries/glslang/glslang/Include/Types.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Include/Types.h 2019-10-27 13:44:49.000000000 +0000 @@ -2,6 +2,7 @@ // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. // Copyright (C) 2015-2016 Google, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -80,6 +81,7 @@ bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler bool sampler : 1; // true means a pure sampler, other fields should be clear() bool external : 1; // GL_OES_EGL_image_external + bool yuv : 1; // GL_EXT_YUV_target unsigned int vectorSize : 3; // vector return type size. // Some languages support structures as sample results. Storing the whole structure in the @@ -115,6 +117,7 @@ combined = false; sampler = false; external = false; + yuv = false; structReturnIndex = noReturnStruct; // by default, returns a single vec4; @@ -185,6 +188,7 @@ combined == right.combined && sampler == right.sampler && external == right.external && + yuv == right.yuv && vectorSize == right.vectorSize && structReturnIndex == right.structReturnIndex; } @@ -204,9 +208,18 @@ } switch (type) { - case EbtFloat: break; - case EbtInt: s.append("i"); break; - case EbtUint: s.append("u"); break; + case EbtFloat: break; +#ifdef AMD_EXTENSIONS + case EbtFloat16: s.append("f16"); break; +#endif + case EbtInt8: s.append("i8"); break; + case EbtUint16: s.append("u8"); break; + case EbtInt16: s.append("i16"); break; + case EbtUint8: s.append("u16"); break; + case EbtInt: s.append("i"); break; + case EbtUint: s.append("u"); break; + case EbtInt64: s.append("i64"); break; + case EbtUint64: s.append("u64"); break; default: break; // some compilers want this } if (image) { @@ -223,6 +236,9 @@ s.append("ExternalOES"); return s; } + if (yuv) { + return "__" + s + "External2DY2YEXT"; + } switch (dim) { case Esd1D: s.append("1D"); break; case Esd2D: s.append("2D"); break; @@ -267,6 +283,7 @@ ElpStd140, ElpStd430, ElpPacked, + ElpScalar, ElpCount // If expanding, see bitfield width below }; @@ -427,6 +444,7 @@ clearInterstage(); clearMemory(); specConstant = false; + nonUniform = false; clearLayout(); } @@ -446,11 +464,22 @@ #ifdef AMD_EXTENSIONS explicitInterp = false; #endif +#ifdef NV_EXTENSIONS + pervertexNV = false; + perPrimitiveNV = false; + perViewNV = false; + perTaskNV = false; +#endif } void clearMemory() { coherent = false; + devicecoherent = false; + queuefamilycoherent = false; + workgroupcoherent = false; + subgroupcoherent = false; + nonprivate = false; volatil = false; restrict = false; readonly = false; @@ -460,7 +489,7 @@ // Drop just the storage qualification, which perhaps should // never be done, as it is fundamentally inconsistent, but need to // explore what downstream consumers need. - // E.g., in a deference, it is an inconsistency between: + // E.g., in a dereference, it is an inconsistency between: // A) partially dereferenced resource is still in the storage class it started in // B) partially dereferenced resource is a new temporary object // If A, then nothing should change, if B, then everything should change, but this is half way. @@ -468,6 +497,7 @@ { storage = EvqTemporary; specConstant = false; + nonUniform = false; } const char* semanticName; @@ -484,19 +514,41 @@ #ifdef AMD_EXTENSIONS bool explicitInterp : 1; #endif +#ifdef NV_EXTENSIONS + bool pervertexNV : 1; + bool perPrimitiveNV : 1; + bool perViewNV : 1; + bool perTaskNV : 1; +#endif bool patch : 1; bool sample : 1; bool coherent : 1; + bool devicecoherent : 1; + bool queuefamilycoherent : 1; + bool workgroupcoherent : 1; + bool subgroupcoherent : 1; + bool nonprivate : 1; bool volatil : 1; bool restrict : 1; bool readonly : 1; bool writeonly : 1; bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant + bool nonUniform : 1; bool isMemory() const { - return coherent || volatil || restrict || readonly || writeonly; + return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate; + } + bool isMemoryQualifierImageAndSSBOOnly() const + { + return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly; } + bool bufferReferenceNeedsVulkanMemoryModel() const + { + // include qualifiers that map to load/store availability/visibility/nonprivate memory access operands + return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || nonprivate; + } + bool isInterpolation() const { #ifdef AMD_EXTENSIONS @@ -505,9 +557,21 @@ return flat || smooth || nopersp; #endif } + +#ifdef AMD_EXTENSIONS + bool isExplicitInterpolation() const + { + return explicitInterp; + } +#endif + bool isAuxiliary() const { +#ifdef NV_EXTENSIONS + return centroid || patch || sample || pervertexNV; +#else return centroid || patch || sample; +#endif } bool isPipeInput() const @@ -574,6 +638,33 @@ } } + bool isPerPrimitive() const + { +#ifdef NV_EXTENSIONS + return perPrimitiveNV; +#else + return false; +#endif + } + + bool isPerView() const + { +#ifdef NV_EXTENSIONS + return perViewNV; +#else + return false; +#endif + } + + bool isTaskMemory() const + { +#ifdef NV_EXTENSIONS + return perTaskNV; +#else + return false; +#endif + } + bool isIo() const { switch (storage) { @@ -597,6 +688,22 @@ } } + // non-built-in symbols that might link between compilation units + bool isLinkable() const + { + switch (storage) { + case EvqGlobal: + case EvqVaryingIn: + case EvqVaryingOut: + case EvqUniform: + case EvqBuffer: + case EvqShared: + return true; + default: + return false; + } + } + // True if this type of IO is supposed to be arrayed with extra level for per-vertex data bool isArrayedIo(EShLanguage language) const { @@ -607,6 +714,13 @@ return ! patch && (isPipeInput() || isPipeOutput()); case EShLangTessEvaluation: return ! patch && isPipeInput(); +#ifdef NV_EXTENSIONS + case EShLangFragment: + return pervertexNV && isPipeInput(); + case EShLangMeshNV: + return ! perTaskNV && isPipeOutput(); +#endif + default: return false; } @@ -618,13 +732,17 @@ clearUniformLayout(); layoutPushConstant = false; + layoutBufferReference = false; #ifdef NV_EXTENSIONS layoutPassthrough = false; layoutViewportRelative = false; // -2048 as the default value indicating layoutSecondaryViewportRelative is not set layoutSecondaryViewportRelativeOffset = -2048; + layoutShaderRecordNV = false; #endif + layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd; + clearInterstageLayout(); layoutSpecConstantId = layoutSpecConstantIdEnd; @@ -656,7 +774,11 @@ hasAnyLocation() || hasStream() || hasFormat() || - layoutPushConstant; +#ifdef NV_EXTENSIONS + layoutShaderRecordNV || +#endif + layoutPushConstant || + layoutBufferReference; } bool hasLayout() const { @@ -668,47 +790,53 @@ int layoutOffset; int layoutAlign; - unsigned int layoutLocation :12; - static const unsigned int layoutLocationEnd = 0xFFF; + unsigned int layoutLocation : 12; + static const unsigned int layoutLocationEnd = 0xFFF; - unsigned int layoutComponent : 3; - static const unsigned int layoutComponentEnd = 4; + unsigned int layoutComponent : 3; + static const unsigned int layoutComponentEnd = 4; - unsigned int layoutSet : 7; - static const unsigned int layoutSetEnd = 0x3F; + unsigned int layoutSet : 7; + static const unsigned int layoutSetEnd = 0x3F; - unsigned int layoutBinding : 16; - static const unsigned int layoutBindingEnd = 0xFFFF; + unsigned int layoutBinding : 16; + static const unsigned int layoutBindingEnd = 0xFFFF; - unsigned int layoutIndex : 8; - static const unsigned int layoutIndexEnd = 0xFF; + unsigned int layoutIndex : 8; + static const unsigned int layoutIndexEnd = 0xFF; - unsigned int layoutStream : 8; - static const unsigned int layoutStreamEnd = 0xFF; + unsigned int layoutStream : 8; + static const unsigned int layoutStreamEnd = 0xFF; - unsigned int layoutXfbBuffer : 4; - static const unsigned int layoutXfbBufferEnd = 0xF; + unsigned int layoutXfbBuffer : 4; + static const unsigned int layoutXfbBufferEnd = 0xF; - unsigned int layoutXfbStride : 10; - static const unsigned int layoutXfbStrideEnd = 0x3FF; + unsigned int layoutXfbStride : 14; + static const unsigned int layoutXfbStrideEnd = 0x3FFF; - unsigned int layoutXfbOffset : 10; - static const unsigned int layoutXfbOffsetEnd = 0x3FF; + unsigned int layoutXfbOffset : 13; + static const unsigned int layoutXfbOffsetEnd = 0x1FFF; - unsigned int layoutAttachment : 8; // for input_attachment_index - static const unsigned int layoutAttachmentEnd = 0XFF; + unsigned int layoutAttachment : 8; // for input_attachment_index + static const unsigned int layoutAttachmentEnd = 0XFF; unsigned int layoutSpecConstantId : 11; static const unsigned int layoutSpecConstantIdEnd = 0x7FF; - TLayoutFormat layoutFormat : 8; + // stored as log2 of the actual alignment value + unsigned int layoutBufferReferenceAlign : 6; + static const unsigned int layoutBufferReferenceAlignEnd = 0x3F; + + TLayoutFormat layoutFormat : 8; bool layoutPushConstant; + bool layoutBufferReference; #ifdef NV_EXTENSIONS bool layoutPassthrough; bool layoutViewportRelative; int layoutSecondaryViewportRelativeOffset; + bool layoutShaderRecordNV; #endif bool hasUniformLayout() const @@ -810,6 +938,10 @@ // is just whether or not it was declared with an ID. return layoutSpecConstantId != layoutSpecConstantIdEnd; } + bool hasBufferReferenceAlign() const + { + return layoutBufferReferenceAlign != layoutBufferReferenceAlignEnd; + } bool isSpecConstant() const { // True if type is a specialization constant, whether or not it @@ -817,6 +949,10 @@ // true front-end constant. return specConstant; } + bool isNonUniform() const + { + return nonUniform; + } bool isFrontEndConstant() const { // True if the front-end knows the final constant value. @@ -840,6 +976,7 @@ case ElpShared: return "shared"; case ElpStd140: return "std140"; case ElpStd430: return "std430"; + case ElpScalar: return "scalar"; default: return "none"; } } @@ -982,7 +1119,7 @@ bool pixelCenterInteger; // fragment shader bool originUpperLeft; // fragment shader int invocations; - int vertices; // both for tessellation "vertices" and geometry "max_vertices" + int vertices; // for tessellation "vertices", geometry & mesh "max_vertices" TVertexSpacing spacing; TVertexOrder order; bool pointMode; @@ -995,7 +1132,10 @@ int numViews; // multiview extenstions #ifdef NV_EXTENSIONS - bool layoutOverrideCoverage; // true if layout override_coverage set + bool layoutOverrideCoverage; // true if layout override_coverage set + bool layoutDerivativeGroupQuads; // true if layout derivative_group_quadsNV set + bool layoutDerivativeGroupLinear; // true if layout derivative_group_linearNV set + int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set #endif void init() @@ -1020,7 +1160,10 @@ blendEquation = false; numViews = TQualifier::layoutNotSet; #ifdef NV_EXTENSIONS - layoutOverrideCoverage = false; + layoutOverrideCoverage = false; + layoutDerivativeGroupQuads = false; + layoutDerivativeGroupLinear = false; + primitives = TQualifier::layoutNotSet; #endif } @@ -1065,6 +1208,12 @@ #ifdef NV_EXTENSIONS if (src.layoutOverrideCoverage) layoutOverrideCoverage = src.layoutOverrideCoverage; + if (src.layoutDerivativeGroupQuads) + layoutDerivativeGroupQuads = src.layoutDerivativeGroupQuads; + if (src.layoutDerivativeGroupLinear) + layoutDerivativeGroupLinear = src.layoutDerivativeGroupLinear; + if (src.primitives != TQualifier::layoutNotSet) + primitives = src.primitives; #endif } }; @@ -1086,9 +1235,11 @@ int vectorSize : 4; int matrixCols : 4; int matrixRows : 4; + bool coopmat : 1; TArraySizes* arraySizes; const TType* userDef; TSourceLoc loc; + TArraySizes* typeParameters; void initType(const TSourceLoc& l) { @@ -1099,6 +1250,8 @@ arraySizes = nullptr; userDef = nullptr; loc = l; + typeParameters = nullptr; + coopmat = false; } void initQualifiers(bool global = false) @@ -1150,8 +1303,8 @@ // for "empty" type (no args) or simple scalar/vector/matrix explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : - basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) { sampler.clear(); qualifier.clear(); @@ -1161,8 +1314,8 @@ // for explicit precision qualifier TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : - basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) { sampler.clear(); qualifier.clear(); @@ -1174,8 +1327,8 @@ // for turning a TPublicType into a TType, using a shallow copy explicit TType(const TPublicType& p) : basicType(p.basicType), - vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), - arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr) + vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat), + arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters) { if (basicType == EbtSampler) sampler = p.sampler; @@ -1183,15 +1336,26 @@ sampler.clear(); qualifier = p.qualifier; if (p.userDef) { - structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues + if (p.userDef->basicType == EbtReference) { + basicType = EbtReference; + referentType = p.userDef->referentType; + } else { + structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues + } typeName = NewPoolTString(p.userDef->getTypeName().c_str()); } + if (p.coopmat && p.basicType == EbtFloat && + p.typeParameters && p.typeParameters->getNumDims() > 0 && + p.typeParameters->getDimSize(0) == 16) { + basicType = EbtFloat16; + qualifier.precision = EpqNone; + } } // for construction of sampler types TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) : - basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), + basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr), - sampler(sampler) + sampler(sampler), typeParameters(nullptr) { qualifier.clear(); qualifier.storage = q; @@ -1232,13 +1396,16 @@ // dereference from vector to scalar vectorSize = 1; vector1 = false; + } else if (isCoopMat()) { + coopmat = false; + typeParameters = nullptr; } } } // for making structures, ... TType(TTypeList* userDef, const TString& n) : - basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), - arraySizes(nullptr), structure(userDef), fieldName(nullptr) + basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), + arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) { sampler.clear(); qualifier.clear(); @@ -1246,12 +1413,23 @@ } // For interface blocks TType(TTypeList* userDef, const TString& n, const TQualifier& q) : - basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), - qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr) + basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), + qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) { sampler.clear(); typeName = NewPoolTString(n.c_str()); } + // for block reference (first parameter must be EbtReference) + explicit TType(TBasicType t, const TType &p, const TString& n) : + basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) + { + assert(t == EbtReference); + typeName = NewPoolTString(n.c_str()); + qualifier.clear(); + qualifier.storage = p.qualifier.storage; + referentType = p.clone(); + } virtual ~TType() {} // Not for use across pool pops; it will cause multiple instances of TType to point to the same information. @@ -1267,9 +1445,15 @@ matrixRows = copyOf.matrixRows; vector1 = copyOf.vector1; arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents - structure = copyOf.structure; fieldName = copyOf.fieldName; typeName = copyOf.typeName; + if (isStruct()) { + structure = copyOf.structure; + } else { + referentType = copyOf.referentType; + } + typeParameters = copyOf.typeParameters; + coopmat = copyOf.coopmat; } // Make complete copy of the whole type graph rooted at 'copyOf'. @@ -1299,31 +1483,9 @@ void makeVector() { vector1 = true; } - // Merge type from parent, where a parentType is at the beginning of a declaration, - // establishing some characteristics for all subsequent names, while this type - // is on the individual names. - void mergeType(const TPublicType& parentType) - { - // arrayness is currently the only child aspect that has to be preserved - basicType = parentType.basicType; - vectorSize = parentType.vectorSize; - matrixCols = parentType.matrixCols; - matrixRows = parentType.matrixRows; - vector1 = false; // TPublicType is only GLSL which so far has no vec1 - qualifier = parentType.qualifier; - sampler = parentType.sampler; - if (parentType.arraySizes) - newArraySizes(*parentType.arraySizes); - if (parentType.userDef) { - structure = parentType.userDef->getWritableStruct(); - setTypeName(parentType.userDef->getTypeName()); - } - } - virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; } virtual bool hiddenMember() const { return basicType == EbtVoid; } - virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); } virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); } virtual const TString& getTypeName() const { @@ -1353,33 +1515,34 @@ virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } virtual const TArraySizes* getArraySizes() const { return arraySizes; } - virtual TArraySizes& getArraySizes() { assert(arraySizes != nullptr); return *arraySizes; } + virtual TArraySizes* getArraySizes() { return arraySizes; } + virtual TType* getReferentType() const { return referentType; } + virtual const TArraySizes* getTypeParameters() const { return typeParameters; } + virtual TArraySizes* getTypeParameters() { return typeParameters; } virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); } virtual bool isScalarOrVec1() const { return isScalar() || vector1; } virtual bool isVector() const { return vectorSize > 1 || vector1; } virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != nullptr; } - virtual bool isExplicitlySizedArray() const { return isArray() && getOuterArraySize() != UnsizedArraySize; } - virtual bool isImplicitlySizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage != EvqBuffer; } - virtual bool isRuntimeSizedArray() const { return isArray() && getOuterArraySize() == UnsizedArraySize && qualifier.storage == EvqBuffer; } - virtual bool isStruct() const { return structure != nullptr; } -#ifdef AMD_EXTENSIONS + virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); } + virtual bool isUnsizedArray() const { return isArray() && !arraySizes->isSized(); } + virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); } + virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); } + virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); } + virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; } virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; } -#else - virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble; } -#endif virtual bool isIntegerDomain() const { switch (basicType) { + case EbtInt8: + case EbtUint8: + case EbtInt16: + case EbtUint16: case EbtInt: case EbtUint: case EbtInt64: case EbtUint64: -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: -#endif case EbtAtomicUint: return true; default: @@ -1387,15 +1550,22 @@ } return false; } - virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint; } + virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint +#ifdef NV_EXTENSIONS + || basicType == EbtAccStructNV +#endif + ; } virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; } // "Image" is a superset of "Subpass" - virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } + virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } + virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } + virtual bool isParameterized() const { return typeParameters != nullptr; } + virtual bool isCoopMat() const { return coopmat; } // return true if this type contains any subtype which satisfies the given predicate. - template + template bool contains(P predicate) const { if (predicate(this)) @@ -1403,7 +1573,7 @@ const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); }; - return structure && std::any_of(structure->begin(), structure->end(), hasa); + return isStruct() && std::any_of(structure->begin(), structure->end(), hasa); } // Recursively checks if the type contains the given basic type @@ -1424,10 +1594,10 @@ return contains([this](const TType* t) { return t != this && t->isStruct(); } ); } - // Recursively check the structure for any implicitly-sized arrays, needed for triggering a copyUp(). - virtual bool containsImplicitlySizedArray() const + // Recursively check the structure for any unsized arrays, needed for triggering a copyUp(). + virtual bool containsUnsizedArray() const { - return contains([](const TType* t) { return t->isImplicitlySizedArray(); } ); + return contains([](const TType* t) { return t->isUnsizedArray(); } ); } virtual bool containsOpaque() const @@ -1448,18 +1618,17 @@ case EbtVoid: case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif + case EbtInt8: + case EbtUint8: + case EbtInt16: + case EbtUint16: case EbtInt: case EbtUint: case EbtInt64: case EbtUint64: -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: -#endif case EbtBool: + case EbtReference: return true; default: return false; @@ -1474,6 +1643,21 @@ return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } ); } + virtual bool contains16BitInt() const + { + return containsBasicType(EbtInt16) || containsBasicType(EbtUint16); + } + + virtual bool contains8BitInt() const + { + return containsBasicType(EbtInt8) || containsBasicType(EbtUint8); + } + + virtual bool containsCoopMat() const + { + return contains([](const TType* t) { return t->coopmat; } ); + } + // Array editing methods. Array descriptors can be shared across // type instances. This allows all uses of the same array // to be updated at once. E.g., all nodes can be explicitly sized @@ -1493,37 +1677,99 @@ assert(type.arraySizes != nullptr); *arraySizes = *type.arraySizes; } - void newArraySizes(const TArraySizes& s) + void copyArraySizes(const TArraySizes& s) { // For setting a fresh new set of array sizes, not yet worrying about sharing. arraySizes = new TArraySizes; *arraySizes = s; } - void clearArraySizes() + void transferArraySizes(TArraySizes* s) { - arraySizes = 0; + // For setting an already allocated set of sizes that this type can use + // (no copy made). + arraySizes = s; } - void addArrayOuterSizes(const TArraySizes& s) + void clearArraySizes() { - if (arraySizes == nullptr) - newArraySizes(s); - else - arraySizes->addOuterSizes(s); + arraySizes = nullptr; + } + + // Add inner array sizes, to any existing sizes, via copy; the + // sizes passed in can still be reused for other purposes. + void copyArrayInnerSizes(const TArraySizes* s) + { + if (s != nullptr) { + if (arraySizes == nullptr) + copyArraySizes(*s); + else + arraySizes->addInnerSizes(*s); + } } void changeOuterArraySize(int s) { arraySizes->changeOuterSize(s); } - void setImplicitArraySize(int s) { arraySizes->setImplicitSize(s); } - // Recursively make the implicit array size the explicit array size, through the type tree. - void adoptImplicitArraySizes() + // Recursively make the implicit array size the explicit array size. + // Expicit arrays are compile-time or link-time sized, never run-time sized. + // Sometimes, policy calls for an array to be run-time sized even if it was + // never variably indexed: Don't turn a 'skipNonvariablyIndexed' array into + // an explicit array. + void adoptImplicitArraySizes(bool skipNonvariablyIndexed) { - if (isImplicitlySizedArray()) + if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed())) changeOuterArraySize(getImplicitArraySize()); - if (isStruct()) { - for (int i = 0; i < (int)structure->size(); ++i) - (*structure)[i].type->adoptImplicitArraySizes(); +#ifdef NV_EXTENSIONS + // For multi-dim per-view arrays, set unsized inner dimension size to 1 + if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized()) + arraySizes->clearInnerUnsized(); +#endif + if (isStruct() && structure->size() > 0) { + int lastMember = (int)structure->size() - 1; + for (int i = 0; i < lastMember; ++i) + (*structure)[i].type->adoptImplicitArraySizes(false); + // implement the "last member of an SSBO" policy + (*structure)[lastMember].type->adoptImplicitArraySizes(getQualifier().storage == EvqBuffer); } } + + void updateTypeParameters(const TType& type) + { + // For when we may already be sharing existing array descriptors, + // keeping the pointers the same, just updating the contents. + assert(typeParameters != nullptr); + assert(type.typeParameters != nullptr); + *typeParameters = *type.typeParameters; + } + void copyTypeParameters(const TArraySizes& s) + { + // For setting a fresh new set of type parameters, not yet worrying about sharing. + typeParameters = new TArraySizes; + *typeParameters = s; + } + void transferTypeParameters(TArraySizes* s) + { + // For setting an already allocated set of sizes that this type can use + // (no copy made). + typeParameters = s; + } + void clearTypeParameters() + { + typeParameters = nullptr; + } + + // Add inner array sizes, to any existing sizes, via copy; the + // sizes passed in can still be reused for other purposes. + void copyTypeParametersInnerSizes(const TArraySizes* s) + { + if (s != nullptr) { + if (typeParameters == nullptr) + copyTypeParameters(*s); + else + typeParameters->addInnerSizes(*s); + } + } + + + const char* getBasicString() const { return TType::getBasicString(basicType); @@ -1535,22 +1781,24 @@ case EbtVoid: return "void"; case EbtFloat: return "float"; case EbtDouble: return "double"; -#ifdef AMD_EXTENSIONS case EbtFloat16: return "float16_t"; -#endif + case EbtInt8: return "int8_t"; + case EbtUint8: return "uint8_t"; + case EbtInt16: return "int16_t"; + case EbtUint16: return "uint16_t"; case EbtInt: return "int"; case EbtUint: return "uint"; case EbtInt64: return "int64_t"; case EbtUint64: return "uint64_t"; -#ifdef AMD_EXTENSIONS - case EbtInt16: return "int16_t"; - case EbtUint16: return "uint16_t"; -#endif case EbtBool: return "bool"; case EbtAtomicUint: return "atomic_uint"; case EbtSampler: return "sampler/image"; case EbtStruct: return "structure"; case EbtBlock: return "block"; +#ifdef NV_EXTENSIONS + case EbtAccStructNV: return "accelerationStructureNV"; +#endif + case EbtReference: return "reference"; default: return "unknown type"; } } @@ -1636,6 +1884,12 @@ } if (qualifier.layoutPushConstant) appendStr(" push_constant"); + if (qualifier.layoutBufferReference) + appendStr(" buffer_reference"); + if (qualifier.hasBufferReferenceAlign()) { + appendStr(" buffer_reference_align="); + appendUint(1u << qualifier.layoutBufferReferenceAlign); + } #ifdef NV_EXTENSIONS if (qualifier.layoutPassthrough) @@ -1646,6 +1900,8 @@ appendStr(" layoutSecondaryViewportRelativeOffset="); appendInt(qualifier.layoutSecondaryViewportRelativeOffset); } + if (qualifier.layoutShaderRecordNV) + appendStr(" shaderRecordNV"); #endif appendStr(")"); @@ -1668,12 +1924,32 @@ if (qualifier.explicitInterp) appendStr(" __explicitInterpAMD"); #endif +#ifdef NV_EXTENSIONS + if (qualifier.pervertexNV) + appendStr(" pervertexNV"); + if (qualifier.perPrimitiveNV) + appendStr(" perprimitiveNV"); + if (qualifier.perViewNV) + appendStr(" perviewNV"); + if (qualifier.perTaskNV) + appendStr(" taskNV"); +#endif if (qualifier.patch) appendStr(" patch"); if (qualifier.sample) appendStr(" sample"); if (qualifier.coherent) appendStr(" coherent"); + if (qualifier.devicecoherent) + appendStr(" devicecoherent"); + if (qualifier.queuefamilycoherent) + appendStr(" queuefamilycoherent"); + if (qualifier.workgroupcoherent) + appendStr(" workgroupcoherent"); + if (qualifier.subgroupcoherent) + appendStr(" subgroupcoherent"); + if (qualifier.nonprivate) + appendStr(" nonprivate"); if (qualifier.volatil) appendStr(" volatile"); if (qualifier.restrict) @@ -1684,20 +1960,39 @@ appendStr(" writeonly"); if (qualifier.specConstant) appendStr(" specialization-constant"); + if (qualifier.nonUniform) + appendStr(" nonuniform"); appendStr(" "); appendStr(getStorageQualifierString()); if (isArray()) { for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) { int size = arraySizes->getDimSize(i); - if (size == 0) - appendStr(" implicitly-sized array of"); + if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed()) + appendStr(" runtime-sized array of"); else { - appendStr(" "); - appendInt(arraySizes->getDimSize(i)); + if (size == UnsizedArraySize) { + appendStr(" unsized"); + if (i == 0) { + appendStr(" "); + appendInt(arraySizes->getImplicitSize()); + } + } else { + appendStr(" "); + appendInt(arraySizes->getDimSize(i)); + } appendStr("-element array of"); } } } + if (isParameterized()) { + appendStr("<"); + for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) { + appendInt(typeParameters->getDimSize(i)); + if (i != (int)typeParameters->getNumDims() - 1) + appendStr(", "); + } + appendStr(">"); + } if (qualifier.precision != EpqNone) { appendStr(" "); appendStr(getPrecisionQualifierString()); @@ -1723,7 +2018,7 @@ } // Add struct/block members - if (structure) { + if (isStruct() && structure) { appendStr("{"); for (size_t i = 0; i < structure->size(); ++i) { if (! (*structure)[i].type->hiddenMember()) { @@ -1751,9 +2046,9 @@ const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); } const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); } const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); } - const TTypeList* getStruct() const { return structure; } - void setStruct(TTypeList* s) { structure = s; } - TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads + const TTypeList* getStruct() const { assert(isStruct()); return structure; } + void setStruct(TTypeList* s) { assert(isStruct()); structure = s; } + TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads int computeNumComponents() const { @@ -1792,11 +2087,12 @@ bool sameStructType(const TType& right) const { // Most commonly, they are both nullptr, or the same pointer to the same actual structure - if (structure == right.structure) + if ((!isStruct() && !right.isStruct()) || + (isStruct() && right.isStruct() && structure == right.structure)) return true; // Both being nullptr was caught above, now they both have to be structures of the same number of elements - if (structure == nullptr || right.structure == nullptr || + if (!isStruct() || !right.isStruct() || structure->size() != right.structure->size()) return false; @@ -1816,6 +2112,23 @@ return true; } + bool sameReferenceType(const TType& right) const + { + if ((basicType == EbtReference) != (right.basicType == EbtReference)) + return false; + + if ((basicType != EbtReference) && (right.basicType != EbtReference)) + return true; + + assert(referentType != nullptr); + assert(right.referentType != nullptr); + + if (referentType == right.referentType) + return true; + + return *referentType == *right.referentType; + } + // See if two types match, in all aspects except arrayness bool sameElementType(const TType& right) const { @@ -1836,6 +2149,13 @@ return arraySizes->sameInnerArrayness(*right.arraySizes); } + // See if two type's parameters match + bool sameTypeParameters(const TType& right) const + { + return ((typeParameters == nullptr && right.typeParameters == nullptr) || + (typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters)); + } + // See if two type's elements match in all ways except basic type bool sameElementShape(const TType& right) const { @@ -1844,13 +2164,23 @@ matrixCols == right.matrixCols && matrixRows == right.matrixRows && vector1 == right.vector1 && - sameStructType(right); + coopmat == right.coopmat && + sameStructType(right) && + sameReferenceType(right); + } + + // See if a cooperative matrix type parameter with unspecified parameters is + // an OK function parameter + bool coopMatParameterOK(const TType& right) const + { + return coopmat && right.coopmat && + typeParameters == nullptr && right.typeParameters != nullptr; } // See if two types match in all ways (just the actual type, not qualification) bool operator==(const TType& right) const { - return sameElementType(right) && sameArrayness(right); + return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right); } bool operator!=(const TType& right) const @@ -1858,6 +2188,16 @@ return ! operator==(right); } + unsigned int getBufferReferenceAlignment() const + { + if (getBasicType() == glslang::EbtReference) { + return getReferentType()->getQualifier().hasBufferReferenceAlign() ? + (1u << getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u; + } else { + return 0; + } + } + protected: // Require consumer to pick between deep copy and shallow copy. TType(const TType& type); @@ -1875,7 +2215,12 @@ *arraySizes = *copyOf.arraySizes; } - if (copyOf.structure) { + if (copyOf.typeParameters) { + typeParameters = new TArraySizes; + *typeParameters = *copyOf.typeParameters; + } + + if (copyOf.isStruct() && copyOf.structure) { auto prevCopy = copiedMap.find(copyOf.structure); if (prevCopy != copiedMap.end()) structure = prevCopy->second; @@ -1910,13 +2255,20 @@ // functionality is added. // HLSL does have a 1-component vectors, so this will be true to disambiguate // from a scalar. + bool coopmat : 1; TQualifier qualifier; TArraySizes* arraySizes; // nullptr unless an array; can be shared across types - TTypeList* structure; // nullptr unless this is a struct; can be shared across types + // A type can't be both a structure (EbtStruct/EbtBlock) and a reference (EbtReference), so + // conserve space by making these a union + union { + TTypeList* structure; // invalid unless this is a struct; can be shared across types + TType *referentType; // invalid unless this is an EbtReference + }; TString *fieldName; // for structure field names TString *typeName; // for structure type name TSampler sampler; + TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types }; } // end namespace glslang diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,343 @@ +// +// Copyright (C) 2017 LunarG, Inc. +// Copyright (C) 2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google, Inc., nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "attribute.h" +#include "../Include/intermediate.h" +#include "ParseHelper.h" + +namespace glslang { + +// extract integers out of attribute arguments stored in attribute aggregate +bool TAttributeArgs::getInt(int& value, int argNum) const +{ + const TConstUnion* intConst = getConstUnion(EbtInt, argNum); + + if (intConst == nullptr) + return false; + + value = intConst->getIConst(); + return true; +} + + +// extract strings out of attribute arguments stored in attribute aggregate. +// convert to lower case if converToLower is true (for case-insensitive compare convenience) +bool TAttributeArgs::getString(TString& value, int argNum, bool convertToLower) const +{ + const TConstUnion* stringConst = getConstUnion(EbtString, argNum); + + if (stringConst == nullptr) + return false; + + value = *stringConst->getSConst(); + + // Convenience. + if (convertToLower) + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + + return true; +} + +// How many arguments were supplied? +int TAttributeArgs::size() const +{ + return args == nullptr ? 0 : (int)args->getSequence().size(); +} + +// Helper to get attribute const union. Returns nullptr on failure. +const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNum) const +{ + if (args == nullptr) + return nullptr; + + if (argNum >= (int)args->getSequence().size()) + return nullptr; + + if (args->getSequence()[argNum]->getAsConstantUnion() == nullptr) + return nullptr; + + const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0]; + if (constVal == nullptr || constVal->getType() != basicType) + return nullptr; + + return constVal; +} + +// Implementation of TParseContext parts of attributes +TAttributeType TParseContext::attributeFromName(const TString& name) const +{ + if (name == "branch" || name == "dont_flatten") + return EatBranch; + else if (name == "flatten") + return EatFlatten; + else if (name == "unroll") + return EatUnroll; + else if (name == "loop" || name == "dont_unroll") + return EatLoop; + else if (name == "dependency_infinite") + return EatDependencyInfinite; + else if (name == "dependency_length") + return EatDependencyLength; + else if (name == "min_iterations") + return EatMinIterations; + else if (name == "max_iterations") + return EatMaxIterations; + else if (name == "iteration_multiple") + return EatIterationMultiple; + else if (name == "peel_count") + return EatPeelCount; + else if (name == "partial_count") + return EatPartialCount; + else + return EatNone; +} + +// Make an initial leaf for the grammar from a no-argument attribute +TAttributes* TParseContext::makeAttributes(const TString& identifier) const +{ + TAttributes *attributes = nullptr; + attributes = NewPoolObject(attributes); + TAttributeArgs args = { attributeFromName(identifier), nullptr }; + attributes->push_back(args); + return attributes; +} + +// Make an initial leaf for the grammar from a one-argument attribute +TAttributes* TParseContext::makeAttributes(const TString& identifier, TIntermNode* node) const +{ + TAttributes *attributes = nullptr; + attributes = NewPoolObject(attributes); + + // for now, node is always a simple single expression, but other code expects + // a list, so make it so + TIntermAggregate* agg = intermediate.makeAggregate(node); + TAttributeArgs args = { attributeFromName(identifier), agg }; + attributes->push_back(args); + return attributes; +} + +// Merge two sets of attributes into a single set. +// The second argument is destructively consumed. +TAttributes* TParseContext::mergeAttributes(TAttributes* attr1, TAttributes* attr2) const +{ + attr1->splice(attr1->end(), *attr2); + return attr1; +} + +// +// Selection attributes +// +void TParseContext::handleSelectionAttributes(const TAttributes& attributes, TIntermNode* node) +{ + TIntermSelection* selection = node->getAsSelectionNode(); + if (selection == nullptr) + return; + + for (auto it = attributes.begin(); it != attributes.end(); ++it) { + if (it->size() > 0) { + warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", ""); + continue; + } + + switch (it->name) { + case EatFlatten: + selection->setFlatten(); + break; + case EatBranch: + selection->setDontFlatten(); + break; + default: + warn(node->getLoc(), "attribute does not apply to a selection", "", ""); + break; + } + } +} + +// +// Switch attributes +// +void TParseContext::handleSwitchAttributes(const TAttributes& attributes, TIntermNode* node) +{ + TIntermSwitch* selection = node->getAsSwitchNode(); + if (selection == nullptr) + return; + + for (auto it = attributes.begin(); it != attributes.end(); ++it) { + if (it->size() > 0) { + warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", ""); + continue; + } + + switch (it->name) { + case EatFlatten: + selection->setFlatten(); + break; + case EatBranch: + selection->setDontFlatten(); + break; + default: + warn(node->getLoc(), "attribute does not apply to a switch", "", ""); + break; + } + } +} + +// +// Loop attributes +// +void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermNode* node) +{ + TIntermLoop* loop = node->getAsLoopNode(); + if (loop == nullptr) { + // the actual loop might be part of a sequence + TIntermAggregate* agg = node->getAsAggregate(); + if (agg == nullptr) + return; + for (auto it = agg->getSequence().begin(); it != agg->getSequence().end(); ++it) { + loop = (*it)->getAsLoopNode(); + if (loop != nullptr) + break; + } + if (loop == nullptr) + return; + } + + for (auto it = attributes.begin(); it != attributes.end(); ++it) { + + const auto noArgument = [&](const char* feature) { + if (it->size() > 0) { + warn(node->getLoc(), "expected no arguments", feature, ""); + return false; + } + return true; + }; + + const auto positiveSignedArgument = [&](const char* feature, int& value) { + if (it->size() == 1 && it->getInt(value)) { + if (value <= 0) { + error(node->getLoc(), "must be positive", feature, ""); + return false; + } + } else { + warn(node->getLoc(), "expected a single integer argument", feature, ""); + return false; + } + return true; + }; + + const auto unsignedArgument = [&](const char* feature, unsigned int& uiValue) { + int value; + if (!(it->size() == 1 && it->getInt(value))) { + warn(node->getLoc(), "expected a single integer argument", feature, ""); + return false; + } + uiValue = (unsigned int)value; + return true; + }; + + const auto positiveUnsignedArgument = [&](const char* feature, unsigned int& uiValue) { + int value; + if (it->size() == 1 && it->getInt(value)) { + if (value == 0) { + error(node->getLoc(), "must be greater than or equal to 1", feature, ""); + return false; + } + } else { + warn(node->getLoc(), "expected a single integer argument", feature, ""); + return false; + } + uiValue = (unsigned int)value; + return true; + }; + + const auto spirv14 = [&](const char* feature) { + if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) + warn(node->getLoc(), "attribute requires a SPIR-V 1.4 target-env", feature, ""); + }; + + int value = 0; + unsigned uiValue = 0; + switch (it->name) { + case EatUnroll: + if (noArgument("unroll")) + loop->setUnroll(); + break; + case EatLoop: + if (noArgument("dont_unroll")) + loop->setDontUnroll(); + break; + case EatDependencyInfinite: + if (noArgument("dependency_infinite")) + loop->setLoopDependency(TIntermLoop::dependencyInfinite); + break; + case EatDependencyLength: + if (positiveSignedArgument("dependency_length", value)) + loop->setLoopDependency(value); + break; + case EatMinIterations: + spirv14("min_iterations"); + if (unsignedArgument("min_iterations", uiValue)) + loop->setMinIterations(uiValue); + break; + case EatMaxIterations: + spirv14("max_iterations"); + if (unsignedArgument("max_iterations", uiValue)) + loop->setMaxIterations(uiValue); + break; + case EatIterationMultiple: + spirv14("iteration_multiple"); + if (positiveUnsignedArgument("iteration_multiple", uiValue)) + loop->setIterationMultiple(uiValue); + break; + case EatPeelCount: + spirv14("peel_count"); + if (unsignedArgument("peel_count", uiValue)) + loop->setPeelCount(uiValue); + break; + case EatPartialCount: + spirv14("partial_count"); + if (unsignedArgument("partial_count", uiValue)) + loop->setPartialCount(uiValue); + break; + default: + warn(node->getLoc(), "attribute does not apply to a loop", "", ""); + break; + } + } +} + + +} // end namespace glslang diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/attribute.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/attribute.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/attribute.h 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/attribute.h 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,107 @@ +// +// Copyright (C) 2017 LunarG, Inc. +// Copyright (C) 2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _ATTRIBUTE_INCLUDED_ +#define _ATTRIBUTE_INCLUDED_ + +#include "../Include/Common.h" +#include "../Include/ConstantUnion.h" + +namespace glslang { + + enum TAttributeType { + EatNone, + EatAllow_uav_condition, + EatBranch, + EatCall, + EatDomain, + EatEarlyDepthStencil, + EatFastOpt, + EatFlatten, + EatForceCase, + EatInstance, + EatMaxTessFactor, + EatNumThreads, + EatMaxVertexCount, + EatOutputControlPoints, + EatOutputTopology, + EatPartitioning, + EatPatchConstantFunc, + EatPatchSize, + EatUnroll, + EatLoop, + EatBinding, + EatGlobalBinding, + EatLocation, + EatInputAttachment, + EatBuiltIn, + EatPushConstant, + EatConstantId, + EatDependencyInfinite, + EatDependencyLength, + EatMinIterations, + EatMaxIterations, + EatIterationMultiple, + EatPeelCount, + EatPartialCount + }; + + class TIntermAggregate; + + struct TAttributeArgs { + TAttributeType name; + const TIntermAggregate* args; + + // Obtain attribute as integer + // Return false if it cannot be obtained + bool getInt(int& value, int argNum = 0) const; + + // Obtain attribute as string, with optional to-lower transform + // Return false if it cannot be obtained + bool getString(TString& value, int argNum = 0, bool convertToLower = true) const; + + // How many arguments were provided to the attribute? + int size() const; + + protected: + const TConstUnion* getConstUnion(TBasicType basicType, int argNum) const; + }; + + typedef TList TAttributes; + +} // end namespace glslang + +#endif // _ATTRIBUTE_INCLUDED_ diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2018 Google, Inc. // // All rights reserved. // @@ -177,60 +179,79 @@ switch (getType().getBasicType()) { case EbtDouble: case EbtFloat: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif - newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst()); + if (rightUnionArray[i].getDConst() != 0.0) + newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst()); + else if (leftUnionArray[i].getDConst() > 0.0) + newConstArray[i].setDConst((double)INFINITY); + else if (leftUnionArray[i].getDConst() < 0.0) + newConstArray[i].setDConst(-(double)INFINITY); + else + newConstArray[i].setDConst((double)NAN); + break; + case EbtInt8: + if (rightUnionArray[i] == (signed char)0) + newConstArray[i].setI8Const((signed char)0x7F); + else if (rightUnionArray[i].getI8Const() == (signed char)-1 && leftUnionArray[i].getI8Const() == (signed char)-0x80) + newConstArray[i].setI8Const((signed char)-0x80); + else + newConstArray[i].setI8Const(leftUnionArray[i].getI8Const() / rightUnionArray[i].getI8Const()); + break; + + case EbtUint8: + if (rightUnionArray[i] == (unsigned char)0u) + newConstArray[i].setU8Const((unsigned char)0xFFu); + else + newConstArray[i].setU8Const(leftUnionArray[i].getU8Const() / rightUnionArray[i].getU8Const()); + break; + + case EbtInt16: + if (rightUnionArray[i] == (signed short)0) + newConstArray[i].setI16Const((signed short)0x7FFF); + else if (rightUnionArray[i].getI16Const() == (signed short)-1 && leftUnionArray[i].getI16Const() == (signed short)-0x8000) + newConstArray[i].setI16Const((signed short)-0x8000); + else + newConstArray[i].setI16Const(leftUnionArray[i].getI16Const() / rightUnionArray[i].getI16Const()); + break; + + case EbtUint16: + if (rightUnionArray[i] == (unsigned short)0u) + newConstArray[i].setU16Const((unsigned short)0xFFFFu); + else + newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const()); break; case EbtInt: if (rightUnionArray[i] == 0) newConstArray[i].setIConst(0x7FFFFFFF); - else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)0x80000000) - newConstArray[i].setIConst(0x80000000); + else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll) + newConstArray[i].setIConst((int)-0x80000000ll); else newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst()); break; case EbtUint: - if (rightUnionArray[i] == 0) { + if (rightUnionArray[i] == 0u) newConstArray[i].setUConst(0xFFFFFFFFu); - } else + else newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); break; case EbtInt64: - if (rightUnionArray[i] == 0) + if (rightUnionArray[i] == 0ll) newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll); - else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)0x8000000000000000) - newConstArray[i].setI64Const(0x8000000000000000); + else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)-0x8000000000000000ll) + newConstArray[i].setI64Const((long long)-0x8000000000000000ll); else newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const()); break; case EbtUint64: - if (rightUnionArray[i] == 0) { + if (rightUnionArray[i] == 0ull) newConstArray[i].setU64Const(0xFFFFFFFFFFFFFFFFull); - } else - newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const()); - break; -#ifdef AMD_EXTENSIONS - case EbtInt16: - if (rightUnionArray[i] == 0) - newConstArray[i].setIConst(0x7FFF); - else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)0x8000) - newConstArray[i].setIConst(0x8000); else - newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst()); - break; - - case EbtUint16: - if (rightUnionArray[i] == 0) { - newConstArray[i].setUConst(0xFFFFu); - } else - newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); + newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const()); break; -#endif default: return 0; } @@ -411,6 +432,12 @@ resultSize = 2; break; + case EOpPack16: + case EOpPack32: + case EOpPack64: + case EOpUnpack32: + case EOpUnpack16: + case EOpUnpack8: case EOpNormalize: componentWise = false; resultSize = objectSize; @@ -469,6 +496,12 @@ case EOpPackSnorm2x16: case EOpPackUnorm2x16: case EOpPackHalf2x16: + case EOpPack16: + case EOpPack32: + case EOpPack64: + case EOpUnpack32: + case EOpUnpack16: + case EOpUnpack8: case EOpUnpackSnorm2x16: case EOpUnpackUnorm2x16: @@ -494,17 +527,13 @@ case EOpNegative: switch (getType().getBasicType()) { case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; -#ifdef AMD_EXTENSIONS - case EbtInt16: -#endif + case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break; + case EbtUint8: newConstArray[i].setU8Const(static_cast(-static_cast(unionArray[i].getU8Const()))); break; + case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break; + case EbtUint16:newConstArray[i].setU16Const(static_cast(-static_cast(unionArray[i].getU16Const()))); break; case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; -#ifdef AMD_EXTENSIONS - case EbtUint16: -#endif case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break; case EbtUint64: newConstArray[i].setU64Const(static_cast(-static_cast(unionArray[i].getU64Const()))); break; @@ -642,6 +671,283 @@ break; } + case EOpConvInt8ToBool: + newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break; + case EOpConvUint8ToBool: + newConstArray[i].setBConst(unionArray[i].getU8Const() != 0); break; + case EOpConvInt16ToBool: + newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break; + case EOpConvUint16ToBool: + newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break; + case EOpConvIntToBool: + newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break; + case EOpConvUintToBool: + newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break; + case EOpConvInt64ToBool: + newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break; + case EOpConvUint64ToBool: + newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break; + case EOpConvFloat16ToBool: + newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; + case EOpConvFloatToBool: + newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; + case EOpConvDoubleToBool: + newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; + + case EOpConvBoolToInt8: + newConstArray[i].setI8Const(unionArray[i].getBConst()); break; + case EOpConvBoolToUint8: + newConstArray[i].setU8Const(unionArray[i].getBConst()); break; + case EOpConvBoolToInt16: + newConstArray[i].setI16Const(unionArray[i].getBConst()); break; + case EOpConvBoolToUint16: + newConstArray[i].setU16Const(unionArray[i].getBConst()); break; + case EOpConvBoolToInt: + newConstArray[i].setIConst(unionArray[i].getBConst()); break; + case EOpConvBoolToUint: + newConstArray[i].setUConst(unionArray[i].getBConst()); break; + case EOpConvBoolToInt64: + newConstArray[i].setI64Const(unionArray[i].getBConst()); break; + case EOpConvBoolToUint64: + newConstArray[i].setU64Const(unionArray[i].getBConst()); break; + case EOpConvBoolToFloat16: + newConstArray[i].setDConst(unionArray[i].getBConst()); break; + case EOpConvBoolToFloat: + newConstArray[i].setDConst(unionArray[i].getBConst()); break; + case EOpConvBoolToDouble: + newConstArray[i].setDConst(unionArray[i].getBConst()); break; + + case EOpConvInt8ToInt16: + newConstArray[i].setI16Const(unionArray[i].getI8Const()); break; + case EOpConvInt8ToInt: + newConstArray[i].setIConst(unionArray[i].getI8Const()); break; + case EOpConvInt8ToInt64: + newConstArray[i].setI64Const(unionArray[i].getI8Const()); break; + case EOpConvInt8ToUint8: + newConstArray[i].setU8Const(unionArray[i].getI8Const()); break; + case EOpConvInt8ToUint16: + newConstArray[i].setU16Const(unionArray[i].getI8Const()); break; + case EOpConvInt8ToUint: + newConstArray[i].setUConst(unionArray[i].getI8Const()); break; + case EOpConvInt8ToUint64: + newConstArray[i].setU64Const(unionArray[i].getI8Const()); break; + case EOpConvUint8ToInt8: + newConstArray[i].setI8Const(unionArray[i].getU8Const()); break; + case EOpConvUint8ToInt16: + newConstArray[i].setI16Const(unionArray[i].getU8Const()); break; + case EOpConvUint8ToInt: + newConstArray[i].setIConst(unionArray[i].getU8Const()); break; + case EOpConvUint8ToInt64: + newConstArray[i].setI64Const(unionArray[i].getU8Const()); break; + case EOpConvUint8ToUint16: + newConstArray[i].setU16Const(unionArray[i].getU8Const()); break; + case EOpConvUint8ToUint: + newConstArray[i].setUConst(unionArray[i].getU8Const()); break; + case EOpConvUint8ToUint64: + newConstArray[i].setU64Const(unionArray[i].getU8Const()); break; + case EOpConvInt8ToFloat16: + newConstArray[i].setDConst(unionArray[i].getI8Const()); break; + case EOpConvInt8ToFloat: + newConstArray[i].setDConst(unionArray[i].getI8Const()); break; + case EOpConvInt8ToDouble: + newConstArray[i].setDConst(unionArray[i].getI8Const()); break; + case EOpConvUint8ToFloat16: + newConstArray[i].setDConst(unionArray[i].getU8Const()); break; + case EOpConvUint8ToFloat: + newConstArray[i].setDConst(unionArray[i].getU8Const()); break; + case EOpConvUint8ToDouble: + newConstArray[i].setDConst(unionArray[i].getU8Const()); break; + + case EOpConvInt16ToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getI16Const())); break; + case EOpConvInt16ToInt: + newConstArray[i].setIConst(unionArray[i].getI16Const()); break; + case EOpConvInt16ToInt64: + newConstArray[i].setI64Const(unionArray[i].getI16Const()); break; + case EOpConvInt16ToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getI16Const())); break; + case EOpConvInt16ToUint16: + newConstArray[i].setU16Const(unionArray[i].getI16Const()); break; + case EOpConvInt16ToUint: + newConstArray[i].setUConst(unionArray[i].getI16Const()); break; + case EOpConvInt16ToUint64: + newConstArray[i].setU64Const(unionArray[i].getI16Const()); break; + case EOpConvUint16ToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getU16Const())); break; + case EOpConvUint16ToInt16: + newConstArray[i].setI16Const(unionArray[i].getU16Const()); break; + case EOpConvUint16ToInt: + newConstArray[i].setIConst(unionArray[i].getU16Const()); break; + case EOpConvUint16ToInt64: + newConstArray[i].setI64Const(unionArray[i].getU16Const()); break; + case EOpConvUint16ToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getU16Const())); break; + + case EOpConvUint16ToUint: + newConstArray[i].setUConst(unionArray[i].getU16Const()); break; + case EOpConvUint16ToUint64: + newConstArray[i].setU64Const(unionArray[i].getU16Const()); break; + case EOpConvInt16ToFloat16: + newConstArray[i].setDConst(unionArray[i].getI16Const()); break; + case EOpConvInt16ToFloat: + newConstArray[i].setDConst(unionArray[i].getI16Const()); break; + case EOpConvInt16ToDouble: + newConstArray[i].setDConst(unionArray[i].getI16Const()); break; + case EOpConvUint16ToFloat16: + newConstArray[i].setDConst(unionArray[i].getU16Const()); break; + case EOpConvUint16ToFloat: + newConstArray[i].setDConst(unionArray[i].getU16Const()); break; + case EOpConvUint16ToDouble: + newConstArray[i].setDConst(unionArray[i].getU16Const()); break; + + case EOpConvIntToInt8: + newConstArray[i].setI8Const((signed char)unionArray[i].getIConst()); break; + case EOpConvIntToInt16: + newConstArray[i].setI16Const((signed short)unionArray[i].getIConst()); break; + case EOpConvIntToInt64: + newConstArray[i].setI64Const(unionArray[i].getIConst()); break; + case EOpConvIntToUint8: + newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break; + case EOpConvIntToUint16: + newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break; + case EOpConvIntToUint: + newConstArray[i].setUConst(unionArray[i].getIConst()); break; + case EOpConvIntToUint64: + newConstArray[i].setU64Const(unionArray[i].getIConst()); break; + + case EOpConvUintToInt8: + newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break; + case EOpConvUintToInt16: + newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break; + case EOpConvUintToInt: + newConstArray[i].setIConst(unionArray[i].getUConst()); break; + case EOpConvUintToInt64: + newConstArray[i].setI64Const(unionArray[i].getUConst()); break; + case EOpConvUintToUint8: + newConstArray[i].setU8Const((unsigned char)unionArray[i].getUConst()); break; + case EOpConvUintToUint16: + newConstArray[i].setU16Const((unsigned short)unionArray[i].getUConst()); break; + case EOpConvUintToUint64: + newConstArray[i].setU64Const(unionArray[i].getUConst()); break; + case EOpConvIntToFloat16: + newConstArray[i].setDConst(unionArray[i].getIConst()); break; + case EOpConvIntToFloat: + newConstArray[i].setDConst(unionArray[i].getIConst()); break; + case EOpConvIntToDouble: + newConstArray[i].setDConst(unionArray[i].getIConst()); break; + case EOpConvUintToFloat16: + newConstArray[i].setDConst(unionArray[i].getUConst()); break; + case EOpConvUintToFloat: + newConstArray[i].setDConst(unionArray[i].getUConst()); break; + case EOpConvUintToDouble: + newConstArray[i].setDConst(unionArray[i].getUConst()); break; + case EOpConvInt64ToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToInt16: + newConstArray[i].setI16Const(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToUint16: + newConstArray[i].setU16Const(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToUint64: + newConstArray[i].setU64Const(unionArray[i].getI64Const()); break; + case EOpConvUint64ToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToInt16: + newConstArray[i].setI16Const(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToInt64: + newConstArray[i].setI64Const(unionArray[i].getU64Const()); break; + case EOpConvUint64ToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToUint16: + newConstArray[i].setU16Const(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getU64Const())); break; + case EOpConvInt64ToFloat16: + newConstArray[i].setDConst(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToFloat: + newConstArray[i].setDConst(static_cast(unionArray[i].getI64Const())); break; + case EOpConvInt64ToDouble: + newConstArray[i].setDConst(static_cast(unionArray[i].getI64Const())); break; + case EOpConvUint64ToFloat16: + newConstArray[i].setDConst(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToFloat: + newConstArray[i].setDConst(static_cast(unionArray[i].getU64Const())); break; + case EOpConvUint64ToDouble: + newConstArray[i].setDConst(static_cast(unionArray[i].getU64Const())); break; + case EOpConvFloat16ToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToInt16: + newConstArray[i].setI16Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToInt64: + newConstArray[i].setI64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToUint16: + newConstArray[i].setU16Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToUint64: + newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloat16ToFloat: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvFloat16ToDouble: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvFloatToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToInt16: + newConstArray[i].setI16Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToInt64: + newConstArray[i].setI64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToUint16: + newConstArray[i].setU16Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToUint64: + newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToFloat16: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvFloatToDouble: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvDoubleToInt8: + newConstArray[i].setI8Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToInt16: + newConstArray[i].setI16Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToInt64: + newConstArray[i].setI64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToUint8: + newConstArray[i].setU8Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToUint16: + newConstArray[i].setU16Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToUint64: + newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToFloat16: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvDoubleToFloat: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvPtrToUint64: + case EOpConvUint64ToPtr: + case EOpConstructReference: + newConstArray[i].setU64Const(unionArray[i].getU64Const()); break; + + + // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out case EOpSinh: @@ -659,13 +965,10 @@ case EOpDoubleBitsToUint64: case EOpInt64BitsToDouble: case EOpUint64BitsToDouble: -#ifdef AMD_EXTENSIONS case EOpFloat16BitsToInt16: case EOpFloat16BitsToUint16: case EOpInt16BitsToFloat16: case EOpUint16BitsToFloat16: -#endif - default: return 0; } @@ -749,20 +1052,6 @@ for (unsigned int arg = 0; arg < children.size(); ++arg) childConstUnions.push_back(children[arg]->getAsConstantUnion()->getConstArray()); - // Second, do the actual folding - - bool isFloatingPoint = children[0]->getAsTyped()->getBasicType() == EbtFloat || -#ifdef AMD_EXTENSIONS - children[0]->getAsTyped()->getBasicType() == EbtFloat16 || -#endif - children[0]->getAsTyped()->getBasicType() == EbtDouble; - bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt || -#ifdef AMD_EXTENSIONS - children[0]->getAsTyped()->getBasicType() == EbtInt16 || -#endif - children[0]->getAsTyped()->getBasicType() == EbtInt64; - bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 || - children[0]->getAsTyped()->getBasicType() == EbtUint64; if (componentwise) { for (int comp = 0; comp < objectSize; comp++) { @@ -783,53 +1072,114 @@ newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); break; case EOpMin: - if (isFloatingPoint) + switch(children[0]->getAsTyped()->getBasicType()) { + case EbtFloat16: + case EbtFloat: + case EbtDouble: newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); - else if (isSigned) { - if (isInt64) - newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); - else - newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); - } else { - if (isInt64) - newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); - else - newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + break; + case EbtInt8: + newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); + break; + case EbtUint8: + newConstArray[comp].setU8Const(std::min(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const())); + break; + case EbtInt16: + newConstArray[comp].setI16Const(std::min(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const())); + break; + case EbtUint16: + newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const())); + break; + case EbtInt: + newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); + break; + case EbtUint: + newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + break; + case EbtInt64: + newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); + break; + case EbtUint64: + newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); + break; + default: assert(false && "Default missing"); } break; case EOpMax: - if (isFloatingPoint) + switch(children[0]->getAsTyped()->getBasicType()) { + case EbtFloat16: + case EbtFloat: + case EbtDouble: newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); - else if (isSigned) { - if (isInt64) - newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); - else - newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); - } else { - if (isInt64) - newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); - else - newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + break; + case EbtInt8: + newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); + break; + case EbtUint8: + newConstArray[comp].setU8Const(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const())); + break; + case EbtInt16: + newConstArray[comp].setI16Const(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const())); + break; + case EbtUint16: + newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const())); + break; + case EbtInt: + newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); + break; + case EbtUint: + newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); + break; + case EbtInt64: + newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const())); + break; + case EbtUint64: + newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); + break; + default: assert(false && "Default missing"); } break; case EOpClamp: - if (isFloatingPoint) + switch(children[0]->getAsTyped()->getBasicType()) { + case EbtFloat16: + case EbtFloat: + case EbtDouble: newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()), childConstUnions[2][arg2comp].getDConst())); - else if (isSigned) { - if (isInt64) - newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()), - childConstUnions[2][arg2comp].getI64Const())); - else - newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), + break; + case EbtInt8: + newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()), + childConstUnions[2][arg2comp].getI8Const())); + break; + case EbtUint8: + newConstArray[comp].setU8Const(std::min(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()), + childConstUnions[2][arg2comp].getU8Const())); + break; + case EbtInt16: + newConstArray[comp].setI16Const(std::min(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()), + childConstUnions[2][arg2comp].getI16Const())); + break; + case EbtUint16: + newConstArray[comp].setU16Const(std::min(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()), + childConstUnions[2][arg2comp].getU16Const())); + break; + case EbtInt: + newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), childConstUnions[2][arg2comp].getIConst())); - } else { - if (isInt64) - newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()), - childConstUnions[2][arg2comp].getU64Const())); - else - newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), + break; + case EbtUint: + newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), childConstUnions[2][arg2comp].getUConst())); + break; + case EbtInt64: + newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()), + childConstUnions[2][arg2comp].getI64Const())); + break; + case EbtUint64: + newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()), + childConstUnions[2][arg2comp].getU64Const())); + break; + default: assert(false && "Default missing"); } break; case EOpLessThan: @@ -1008,7 +1358,9 @@ // arrays, vectors, matrices, all use simple multiplicative math // while structures need to add up heterogeneous members int start; - if (node->isArray() || ! node->isStruct()) + if (node->getType().isCoopMat()) + start = 0; + else if (node->isArray() || ! node->isStruct()) start = size * index; else { // it is a structure diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0" +#define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -62,7 +62,7 @@ /* Copy the first part of user declarations. */ -#line 41 "MachineIndependent/glslang.y" /* yacc.c:339 */ +#line 43 "MachineIndependent/glslang.y" /* yacc.c:339 */ /* Based on: @@ -83,17 +83,18 @@ #include "SymbolTable.h" #include "ParseHelper.h" #include "../Public/ShaderLang.h" +#include "attribute.h" using namespace glslang; -#line 91 "MachineIndependent/glslang_tab.cpp" /* yacc.c:339 */ +#line 92 "MachineIndependent/glslang_tab.cpp" /* yacc.c:339 */ -# ifndef YY_NULL +# ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr +# define YY_NULLPTR nullptr # else -# define YY_NULL 0 +# define YY_NULLPTR 0 # endif # endif @@ -124,308 +125,418 @@ { ATTRIBUTE = 258, VARYING = 259, - CONST = 260, - BOOL = 261, - FLOAT = 262, + FLOAT16_T = 260, + FLOAT = 261, + FLOAT32_T = 262, DOUBLE = 263, - INT = 264, - UINT = 265, - INT64_T = 266, - UINT64_T = 267, - INT16_T = 268, - UINT16_T = 269, - FLOAT16_T = 270, - BREAK = 271, - CONTINUE = 272, - DO = 273, - ELSE = 274, - FOR = 275, - IF = 276, - DISCARD = 277, - RETURN = 278, - SWITCH = 279, - CASE = 280, - DEFAULT = 281, - SUBROUTINE = 282, - BVEC2 = 283, - BVEC3 = 284, - BVEC4 = 285, - IVEC2 = 286, - IVEC3 = 287, - IVEC4 = 288, - I64VEC2 = 289, - I64VEC3 = 290, - I64VEC4 = 291, - UVEC2 = 292, - UVEC3 = 293, - UVEC4 = 294, - U64VEC2 = 295, - U64VEC3 = 296, - U64VEC4 = 297, - VEC2 = 298, - VEC3 = 299, - VEC4 = 300, - MAT2 = 301, - MAT3 = 302, - MAT4 = 303, - CENTROID = 304, - IN = 305, - OUT = 306, - INOUT = 307, - UNIFORM = 308, - PATCH = 309, - SAMPLE = 310, - BUFFER = 311, - SHARED = 312, - COHERENT = 313, - VOLATILE = 314, - RESTRICT = 315, - READONLY = 316, - WRITEONLY = 317, - DVEC2 = 318, - DVEC3 = 319, - DVEC4 = 320, - DMAT2 = 321, - DMAT3 = 322, - DMAT4 = 323, - F16VEC2 = 324, - F16VEC3 = 325, - F16VEC4 = 326, - F16MAT2 = 327, - F16MAT3 = 328, - F16MAT4 = 329, - I16VEC2 = 330, - I16VEC3 = 331, - I16VEC4 = 332, - U16VEC2 = 333, - U16VEC3 = 334, - U16VEC4 = 335, - NOPERSPECTIVE = 336, - FLAT = 337, - SMOOTH = 338, - LAYOUT = 339, - __EXPLICITINTERPAMD = 340, - MAT2X2 = 341, - MAT2X3 = 342, - MAT2X4 = 343, - MAT3X2 = 344, - MAT3X3 = 345, - MAT3X4 = 346, - MAT4X2 = 347, - MAT4X3 = 348, - MAT4X4 = 349, - DMAT2X2 = 350, - DMAT2X3 = 351, - DMAT2X4 = 352, - DMAT3X2 = 353, - DMAT3X3 = 354, - DMAT3X4 = 355, - DMAT4X2 = 356, - DMAT4X3 = 357, - DMAT4X4 = 358, - F16MAT2X2 = 359, - F16MAT2X3 = 360, - F16MAT2X4 = 361, - F16MAT3X2 = 362, - F16MAT3X3 = 363, - F16MAT3X4 = 364, - F16MAT4X2 = 365, - F16MAT4X3 = 366, - F16MAT4X4 = 367, - ATOMIC_UINT = 368, - SAMPLER1D = 369, - SAMPLER2D = 370, - SAMPLER3D = 371, - SAMPLERCUBE = 372, - SAMPLER1DSHADOW = 373, - SAMPLER2DSHADOW = 374, - SAMPLERCUBESHADOW = 375, - SAMPLER1DARRAY = 376, - SAMPLER2DARRAY = 377, - SAMPLER1DARRAYSHADOW = 378, - SAMPLER2DARRAYSHADOW = 379, - ISAMPLER1D = 380, - ISAMPLER2D = 381, - ISAMPLER3D = 382, - ISAMPLERCUBE = 383, - ISAMPLER1DARRAY = 384, - ISAMPLER2DARRAY = 385, - USAMPLER1D = 386, - USAMPLER2D = 387, - USAMPLER3D = 388, - USAMPLERCUBE = 389, - USAMPLER1DARRAY = 390, - USAMPLER2DARRAY = 391, - SAMPLER2DRECT = 392, - SAMPLER2DRECTSHADOW = 393, - ISAMPLER2DRECT = 394, - USAMPLER2DRECT = 395, - SAMPLERBUFFER = 396, - ISAMPLERBUFFER = 397, - USAMPLERBUFFER = 398, - SAMPLERCUBEARRAY = 399, - SAMPLERCUBEARRAYSHADOW = 400, - ISAMPLERCUBEARRAY = 401, - USAMPLERCUBEARRAY = 402, - SAMPLER2DMS = 403, - ISAMPLER2DMS = 404, - USAMPLER2DMS = 405, - SAMPLER2DMSARRAY = 406, - ISAMPLER2DMSARRAY = 407, - USAMPLER2DMSARRAY = 408, - SAMPLEREXTERNALOES = 409, - SAMPLER = 410, - SAMPLERSHADOW = 411, - TEXTURE1D = 412, - TEXTURE2D = 413, - TEXTURE3D = 414, - TEXTURECUBE = 415, - TEXTURE1DARRAY = 416, - TEXTURE2DARRAY = 417, - ITEXTURE1D = 418, - ITEXTURE2D = 419, - ITEXTURE3D = 420, - ITEXTURECUBE = 421, - ITEXTURE1DARRAY = 422, - ITEXTURE2DARRAY = 423, - UTEXTURE1D = 424, - UTEXTURE2D = 425, - UTEXTURE3D = 426, - UTEXTURECUBE = 427, - UTEXTURE1DARRAY = 428, - UTEXTURE2DARRAY = 429, - TEXTURE2DRECT = 430, - ITEXTURE2DRECT = 431, - UTEXTURE2DRECT = 432, - TEXTUREBUFFER = 433, - ITEXTUREBUFFER = 434, - UTEXTUREBUFFER = 435, - TEXTURECUBEARRAY = 436, - ITEXTURECUBEARRAY = 437, - UTEXTURECUBEARRAY = 438, - TEXTURE2DMS = 439, - ITEXTURE2DMS = 440, - UTEXTURE2DMS = 441, - TEXTURE2DMSARRAY = 442, - ITEXTURE2DMSARRAY = 443, - UTEXTURE2DMSARRAY = 444, - SUBPASSINPUT = 445, - SUBPASSINPUTMS = 446, - ISUBPASSINPUT = 447, - ISUBPASSINPUTMS = 448, - USUBPASSINPUT = 449, - USUBPASSINPUTMS = 450, - IMAGE1D = 451, - IIMAGE1D = 452, - UIMAGE1D = 453, - IMAGE2D = 454, - IIMAGE2D = 455, - UIMAGE2D = 456, - IMAGE3D = 457, - IIMAGE3D = 458, - UIMAGE3D = 459, - IMAGE2DRECT = 460, - IIMAGE2DRECT = 461, - UIMAGE2DRECT = 462, - IMAGECUBE = 463, - IIMAGECUBE = 464, - UIMAGECUBE = 465, - IMAGEBUFFER = 466, - IIMAGEBUFFER = 467, - UIMAGEBUFFER = 468, - IMAGE1DARRAY = 469, - IIMAGE1DARRAY = 470, - UIMAGE1DARRAY = 471, - IMAGE2DARRAY = 472, - IIMAGE2DARRAY = 473, - UIMAGE2DARRAY = 474, - IMAGECUBEARRAY = 475, - IIMAGECUBEARRAY = 476, - UIMAGECUBEARRAY = 477, - IMAGE2DMS = 478, - IIMAGE2DMS = 479, - UIMAGE2DMS = 480, - IMAGE2DMSARRAY = 481, - IIMAGE2DMSARRAY = 482, - UIMAGE2DMSARRAY = 483, - STRUCT = 484, - VOID = 485, - WHILE = 486, - IDENTIFIER = 487, - TYPE_NAME = 488, - FLOATCONSTANT = 489, - DOUBLECONSTANT = 490, - INTCONSTANT = 491, - UINTCONSTANT = 492, - INT64CONSTANT = 493, - UINT64CONSTANT = 494, - INT16CONSTANT = 495, - UINT16CONSTANT = 496, - BOOLCONSTANT = 497, - FLOAT16CONSTANT = 498, - LEFT_OP = 499, - RIGHT_OP = 500, - INC_OP = 501, - DEC_OP = 502, - LE_OP = 503, - GE_OP = 504, - EQ_OP = 505, - NE_OP = 506, - AND_OP = 507, - OR_OP = 508, - XOR_OP = 509, - MUL_ASSIGN = 510, - DIV_ASSIGN = 511, - ADD_ASSIGN = 512, - MOD_ASSIGN = 513, - LEFT_ASSIGN = 514, - RIGHT_ASSIGN = 515, - AND_ASSIGN = 516, - XOR_ASSIGN = 517, - OR_ASSIGN = 518, - SUB_ASSIGN = 519, - LEFT_PAREN = 520, - RIGHT_PAREN = 521, - LEFT_BRACKET = 522, - RIGHT_BRACKET = 523, - LEFT_BRACE = 524, - RIGHT_BRACE = 525, - DOT = 526, - COMMA = 527, - COLON = 528, - EQUAL = 529, - SEMICOLON = 530, - BANG = 531, - DASH = 532, - TILDE = 533, - PLUS = 534, - STAR = 535, - SLASH = 536, - PERCENT = 537, - LEFT_ANGLE = 538, - RIGHT_ANGLE = 539, - VERTICAL_BAR = 540, - CARET = 541, - AMPERSAND = 542, - QUESTION = 543, - INVARIANT = 544, - PRECISE = 545, - HIGH_PRECISION = 546, - MEDIUM_PRECISION = 547, - LOW_PRECISION = 548, - PRECISION = 549, - PACKED = 550, - RESOURCE = 551, - SUPERP = 552 + FLOAT64_T = 264, + CONST = 265, + BOOL = 266, + INT = 267, + UINT = 268, + INT64_T = 269, + UINT64_T = 270, + INT32_T = 271, + UINT32_T = 272, + INT16_T = 273, + UINT16_T = 274, + INT8_T = 275, + UINT8_T = 276, + BREAK = 277, + CONTINUE = 278, + DO = 279, + ELSE = 280, + FOR = 281, + IF = 282, + DISCARD = 283, + RETURN = 284, + SWITCH = 285, + CASE = 286, + DEFAULT = 287, + SUBROUTINE = 288, + BVEC2 = 289, + BVEC3 = 290, + BVEC4 = 291, + IVEC2 = 292, + IVEC3 = 293, + IVEC4 = 294, + UVEC2 = 295, + UVEC3 = 296, + UVEC4 = 297, + I64VEC2 = 298, + I64VEC3 = 299, + I64VEC4 = 300, + U64VEC2 = 301, + U64VEC3 = 302, + U64VEC4 = 303, + I32VEC2 = 304, + I32VEC3 = 305, + I32VEC4 = 306, + U32VEC2 = 307, + U32VEC3 = 308, + U32VEC4 = 309, + I16VEC2 = 310, + I16VEC3 = 311, + I16VEC4 = 312, + U16VEC2 = 313, + U16VEC3 = 314, + U16VEC4 = 315, + I8VEC2 = 316, + I8VEC3 = 317, + I8VEC4 = 318, + U8VEC2 = 319, + U8VEC3 = 320, + U8VEC4 = 321, + VEC2 = 322, + VEC3 = 323, + VEC4 = 324, + MAT2 = 325, + MAT3 = 326, + MAT4 = 327, + CENTROID = 328, + IN = 329, + OUT = 330, + INOUT = 331, + UNIFORM = 332, + PATCH = 333, + SAMPLE = 334, + BUFFER = 335, + SHARED = 336, + NONUNIFORM = 337, + PAYLOADNV = 338, + PAYLOADINNV = 339, + HITATTRNV = 340, + CALLDATANV = 341, + CALLDATAINNV = 342, + COHERENT = 343, + VOLATILE = 344, + RESTRICT = 345, + READONLY = 346, + WRITEONLY = 347, + DEVICECOHERENT = 348, + QUEUEFAMILYCOHERENT = 349, + WORKGROUPCOHERENT = 350, + SUBGROUPCOHERENT = 351, + NONPRIVATE = 352, + DVEC2 = 353, + DVEC3 = 354, + DVEC4 = 355, + DMAT2 = 356, + DMAT3 = 357, + DMAT4 = 358, + F16VEC2 = 359, + F16VEC3 = 360, + F16VEC4 = 361, + F16MAT2 = 362, + F16MAT3 = 363, + F16MAT4 = 364, + F32VEC2 = 365, + F32VEC3 = 366, + F32VEC4 = 367, + F32MAT2 = 368, + F32MAT3 = 369, + F32MAT4 = 370, + F64VEC2 = 371, + F64VEC3 = 372, + F64VEC4 = 373, + F64MAT2 = 374, + F64MAT3 = 375, + F64MAT4 = 376, + NOPERSPECTIVE = 377, + FLAT = 378, + SMOOTH = 379, + LAYOUT = 380, + EXPLICITINTERPAMD = 381, + PERVERTEXNV = 382, + PERPRIMITIVENV = 383, + PERVIEWNV = 384, + PERTASKNV = 385, + MAT2X2 = 386, + MAT2X3 = 387, + MAT2X4 = 388, + MAT3X2 = 389, + MAT3X3 = 390, + MAT3X4 = 391, + MAT4X2 = 392, + MAT4X3 = 393, + MAT4X4 = 394, + DMAT2X2 = 395, + DMAT2X3 = 396, + DMAT2X4 = 397, + DMAT3X2 = 398, + DMAT3X3 = 399, + DMAT3X4 = 400, + DMAT4X2 = 401, + DMAT4X3 = 402, + DMAT4X4 = 403, + F16MAT2X2 = 404, + F16MAT2X3 = 405, + F16MAT2X4 = 406, + F16MAT3X2 = 407, + F16MAT3X3 = 408, + F16MAT3X4 = 409, + F16MAT4X2 = 410, + F16MAT4X3 = 411, + F16MAT4X4 = 412, + F32MAT2X2 = 413, + F32MAT2X3 = 414, + F32MAT2X4 = 415, + F32MAT3X2 = 416, + F32MAT3X3 = 417, + F32MAT3X4 = 418, + F32MAT4X2 = 419, + F32MAT4X3 = 420, + F32MAT4X4 = 421, + F64MAT2X2 = 422, + F64MAT2X3 = 423, + F64MAT2X4 = 424, + F64MAT3X2 = 425, + F64MAT3X3 = 426, + F64MAT3X4 = 427, + F64MAT4X2 = 428, + F64MAT4X3 = 429, + F64MAT4X4 = 430, + ATOMIC_UINT = 431, + ACCSTRUCTNV = 432, + FCOOPMATNV = 433, + SAMPLER1D = 434, + SAMPLER2D = 435, + SAMPLER3D = 436, + SAMPLERCUBE = 437, + SAMPLER1DSHADOW = 438, + SAMPLER2DSHADOW = 439, + SAMPLERCUBESHADOW = 440, + SAMPLER1DARRAY = 441, + SAMPLER2DARRAY = 442, + SAMPLER1DARRAYSHADOW = 443, + SAMPLER2DARRAYSHADOW = 444, + ISAMPLER1D = 445, + ISAMPLER2D = 446, + ISAMPLER3D = 447, + ISAMPLERCUBE = 448, + ISAMPLER1DARRAY = 449, + ISAMPLER2DARRAY = 450, + USAMPLER1D = 451, + USAMPLER2D = 452, + USAMPLER3D = 453, + USAMPLERCUBE = 454, + USAMPLER1DARRAY = 455, + USAMPLER2DARRAY = 456, + SAMPLER2DRECT = 457, + SAMPLER2DRECTSHADOW = 458, + ISAMPLER2DRECT = 459, + USAMPLER2DRECT = 460, + SAMPLERBUFFER = 461, + ISAMPLERBUFFER = 462, + USAMPLERBUFFER = 463, + SAMPLERCUBEARRAY = 464, + SAMPLERCUBEARRAYSHADOW = 465, + ISAMPLERCUBEARRAY = 466, + USAMPLERCUBEARRAY = 467, + SAMPLER2DMS = 468, + ISAMPLER2DMS = 469, + USAMPLER2DMS = 470, + SAMPLER2DMSARRAY = 471, + ISAMPLER2DMSARRAY = 472, + USAMPLER2DMSARRAY = 473, + SAMPLEREXTERNALOES = 474, + SAMPLEREXTERNAL2DY2YEXT = 475, + F16SAMPLER1D = 476, + F16SAMPLER2D = 477, + F16SAMPLER3D = 478, + F16SAMPLER2DRECT = 479, + F16SAMPLERCUBE = 480, + F16SAMPLER1DARRAY = 481, + F16SAMPLER2DARRAY = 482, + F16SAMPLERCUBEARRAY = 483, + F16SAMPLERBUFFER = 484, + F16SAMPLER2DMS = 485, + F16SAMPLER2DMSARRAY = 486, + F16SAMPLER1DSHADOW = 487, + F16SAMPLER2DSHADOW = 488, + F16SAMPLER1DARRAYSHADOW = 489, + F16SAMPLER2DARRAYSHADOW = 490, + F16SAMPLER2DRECTSHADOW = 491, + F16SAMPLERCUBESHADOW = 492, + F16SAMPLERCUBEARRAYSHADOW = 493, + SAMPLER = 494, + SAMPLERSHADOW = 495, + TEXTURE1D = 496, + TEXTURE2D = 497, + TEXTURE3D = 498, + TEXTURECUBE = 499, + TEXTURE1DARRAY = 500, + TEXTURE2DARRAY = 501, + ITEXTURE1D = 502, + ITEXTURE2D = 503, + ITEXTURE3D = 504, + ITEXTURECUBE = 505, + ITEXTURE1DARRAY = 506, + ITEXTURE2DARRAY = 507, + UTEXTURE1D = 508, + UTEXTURE2D = 509, + UTEXTURE3D = 510, + UTEXTURECUBE = 511, + UTEXTURE1DARRAY = 512, + UTEXTURE2DARRAY = 513, + TEXTURE2DRECT = 514, + ITEXTURE2DRECT = 515, + UTEXTURE2DRECT = 516, + TEXTUREBUFFER = 517, + ITEXTUREBUFFER = 518, + UTEXTUREBUFFER = 519, + TEXTURECUBEARRAY = 520, + ITEXTURECUBEARRAY = 521, + UTEXTURECUBEARRAY = 522, + TEXTURE2DMS = 523, + ITEXTURE2DMS = 524, + UTEXTURE2DMS = 525, + TEXTURE2DMSARRAY = 526, + ITEXTURE2DMSARRAY = 527, + UTEXTURE2DMSARRAY = 528, + F16TEXTURE1D = 529, + F16TEXTURE2D = 530, + F16TEXTURE3D = 531, + F16TEXTURE2DRECT = 532, + F16TEXTURECUBE = 533, + F16TEXTURE1DARRAY = 534, + F16TEXTURE2DARRAY = 535, + F16TEXTURECUBEARRAY = 536, + F16TEXTUREBUFFER = 537, + F16TEXTURE2DMS = 538, + F16TEXTURE2DMSARRAY = 539, + SUBPASSINPUT = 540, + SUBPASSINPUTMS = 541, + ISUBPASSINPUT = 542, + ISUBPASSINPUTMS = 543, + USUBPASSINPUT = 544, + USUBPASSINPUTMS = 545, + F16SUBPASSINPUT = 546, + F16SUBPASSINPUTMS = 547, + IMAGE1D = 548, + IIMAGE1D = 549, + UIMAGE1D = 550, + IMAGE2D = 551, + IIMAGE2D = 552, + UIMAGE2D = 553, + IMAGE3D = 554, + IIMAGE3D = 555, + UIMAGE3D = 556, + IMAGE2DRECT = 557, + IIMAGE2DRECT = 558, + UIMAGE2DRECT = 559, + IMAGECUBE = 560, + IIMAGECUBE = 561, + UIMAGECUBE = 562, + IMAGEBUFFER = 563, + IIMAGEBUFFER = 564, + UIMAGEBUFFER = 565, + IMAGE1DARRAY = 566, + IIMAGE1DARRAY = 567, + UIMAGE1DARRAY = 568, + IMAGE2DARRAY = 569, + IIMAGE2DARRAY = 570, + UIMAGE2DARRAY = 571, + IMAGECUBEARRAY = 572, + IIMAGECUBEARRAY = 573, + UIMAGECUBEARRAY = 574, + IMAGE2DMS = 575, + IIMAGE2DMS = 576, + UIMAGE2DMS = 577, + IMAGE2DMSARRAY = 578, + IIMAGE2DMSARRAY = 579, + UIMAGE2DMSARRAY = 580, + F16IMAGE1D = 581, + F16IMAGE2D = 582, + F16IMAGE3D = 583, + F16IMAGE2DRECT = 584, + F16IMAGECUBE = 585, + F16IMAGE1DARRAY = 586, + F16IMAGE2DARRAY = 587, + F16IMAGECUBEARRAY = 588, + F16IMAGEBUFFER = 589, + F16IMAGE2DMS = 590, + F16IMAGE2DMSARRAY = 591, + STRUCT = 592, + VOID = 593, + WHILE = 594, + IDENTIFIER = 595, + TYPE_NAME = 596, + FLOATCONSTANT = 597, + DOUBLECONSTANT = 598, + INT16CONSTANT = 599, + UINT16CONSTANT = 600, + INT32CONSTANT = 601, + UINT32CONSTANT = 602, + INTCONSTANT = 603, + UINTCONSTANT = 604, + INT64CONSTANT = 605, + UINT64CONSTANT = 606, + BOOLCONSTANT = 607, + FLOAT16CONSTANT = 608, + LEFT_OP = 609, + RIGHT_OP = 610, + INC_OP = 611, + DEC_OP = 612, + LE_OP = 613, + GE_OP = 614, + EQ_OP = 615, + NE_OP = 616, + AND_OP = 617, + OR_OP = 618, + XOR_OP = 619, + MUL_ASSIGN = 620, + DIV_ASSIGN = 621, + ADD_ASSIGN = 622, + MOD_ASSIGN = 623, + LEFT_ASSIGN = 624, + RIGHT_ASSIGN = 625, + AND_ASSIGN = 626, + XOR_ASSIGN = 627, + OR_ASSIGN = 628, + SUB_ASSIGN = 629, + LEFT_PAREN = 630, + RIGHT_PAREN = 631, + LEFT_BRACKET = 632, + RIGHT_BRACKET = 633, + LEFT_BRACE = 634, + RIGHT_BRACE = 635, + DOT = 636, + COMMA = 637, + COLON = 638, + EQUAL = 639, + SEMICOLON = 640, + BANG = 641, + DASH = 642, + TILDE = 643, + PLUS = 644, + STAR = 645, + SLASH = 646, + PERCENT = 647, + LEFT_ANGLE = 648, + RIGHT_ANGLE = 649, + VERTICAL_BAR = 650, + CARET = 651, + AMPERSAND = 652, + QUESTION = 653, + INVARIANT = 654, + PRECISE = 655, + HIGH_PRECISION = 656, + MEDIUM_PRECISION = 657, + LOW_PRECISION = 658, + PRECISION = 659, + PACKED = 660, + RESOURCE = 661, + SUPERP = 662 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; + union YYSTYPE { -#line 68 "MachineIndependent/glslang.y" /* yacc.c:355 */ +#line 71 "MachineIndependent/glslang.y" /* yacc.c:355 */ struct { glslang::TSourceLoc loc; @@ -447,6 +558,7 @@ TIntermNode* intermNode; glslang::TIntermNodePair nodePair; glslang::TIntermTyped* intermTypedNode; + glslang::TAttributes* attributes; }; union { glslang::TPublicType type; @@ -457,10 +569,13 @@ glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; -#line 463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ +#line 576 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ }; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif @@ -472,7 +587,7 @@ #endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 102 "MachineIndependent/glslang.y" /* yacc.c:358 */ +#line 107 "MachineIndependent/glslang.y" /* yacc.c:358 */ /* windows only pragma */ @@ -488,7 +603,7 @@ extern int yylex(YYSTYPE*, TParseContext&); -#line 492 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ +#line 607 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -545,11 +660,30 @@ # endif #endif -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if (! defined __GNUC__ || __GNUC__ < 2 \ - || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) -# define __attribute__(Spec) /* empty */ +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif @@ -709,23 +843,23 @@ #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 274 +#define YYFINAL 384 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 6614 +#define YYLAST 9348 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 298 +#define YYNTOKENS 408 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 100 +#define YYNNTS 110 /* YYNRULES -- Number of rules. */ -#define YYNRULES 450 +#define YYNRULES 578 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 582 +#define YYNSTATES 722 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 552 +#define YYMAXUTOK 662 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -789,59 +923,82 @@ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297 + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 253, 253, 259, 262, 265, 269, 273, 277, 283, - 289, 292, 296, 302, 305, 313, 316, 319, 322, 325, - 330, 338, 345, 352, 358, 362, 369, 372, 378, 385, - 395, 403, 408, 438, 444, 448, 452, 472, 473, 474, - 475, 481, 482, 487, 492, 501, 502, 507, 515, 516, - 522, 531, 532, 537, 542, 547, 555, 556, 564, 575, - 576, 585, 586, 595, 596, 605, 606, 614, 615, 623, - 624, 632, 633, 633, 651, 652, 667, 671, 675, 679, - 684, 688, 692, 696, 700, 704, 708, 715, 718, 729, - 736, 741, 746, 754, 758, 762, 766, 771, 776, 785, - 785, 796, 800, 807, 814, 817, 824, 832, 852, 875, - 890, 913, 924, 934, 944, 954, 963, 966, 970, 974, - 979, 987, 992, 997, 1002, 1007, 1016, 1027, 1054, 1063, - 1070, 1077, 1084, 1096, 1102, 1105, 1112, 1116, 1120, 1128, - 1137, 1140, 1151, 1154, 1157, 1161, 1165, 1169, 1176, 1180, - 1192, 1206, 1211, 1217, 1223, 1230, 1236, 1241, 1246, 1251, - 1259, 1263, 1267, 1271, 1275, 1279, 1285, 1294, 1297, 1305, - 1309, 1318, 1323, 1331, 1335, 1345, 1349, 1353, 1358, 1365, - 1369, 1374, 1379, 1384, 1391, 1398, 1402, 1407, 1412, 1417, - 1423, 1429, 1435, 1443, 1451, 1459, 1464, 1469, 1474, 1479, - 1484, 1489, 1495, 1501, 1507, 1515, 1523, 1531, 1537, 1543, - 1549, 1555, 1561, 1567, 1575, 1583, 1591, 1596, 1601, 1606, - 1611, 1616, 1621, 1626, 1631, 1636, 1641, 1646, 1651, 1657, - 1663, 1669, 1675, 1681, 1687, 1693, 1699, 1705, 1711, 1717, - 1723, 1731, 1739, 1747, 1755, 1763, 1771, 1779, 1787, 1795, - 1803, 1811, 1819, 1824, 1829, 1834, 1839, 1844, 1849, 1854, - 1859, 1864, 1869, 1874, 1879, 1884, 1889, 1894, 1899, 1904, - 1909, 1914, 1919, 1924, 1929, 1934, 1939, 1944, 1949, 1954, - 1959, 1964, 1969, 1974, 1979, 1984, 1989, 1994, 1999, 2004, - 2009, 2014, 2019, 2024, 2029, 2034, 2039, 2044, 2049, 2054, - 2059, 2064, 2069, 2074, 2079, 2084, 2089, 2094, 2099, 2104, - 2109, 2114, 2119, 2124, 2129, 2134, 2139, 2144, 2149, 2154, - 2159, 2164, 2169, 2174, 2179, 2184, 2189, 2194, 2199, 2204, - 2209, 2214, 2219, 2224, 2229, 2234, 2239, 2244, 2249, 2254, - 2259, 2264, 2269, 2274, 2279, 2284, 2289, 2294, 2299, 2304, - 2309, 2314, 2319, 2324, 2329, 2334, 2339, 2344, 2349, 2354, - 2359, 2364, 2370, 2376, 2382, 2388, 2394, 2400, 2406, 2411, - 2427, 2432, 2437, 2445, 2445, 2456, 2456, 2466, 2469, 2482, - 2500, 2524, 2528, 2534, 2539, 2550, 2553, 2559, 2568, 2571, - 2577, 2581, 2582, 2588, 2589, 2590, 2591, 2592, 2593, 2594, - 2598, 2599, 2603, 2599, 2615, 2616, 2620, 2620, 2627, 2627, - 2641, 2644, 2652, 2660, 2671, 2672, 2676, 2683, 2687, 2695, - 2699, 2712, 2712, 2732, 2735, 2741, 2753, 2765, 2765, 2780, - 2780, 2796, 2796, 2817, 2820, 2826, 2829, 2835, 2839, 2846, - 2851, 2856, 2863, 2866, 2875, 2879, 2888, 2891, 2894, 2902, - 2902 + 0, 302, 302, 308, 311, 315, 319, 322, 326, 330, + 334, 338, 342, 345, 349, 353, 356, 364, 367, 370, + 373, 376, 381, 389, 396, 403, 409, 413, 420, 423, + 429, 436, 446, 454, 459, 486, 494, 500, 504, 508, + 528, 529, 530, 531, 537, 538, 543, 548, 557, 558, + 563, 571, 572, 578, 587, 588, 593, 598, 603, 611, + 612, 621, 633, 634, 643, 644, 653, 654, 663, 664, + 672, 673, 681, 682, 690, 691, 691, 709, 710, 726, + 730, 734, 738, 743, 747, 751, 755, 759, 763, 767, + 774, 777, 788, 795, 800, 805, 813, 817, 821, 825, + 830, 835, 844, 844, 855, 859, 866, 873, 876, 883, + 891, 911, 934, 949, 974, 985, 995, 1005, 1015, 1024, + 1027, 1031, 1035, 1040, 1048, 1053, 1058, 1063, 1068, 1077, + 1088, 1115, 1124, 1131, 1138, 1149, 1158, 1168, 1180, 1189, + 1201, 1207, 1210, 1217, 1221, 1225, 1233, 1242, 1245, 1256, + 1259, 1262, 1266, 1270, 1274, 1278, 1284, 1288, 1300, 1314, + 1319, 1325, 1331, 1338, 1344, 1349, 1354, 1359, 1369, 1379, + 1389, 1399, 1408, 1420, 1424, 1429, 1434, 1439, 1444, 1449, + 1453, 1457, 1461, 1465, 1471, 1480, 1487, 1490, 1498, 1503, + 1513, 1518, 1526, 1530, 1540, 1543, 1549, 1555, 1562, 1572, + 1576, 1580, 1585, 1590, 1595, 1600, 1604, 1609, 1614, 1619, + 1624, 1629, 1634, 1639, 1644, 1649, 1653, 1658, 1663, 1668, + 1674, 1680, 1686, 1692, 1698, 1704, 1710, 1716, 1722, 1728, + 1734, 1740, 1745, 1750, 1755, 1760, 1765, 1770, 1776, 1782, + 1788, 1794, 1800, 1806, 1812, 1818, 1824, 1830, 1836, 1842, + 1848, 1854, 1860, 1866, 1872, 1878, 1884, 1890, 1896, 1902, + 1908, 1914, 1920, 1926, 1932, 1937, 1942, 1947, 1952, 1957, + 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1998, 2004, 2010, + 2016, 2022, 2028, 2034, 2040, 2046, 2052, 2058, 2064, 2070, + 2076, 2082, 2088, 2094, 2100, 2106, 2112, 2118, 2124, 2130, + 2136, 2142, 2148, 2154, 2160, 2166, 2172, 2178, 2184, 2190, + 2196, 2202, 2208, 2214, 2220, 2226, 2232, 2238, 2244, 2250, + 2256, 2262, 2268, 2274, 2280, 2286, 2291, 2296, 2301, 2306, + 2311, 2316, 2321, 2326, 2331, 2336, 2341, 2346, 2351, 2356, + 2364, 2372, 2380, 2388, 2396, 2404, 2412, 2420, 2428, 2436, + 2444, 2452, 2460, 2465, 2470, 2475, 2480, 2485, 2490, 2495, + 2500, 2505, 2510, 2515, 2520, 2525, 2530, 2535, 2540, 2548, + 2556, 2561, 2566, 2571, 2579, 2584, 2589, 2594, 2602, 2607, + 2612, 2617, 2625, 2630, 2635, 2640, 2645, 2650, 2658, 2663, + 2671, 2676, 2684, 2689, 2697, 2702, 2710, 2715, 2723, 2728, + 2736, 2741, 2746, 2751, 2756, 2761, 2766, 2771, 2776, 2781, + 2786, 2791, 2796, 2801, 2806, 2811, 2819, 2824, 2829, 2834, + 2842, 2847, 2852, 2857, 2865, 2870, 2875, 2880, 2888, 2893, + 2898, 2903, 2911, 2916, 2921, 2926, 2934, 2939, 2944, 2949, + 2957, 2962, 2967, 2972, 2980, 2985, 2990, 2995, 3003, 3008, + 3013, 3018, 3026, 3031, 3036, 3041, 3049, 3054, 3059, 3064, + 3072, 3077, 3082, 3087, 3095, 3100, 3105, 3110, 3118, 3123, + 3128, 3133, 3141, 3146, 3151, 3157, 3163, 3169, 3175, 3184, + 3193, 3199, 3205, 3211, 3217, 3223, 3228, 3244, 3249, 3254, + 3262, 3262, 3273, 3273, 3283, 3286, 3299, 3321, 3348, 3352, + 3358, 3363, 3374, 3377, 3383, 3392, 3395, 3401, 3405, 3406, + 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3422, 3423, 3427, + 3423, 3439, 3440, 3444, 3444, 3451, 3451, 3465, 3468, 3476, + 3484, 3495, 3496, 3500, 3503, 3509, 3516, 3520, 3528, 3532, + 3545, 3548, 3554, 3554, 3574, 3577, 3583, 3595, 3607, 3610, + 3616, 3616, 3631, 3631, 3647, 3647, 3668, 3671, 3677, 3680, + 3686, 3690, 3697, 3702, 3707, 3714, 3717, 3726, 3730, 3739, + 3742, 3745, 3753, 3753, 3775, 3781, 3784, 3789, 3792 }; #endif @@ -850,24 +1007,37 @@ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "ATTRIBUTE", "VARYING", "CONST", "BOOL", - "FLOAT", "DOUBLE", "INT", "UINT", "INT64_T", "UINT64_T", "INT16_T", - "UINT16_T", "FLOAT16_T", "BREAK", "CONTINUE", "DO", "ELSE", "FOR", "IF", - "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "SUBROUTINE", "BVEC2", - "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "I64VEC2", "I64VEC3", - "I64VEC4", "UVEC2", "UVEC3", "UVEC4", "U64VEC2", "U64VEC3", "U64VEC4", - "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4", "CENTROID", "IN", "OUT", - "INOUT", "UNIFORM", "PATCH", "SAMPLE", "BUFFER", "SHARED", "COHERENT", - "VOLATILE", "RESTRICT", "READONLY", "WRITEONLY", "DVEC2", "DVEC3", + "$end", "error", "$undefined", "ATTRIBUTE", "VARYING", "FLOAT16_T", + "FLOAT", "FLOAT32_T", "DOUBLE", "FLOAT64_T", "CONST", "BOOL", "INT", + "UINT", "INT64_T", "UINT64_T", "INT32_T", "UINT32_T", "INT16_T", + "UINT16_T", "INT8_T", "UINT8_T", "BREAK", "CONTINUE", "DO", "ELSE", + "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", + "SUBROUTINE", "BVEC2", "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", + "UVEC2", "UVEC3", "UVEC4", "I64VEC2", "I64VEC3", "I64VEC4", "U64VEC2", + "U64VEC3", "U64VEC4", "I32VEC2", "I32VEC3", "I32VEC4", "U32VEC2", + "U32VEC3", "U32VEC4", "I16VEC2", "I16VEC3", "I16VEC4", "U16VEC2", + "U16VEC3", "U16VEC4", "I8VEC2", "I8VEC3", "I8VEC4", "U8VEC2", "U8VEC3", + "U8VEC4", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4", "CENTROID", + "IN", "OUT", "INOUT", "UNIFORM", "PATCH", "SAMPLE", "BUFFER", "SHARED", + "NONUNIFORM", "PAYLOADNV", "PAYLOADINNV", "HITATTRNV", "CALLDATANV", + "CALLDATAINNV", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", + "WRITEONLY", "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", + "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", "DVEC2", "DVEC3", "DVEC4", "DMAT2", "DMAT3", "DMAT4", "F16VEC2", "F16VEC3", "F16VEC4", - "F16MAT2", "F16MAT3", "F16MAT4", "I16VEC2", "I16VEC3", "I16VEC4", - "U16VEC2", "U16VEC3", "U16VEC4", "NOPERSPECTIVE", "FLAT", "SMOOTH", - "LAYOUT", "__EXPLICITINTERPAMD", "MAT2X2", "MAT2X3", "MAT2X4", "MAT3X2", + "F16MAT2", "F16MAT3", "F16MAT4", "F32VEC2", "F32VEC3", "F32VEC4", + "F32MAT2", "F32MAT3", "F32MAT4", "F64VEC2", "F64VEC3", "F64VEC4", + "F64MAT2", "F64MAT3", "F64MAT4", "NOPERSPECTIVE", "FLAT", "SMOOTH", + "LAYOUT", "EXPLICITINTERPAMD", "PERVERTEXNV", "PERPRIMITIVENV", + "PERVIEWNV", "PERTASKNV", "MAT2X2", "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", "MAT4X4", "DMAT2X2", "DMAT2X3", "DMAT2X4", "DMAT3X2", "DMAT3X3", "DMAT3X4", "DMAT4X2", "DMAT4X3", "DMAT4X4", "F16MAT2X2", "F16MAT2X3", "F16MAT2X4", "F16MAT3X2", "F16MAT3X3", "F16MAT3X4", "F16MAT4X2", "F16MAT4X3", "F16MAT4X4", - "ATOMIC_UINT", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", + "F32MAT2X2", "F32MAT2X3", "F32MAT2X4", "F32MAT3X2", "F32MAT3X3", + "F32MAT3X4", "F32MAT4X2", "F32MAT4X3", "F32MAT4X4", "F64MAT2X2", + "F64MAT2X3", "F64MAT2X4", "F64MAT3X2", "F64MAT3X3", "F64MAT3X4", + "F64MAT4X2", "F64MAT4X3", "F64MAT4X4", "ATOMIC_UINT", "ACCSTRUCTNV", + "FCOOPMATNV", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", @@ -878,8 +1048,15 @@ "USAMPLERBUFFER", "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", "USAMPLERCUBEARRAY", "SAMPLER2DMS", "ISAMPLER2DMS", "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", - "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLER", "SAMPLERSHADOW", - "TEXTURE1D", "TEXTURE2D", "TEXTURE3D", "TEXTURECUBE", "TEXTURE1DARRAY", + "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", + "F16SAMPLER1D", "F16SAMPLER2D", "F16SAMPLER3D", "F16SAMPLER2DRECT", + "F16SAMPLERCUBE", "F16SAMPLER1DARRAY", "F16SAMPLER2DARRAY", + "F16SAMPLERCUBEARRAY", "F16SAMPLERBUFFER", "F16SAMPLER2DMS", + "F16SAMPLER2DMSARRAY", "F16SAMPLER1DSHADOW", "F16SAMPLER2DSHADOW", + "F16SAMPLER1DARRAYSHADOW", "F16SAMPLER2DARRAYSHADOW", + "F16SAMPLER2DRECTSHADOW", "F16SAMPLERCUBESHADOW", + "F16SAMPLERCUBEARRAYSHADOW", "SAMPLER", "SAMPLERSHADOW", "TEXTURE1D", + "TEXTURE2D", "TEXTURE3D", "TEXTURECUBE", "TEXTURE1DARRAY", "TEXTURE2DARRAY", "ITEXTURE1D", "ITEXTURE2D", "ITEXTURE3D", "ITEXTURECUBE", "ITEXTURE1DARRAY", "ITEXTURE2DARRAY", "UTEXTURE1D", "UTEXTURE2D", "UTEXTURE3D", "UTEXTURECUBE", "UTEXTURE1DARRAY", @@ -887,8 +1064,12 @@ "TEXTUREBUFFER", "ITEXTUREBUFFER", "UTEXTUREBUFFER", "TEXTURECUBEARRAY", "ITEXTURECUBEARRAY", "UTEXTURECUBEARRAY", "TEXTURE2DMS", "ITEXTURE2DMS", "UTEXTURE2DMS", "TEXTURE2DMSARRAY", "ITEXTURE2DMSARRAY", - "UTEXTURE2DMSARRAY", "SUBPASSINPUT", "SUBPASSINPUTMS", "ISUBPASSINPUT", - "ISUBPASSINPUTMS", "USUBPASSINPUT", "USUBPASSINPUTMS", "IMAGE1D", + "UTEXTURE2DMSARRAY", "F16TEXTURE1D", "F16TEXTURE2D", "F16TEXTURE3D", + "F16TEXTURE2DRECT", "F16TEXTURECUBE", "F16TEXTURE1DARRAY", + "F16TEXTURE2DARRAY", "F16TEXTURECUBEARRAY", "F16TEXTUREBUFFER", + "F16TEXTURE2DMS", "F16TEXTURE2DMSARRAY", "SUBPASSINPUT", + "SUBPASSINPUTMS", "ISUBPASSINPUT", "ISUBPASSINPUTMS", "USUBPASSINPUT", + "USUBPASSINPUTMS", "F16SUBPASSINPUT", "F16SUBPASSINPUTMS", "IMAGE1D", "IIMAGE1D", "UIMAGE1D", "IMAGE2D", "IIMAGE2D", "UIMAGE2D", "IMAGE3D", "IIMAGE3D", "UIMAGE3D", "IMAGE2DRECT", "IIMAGE2DRECT", "UIMAGE2DRECT", "IMAGECUBE", "IIMAGECUBE", "UIMAGECUBE", "IMAGEBUFFER", "IIMAGEBUFFER", @@ -896,9 +1077,13 @@ "IMAGE2DARRAY", "IIMAGE2DARRAY", "UIMAGE2DARRAY", "IMAGECUBEARRAY", "IIMAGECUBEARRAY", "UIMAGECUBEARRAY", "IMAGE2DMS", "IIMAGE2DMS", "UIMAGE2DMS", "IMAGE2DMSARRAY", "IIMAGE2DMSARRAY", "UIMAGE2DMSARRAY", - "STRUCT", "VOID", "WHILE", "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", - "DOUBLECONSTANT", "INTCONSTANT", "UINTCONSTANT", "INT64CONSTANT", - "UINT64CONSTANT", "INT16CONSTANT", "UINT16CONSTANT", "BOOLCONSTANT", + "F16IMAGE1D", "F16IMAGE2D", "F16IMAGE3D", "F16IMAGE2DRECT", + "F16IMAGECUBE", "F16IMAGE1DARRAY", "F16IMAGE2DARRAY", + "F16IMAGECUBEARRAY", "F16IMAGEBUFFER", "F16IMAGE2DMS", + "F16IMAGE2DMSARRAY", "STRUCT", "VOID", "WHILE", "IDENTIFIER", + "TYPE_NAME", "FLOATCONSTANT", "DOUBLECONSTANT", "INT16CONSTANT", + "UINT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", "INTCONSTANT", + "UINTCONSTANT", "INT64CONSTANT", "UINT64CONSTANT", "BOOLCONSTANT", "FLOAT16CONSTANT", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", @@ -928,20 +1113,25 @@ "fully_specified_type", "invariant_qualifier", "interpolation_qualifier", "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", "precise_qualifier", "type_qualifier", "single_type_qualifier", - "storage_qualifier", "type_name_list", "type_specifier", - "array_specifier", "type_specifier_nonarray", "precision_qualifier", - "struct_specifier", "$@3", "$@4", "struct_declaration_list", - "struct_declaration", "struct_declarator_list", "struct_declarator", - "initializer", "initializer_list", "declaration_statement", "statement", + "storage_qualifier", "non_uniform_qualifier", "type_name_list", + "type_specifier", "array_specifier", "type_parameter_specifier_opt", + "type_parameter_specifier", "type_parameter_specifier_list", + "type_specifier_nonarray", "precision_qualifier", "struct_specifier", + "$@3", "$@4", "struct_declaration_list", "struct_declaration", + "struct_declarator_list", "struct_declarator", "initializer", + "initializer_list", "declaration_statement", "statement", "simple_statement", "compound_statement", "$@5", "$@6", "statement_no_new_scope", "statement_scoped", "$@7", "$@8", "compound_statement_no_new_scope", "statement_list", "expression_statement", "selection_statement", - "selection_rest_statement", "condition", "switch_statement", "$@9", - "switch_statement_list", "case_label", "iteration_statement", "$@10", - "$@11", "$@12", "for_init_statement", "conditionopt", - "for_rest_statement", "jump_statement", "translation_unit", - "external_declaration", "function_definition", "$@13", YY_NULL + "selection_statement_nonattributed", "selection_rest_statement", + "condition", "switch_statement", "switch_statement_nonattributed", "$@9", + "switch_statement_list", "case_label", "iteration_statement", + "iteration_statement_nonattributed", "$@10", "$@11", "$@12", + "for_init_statement", "conditionopt", "for_rest_statement", + "jump_statement", "translation_unit", "external_declaration", + "function_definition", "$@13", "attribute", "attribute_list", + "single_attribute", YY_NULLPTR }; #endif @@ -979,16 +1169,27 @@ 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, - 545, 546, 547, 548, 549, 550, 551, 552 + 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, + 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, + 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, + 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, + 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, + 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, + 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, + 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, + 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, + 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662 }; # endif -#define YYPACT_NINF -525 +#define YYPACT_NINF -659 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-525))) + (!!((Yystate) == (-659))) -#define YYTABLE_NINF -407 +#define YYTABLE_NINF -524 #define yytable_value_is_error(Yytable_value) \ 0 @@ -997,65 +1198,79 @@ STATE-NUM. */ static const yytype_int16 yypact[] = { - 2619, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -243, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -228, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -215, -525, -525, -525, - -525, -525, -525, -525, -525, -157, -525, -216, -218, -205, - -141, 4260, -165, -525, -94, -525, -525, -525, -525, 3183, - -525, -525, -525, -117, -525, -525, 575, -525, -525, -80, - -48, -114, -525, 6381, -242, -525, -525, -113, -525, 4260, - -525, -525, -525, 4260, -75, -74, -525, -235, -190, -525, - -525, -525, 4765, -108, -525, -525, -525, -186, -525, -112, - -178, -525, -525, 4260, -115, -525, -226, 867, -525, -525, - -525, -525, -117, -229, -525, 5039, -224, -525, -71, -525, - -158, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, 5861, 5861, 5861, -525, -525, -525, -525, -525, - -525, -525, -223, -525, -525, -525, -102, -177, 6121, -100, - -525, 5861, -204, -171, -132, -221, -199, -124, -120, -111, - -84, -83, -233, -98, -525, 5313, -525, -60, 5861, -525, - -48, 4260, 4260, -59, 3456, -525, -525, -525, -99, -97, - -525, -90, -88, -96, 5587, -85, 5861, -92, -79, -81, - -525, -525, -191, -525, -525, -153, -525, -218, -78, -525, - -525, -525, -525, 1159, -525, -525, -525, -525, -525, -525, - -108, 5039, -193, 5039, -525, -525, 5039, 4260, -525, -47, - -525, -525, -525, -176, -525, -525, 5861, -42, -525, -525, - 5861, -73, -525, -525, -525, 5861, 5861, 5861, 5861, 5861, - 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, 5861, - 5861, 5861, 5861, 5861, -525, -525, -525, -76, -525, -525, - -525, -525, 3724, -59, -117, -152, -525, -525, -525, -525, - -525, 1451, -525, 5861, -525, -525, -143, 5861, -180, -525, - -525, -525, 1451, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, 5861, 5861, -525, -525, -525, -525, - 5039, -525, -133, -525, 3992, -525, -525, -72, -77, -525, - -525, -525, -525, -525, -204, -204, -171, -171, -132, -132, - -132, -132, -221, -221, -199, -124, -120, -111, -84, -83, - 5861, -525, -525, -142, -108, -59, -525, -37, 2327, -175, - -525, -163, -525, 2892, 1451, -525, -525, -525, -525, 4491, - -525, -525, -129, -525, -525, -68, -525, -525, 2892, -70, - -525, -77, -32, 4260, -63, -66, -525, -525, 5861, 5861, - -525, -69, -61, 188, -58, 2035, -525, -56, -57, 1743, - -525, -525, -161, 5861, 1743, -70, -525, -525, 1451, 5039, - -525, -525, -525, -67, -77, -525, -525, 1451, -54, -525, - -525, -525 + 3535, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -331, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -324, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -319, -659, -659, -659, -659, -659, + -659, -659, -659, -256, -659, -314, -351, -309, -306, 5942, + -257, -659, -217, -659, -659, -659, -659, 4338, -659, -659, + -659, -659, -241, -659, -659, 721, -659, -659, -204, -71, + -219, -659, 9007, -349, -659, -659, -215, -659, 5942, -659, + -659, -659, 5942, -178, -172, -659, -337, -267, -659, -659, + -659, 8237, -207, -659, -659, -659, -659, -341, -659, -211, + -330, -659, -659, 5942, -210, 6697, -659, -322, 1123, -659, + -659, -659, -659, -207, -328, -659, 7082, -304, -659, -163, + -659, -252, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -659, -659, -659, 8237, 8237, 8237, -659, -659, + -659, -659, -659, -659, -303, -659, -659, -659, -196, -299, + 8622, -194, -659, 8237, -659, -659, -355, -195, -659, -157, + 8237, -659, -71, 5942, 5942, -155, 4739, -659, -659, -659, + -659, -242, -236, -249, -335, -206, -191, -187, -209, -149, + -150, -333, -162, 7467, -659, -170, -168, -659, -154, -153, + -167, 7852, -152, 8237, -159, -148, -151, -160, -659, -659, + -274, -659, -659, -251, -659, -351, -147, -144, -659, -659, + -659, -659, 1525, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -19, -195, 7082, -302, 7082, -659, -659, 7082, + 5942, -659, -115, -659, -659, -659, -292, -659, -659, 8237, + -108, -659, -659, 8237, -143, -659, -659, -659, 8237, -659, + -659, -659, -659, -659, 5140, -155, -207, -250, -659, -659, + -659, 8237, 8237, 8237, 8237, 8237, 8237, 8237, 8237, 8237, + 8237, 8237, 8237, 8237, 8237, 8237, 8237, 8237, 8237, 8237, + -659, -659, -659, -142, -659, -659, 1927, -659, 8237, -659, + -659, -245, 8237, -226, -659, -659, -106, -659, 1927, -659, + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + 8237, 8237, -659, -659, -659, -659, -659, -659, -659, 7082, + -659, -238, -659, 5541, -659, -659, -141, -140, -659, -659, + -659, -659, -244, -195, -155, -659, -659, -659, -659, -242, + -242, -236, -236, -249, -249, -249, -249, -335, -335, -206, + -191, -187, -209, -149, -150, 8237, -659, -104, 3133, -263, + -659, -260, -659, 3937, -136, -297, -659, 1927, -659, -659, + -659, -659, 6312, -659, -659, -659, -659, -224, -135, -659, + -659, 3937, -138, -659, -140, -97, 5942, -132, 8237, -133, + -106, -134, -659, -659, 8237, 8237, -659, -137, -129, 224, + -128, 2731, -659, -127, -131, 2329, -126, -659, -659, -659, + -659, -255, 8237, 2329, -138, -659, -659, 1927, 7082, -659, + -659, -659, -659, -130, -140, -659, -659, 1927, -123, -659, + -659, -659 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1063,95 +1278,111 @@ means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 149, 150, 148, 185, 176, 177, 179, 180, 181, - 182, 183, 184, 178, 165, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 207, 208, 209, 210, 211, 212, - 186, 187, 188, 216, 217, 218, 154, 152, 153, 151, - 157, 155, 156, 158, 159, 160, 161, 162, 163, 164, - 189, 190, 191, 228, 229, 230, 192, 193, 194, 240, - 241, 242, 204, 205, 206, 213, 214, 215, 131, 130, - 129, 0, 132, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 266, 267, 268, 269, 270, 271, 273, 274, - 275, 276, 277, 278, 280, 281, 282, 283, 284, 285, - 286, 264, 265, 272, 279, 287, 288, 289, 290, 291, - 292, 361, 293, 294, 295, 296, 297, 298, 299, 300, - 302, 303, 304, 305, 306, 307, 309, 310, 311, 312, - 313, 314, 316, 317, 318, 319, 320, 321, 301, 308, - 315, 322, 323, 324, 325, 326, 327, 362, 363, 364, - 365, 366, 367, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 0, 175, 369, 448, - 128, 139, 370, 371, 372, 0, 447, 0, 449, 0, - 105, 104, 0, 116, 121, 146, 145, 143, 147, 0, - 140, 142, 126, 169, 144, 368, 0, 444, 446, 0, - 0, 0, 375, 0, 0, 93, 90, 0, 103, 0, - 112, 106, 114, 0, 115, 0, 91, 122, 0, 96, - 141, 127, 0, 170, 1, 445, 167, 0, 138, 136, - 0, 134, 373, 0, 0, 94, 0, 0, 450, 107, - 111, 113, 109, 117, 108, 0, 123, 99, 0, 97, - 0, 2, 10, 11, 4, 5, 6, 7, 8, 9, - 13, 12, 0, 0, 0, 171, 39, 38, 40, 37, - 3, 15, 33, 17, 22, 23, 0, 0, 27, 0, - 41, 0, 45, 48, 51, 56, 59, 61, 63, 65, - 67, 69, 71, 0, 31, 0, 166, 0, 0, 133, - 0, 0, 0, 0, 0, 377, 92, 95, 0, 0, - 429, 0, 0, 0, 0, 0, 0, 0, 0, 401, - 410, 414, 41, 74, 87, 0, 390, 0, 126, 393, - 412, 392, 391, 0, 394, 395, 396, 397, 398, 399, - 110, 0, 118, 0, 385, 125, 0, 0, 101, 0, - 98, 34, 35, 0, 19, 20, 0, 0, 25, 24, - 0, 175, 28, 30, 36, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 72, 172, 173, 0, 168, 89, - 137, 135, 0, 0, 383, 0, 381, 376, 378, 440, - 439, 0, 431, 0, 443, 441, 0, 0, 0, 426, - 427, 400, 0, 77, 78, 80, 79, 82, 83, 84, - 85, 86, 81, 76, 0, 0, 415, 411, 413, 120, - 0, 388, 0, 124, 0, 102, 14, 0, 21, 18, - 29, 42, 43, 44, 47, 46, 49, 50, 54, 55, - 52, 53, 57, 58, 60, 62, 64, 66, 68, 70, - 0, 174, 374, 0, 384, 0, 379, 0, 0, 0, - 442, 0, 425, 0, 402, 75, 88, 119, 386, 0, - 100, 16, 0, 380, 382, 0, 434, 433, 436, 408, - 421, 419, 0, 0, 0, 0, 387, 389, 0, 0, - 435, 0, 0, 418, 0, 0, 416, 0, 0, 0, - 403, 73, 0, 437, 0, 408, 407, 409, 423, 0, - 405, 428, 404, 0, 438, 432, 417, 424, 0, 420, - 430, 422 + 0, 157, 158, 202, 200, 203, 201, 204, 156, 215, + 205, 206, 213, 214, 211, 212, 209, 210, 207, 208, + 183, 231, 232, 233, 234, 235, 236, 249, 250, 251, + 246, 247, 248, 261, 262, 263, 243, 244, 245, 258, + 259, 260, 240, 241, 242, 255, 256, 257, 237, 238, + 239, 252, 253, 254, 216, 217, 218, 264, 265, 266, + 162, 160, 161, 159, 165, 163, 164, 166, 172, 185, + 168, 169, 167, 170, 171, 173, 179, 180, 181, 182, + 174, 175, 176, 177, 178, 219, 220, 221, 276, 277, + 278, 222, 223, 224, 288, 289, 290, 225, 226, 227, + 300, 301, 302, 228, 229, 230, 312, 313, 314, 134, + 133, 132, 0, 135, 136, 137, 138, 139, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 325, 324, 484, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 352, 353, 354, + 355, 356, 357, 359, 360, 361, 362, 363, 364, 366, + 367, 370, 371, 372, 374, 375, 337, 338, 358, 365, + 376, 378, 379, 380, 382, 383, 474, 475, 339, 340, + 341, 368, 342, 346, 347, 350, 373, 377, 381, 343, + 344, 348, 349, 369, 345, 351, 384, 385, 386, 388, + 390, 392, 394, 396, 400, 401, 402, 403, 404, 405, + 407, 408, 409, 410, 411, 412, 414, 416, 417, 418, + 420, 421, 398, 406, 413, 422, 424, 425, 426, 428, + 429, 387, 389, 391, 415, 393, 395, 397, 399, 419, + 423, 427, 476, 477, 480, 481, 482, 483, 478, 479, + 430, 432, 433, 434, 436, 437, 438, 440, 441, 442, + 444, 445, 446, 448, 449, 450, 452, 453, 454, 456, + 457, 458, 460, 461, 462, 464, 465, 466, 468, 469, + 470, 472, 473, 431, 435, 439, 443, 447, 455, 459, + 463, 451, 467, 471, 0, 199, 486, 571, 131, 146, + 487, 488, 489, 0, 570, 0, 572, 0, 108, 107, + 0, 119, 124, 153, 152, 150, 154, 0, 147, 149, + 155, 129, 195, 151, 485, 0, 567, 569, 0, 0, + 0, 492, 0, 0, 96, 93, 0, 106, 0, 115, + 109, 117, 0, 118, 0, 94, 125, 0, 99, 148, + 130, 0, 188, 194, 1, 568, 186, 0, 145, 143, + 0, 141, 490, 0, 0, 0, 97, 0, 0, 573, + 110, 114, 116, 112, 120, 111, 0, 126, 102, 0, + 100, 0, 2, 12, 13, 10, 11, 4, 5, 6, + 7, 8, 9, 15, 14, 0, 0, 0, 42, 41, + 43, 40, 3, 17, 36, 19, 24, 25, 0, 0, + 29, 0, 197, 0, 35, 33, 0, 189, 184, 0, + 0, 140, 0, 0, 0, 0, 0, 494, 95, 190, + 44, 48, 51, 54, 59, 62, 64, 66, 68, 70, + 72, 74, 0, 0, 98, 0, 0, 552, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 518, 527, 531, + 44, 77, 90, 0, 507, 0, 155, 129, 510, 529, + 509, 508, 0, 511, 512, 533, 513, 540, 514, 515, + 548, 516, 0, 113, 0, 121, 0, 502, 128, 0, + 0, 104, 0, 101, 37, 38, 0, 21, 22, 0, + 0, 27, 26, 0, 199, 30, 32, 39, 0, 196, + 187, 92, 144, 142, 0, 0, 500, 0, 498, 493, + 495, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 75, 191, 192, 0, 563, 562, 0, 554, 0, 566, + 564, 0, 0, 0, 547, 550, 0, 517, 0, 80, + 81, 83, 82, 85, 86, 87, 88, 89, 84, 79, + 0, 0, 532, 528, 530, 534, 541, 549, 123, 0, + 505, 0, 127, 0, 105, 16, 0, 23, 20, 31, + 198, 491, 0, 501, 0, 496, 45, 46, 47, 50, + 49, 52, 53, 57, 58, 55, 56, 60, 61, 63, + 65, 67, 69, 71, 73, 0, 193, 0, 0, 0, + 565, 0, 546, 0, 577, 0, 575, 519, 78, 91, + 122, 503, 0, 103, 18, 497, 499, 0, 0, 557, + 556, 559, 525, 542, 538, 0, 0, 0, 0, 0, + 0, 0, 504, 506, 0, 0, 558, 0, 0, 537, + 0, 0, 535, 0, 0, 0, 0, 574, 576, 520, + 76, 0, 560, 0, 525, 524, 526, 544, 0, 522, + 551, 521, 578, 0, 561, 555, 536, 545, 0, 539, + 553, 543 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -525, -525, -525, -525, -525, -525, -525, -525, -525, -525, - -525, -525, -103, -525, -278, -274, -297, -273, -214, -211, - -210, -212, -209, -208, -525, -261, -525, -292, -525, -308, - -525, 4, -525, -525, -525, 5, -525, -525, -525, -41, - -38, -39, -525, -525, -504, -525, -525, -525, -525, -123, - -525, -230, -237, -525, -525, 0, -246, -525, 1, -525, - -525, -525, -337, -342, -207, -286, -378, -525, -285, -376, - -524, -322, -525, -525, -330, -327, -525, -525, -22, -452, - -275, -525, -525, -298, -525, -525, -525, -525, -525, -525, - -525, -525, -525, -525, -525, -525, -525, -2, -525, -525 + -659, -659, -659, -659, -659, -659, -659, -659, -659, -659, + -659, -659, -364, -659, -389, -385, -457, -384, -310, -307, + -305, -308, -301, -298, -659, -386, -659, -390, -659, -415, + -418, 1, -659, -659, -659, 2, -659, -659, -659, -110, + -105, -107, -659, -659, -628, -659, -659, -659, -659, -188, + -659, -336, -343, -659, 6, -659, 0, -334, -659, -659, + -659, -659, -67, -659, -659, -659, -431, -437, -277, -350, + -501, -659, -375, -488, -658, -414, -659, -659, -428, -426, + -659, -659, -87, -568, -368, -659, -231, -659, -388, -659, + -230, -659, -659, -659, -659, -228, -659, -659, -659, -659, + -659, -659, -659, -659, -70, -659, -659, -659, -659, -394 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 320, 321, 322, 487, 323, 324, 325, 326, 327, - 328, 329, 372, 331, 332, 333, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 373, 510, 374, 474, 375, - 440, 376, 227, 397, 300, 377, 229, 230, 231, 260, - 261, 262, 232, 233, 234, 235, 236, 237, 280, 281, - 238, 239, 240, 241, 277, 344, 273, 243, 244, 245, - 351, 283, 354, 355, 445, 446, 395, 482, 379, 380, - 381, 382, 462, 545, 571, 553, 554, 555, 572, 383, - 384, 385, 556, 544, 386, 557, 578, 387, 388, 523, - 451, 518, 538, 551, 552, 389, 246, 247, 248, 257 + -1, 432, 433, 434, 616, 435, 436, 437, 438, 439, + 440, 441, 490, 443, 461, 462, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 491, 645, 492, 600, 493, + 542, 494, 335, 520, 411, 495, 337, 338, 339, 369, + 370, 371, 340, 341, 342, 343, 344, 345, 390, 391, + 346, 347, 348, 349, 444, 387, 445, 397, 382, 383, + 446, 352, 353, 354, 453, 393, 456, 457, 547, 548, + 518, 611, 498, 499, 500, 501, 588, 681, 710, 689, + 690, 691, 711, 502, 503, 504, 505, 692, 677, 506, + 507, 693, 718, 508, 509, 510, 653, 576, 648, 671, + 687, 688, 511, 355, 356, 357, 366, 512, 655, 656 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1159,67 +1390,162 @@ number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 242, 263, 270, 394, 226, 228, 403, 478, 286, 278, - 524, 343, 448, 479, 442, 481, 254, 251, 483, 542, - 433, 296, 249, 404, 405, 272, 270, 422, 423, 263, - 294, 567, 272, 285, 542, 570, 412, 250, 272, 295, - 570, 345, -32, 345, 406, 391, 390, 392, 407, 357, - 396, 426, 427, 352, 252, 434, 456, 256, 458, 255, - 484, 258, 424, 425, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, 345, 517, 415, 416, 417, 297, - 346, 480, 298, 473, 437, 299, 347, 439, 349, 409, - 486, 539, 475, 522, 350, 410, 475, 475, 488, 394, - 448, 394, 527, 540, 394, 573, 418, 265, 419, 475, - 266, 475, 420, 421, 399, 270, 577, 400, 490, 475, - 515, 352, 476, 516, 352, 498, 499, 500, 501, 475, - 515, 259, 520, 533, 222, 223, 224, 528, 267, 529, - 494, 495, 448, 475, 548, 519, 496, 497, 478, 521, - 272, 547, 276, 502, 503, 282, 287, 292, 293, 345, - 356, 398, 348, 428, 408, 413, 429, 352, 431, 330, - 435, 432, 438, 444, 430, 452, 449, 453, 450, 454, - 457, 459, 525, 526, 279, 485, 460, -31, 394, 461, - 489, 579, 511, -26, 535, 475, 531, 549, 514, -406, - 558, 478, 532, 559, 560, 564, 563, 565, 580, 401, - 402, 369, 352, 568, 504, 541, 581, 569, 505, 507, - 506, 289, 290, 508, 291, 509, 253, 441, 414, 534, - 541, 264, 566, 536, 575, 288, 513, 394, 576, 271, - 550, 562, 330, 537, 275, 330, 242, 0, 0, 0, - 226, 228, 0, 284, 352, 574, 561, 0, 0, 264, - 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, - 0, 0, 0, 353, 0, 0, 0, 378, 0, 0, - 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 270, 0, 543, 0, - 0, 0, 491, 492, 493, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 353, 443, 0, 353, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 353, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 351, 334, 336, 372, 379, 477, 350, 478, 479, 472, + 388, 482, 526, 608, 604, 610, 517, 442, 612, 550, + 657, 360, 544, 558, 559, 675, 363, 538, 395, 379, + 569, 460, 372, 706, 365, 448, 396, 709, 405, 539, + 395, 449, 407, 675, 358, 709, 451, 406, 447, 395, + 535, 359, 452, 527, 528, 473, 514, 454, 560, 561, + 361, 524, 525, 474, 541, 570, 581, 367, 583, 513, + 515, 364, -34, 473, 529, 473, 368, 532, 530, 537, + 519, 679, 609, 533, 615, 680, 460, 573, 647, 613, + 601, 589, 590, 591, 592, 593, 594, 595, 596, 597, + 598, 633, 634, 635, 636, 556, 557, 550, 660, 460, + 599, 379, 408, 672, 617, 409, 673, 454, 410, 601, + 454, 713, 601, 376, 517, 374, 517, 601, 375, 517, + 522, 601, 624, 523, 602, 625, 386, 601, 624, 717, + 650, 665, 661, 619, 662, 330, 331, 332, 551, 552, + 553, 554, 381, 555, 562, 563, 601, 652, 601, 684, + 392, 683, 403, 649, 398, 629, 630, 651, 404, 604, + 395, 631, 632, 450, 620, 458, 550, 521, 637, 638, + 531, 536, 473, 540, 454, 546, 566, 626, 627, 628, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, 460, 564, 719, 454, 565, + 658, 659, 623, 567, 568, 574, 571, 575, 579, 517, + 587, 577, 578, 582, 584, 614, 586, 585, -35, 604, + 667, -33, 618, -28, 654, 668, 646, 664, 674, 678, + 685, -523, 601, 694, 695, 697, 699, 703, 702, 704, + 712, 487, 707, 708, 639, 720, 674, 721, 640, 642, + 696, 641, 401, 400, 543, 402, 362, 643, 622, 389, + 701, 644, 517, 669, 666, 715, 705, 454, 716, 399, + 670, 605, 606, 686, 607, 385, 698, 714, 0, 0, + 0, 0, 541, 0, 700, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 460, 0, 0, 676, 517, 0, + 485, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 379, 0, 676, 0, 0, 0, 373, + 0, 0, 0, 0, 0, 350, 0, 380, 0, 0, + 0, 0, 0, 350, 0, 351, 334, 336, 0, 0, + 0, 350, 394, 0, 0, 0, 0, 0, 373, 0, + 0, 0, 373, 0, 350, 0, 0, 0, 350, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 455, 0, 0, 0, 0, 497, 350, + 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 455, 545, 0, 455, 0, 0, 350, + 350, 0, 350, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 497, 0, 0, 0, 0, 0, 496, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 455, 0, 0, 0, 0, 0, 350, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 455, 0, 0, 0, 0, 0, + 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, + 0, 0, 496, 0, 0, 0, 0, 0, 497, 0, + 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 455, 0, 0, 0, 0, 0, 350, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 497, 0, + 0, 0, 0, 497, 496, 0, 0, 497, 0, 496, + 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, + 0, 497, 0, 0, 0, 0, 380, 496, 0, 0, + 0, 0, 350, 0, 0, 0, 0, 0, 0, 0, + 0, 497, 0, 0, 0, 497, 0, 496, 0, 0, + 0, 496, 0, 497, 0, 0, 0, 497, 0, 496, + 0, 0, 0, 496, 0, 0, 0, 497, 0, 0, + 0, 384, 0, 496, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 0, 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, - 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, - 0, 0, 0, 378, 378, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, - 0, 0, 0, 271, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 378, 0, 0, 0, 378, - 0, 0, 0, 0, 378, 0, 0, 0, 378, 0, - 0, 0, 0, 0, 0, 274, 0, 378, 1, 2, + 328, 329, 330, 331, 332, 333, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 475, 476, 477, 0, 478, + 479, 480, 481, 482, 483, 484, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 325, 485, 412, 326, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 0, 0, 425, + 426, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, + 486, 0, 487, 488, 0, 0, 0, 0, 489, 428, + 429, 430, 431, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 328, 329, 330, 331, 332, 333, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 14, 15, 16, 17, 18, 19, 20, 21, + 13, 14, 15, 16, 17, 18, 19, 475, 476, 477, + 0, 478, 479, 480, 481, 482, 483, 484, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, @@ -1239,16 +1565,27 @@ 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 0, 0, 218, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 220, 221, 222, 223, 224, 225, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 485, 412, 326, 413, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 0, + 0, 425, 426, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 427, 0, 486, 0, 487, 603, 0, 0, 0, 0, + 489, 428, 429, 430, 431, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 328, 329, 330, 331, 332, 333, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 358, 359, 360, 0, 361, 362, 363, - 364, 365, 366, 367, 14, 15, 16, 17, 18, 19, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 475, + 476, 477, 0, 478, 479, 480, 481, 482, 483, 484, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, @@ -1268,17 +1605,28 @@ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 368, 301, - 218, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 314, 0, 0, 0, 369, 370, 0, 0, - 0, 0, 371, 316, 317, 318, 319, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 220, 221, 222, 223, - 224, 225, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 358, 359, 360, 0, 361, - 362, 363, 364, 365, 366, 367, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 485, 412, 326, 413, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 0, 0, 425, 426, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 427, 0, 486, 0, 487, 0, 0, 0, + 0, 0, 489, 428, 429, 430, 431, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 328, 329, 330, 331, + 332, 333, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 475, 476, 477, 0, 478, 479, 480, 481, 482, + 483, 484, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, @@ -1298,16 +1646,27 @@ 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 368, 301, 218, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 0, 0, 312, 313, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 314, 0, 0, 0, 369, 477, - 0, 0, 0, 0, 371, 316, 317, 318, 319, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 220, 221, - 222, 223, 224, 225, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 358, 359, 360, - 0, 361, 362, 363, 364, 365, 366, 367, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 485, 412, + 326, 413, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 0, 0, 425, 426, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 427, 0, 486, 0, 398, 0, + 0, 0, 0, 0, 489, 428, 429, 430, 431, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 328, 329, + 330, 331, 332, 333, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 475, 476, 477, 0, 478, 479, 480, + 481, 482, 483, 484, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, @@ -1327,16 +1686,27 @@ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 368, 301, 218, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, - 369, 0, 0, 0, 0, 0, 371, 316, 317, 318, - 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 220, 221, 222, 223, 224, 225, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 358, - 359, 360, 0, 361, 362, 363, 364, 365, 366, 367, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 485, 412, 326, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 0, 0, 425, 426, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 427, 0, 486, 0, + 0, 0, 0, 0, 0, 0, 489, 428, 429, 430, + 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 328, 329, 330, 331, 332, 333, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, @@ -1356,16 +1726,27 @@ 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 368, 301, 218, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 0, 0, 312, - 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 314, 0, - 0, 0, 287, 0, 0, 0, 0, 0, 371, 316, - 317, 318, 319, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 220, 221, 222, 223, 224, 225, 1, 2, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 325, 0, 412, 326, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 0, 0, 425, + 426, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 427, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 489, 428, + 429, 430, 431, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 328, 329, 330, 331, 332, 333, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 358, 359, 360, 0, 361, 362, 363, 364, 365, - 366, 367, 14, 15, 16, 17, 18, 19, 20, 21, + 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, @@ -1385,16 +1766,27 @@ 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 368, 301, 218, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 0, - 0, 312, 313, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 371, 316, 317, 318, 319, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 220, 221, 222, 223, 224, 225, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 0, 0, 326, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 328, 329, 330, 331, 332, 333, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 14, 15, 16, 17, 18, 19, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, @@ -1414,17 +1806,68 @@ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 0, 301, - 218, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 371, 316, 317, 318, 319, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 220, 221, 222, 223, - 224, 225, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 0, 412, 326, 413, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 0, 0, 425, 426, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 428, 429, 430, 431, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 328, 329, 330, 331, + 332, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 0, 377, 326, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 328, 329, 330, + 331, 332, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, @@ -1444,151 +1887,27 @@ 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 219, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 220, 221, - 222, 223, 224, 225, 0, 0, 0, 0, 0, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 0, 301, 218, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 0, 0, 312, 313, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 316, 317, - 318, 319, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 220, 221, 222, 223, 224, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 0, 268, 218, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 269, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 220, 221, 222, 223, 224, 0, 0, 0, - 0, 0, 0, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 0, 0, 218, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 447, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 0, 0, 0, 0, 0, 220, 221, 222, 223, 224, - 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 0, 0, 218, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 512, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, - 0, 0, 0, 220, 221, 222, 223, 224, 0, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 0, 0, 218, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 530, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, - 0, 220, 221, 222, 223, 224, 0, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 0, 0, + 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 549, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 328, 329, + 330, 331, 332, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, @@ -1608,15 +1927,32 @@ 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 0, 0, 218, 0, 0, 0, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 0, + 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 621, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 328, + 329, 330, 331, 332, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, - 221, 222, 223, 224, 50, 51, 52, 53, 54, 55, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, @@ -1631,261 +1967,28 @@ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 0, 301, 218, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 0, 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, - 393, 546, 0, 0, 0, 0, 0, 316, 317, 318, - 319, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 0, 0, 0, 0, - 0, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 0, 301, 218, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 0, - 0, 312, 313, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 314, 0, 0, 315, 0, 0, 0, 0, 0, 0, - 0, 316, 317, 318, 319, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 0, 0, 0, 0, 0, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 0, 301, 218, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 0, 0, 312, 313, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 314, 0, 0, 0, 393, 0, - 0, 0, 0, 0, 0, 316, 317, 318, 319, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 0, 0, 0, 0, 0, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 0, 301, 218, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 0, 0, 312, - 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 314, 0, - 0, 436, 0, 0, 0, 0, 0, 0, 0, 316, - 317, 318, 319, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 0, 0, - 0, 0, 0, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 0, 301, - 218, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 455, 316, 317, 318, 319, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 0, 301, 218, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 314, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 316, 317, 318, - 319, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 411, 0, 301, 218, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 0, 0, 312, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 314, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 316, 317, 318, - 319, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 0, 663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 0, 0, 0, 0, 0, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 0, 0, 218 -}; - -static const yytype_int16 yycheck[] = -{ - 0, 231, 239, 295, 0, 0, 314, 383, 254, 57, - 462, 272, 354, 391, 351, 393, 232, 232, 396, 523, - 253, 267, 265, 246, 247, 267, 263, 248, 249, 259, - 265, 555, 267, 275, 538, 559, 328, 265, 267, 274, - 564, 267, 265, 267, 267, 274, 292, 293, 271, 275, - 274, 250, 251, 283, 269, 288, 364, 275, 366, 275, - 397, 266, 283, 284, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 267, 451, 280, 281, 282, 269, - 266, 274, 272, 274, 345, 275, 272, 348, 266, 266, - 266, 266, 272, 273, 272, 272, 272, 272, 406, 391, - 442, 393, 480, 266, 396, 266, 277, 272, 279, 272, - 275, 272, 244, 245, 272, 352, 568, 275, 410, 272, - 272, 351, 275, 275, 354, 422, 423, 424, 425, 272, - 272, 272, 275, 275, 291, 292, 293, 270, 232, 272, - 418, 419, 484, 272, 273, 453, 420, 421, 524, 457, - 267, 529, 232, 426, 427, 269, 269, 232, 232, 267, - 275, 232, 274, 287, 266, 265, 286, 397, 252, 272, - 268, 254, 232, 232, 285, 265, 275, 265, 275, 275, - 265, 273, 474, 475, 232, 232, 265, 265, 480, 270, - 232, 569, 268, 266, 231, 272, 268, 265, 444, 269, - 232, 577, 510, 266, 270, 266, 275, 19, 275, 312, - 313, 269, 442, 269, 428, 523, 270, 274, 429, 431, - 430, 259, 263, 432, 263, 433, 225, 350, 331, 515, - 538, 231, 554, 518, 564, 257, 443, 529, 565, 239, - 538, 549, 345, 518, 246, 348, 246, -1, -1, -1, - 246, 246, -1, 253, 484, 563, 548, -1, -1, 259, - -1, -1, -1, 263, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 569, -1, -1, - -1, -1, -1, 283, -1, -1, -1, 287, -1, -1, - -1, -1, -1, 523, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 543, -1, 538, -1, - -1, -1, 415, 416, 417, 418, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - 433, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 351, 352, -1, 354, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 383, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 397, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 442, -1, -1, -1, -1, -1, -1, -1, - -1, 451, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 462, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 484, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 518, -1, - -1, -1, -1, 523, 524, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 538, -1, - -1, -1, -1, 543, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 555, -1, -1, -1, 559, - -1, -1, -1, -1, 564, -1, -1, -1, 568, -1, - -1, -1, -1, -1, -1, 0, -1, 577, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 27, 28, 29, 30, 31, 32, 33, 34, + 328, 329, 330, 331, 332, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, @@ -1905,142 +2008,33 @@ 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, -1, -1, 233, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 289, 290, 291, 292, 293, 294, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, -1, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, -1, -1, 246, 247, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 265, -1, -1, -1, 269, 270, -1, -1, - -1, -1, 275, 276, 277, 278, 279, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 289, 290, 291, 292, - 293, 294, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, -1, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, -1, -1, 246, 247, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 265, -1, -1, -1, 269, 270, - -1, -1, -1, -1, 275, 276, 277, 278, 279, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 289, 290, - 291, 292, 293, 294, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 265, -1, -1, -1, - 269, -1, -1, -1, -1, -1, 275, 276, 277, 278, - 279, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 289, 290, 291, 292, 293, 294, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, -1, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, -1, -1, 246, - 247, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 265, -1, - -1, -1, 269, -1, -1, -1, -1, -1, 275, 276, - 277, 278, 279, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 289, 290, 291, 292, 293, 294, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, -1, 20, 21, 22, 23, 24, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 0, 0, 326, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, + 6, 7, 0, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 328, 329, 330, 331, 332, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 105, 106, 107, 108, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, @@ -2052,217 +2046,33 @@ 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, -1, - -1, 246, 247, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 265, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 275, 276, 277, 278, 279, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 289, 290, 291, 292, 293, 294, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, -1, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, -1, -1, 246, 247, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 265, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 275, 276, 277, 278, 279, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 289, 290, 291, 292, - 293, 294, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - -1, -1, 233, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 275, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 289, 290, - 291, 292, 293, 294, -1, -1, -1, -1, -1, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, -1, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, -1, -1, 246, 247, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 265, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 276, 277, - 278, 279, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 289, 290, 291, 292, 293, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, -1, 232, 233, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 275, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 289, 290, 291, 292, 293, -1, -1, -1, - -1, -1, -1, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, -1, -1, 233, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 270, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - -1, -1, -1, -1, -1, 289, 290, 291, 292, 293, - -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, -1, -1, 233, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 270, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, -1, -1, - -1, -1, -1, 289, 290, 291, 292, 293, -1, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, -1, -1, 233, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 270, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, - -1, 289, 290, 291, 292, 293, -1, 27, 28, 29, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 0, 412, 326, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 0, 0, 425, 426, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, + 0, 516, 682, 0, 0, 0, 0, 0, 428, 429, + 430, 431, 3, 4, 5, 6, 7, 0, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, @@ -2274,46 +2084,34 @@ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, -1, -1, 233, -1, -1, -1, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 289, - 290, 291, 292, 293, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, -1, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 265, -1, -1, -1, - 269, 270, -1, -1, -1, -1, -1, 276, 277, 278, - 279, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 0, 412, 326, 413, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 0, 0, 425, 426, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 427, 0, 0, 459, 0, 0, 0, 0, + 0, 0, 0, 428, 429, 430, 431, 3, 4, 5, + 6, 7, 0, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, -1, -1, -1, -1, - -1, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 105, 106, 107, 108, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, @@ -2324,128 +2122,294 @@ 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, -1, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, -1, - -1, 246, 247, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 265, -1, -1, 268, -1, -1, -1, -1, -1, -1, - -1, 276, 277, 278, 279, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - -1, -1, -1, -1, -1, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - -1, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, -1, -1, 246, 247, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 265, -1, -1, -1, 269, -1, - -1, -1, -1, -1, -1, 276, 277, 278, 279, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, -1, -1, -1, -1, -1, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, -1, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, -1, -1, 246, - 247, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 265, -1, - -1, 268, -1, -1, -1, -1, -1, -1, -1, 276, - 277, 278, 279, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, - -1, -1, -1, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, -1, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, -1, -1, 246, 247, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 265, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 275, 276, 277, 278, 279, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, -1, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 265, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 276, 277, 278, - 279, -1, -1, -1, -1, -1, -1, -1, -1, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 63, 64, 65, 66, 67, 68, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 0, 412, 326, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 0, 0, 425, 426, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, + 0, 516, 0, 0, 0, 0, 0, 0, 428, 429, + 430, 431, 3, 4, 5, 6, 7, 0, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 0, 412, 326, 413, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 0, 0, 425, 426, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 427, 0, 0, 572, 0, 0, 0, 0, + 0, 0, 0, 428, 429, 430, 431, 3, 4, 5, + 6, 7, 0, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 0, 412, 326, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 0, 0, 425, 426, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 580, 428, 429, + 430, 431, 3, 4, 5, 6, 7, 0, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 0, 412, 326, 413, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 0, 0, 425, 426, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 428, 429, 430, 431, 3, 4, 5, + 6, 7, 0, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 534, 0, 412, 326, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 0, 0, 425, 426, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 428, 429, + 430, 431, 3, 4, 5, 6, 7, 0, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 0, 0, 326 +}; + +static const yytype_int16 yycheck[] = +{ + 0, 0, 0, 339, 347, 24, 0, 26, 27, 395, + 81, 30, 427, 514, 502, 516, 406, 381, 519, 456, + 588, 340, 453, 358, 359, 653, 340, 382, 377, 372, + 363, 395, 368, 691, 385, 376, 385, 695, 375, 394, + 377, 382, 376, 671, 375, 703, 376, 384, 382, 377, + 440, 375, 382, 356, 357, 377, 384, 393, 393, 394, + 379, 425, 426, 385, 450, 398, 481, 376, 483, 403, + 404, 385, 375, 377, 377, 377, 382, 376, 381, 443, + 384, 378, 384, 382, 376, 382, 450, 473, 576, 520, + 382, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 558, 559, 560, 561, 354, 355, 544, 609, 473, + 384, 454, 379, 376, 529, 382, 376, 453, 385, 382, + 456, 376, 382, 340, 514, 382, 516, 382, 385, 519, + 382, 382, 382, 385, 385, 385, 340, 382, 382, 707, + 385, 385, 380, 533, 382, 401, 402, 403, 390, 391, + 392, 387, 393, 389, 360, 361, 382, 383, 382, 383, + 379, 662, 340, 578, 379, 554, 555, 582, 340, 657, + 377, 556, 557, 384, 538, 385, 613, 340, 562, 563, + 376, 375, 377, 340, 520, 340, 395, 551, 552, 553, + 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 397, 708, 544, 396, + 600, 601, 546, 362, 364, 385, 378, 385, 385, 609, + 380, 375, 375, 375, 383, 340, 377, 375, 375, 717, + 645, 375, 340, 376, 340, 339, 378, 378, 653, 375, + 375, 379, 382, 340, 376, 378, 380, 376, 385, 25, + 376, 379, 379, 384, 564, 385, 671, 380, 565, 567, + 678, 566, 372, 368, 452, 372, 333, 568, 545, 340, + 685, 569, 662, 648, 624, 703, 690, 613, 704, 366, + 648, 512, 512, 671, 512, 355, 680, 702, -1, -1, + -1, -1, 678, -1, 684, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 678, -1, -1, 653, 708, -1, + 339, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 676, -1, 671, -1, -1, -1, 339, + -1, -1, -1, -1, -1, 339, -1, 347, -1, -1, + -1, -1, -1, 347, -1, 355, 355, 355, -1, -1, + -1, 355, 362, -1, -1, -1, -1, -1, 368, -1, + -1, -1, 372, -1, 368, -1, -1, -1, 372, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 393, -1, -1, -1, -1, 398, 393, + -1, -1, -1, -1, 398, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 453, 454, -1, 456, -1, -1, 453, + 454, -1, 456, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 502, -1, -1, -1, -1, -1, 502, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 520, -1, -1, -1, -1, -1, 520, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 544, -1, -1, -1, -1, -1, + 544, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 576, -1, -1, -1, + -1, -1, 576, -1, -1, -1, -1, -1, 588, -1, + -1, -1, -1, -1, 588, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 613, -1, -1, -1, -1, -1, 613, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 648, -1, + -1, -1, -1, 653, 648, -1, -1, 657, -1, 653, + -1, -1, -1, 657, -1, -1, -1, -1, -1, -1, + -1, 671, -1, -1, -1, -1, 676, 671, -1, -1, + -1, -1, 676, -1, -1, -1, -1, -1, -1, -1, + -1, 691, -1, -1, -1, 695, -1, 691, -1, -1, + -1, 695, -1, 703, -1, -1, -1, 707, -1, 703, + -1, -1, -1, 707, -1, -1, -1, 717, -1, -1, + -1, 0, -1, 717, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, @@ -2460,41 +2424,107 @@ 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, -1, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, -1, -1, 246, 247, -1, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + -1, -1, 341, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 265, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 276, 277, 278, - 279, -1, -1, -1, -1, -1, -1, -1, -1, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, -1, -1, -1, -1, -1, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, -1, -1, 233 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 27, 28, 29, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 385, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 399, 400, 401, 402, 403, 404, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, -1, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, -1, -1, 356, + 357, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 375, -1, + 377, -1, 379, 380, -1, -1, -1, -1, 385, 386, + 387, 388, 389, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 399, 400, 401, 402, 403, 404, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, -1, + -1, 356, 357, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 375, -1, 377, -1, 379, 380, -1, -1, -1, -1, + 385, 386, 387, 388, 389, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 399, 400, 401, 402, 403, 404, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, @@ -2514,4650 +2544,6776 @@ 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 233, 275, - 289, 290, 291, 292, 293, 294, 329, 330, 333, 334, - 335, 336, 340, 341, 342, 343, 344, 345, 348, 349, - 350, 351, 353, 355, 356, 357, 394, 395, 396, 265, - 265, 232, 269, 356, 232, 275, 275, 397, 266, 272, - 337, 338, 339, 349, 353, 272, 275, 232, 232, 275, - 350, 353, 267, 354, 0, 395, 232, 352, 57, 232, - 346, 347, 269, 359, 353, 275, 354, 269, 376, 338, - 337, 339, 232, 232, 265, 274, 354, 269, 272, 275, - 332, 232, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 246, 247, 265, 268, 276, 277, 278, 279, - 299, 300, 301, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 353, 267, 266, 272, 274, 266, - 272, 358, 349, 353, 360, 361, 275, 275, 16, 17, - 18, 20, 21, 22, 23, 24, 25, 26, 231, 269, - 270, 275, 310, 323, 325, 327, 329, 333, 353, 366, - 367, 368, 369, 377, 378, 379, 382, 385, 386, 393, - 354, 274, 354, 269, 325, 364, 274, 331, 232, 272, - 275, 310, 310, 327, 246, 247, 267, 271, 266, 266, - 272, 230, 325, 265, 310, 280, 281, 282, 277, 279, - 244, 245, 248, 249, 283, 284, 250, 251, 287, 286, - 285, 252, 254, 253, 288, 268, 268, 323, 232, 323, - 328, 347, 360, 353, 232, 362, 363, 270, 361, 275, - 275, 388, 265, 265, 275, 275, 327, 265, 327, 273, - 265, 270, 370, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 274, 326, 272, 275, 270, 367, 364, - 274, 364, 365, 364, 360, 232, 266, 302, 327, 232, - 325, 310, 310, 310, 312, 312, 313, 313, 314, 314, - 314, 314, 315, 315, 316, 317, 318, 319, 320, 321, - 324, 268, 270, 362, 354, 272, 275, 367, 389, 327, - 275, 327, 273, 387, 377, 325, 325, 364, 270, 272, - 270, 268, 327, 275, 363, 231, 366, 378, 390, 266, - 266, 327, 342, 349, 381, 371, 270, 364, 273, 265, - 381, 391, 392, 373, 374, 375, 380, 383, 232, 266, - 270, 325, 327, 275, 266, 19, 369, 368, 269, 274, - 368, 372, 376, 266, 327, 372, 373, 377, 384, 364, - 275, 270 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 298, 299, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 301, 301, 301, 301, 301, - 301, 302, 303, 304, 305, 305, 306, 306, 307, 307, - 308, 309, 309, 310, 310, 310, 310, 311, 311, 311, - 311, 312, 312, 312, 312, 313, 313, 313, 314, 314, - 314, 315, 315, 315, 315, 315, 316, 316, 316, 317, - 317, 318, 318, 319, 319, 320, 320, 321, 321, 322, - 322, 323, 324, 323, 325, 325, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 327, 327, 328, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 331, - 330, 332, 332, 333, 334, 334, 335, 335, 336, 337, - 337, 338, 338, 338, 338, 339, 340, 340, 340, 340, - 340, 341, 341, 341, 341, 341, 342, 342, 343, 344, - 344, 344, 344, 345, 346, 346, 347, 347, 347, 348, - 349, 349, 350, 350, 350, 350, 350, 350, 351, 351, - 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, - 351, 351, 351, 351, 351, 351, 351, 352, 352, 353, - 353, 354, 354, 354, 354, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 355, 355, 355, 355, 355, 355, 355, 355, 355, 355, - 356, 356, 356, 358, 357, 359, 357, 360, 360, 361, - 361, 362, 362, 363, 363, 364, 364, 364, 365, 365, - 366, 367, 367, 368, 368, 368, 368, 368, 368, 368, - 369, 370, 371, 369, 372, 372, 374, 373, 375, 373, - 376, 376, 377, 377, 378, 378, 379, 380, 380, 381, - 381, 383, 382, 384, 384, 385, 385, 387, 386, 388, - 386, 389, 386, 390, 390, 391, 391, 392, 392, 393, - 393, 393, 393, 393, 394, 394, 395, 395, 395, 397, - 396 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, 3, 2, - 2, 1, 1, 1, 2, 2, 2, 1, 2, 3, - 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, - 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, - 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 0, 6, 1, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 2, 2, 4, 2, 3, 4, 2, 3, 4, 0, - 6, 2, 3, 2, 1, 1, 2, 3, 3, 2, - 3, 2, 1, 2, 1, 1, 1, 3, 4, 6, - 5, 1, 2, 3, 5, 4, 1, 2, 1, 1, - 1, 1, 1, 4, 1, 3, 1, 3, 1, 1, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 4, 1, 3, 1, - 2, 2, 3, 3, 4, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, - 4, 1, 3, 1, 2, 1, 3, 4, 1, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 0, 0, 5, 1, 1, 0, 2, 0, 2, - 2, 3, 1, 2, 1, 2, 5, 3, 1, 1, - 4, 0, 8, 0, 1, 3, 2, 0, 6, 0, - 8, 0, 7, 1, 1, 1, 0, 2, 3, 2, - 2, 2, 3, 2, 1, 2, 1, 1, 1, 0, - 3 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, -1, -1, 356, 357, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 375, -1, 377, -1, 379, -1, -1, -1, + -1, -1, 385, 386, 387, 388, 389, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 399, 400, 401, 402, + 403, 404, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, -1, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + 351, 352, 353, -1, -1, 356, 357, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 375, -1, 377, -1, 379, -1, + -1, -1, -1, -1, 385, 386, 387, 388, 389, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 399, 400, + 401, 402, 403, 404, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, -1, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 375, -1, 377, -1, + -1, -1, -1, -1, -1, -1, 385, 386, 387, 388, + 389, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 399, 400, 401, 402, 403, 404, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, + 337, 338, -1, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, -1, -1, 356, + 357, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 375, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 385, 386, + 387, 388, 389, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 399, 400, 401, 402, 403, 404, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, -1, -1, 341, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 385, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 399, 400, 401, 402, 403, 404, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, -1, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, -1, -1, 356, 357, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 375, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 386, 387, 388, 389, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 399, 400, 401, 402, + 403, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, 333, 334, 335, 336, 337, 338, -1, 340, 341, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 385, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 399, 400, 401, + 402, 403, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, -1, -1, + 341, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 380, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 399, 400, + 401, 402, 403, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, -1, + -1, 341, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 380, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 399, + 400, 401, 402, 403, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + -1, -1, 341, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 380, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 399, 400, 401, 402, 403, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, -1, -1, 341, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 5, 6, 7, + 8, 9, -1, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, -1, -1, -1, -1, -1, -1, + -1, 399, 400, 401, 402, 403, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, -1, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, 353, -1, -1, 356, 357, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 375, -1, -1, + -1, 379, 380, -1, -1, -1, -1, -1, 386, 387, + 388, 389, 5, 6, 7, 8, 9, -1, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, -1, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, -1, -1, 356, 357, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 375, -1, -1, 378, -1, -1, -1, -1, + -1, -1, -1, 386, 387, 388, 389, 5, 6, 7, + 8, 9, -1, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, -1, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, 353, -1, -1, 356, 357, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 375, -1, -1, + -1, 379, -1, -1, -1, -1, -1, -1, 386, 387, + 388, 389, 5, 6, 7, 8, 9, -1, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, -1, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, -1, -1, 356, 357, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 375, -1, -1, 378, -1, -1, -1, -1, + -1, -1, -1, 386, 387, 388, 389, 5, 6, 7, + 8, 9, -1, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, -1, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, 353, -1, -1, 356, 357, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 375, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 385, 386, 387, + 388, 389, 5, 6, 7, 8, 9, -1, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, -1, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, -1, -1, 356, 357, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 375, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 386, 387, 388, 389, 5, 6, 7, + 8, 9, -1, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 82, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 121, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, + 338, -1, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, 353, -1, -1, 356, 357, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 375, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 386, 387, + 388, 389, 5, 6, 7, 8, 9, -1, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, -1, -1, 341 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint16 yystos[] = +{ + 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 341, 385, 399, 400, + 401, 402, 403, 404, 439, 440, 443, 444, 445, 446, + 450, 451, 452, 453, 454, 455, 458, 459, 460, 461, + 462, 464, 469, 470, 471, 511, 512, 513, 375, 375, + 340, 379, 470, 340, 385, 385, 514, 376, 382, 447, + 448, 449, 459, 464, 382, 385, 340, 340, 385, 460, + 464, 393, 466, 467, 0, 512, 340, 463, 81, 340, + 456, 457, 379, 473, 464, 377, 385, 465, 379, 490, + 448, 447, 449, 340, 340, 375, 384, 465, 379, 382, + 385, 442, 340, 342, 343, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 356, 357, 375, 386, 387, + 388, 389, 409, 410, 411, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 462, 464, 468, 465, 376, 382, + 384, 376, 382, 472, 459, 464, 474, 475, 385, 378, + 420, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 377, 385, 22, 23, 24, 26, 27, + 28, 29, 30, 31, 32, 339, 377, 379, 380, 385, + 420, 433, 435, 437, 439, 443, 462, 464, 480, 481, + 482, 483, 491, 492, 493, 494, 497, 498, 501, 502, + 503, 510, 515, 465, 384, 465, 379, 435, 478, 384, + 441, 340, 382, 385, 420, 420, 437, 356, 357, 377, + 381, 376, 376, 382, 338, 435, 375, 420, 382, 394, + 340, 433, 438, 457, 474, 464, 340, 476, 477, 380, + 475, 390, 391, 392, 387, 389, 354, 355, 358, 359, + 393, 394, 360, 361, 397, 396, 395, 362, 364, 363, + 398, 378, 378, 433, 385, 385, 505, 375, 375, 385, + 385, 437, 375, 437, 383, 375, 377, 380, 484, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 384, + 436, 382, 385, 380, 481, 494, 498, 503, 478, 384, + 478, 479, 478, 474, 340, 376, 412, 437, 340, 435, + 420, 380, 476, 465, 382, 385, 420, 420, 420, 422, + 422, 423, 423, 424, 424, 424, 424, 425, 425, 426, + 427, 428, 429, 430, 431, 434, 378, 481, 506, 437, + 385, 437, 383, 504, 340, 516, 517, 491, 435, 435, + 478, 380, 382, 380, 378, 385, 477, 437, 339, 480, + 492, 507, 376, 376, 437, 452, 459, 496, 375, 378, + 382, 485, 380, 478, 383, 375, 496, 508, 509, 487, + 488, 489, 495, 499, 340, 376, 438, 378, 517, 380, + 435, 437, 385, 376, 25, 483, 482, 379, 384, 482, + 486, 490, 376, 376, 437, 486, 487, 491, 500, 478, + 385, 380 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint16 yyr1[] = +{ + 0, 408, 409, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 411, 411, 411, + 411, 411, 411, 412, 413, 414, 415, 415, 416, 416, + 417, 417, 418, 419, 419, 419, 420, 420, 420, 420, + 421, 421, 421, 421, 422, 422, 422, 422, 423, 423, + 423, 424, 424, 424, 425, 425, 425, 425, 425, 426, + 426, 426, 427, 427, 428, 428, 429, 429, 430, 430, + 431, 431, 432, 432, 433, 434, 433, 435, 435, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 437, 437, 438, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 441, 440, 442, 442, 443, 444, 444, 445, + 445, 446, 447, 447, 448, 448, 448, 448, 449, 450, + 450, 450, 450, 450, 451, 451, 451, 451, 451, 452, + 452, 453, 454, 454, 454, 454, 454, 454, 454, 454, + 455, 456, 456, 457, 457, 457, 458, 459, 459, 460, + 460, 460, 460, 460, 460, 460, 461, 461, 461, 461, + 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, + 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, + 461, 461, 461, 461, 461, 462, 463, 463, 464, 464, + 465, 465, 465, 465, 466, 466, 467, 468, 468, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 470, 470, 470, + 472, 471, 473, 471, 474, 474, 475, 475, 476, 476, + 477, 477, 478, 478, 478, 479, 479, 480, 481, 481, + 482, 482, 482, 482, 482, 482, 482, 483, 484, 485, + 483, 486, 486, 488, 487, 489, 487, 490, 490, 491, + 491, 492, 492, 493, 493, 494, 495, 495, 496, 496, + 497, 497, 499, 498, 500, 500, 501, 501, 502, 502, + 504, 503, 505, 503, 506, 503, 507, 507, 508, 508, + 509, 509, 510, 510, 510, 510, 510, 511, 511, 512, + 512, 512, 514, 513, 515, 516, 516, 517, 517 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, + 3, 2, 2, 1, 1, 1, 2, 2, 2, 1, + 2, 3, 2, 1, 1, 1, 1, 2, 2, 2, + 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, + 3, 1, 3, 3, 1, 3, 3, 3, 3, 1, + 3, 3, 1, 3, 1, 3, 1, 3, 1, 3, + 1, 3, 1, 3, 1, 0, 6, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 2, 2, 4, 2, 3, 4, 2, + 3, 4, 0, 6, 2, 3, 2, 1, 1, 2, + 3, 3, 2, 3, 2, 1, 2, 1, 1, 1, + 3, 4, 6, 5, 1, 2, 3, 5, 4, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 3, 1, 3, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 4, 1, 1, 3, 2, 3, + 2, 3, 3, 4, 1, 0, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 6, 0, 5, 1, 2, 3, 4, 1, 3, + 1, 2, 1, 3, 4, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, + 5, 1, 1, 0, 2, 0, 2, 2, 3, 1, + 2, 1, 2, 1, 2, 5, 3, 1, 1, 4, + 1, 2, 0, 8, 0, 1, 3, 2, 1, 2, + 0, 6, 0, 8, 0, 7, 1, 1, 1, 0, + 2, 3, 2, 2, 2, 3, 2, 1, 2, 1, + 1, 1, 0, 3, 5, 1, 3, 1, 4 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab -#define YYRECOVERING() (!!yyerrstatus) +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (pParseContext, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, pParseContext); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + YYUSE (pParseContext); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) +{ + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, pParseContext); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, glslang::TParseContext* pParseContext) +{ + unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , pParseContext); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule, pParseContext); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (pParseContext, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, glslang::TParseContext* pParseContext) +{ + YYUSE (yyvaluep); + YYUSE (pParseContext); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (glslang::TParseContext* pParseContext) +{ +/* The lookahead symbol. */ +int yychar; + + +/* The semantic value of the lookahead symbol. */ +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +YY_INITIAL_VALUE (static YYSTYPE yyval_default;) +YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 + yysetstate: + *yyssp = yystate; + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; -/* Enable debugging if requested. */ -#if YYDEBUG + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } # endif +#endif /* no yyoverflow */ -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, pParseContext); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ + goto yybackup; -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - YYUSE (pParseContext); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); -} +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) -{ - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + /* Not known => get a lookahead token if don't already have one. */ - yy_symbol_value_print (yyoutput, yytype, yyvaluep, pParseContext); - YYFPRINTF (yyoutput, ")"); -} + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (&yylval, parseContext); + } -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; } - YYFPRINTF (stderr, "\n"); -} -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ + /* Discard the shifted token. */ + yychar = YYEMPTY; -static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, glslang::TParseContext* pParseContext) -{ - unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , pParseContext); - YYFPRINTF (stderr, "\n"); - } -} + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule, pParseContext); \ -} while (0) + goto yynewstate; -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 302 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); + } +#line 4159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif + case 3: +#line 308 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 4167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). + case 4: +#line 311 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 4176 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ + case 5: +#line 315 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 4185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif + case 6: +#line 319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 4193 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 7: +#line 322 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 4202 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -#if YYERROR_VERBOSE + case 8: +#line 326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); + } +#line 4211 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif + case 9: +#line 330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); + } +#line 4220 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; + case 10: +#line 334 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 4229 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - while ((*yyd++ = *yys++) != '\0') - continue; + case 11: +#line 338 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + } +#line 4238 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - return yyd - 1; -} -# endif -# endif + case 12: +#line 342 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 4246 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') + case 13: +#line 345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - YYSIZE_T yyn = 0; - char const *yyp = yystr; + parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); + } +#line 4255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; + case 14: +#line 349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); + } +#line 4264 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; + case 15: +#line 353 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 4272 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; + case 16: +#line 356 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); + if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) + (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } +#line 4282 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - if (! yyres) - return yystrlen (yystr); + case 17: +#line 364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 4290 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - return yystpcpy (yyres, yystr) - yyres; -} -# endif + case 18: +#line 367 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); + } +#line 4298 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. + case 19: +#line 370 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } +#line 4306 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULL; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; + case 20: +#line 373 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); + } +#line 4314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) + case 21: +#line 376 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; + parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); + parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "++", (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "++", EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode)); + } +#line 4324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 22: +#line 381 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); + parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "--", (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "--", EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode)); + } +#line 4334 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } + case 23: +#line 389 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - switch (yycount) + case 24: +#line 396 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ + (yyval.interm.intermTypedNode) = parseContext.handleFunctionCall((yyvsp[0].interm).loc, (yyvsp[0].interm).function, (yyvsp[0].interm).intermNode); + delete (yyvsp[0].interm).function; } +#line 4352 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } + case 25: +#line 403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 4360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - if (*yymsg_alloc < yysize) + case 26: +#line 409 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; + (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).loc = (yyvsp[0].lex).loc; } +#line 4369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ + case 27: +#line 413 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).loc = (yyvsp[0].lex).loc; + } +#line 4378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ + case 28: +#line 420 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + } +#line 4386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, glslang::TParseContext* pParseContext) -{ - YYUSE (yyvaluep); - YYUSE (pParseContext); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + case 29: +#line 423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 4394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yytype); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} + case 30: +#line 429 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TParameter param = { 0, new TType }; + param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); + (yyvsp[-1].interm).function->addParameter(param); + (yyval.interm).function = (yyvsp[-1].interm).function; + (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); + } +#line 4406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 31: +#line 436 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TParameter param = { 0, new TType }; + param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); + (yyvsp[-2].interm).function->addParameter(param); + (yyval.interm).function = (yyvsp[-2].interm).function; + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + } +#line 4418 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 32: +#line 446 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-1].interm); + } +#line 4426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 33: +#line 454 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // Constructor + (yyval.interm).intermNode = 0; + (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); + } +#line 4436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/*----------. -| yyparse. | -`----------*/ + case 34: +#line 459 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // + // Should be a method or subroutine call, but we haven't recognized the arguments yet. + // + (yyval.interm).function = 0; + (yyval.interm).intermNode = 0; -int -yyparse (glslang::TParseContext* pParseContext) -{ -/* The lookahead symbol. */ -int yychar; + TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode(); + if (method) { + (yyval.interm).function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); + (yyval.interm).intermNode = method->getObject(); + } else { + TIntermSymbol* symbol = (yyvsp[0].interm.intermTypedNode)->getAsSymbolNode(); + if (symbol) { + parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName()); + TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid)); + (yyval.interm).function = function; + } else + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "function call, method, or subroutine call expected", "", ""); + } + if ((yyval.interm).function == 0) { + // error recover + TString* empty = NewPoolTString(""); + (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); + } + } +#line 4468 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/* The semantic value of the lookahead symbol. */ -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -YY_INITIAL_VALUE (static YYSTYPE yyval_default;) -YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); + case 35: +#line 486 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // Constructor + (yyval.interm).intermNode = 0; + (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); + } +#line 4478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Number of syntax errors so far. */ - int yynerrs; + case 36: +#line 494 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); + } +#line 4489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; + case 37: +#line 500 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); + } +#line 4498 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. + case 38: +#line 504 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); + } +#line 4507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + case 39: +#line 508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + if ((yyvsp[-1].interm).op != EOpNull) { + char errorOp[2] = {0, 0}; + switch((yyvsp[-1].interm).op) { + case EOpNegative: errorOp[0] = '-'; break; + case EOpLogicalNot: errorOp[0] = '!'; break; + case EOpBitwiseNot: errorOp[0] = '~'; break; + default: break; // some compilers want this + } + (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].interm).loc, errorOp, (yyvsp[-1].interm).op, (yyvsp[0].interm.intermTypedNode)); + } else { + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) + (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); + } + } +#line 4528 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; + case 40: +#line 528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } +#line 4534 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 41: +#line 529 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } +#line 4540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; + case 42: +#line 530 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } +#line 4546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - YYSIZE_T yystacksize; + case 43: +#line 531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } +#line 4553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; + case 44: +#line 537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif + case 45: +#line 538 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + case 46: +#line 543 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; + case 47: +#line 548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; + case 48: +#line 557 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - YYDPRINTF ((stderr, "Starting parse\n")); + case 49: +#line 558 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4606 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; + case 50: +#line 563 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4616 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; + case 51: +#line 571 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4622 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - yysetstate: - *yyssp = yystate; + case 52: +#line 572 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4633 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - if (yyss + yystacksize - 1 <= yyssp) + case 53: +#line 578 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4644 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; + case 54: +#line 587 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); + case 55: +#line 588 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + case 56: +#line 593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ + case 57: +#line 598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; + case 58: +#line 603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + case 59: +#line 611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + case 60: +#line 612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); + parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); + parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); + parseContext.referenceCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "==", EOpEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } +#line 4710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; + case 61: +#line 621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); + parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); + parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); + parseContext.referenceCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "!=", EOpNotEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4724 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - goto yybackup; + case 62: +#line 633 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4730 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/*-----------. -| yybackup. | -`-----------*/ -yybackup: + case 63: +#line 634 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ + case 64: +#line 643 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; + case 65: +#line 644 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } +#line 4758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Not known => get a lookahead token if don't already have one. */ + case 66: +#line 653 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) + case 67: +#line 654 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (&yylval, parseContext); + parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } +#line 4775 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } + case 68: +#line 663 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4781 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) + case 69: +#line 664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } +#line 4791 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; + case 70: +#line 672 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4797 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + case 71: +#line 673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4807 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* Discard the shifted token. */ - yychar = YYEMPTY; + case 72: +#line 681 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END + case 73: +#line 682 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); + if ((yyval.interm.intermTypedNode) == 0) + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + } +#line 4823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - goto yynewstate; + case 74: +#line 690 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4829 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 75: +#line 691 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + ++parseContext.controlFlowNestingLevel; + } +#line 4837 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; + case 76: +#line 694 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + --parseContext.controlFlowNestingLevel; + parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-4].lex).loc, "?", (yyvsp[-5].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addSelection((yyvsp[-5].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-4].lex).loc); + if ((yyval.interm.intermTypedNode) == 0) { + parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } + } +#line 4854 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 77: +#line 709 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } +#line 4860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; + case 78: +#line 710 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); + parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); + parseContext.storage16BitAssignmentCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); + parseContext.specializationCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); + parseContext.lValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)); + parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].interm).loc); + if ((yyval.interm.intermTypedNode) == 0) { + parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + } + } +#line 4878 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. + case 79: +#line 726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpAssign; + } +#line 4887 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; + case 80: +#line 730 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpMulAssign; + } +#line 4896 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 81: +#line 734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpDivAssign; + } +#line 4905 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - YY_REDUCE_PRINT (yyn); - switch (yyn) + case 82: +#line 738 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - case 2: -#line 253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpModAssign; + } +#line 4915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 83: +#line 743 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpAddAssign; } -#line 3344 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 3: -#line 259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 84: +#line 747 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).op = EOpSubAssign; } -#line 3352 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4933 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 4: -#line 262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 85: +#line 751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; } -#line 3360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 5: -#line 265 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 86: +#line 755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; } -#line 3369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4951 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 6: -#line 269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 87: +#line 759 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; } -#line 3378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4960 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 7: -#line 273 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 88: +#line 763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; } -#line 3387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4969 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 8: -#line 277 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 89: +#line 767 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); -#endif + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); + (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; } -#line 3398 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4978 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 9: -#line 283 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 90: +#line 774 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); -#endif + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3409 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4986 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 10: -#line 289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 91: +#line 777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + if ((yyval.interm.intermTypedNode) == 0) { + parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + } } -#line 3417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 11: -#line 292 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 92: +#line 788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); + parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); + (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 12: -#line 296 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 93: +#line 795 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); -#endif + parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); + (yyval.interm.intermNode) = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 3437 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 13: -#line 302 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 94: +#line 800 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) + (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); + (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; } -#line 3445 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 14: -#line 305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 95: +#line 805 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); - if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) - (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); + parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); + + // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope + parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); + parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); + (yyval.interm.intermNode) = 0; } -#line 3455 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5041 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 15: -#line 313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 96: +#line 813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); + (yyval.interm.intermNode) = 0; } -#line 3463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 16: -#line 316 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 97: +#line 817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); + parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); + (yyval.interm.intermNode) = 0; } -#line 3471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5059 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 17: -#line 319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 98: +#line 821 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); + parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); + (yyval.interm.intermNode) = 0; } -#line 3479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5068 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 18: -#line 322 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 99: +#line 825 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); + parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); + parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); + (yyval.interm.intermNode) = 0; } -#line 3487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5078 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 19: -#line 325 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 100: +#line 830 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); - parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "++", (yyvsp[-1].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "++", EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode)); + parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); + parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); + (yyval.interm.intermNode) = 0; } -#line 3497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5088 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 20: -#line 330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 101: +#line 835 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); - parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "--", (yyvsp[-1].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "--", EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode)); + parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); + (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); + parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); + (yyval.interm.intermNode) = 0; } -#line 3507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5099 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 21: -#line 338 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - } -#line 3516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 102: +#line 844 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } +#line 5105 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 22: -#line 345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 103: +#line 844 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleFunctionCall((yyvsp[0].interm).loc, (yyvsp[0].interm).function, (yyvsp[0].interm).intermNode); - delete (yyvsp[0].interm).function; + --parseContext.structNestingLevel; + parseContext.blockName = (yyvsp[-4].lex).string; + parseContext.globalQualifierFixCheck((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).qualifier); + parseContext.checkNoShaderLayouts((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).shaderQualifiers); + parseContext.currentBlockQualifier = (yyvsp[-5].interm.type).qualifier; + (yyval.interm).loc = (yyvsp[-5].interm.type).loc; + (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 3525 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5119 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 23: -#line 352 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 104: +#line 855 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); + (yyval.interm.identifierList) = new TIdentifierList; + (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 3533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5128 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 24: -#line 358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 105: +#line 859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-1].interm); - (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); + (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 3542 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5137 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 25: -#line 362 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 106: +#line 866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm).function = (yyvsp[-1].interm.function); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 3551 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5146 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 26: -#line 369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 107: +#line 873 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-1].interm); + (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 3559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5154 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 27: -#line 372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 108: +#line 876 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); + (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 3567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5162 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 28: -#line 378 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 109: +#line 883 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - TParameter param = { 0, new TType }; - param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); - (yyvsp[-1].interm).function->addParameter(param); - (yyval.interm).function = (yyvsp[-1].interm).function; - (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); + // Add the parameter + (yyval.interm.function) = (yyvsp[-1].interm.function); + if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) + (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param); + else + delete (yyvsp[0].interm).param.type; } -#line 3579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 29: -#line 385 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 110: +#line 891 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - TParameter param = { 0, new TType }; - param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); - (yyvsp[-2].interm).function->addParameter(param); - (yyval.interm).function = (yyvsp[-2].interm).function; - (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + // + // Only first parameter of one-parameter functions can be void + // The check for named parameters not being void is done in parameter_declarator + // + if ((yyvsp[0].interm).param.type->getBasicType() == EbtVoid) { + // + // This parameter > first is void + // + parseContext.error((yyvsp[-1].lex).loc, "cannot be an argument type except for '(void)'", "void", ""); + delete (yyvsp[0].interm).param.type; + } else { + // Add the parameter + (yyval.interm.function) = (yyvsp[-2].interm.function); + (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); + } } -#line 3591 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5197 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 30: -#line 395 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 111: +#line 911 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-1].interm); + if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { + parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", + GetStorageQualifierString((yyvsp[-2].interm.type).qualifier.storage), ""); + } + if ((yyvsp[-2].interm.type).arraySizes) + parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); + + // Add the function as a prototype after parsing it (we do not support recursion) + TFunction *function; + TType type((yyvsp[-2].interm.type)); + + // Potentially rename shader entry point function. No-op most of the time. + parseContext.renameShaderFunction((yyvsp[-1].lex).string); + + // Make the function + function = new TFunction((yyvsp[-1].lex).string, type); + (yyval.interm.function) = function; } -#line 3599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5221 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 31: -#line 403 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 112: +#line 934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // Constructor - (yyval.interm).intermNode = 0; - (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); + if ((yyvsp[-1].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[-1].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck((yyvsp[-1].interm.type).loc, *(yyvsp[-1].interm.type).arraySizes); + } + if ((yyvsp[-1].interm.type).basicType == EbtVoid) { + parseContext.error((yyvsp[0].lex).loc, "illegal use of type 'void'", (yyvsp[0].lex).string->c_str(), ""); + } + parseContext.reservedErrorCheck((yyvsp[0].lex).loc, *(yyvsp[0].lex).string); + + TParameter param = {(yyvsp[0].lex).string, new TType((yyvsp[-1].interm.type))}; + (yyval.interm).loc = (yyvsp[0].lex).loc; + (yyval.interm).param = param; } -#line 3609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 32: -#line 408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 113: +#line 949 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // - // Should be a method or subroutine call, but we haven't recognized the arguments yet. - // - (yyval.interm).function = 0; - (yyval.interm).intermNode = 0; - - TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode(); - if (method) { - (yyval.interm).function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); - (yyval.interm).intermNode = method->getObject(); - } else { - TIntermSymbol* symbol = (yyvsp[0].interm.intermTypedNode)->getAsSymbolNode(); - if (symbol) { - parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName()); - TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid)); - (yyval.interm).function = function; - } else - parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "function call, method, or subroutine call expected", "", ""); + if ((yyvsp[-2].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); } + TType* type = new TType((yyvsp[-2].interm.type)); + type->transferArraySizes((yyvsp[0].interm).arraySizes); + type->copyArrayInnerSizes((yyvsp[-2].interm.type).arraySizes); - if ((yyval.interm).function == 0) { - // error recover - TString empty(""); - (yyval.interm).function = new TFunction(&empty, TType(EbtVoid), EOpNull); - } + parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, type->getArraySizes()); + parseContext.arraySizeRequiredCheck((yyvsp[0].interm).loc, *(yyvsp[0].interm).arraySizes); + parseContext.reservedErrorCheck((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string); + + TParameter param = { (yyvsp[-1].lex).string, type }; + + (yyval.interm).loc = (yyvsp[-1].lex).loc; + (yyval.interm).param = param; } -#line 3641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 33: -#line 438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 114: +#line 974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) - parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); + (yyval.interm) = (yyvsp[0].interm); + if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) + (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + + parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); + parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); + } -#line 3652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 34: -#line 444 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 115: +#line 985 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm) = (yyvsp[0].interm); + + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); + parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); } -#line 3661 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 35: -#line 448 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 116: +#line 995 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm) = (yyvsp[0].interm); + if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) + (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; + parseContext.precisionQualifierCheck((yyvsp[-1].interm.type).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + + parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); + parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 3670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5308 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 36: -#line 452 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 117: +#line 1005 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - if ((yyvsp[-1].interm).op != EOpNull) { - char errorOp[2] = {0, 0}; - switch((yyvsp[-1].interm).op) { - case EOpNegative: errorOp[0] = '-'; break; - case EOpLogicalNot: errorOp[0] = '!'; break; - case EOpBitwiseNot: errorOp[0] = '~'; break; - default: break; // some compilers want this - } - (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].interm).loc, errorOp, (yyvsp[-1].interm).op, (yyvsp[0].interm.intermTypedNode)); - } else { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) - (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); - } - } -#line 3691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; + (yyval.interm) = (yyvsp[0].interm); - case 37: -#line 472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 3697 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); + parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + } +#line 5320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 38: -#line 473 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 3703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 118: +#line 1015 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; + (yyval.interm).param = param; + if ((yyvsp[0].interm.type).arraySizes) + parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); + } +#line 5331 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 39: -#line 474 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 3709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 119: +#line 1024 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[0].interm); + } +#line 5339 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 40: -#line 475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } -#line 3716 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 120: +#line 1027 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-2].interm); + parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); + } +#line 5348 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 41: -#line 481 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 121: +#line 1031 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-3].interm); + parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); + } +#line 5357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 42: -#line 482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 122: +#line 1035 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm).type = (yyvsp[-5].interm).type; + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 3732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5367 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 43: -#line 487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 123: +#line 1040 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm).type = (yyvsp[-4].interm).type; + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 3742 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5377 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 44: -#line 492 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 124: +#line 1048 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm).type = (yyvsp[0].interm.type); + (yyval.interm).intermNode = 0; + parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); } -#line 3753 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 45: -#line 501 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3759 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 125: +#line 1053 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-1].interm.type); + (yyval.interm).intermNode = 0; + parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); + } +#line 5397 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 46: -#line 502 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 126: +#line 1058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm).type = (yyvsp[-2].interm.type); + (yyval.interm).intermNode = 0; + parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); } -#line 3769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5407 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 47: -#line 507 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 127: +#line 1063 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm).type = (yyvsp[-4].interm.type); + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 3779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 48: -#line 515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3785 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 128: +#line 1068 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm).type = (yyvsp[-3].interm.type); + TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); + } +#line 5427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 49: -#line 516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 129: +#line 1077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm.type) = (yyvsp[0].interm.type); + + parseContext.globalQualifierTypeCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyval.interm.type)); + if ((yyvsp[0].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + } + + parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); } -#line 3796 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5443 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 50: -#line 522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 130: +#line 1088 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); + parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); + + if ((yyvsp[0].interm.type).arraySizes) { + parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); + } + + if ((yyvsp[0].interm.type).arraySizes && parseContext.arrayQualifierError((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).qualifier)) + (yyvsp[0].interm.type).arraySizes = nullptr; + + parseContext.checkNoShaderLayouts((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); + (yyvsp[0].interm.type).shaderQualifiers.merge((yyvsp[-1].interm.type).shaderQualifiers); + parseContext.mergeQualifiers((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyvsp[-1].interm.type).qualifier, true); + parseContext.precisionQualifierCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).basicType, (yyvsp[0].interm.type).qualifier); + + (yyval.interm.type) = (yyvsp[0].interm.type); + + if (! (yyval.interm.type).qualifier.isInterpolation() && + ((parseContext.language == EShLangVertex && (yyval.interm.type).qualifier.storage == EvqVaryingOut) || + (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) + (yyval.interm.type).qualifier.smooth = true; } -#line 3807 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5472 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 51: -#line 531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 131: +#line 1115 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); + parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.invariant = true; + } +#line 5483 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 52: -#line 532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 132: +#line 1124 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "smooth"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.smooth = true; } -#line 3823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 53: -#line 537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 133: +#line 1131 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "flat"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.flat = true; } -#line 3833 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 54: -#line 542 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 134: +#line 1138 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); +#ifdef NV_EXTENSIONS + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); +#else + parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "noperspective"); +#endif + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "noperspective"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.nopersp = true; } -#line 3843 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 55: -#line 547 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 135: +#line 1149 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); +#ifdef AMD_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.explicitInterp = true; +#endif } -#line 3853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 56: -#line 555 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3859 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 136: +#line 1158 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef NV_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.pervertexNV = true; +#endif + } +#line 5552 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 57: -#line 556 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 137: +#line 1168 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); - parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); - parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "==", EOpEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); +#ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); + // Fragment shader stage doesn't check for extension. So we explicitly add below extension check. + if (parseContext.language == EShLangFragment) + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.perPrimitiveNV = true; +#endif } -#line 3872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 58: -#line 564 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 138: +#line 1180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); - parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); - parseContext.specializationCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "!=", EOpNotEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); +#ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV"); + parseContext.requireStage((yyvsp[0].lex).loc, EShLangMeshNV, "perviewNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.perViewNV = true; +#endif } -#line 3885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5583 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 59: -#line 575 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 139: +#line 1189 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.perTaskNV = true; +#endif + } +#line 5597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 60: -#line 576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 140: +#line 1201 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm.type) = (yyvsp[-1].interm.type); } -#line 3902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5605 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 61: -#line 585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3908 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 141: +#line 1207 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5613 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 62: -#line 586 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 142: +#line 1210 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm.type) = (yyvsp[-2].interm.type); + (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); + parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 3919 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5623 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 63: -#line 595 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 143: +#line 1217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); + } +#line 5632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 64: -#line 596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 144: +#line 1221 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); + (yyval.interm.type).init((yyvsp[-2].lex).loc); + parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); } -#line 3936 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 65: -#line 605 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 145: +#line 1225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { // because "shared" is both an identifier and a keyword + (yyval.interm.type).init((yyvsp[0].lex).loc); + TString strShared("shared"); + parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); + } +#line 5651 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 66: -#line 606 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 146: +#line 1233 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.noContraction = true; } -#line 3952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 67: -#line 614 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 147: +#line 1242 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 68: -#line 615 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 148: +#line 1245 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + (yyval.interm.type) = (yyvsp[-1].interm.type); + if ((yyval.interm.type).basicType == EbtVoid) + (yyval.interm.type).basicType = (yyvsp[0].interm.type).basicType; + + (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); + parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 3968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5683 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 69: -#line 623 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3974 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 149: +#line 1256 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 70: -#line 624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 150: +#line 1259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); - if ((yyval.interm.intermTypedNode) == 0) - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); + (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 3984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 71: -#line 632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 3990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 151: +#line 1262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5708 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 72: -#line 633 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 152: +#line 1266 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - ++parseContext.controlFlowNestingLevel; + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 3998 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 73: -#line 636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 153: +#line 1270 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - --parseContext.controlFlowNestingLevel; - parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); - parseContext.rValueErrorCheck((yyvsp[-4].lex).loc, "?", (yyvsp[-5].interm.intermTypedNode)); - parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)); - parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addSelection((yyvsp[-5].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-4].lex).loc); - if ((yyval.interm.intermTypedNode) == 0) { - parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - } + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 4015 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 74: -#line 651 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4021 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 154: +#line 1274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5735 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 75: -#line 652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 155: +#line 1278 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); - parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); - parseContext.specializationCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); - parseContext.lValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)); - parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].interm).loc); - if ((yyval.interm.intermTypedNode) == 0) { - parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); - (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); - } + (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 4038 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5743 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 76: -#line 667 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 156: +#line 1284 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).op = EOpAssign; + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } -#line 4047 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5752 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 77: -#line 671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 157: +#line 1288 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).op = EOpMulAssign; + parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); + parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); + parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "attribute"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "attribute"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, EEsProfile, 300, "attribute"); + + parseContext.globalCheck((yyvsp[0].lex).loc, "attribute"); + + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 4056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 78: -#line 675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 158: +#line 1300 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).op = EOpDivAssign; + parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); + parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "varying"); + parseContext.requireNotRemoved((yyvsp[0].lex).loc, EEsProfile, 300, "varying"); + + parseContext.globalCheck((yyvsp[0].lex).loc, "varying"); + + (yyval.interm.type).init((yyvsp[0].lex).loc); + if (parseContext.language == EShLangVertex) + (yyval.interm.type).qualifier.storage = EvqVaryingOut; + else + (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 4065 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 79: -#line 679 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 159: +#line 1314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).op = EOpModAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqInOut; } -#line 4075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5798 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 80: -#line 684 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 160: +#line 1319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).op = EOpAddAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "in"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + (yyval.interm.type).qualifier.storage = EvqIn; } -#line 4084 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5809 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 81: -#line 688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 161: +#line 1325 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).op = EOpSubAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "out"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + (yyval.interm.type).qualifier.storage = EvqOut; } -#line 4093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 82: -#line 692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 162: +#line 1331 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); - (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; + parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck((yyvsp[0].lex).loc, "centroid"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.centroid = true; } -#line 4102 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5832 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 83: -#line 696 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 163: +#line 1338 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); - (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.patch = true; } -#line 4111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5843 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 84: -#line 700 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 164: +#line 1344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); - (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.sample = true; } -#line 4120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 85: -#line 704 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 165: +#line 1349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); - (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqUniform; } -#line 4129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 86: -#line 708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 166: +#line 1354 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); - (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; + parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqBuffer; } -#line 4138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5873 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 87: -#line 715 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 167: +#line 1359 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); +#ifdef NV_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask + | EShLangAnyHitNVMask), "hitAttributeNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqHitAttrNV; +#endif } -#line 4146 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5888 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 88: -#line 718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 168: +#line 1369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); - (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); - if ((yyval.interm.intermTypedNode) == 0) { - parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - } +#ifdef NV_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | + EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqPayloadNV; +#endif } -#line 4159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5903 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 89: -#line 729 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 169: +#line 1379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); - (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); +#ifdef NV_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitNVMask | + EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqPayloadInNV; +#endif } -#line 4168 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 90: -#line 736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 170: +#line 1389 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); - (yyval.interm.intermNode) = 0; - // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature +#ifdef NV_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenNVMask | + EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableDataNV; +#endif } -#line 4178 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5933 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 91: -#line 741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 171: +#line 1399 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) - (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); - (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; +#ifdef NV_EXTENSIONS + parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqCallableDataInNV; +#endif } -#line 4188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5947 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 92: -#line 746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 172: +#line 1408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); + parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 310, 0, "shared"); +#ifdef NV_EXTENSIONS + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); +#else + parseContext.requireStage((yyvsp[0].lex).loc, EShLangCompute, "shared"); +#endif + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqShared; + } +#line 5964 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope - parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); - parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); - (yyval.interm.intermNode) = 0; + case 173: +#line 1420 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.coherent = true; } -#line 4201 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 93: -#line 754 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 174: +#line 1424 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); - (yyval.interm.intermNode) = 0; + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); + (yyval.interm.type).qualifier.devicecoherent = true; } -#line 4210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5983 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 94: -#line 758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 175: +#line 1429 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); - (yyval.interm.intermNode) = 0; + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); + (yyval.interm.type).qualifier.queuefamilycoherent = true; } -#line 4219 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5993 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 95: -#line 762 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 176: +#line 1434 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); - (yyval.interm.intermNode) = 0; + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); + (yyval.interm.type).qualifier.workgroupcoherent = true; } -#line 4228 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6003 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 96: -#line 766 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 177: +#line 1439 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); - parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); - (yyval.interm.intermNode) = 0; + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); + (yyval.interm.type).qualifier.subgroupcoherent = true; } -#line 4238 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6013 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 97: -#line 771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 178: +#line 1444 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); - parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); - (yyval.interm.intermNode) = 0; + (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); + (yyval.interm.type).qualifier.nonprivate = true; } -#line 4248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6023 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 98: -#line 776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 179: +#line 1449 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); - (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); - parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); - (yyval.interm.intermNode) = 0; + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.volatil = true; } -#line 4259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6032 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 99: -#line 785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 4265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 180: +#line 1453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.restrict = true; + } +#line 6041 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 100: -#line 785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 181: +#line 1457 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - --parseContext.structNestingLevel; - parseContext.blockName = (yyvsp[-4].lex).string; - parseContext.globalQualifierFixCheck((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).qualifier); - parseContext.checkNoShaderLayouts((yyvsp[-5].interm.type).loc, (yyvsp[-5].interm.type).shaderQualifiers); - parseContext.currentBlockQualifier = (yyvsp[-5].interm.type).qualifier; - (yyval.interm).loc = (yyvsp[-5].interm.type).loc; - (yyval.interm).typeList = (yyvsp[-1].interm.typeList); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.readonly = true; } -#line 4279 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 101: -#line 796 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 182: +#line 1461 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.identifierList) = new TIdentifierList; - (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.writeonly = true; } -#line 4288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6059 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 102: -#line 800 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 183: +#line 1465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); - (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); + parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); + parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); + parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); + (yyval.interm.type).init((yyvsp[0].lex).loc); } -#line 4297 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 103: -#line 807 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 184: +#line 1471 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).function = (yyvsp[-1].interm.function); - (yyval.interm).loc = (yyvsp[0].lex).loc; + parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); + parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); + parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); + (yyval.interm.type).init((yyvsp[-3].lex).loc); } -#line 4306 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6081 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 104: -#line 814 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 185: +#line 1480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.function) = (yyvsp[0].interm.function); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.nonUniform = true; } -#line 4314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 105: -#line 817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 186: +#line 1487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.function) = (yyvsp[0].interm.function); + // TODO } -#line 4322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6098 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 106: -#line 824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 187: +#line 1490 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // Add the parameter - (yyval.interm.function) = (yyvsp[-1].interm.function); - if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) - (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param); - else - delete (yyvsp[0].interm).param.type; + // TODO: 4.0 semantics: subroutines + // 1) make sure each identifier is a type declared earlier with SUBROUTINE + // 2) save all of the identifiers for future comparison with the declared function } -#line 4335 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6108 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 107: -#line 832 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 188: +#line 1498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // - // Only first parameter of one-parameter functions can be void - // The check for named parameters not being void is done in parameter_declarator - // - if ((yyvsp[0].interm).param.type->getBasicType() == EbtVoid) { - // - // This parameter > first is void - // - parseContext.error((yyvsp[-1].lex).loc, "cannot be an argument type except for '(void)'", "void", ""); - delete (yyvsp[0].interm).param.type; - } else { - // Add the parameter - (yyval.interm.function) = (yyvsp[-2].interm.function); - (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); - } + (yyval.interm.type) = (yyvsp[-1].interm.type); + (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); + (yyval.interm.type).typeParameters = (yyvsp[0].interm.typeParameters); } -#line 4357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6118 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 108: -#line 852 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 189: +#line 1503 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { - parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", - GetStorageQualifierString((yyvsp[-2].interm.type).qualifier.storage), ""); - } - if ((yyvsp[-2].interm.type).arraySizes) - parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); - - // Add the function as a prototype after parsing it (we do not support recursion) - TFunction *function; - TType type((yyvsp[-2].interm.type)); - - // Potentially rename shader entry point function. No-op most of the time. - parseContext.renameShaderFunction((yyvsp[-1].lex).string); - - // Make the function - function = new TFunction((yyvsp[-1].lex).string, type); - (yyval.interm.function) = function; + parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); + (yyval.interm.type) = (yyvsp[-2].interm.type); + (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); + (yyval.interm.type).typeParameters = (yyvsp[-1].interm.typeParameters); + (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; } -#line 4381 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6130 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 109: -#line 875 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 190: +#line 1513 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - if ((yyvsp[-1].interm.type).arraySizes) { - parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); - parseContext.profileRequires((yyvsp[-1].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck((yyvsp[-1].interm.type).loc, *(yyvsp[-1].interm.type).arraySizes); - } - if ((yyvsp[-1].interm.type).basicType == EbtVoid) { - parseContext.error((yyvsp[0].lex).loc, "illegal use of type 'void'", (yyvsp[0].lex).string->c_str(), ""); - } - parseContext.reservedErrorCheck((yyvsp[0].lex).loc, *(yyvsp[0].lex).string); - - TParameter param = {(yyvsp[0].lex).string, new TType((yyvsp[-1].interm.type))}; - (yyval.interm).loc = (yyvsp[0].lex).loc; - (yyval.interm).param = param; + (yyval.interm).loc = (yyvsp[-1].lex).loc; + (yyval.interm).arraySizes = new TArraySizes; + (yyval.interm).arraySizes->addInnerSize(); } -#line 4401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6140 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 110: -#line 890 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 191: +#line 1518 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - if ((yyvsp[-2].interm.type).arraySizes) { - parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); - parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); - parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); - } - parseContext.arrayDimCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.type).arraySizes, (yyvsp[0].interm).arraySizes); - - parseContext.arraySizeRequiredCheck((yyvsp[0].interm).loc, *(yyvsp[0].interm).arraySizes); - parseContext.reservedErrorCheck((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string); + (yyval.interm).loc = (yyvsp[-2].lex).loc; + (yyval.interm).arraySizes = new TArraySizes; - (yyvsp[-2].interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + TArraySize size; + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); + (yyval.interm).arraySizes->addInnerSize(size); + } +#line 6153 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - TParameter param = { (yyvsp[-1].lex).string, new TType((yyvsp[-2].interm.type))}; - (yyval.interm).loc = (yyvsp[-1].lex).loc; - (yyval.interm).param = param; + case 192: +#line 1526 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm) = (yyvsp[-2].interm); + (yyval.interm).arraySizes->addInnerSize(); } -#line 4423 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6162 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 111: -#line 913 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 193: +#line 1530 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); - if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) - (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; - parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + (yyval.interm) = (yyvsp[-3].interm); - parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); - parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); - parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); + TArraySize size; + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); + (yyval.interm).arraySizes->addInnerSize(size); + } +#line 6174 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + case 194: +#line 1540 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); } -#line 4439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6182 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 112: -#line 924 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 195: +#line 1543 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); + (yyval.interm.typeParameters) = 0; + } +#line 6190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; - parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); - parseContext.paramCheckFix((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); - parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + case 196: +#line 1549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); } -#line 4451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 113: -#line 934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 197: +#line 1555 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); - if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) - (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; - parseContext.precisionQualifierCheck((yyvsp[-1].interm.type).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + (yyval.interm.typeParameters) = new TArraySizes; - parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); - parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); - parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); + TArraySize size; + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); + (yyval.interm.typeParameters)->addInnerSize(size); } -#line 4466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 114: -#line 944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 198: +#line 1562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); + (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); - parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); - parseContext.paramCheckFix((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); - parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + TArraySize size; + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); + (yyval.interm.typeParameters)->addInnerSize(size); } -#line 4478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6222 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 115: -#line 954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 199: +#line 1572 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; - (yyval.interm).param = param; - if ((yyvsp[0].interm.type).arraySizes) - parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtVoid; } -#line 4489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6231 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 116: -#line 963 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 200: +#line 1576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[0].interm); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; } -#line 4497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6240 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 117: -#line 966 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 201: +#line 1580 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-2].interm); - parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; } -#line 4506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 118: -#line 970 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 202: +#line 1585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-3].interm); - parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; } -#line 4515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6260 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 119: -#line 974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 203: +#line 1590 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[-5].interm).type; - TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); - (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; } -#line 4525 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 120: -#line 979 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 204: +#line 1595 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[-4].interm).type; - TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); - (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; } -#line 4535 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 121: -#line 987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 205: +#line 1600 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[0].interm.type); - (yyval.interm).intermNode = 0; - parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; } -#line 4545 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6289 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 122: -#line 992 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 206: +#line 1604 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[-1].interm.type); - (yyval.interm).intermNode = 0; - parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; } -#line 4555 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6299 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 123: -#line 997 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 207: +#line 1609 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[-2].interm.type); - (yyval.interm).intermNode = 0; - parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt8; } -#line 4565 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6309 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 124: -#line 1002 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 208: +#line 1614 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[-4].interm.type); - TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); - (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; } -#line 4575 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6319 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 125: -#line 1007 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 209: +#line 1619 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).type = (yyvsp[-3].interm.type); - TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); - (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; } -#line 4585 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6329 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 126: -#line 1016 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 210: +#line 1624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); - - parseContext.globalQualifierTypeCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyval.interm.type)); - if ((yyvsp[0].interm.type).arraySizes) { - parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); - parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); - } - - parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; } -#line 4601 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6339 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 127: -#line 1027 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 211: +#line 1629 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); - parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); - - if ((yyvsp[0].interm.type).arraySizes) { - parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); - parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); - } - - if ((yyvsp[0].interm.type).arraySizes && parseContext.arrayQualifierError((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).qualifier)) - (yyvsp[0].interm.type).arraySizes = 0; - - parseContext.checkNoShaderLayouts((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); - (yyvsp[0].interm.type).shaderQualifiers.merge((yyvsp[-1].interm.type).shaderQualifiers); - parseContext.mergeQualifiers((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyvsp[-1].interm.type).qualifier, true); - parseContext.precisionQualifierCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).basicType, (yyvsp[0].interm.type).qualifier); - - (yyval.interm.type) = (yyvsp[0].interm.type); - - if (! (yyval.interm.type).qualifier.isInterpolation() && - ((parseContext.language == EShLangVertex && (yyval.interm.type).qualifier.storage == EvqVaryingOut) || - (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) - (yyval.interm.type).qualifier.smooth = true; + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; } -#line 4630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6349 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 128: -#line 1054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 212: +#line 1634 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); - parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.invariant = true; + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; } -#line 4641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6359 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 129: -#line 1063 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 213: +#line 1639 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); - parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "smooth"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.smooth = true; + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; } -#line 4653 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 130: -#line 1070 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 214: +#line 1644 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); - parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "flat"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.flat = true; + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint64; } -#line 4665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6379 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 131: -#line 1077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 215: +#line 1649 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); - parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "noperspective"); - parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "noperspective"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.nopersp = true; + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; } -#line 4677 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6388 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 132: -#line 1084 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 216: +#line 1653 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.explicitInterp = true; -#endif + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(2); } -#line 4691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6398 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 133: -#line 1096 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 217: +#line 1658 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[-1].interm.type); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(3); } -#line 4699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6408 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 134: -#line 1102 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 218: +#line 1663 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(4); } -#line 4707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6418 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 135: -#line 1105 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 219: +#line 1668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[-2].interm.type); - (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); - parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(2); } -#line 4717 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6429 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 136: -#line 1112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 220: +#line 1674 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(3); } -#line 4726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6440 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 137: -#line 1116 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 221: +#line 1680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[-2].lex).loc); - parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(4); } -#line 4735 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 138: -#line 1120 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { // because "shared" is both an identifier and a keyword - (yyval.interm.type).init((yyvsp[0].lex).loc); - TString strShared("shared"); - parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); + case 222: +#line 1686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(2); } -#line 4745 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6462 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 139: -#line 1128 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 223: +#line 1692 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.noContraction = true; + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(3); } -#line 4756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6473 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 140: -#line 1137 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 224: +#line 1698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); + parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setVector(4); } -#line 4764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6484 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 141: -#line 1140 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 225: +#line 1704 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[-1].interm.type); - if ((yyval.interm.type).basicType == EbtVoid) - (yyval.interm.type).basicType = (yyvsp[0].interm.type).basicType; - - (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); - parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(2); } -#line 4777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 142: -#line 1151 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 226: +#line 1710 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(3); } -#line 4785 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 143: -#line 1154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 227: +#line 1716 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setVector(4); } -#line 4793 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 144: -#line 1157 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 228: +#line 1722 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); - (yyval.interm.type) = (yyvsp[0].interm.type); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(2); } -#line 4802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6528 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 145: -#line 1161 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 229: +#line 1728 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(3); } -#line 4811 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6539 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 146: -#line 1165 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); + case 230: +#line 1734 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setVector(4); } -#line 4820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 147: -#line 1169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 231: +#line 1740 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(2); } -#line 4829 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6560 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 148: -#line 1176 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 232: +#line 1745 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(3); } -#line 4838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6570 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 149: -#line 1180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 233: +#line 1750 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); - parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); - parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "attribute"); - parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "attribute"); - parseContext.requireNotRemoved((yyvsp[0].lex).loc, EEsProfile, 300, "attribute"); - - parseContext.globalCheck((yyvsp[0].lex).loc, "attribute"); - - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqVaryingIn; + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).setVector(4); } -#line 4855 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6580 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 150: -#line 1192 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 234: +#line 1755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); - parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); - parseContext.requireNotRemoved((yyvsp[0].lex).loc, ECoreProfile, 420, "varying"); - parseContext.requireNotRemoved((yyvsp[0].lex).loc, EEsProfile, 300, "varying"); - - parseContext.globalCheck((yyvsp[0].lex).loc, "varying"); - - (yyval.interm.type).init((yyvsp[0].lex).loc); - if (parseContext.language == EShLangVertex) - (yyval.interm.type).qualifier.storage = EvqVaryingOut; - else - (yyval.interm.type).qualifier.storage = EvqVaryingIn; + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); } -#line 4874 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 151: -#line 1206 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 235: +#line 1760 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqInOut; + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(3); } -#line 4884 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6600 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 152: -#line 1211 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 236: +#line 1765 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "in"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later - (yyval.interm.type).qualifier.storage = EvqIn; + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(4); } -#line 4895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6610 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 153: -#line 1217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 237: +#line 1770 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "out"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later - (yyval.interm.type).qualifier.storage = EvqOut; + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt8; + (yyval.interm.type).setVector(2); } -#line 4906 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6621 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 154: -#line 1223 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 238: +#line 1776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); - parseContext.globalCheck((yyvsp[0].lex).loc, "centroid"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.centroid = true; + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt8; + (yyval.interm.type).setVector(3); } -#line 4918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 155: -#line 1230 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 239: +#line 1782 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.patch = true; + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt8; + (yyval.interm.type).setVector(4); } -#line 4929 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6643 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 156: -#line 1236 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 240: +#line 1788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.sample = true; + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(2); } -#line 4939 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6654 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 157: -#line 1241 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 241: +#line 1794 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqUniform; + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(3); } -#line 4949 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 158: -#line 1246 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 242: +#line 1800 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqBuffer; + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt16; + (yyval.interm.type).setVector(4); } -#line 4959 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 159: -#line 1251 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 243: +#line 1806 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 310, 0, "shared"); - parseContext.requireStage((yyvsp[0].lex).loc, EShLangCompute, "shared"); - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqShared; + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); } -#line 4972 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6687 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 160: -#line 1259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 244: +#line 1812 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.coherent = true; + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(3); } -#line 4981 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 161: -#line 1263 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 245: +#line 1818 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.volatil = true; + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(4); } -#line 4990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 162: -#line 1267 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 246: +#line 1824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.restrict = true; + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(2); } -#line 4999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 163: -#line 1271 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 247: +#line 1830 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.readonly = true; + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(3); } -#line 5008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 164: -#line 1275 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 248: +#line 1836 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.writeonly = true; + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).setVector(4); } -#line 5017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6742 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 165: -#line 1279 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 249: +#line 1842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); - parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); - parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); - (yyval.interm.type).init((yyvsp[0].lex).loc); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(2); } -#line 5028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6753 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 166: -#line 1285 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 250: +#line 1848 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); - parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); - parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); - (yyval.interm.type).init((yyvsp[-3].lex).loc); + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(3); } -#line 5039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 167: -#line 1294 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 251: +#line 1854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // TODO + parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(4); } -#line 5047 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6775 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 168: -#line 1297 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 252: +#line 1860 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - // TODO: 4.0 semantics: subroutines - // 1) make sure each identifier is a type declared earlier with SUBROUTINE - // 2) save all of the identifiers for future comparison with the declared function + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; + (yyval.interm.type).setVector(2); } -#line 5057 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6786 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 169: -#line 1305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 253: +#line 1866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); - (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; + (yyval.interm.type).setVector(3); } -#line 5066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6797 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 170: -#line 1309 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 254: +#line 1872 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.arrayDimCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes, 0); - (yyval.interm.type) = (yyvsp[-1].interm.type); - (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); - (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint8; + (yyval.interm.type).setVector(4); } -#line 5077 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6808 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 171: -#line 1318 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 255: +#line 1878 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[-1].lex).loc; - (yyval.interm).arraySizes = new TArraySizes; - (yyval.interm).arraySizes->addInnerSize(); + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(2); } -#line 5087 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6819 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 172: -#line 1323 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 256: +#line 1884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm).loc = (yyvsp[-2].lex).loc; - (yyval.interm).arraySizes = new TArraySizes; - - TArraySize size; - parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size); - (yyval.interm).arraySizes->addInnerSize(size); + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(3); } -#line 5100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 173: -#line 1331 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm) = (yyvsp[-2].interm); - (yyval.interm).arraySizes->addInnerSize(); + case 257: +#line 1890 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(4); } -#line 5109 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6841 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 174: -#line 1335 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 258: +#line 1896 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm) = (yyvsp[-3].interm); - - TArraySize size; - parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size); - (yyval.interm).arraySizes->addInnerSize(size); + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(2); } -#line 5121 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6852 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 175: -#line 1345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 259: +#line 1902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtVoid; + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(3); } -#line 5130 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 176: -#line 1349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 260: +#line 1908 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(4); } -#line 5139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6874 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 177: -#line 1353 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 261: +#line 1914 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(2); } -#line 5149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 178: -#line 1358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 262: +#line 1920 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float", parseContext.symbolTable.atBuiltInLevel()); + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; -#endif + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(3); } -#line 5161 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6896 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 179: -#line 1365 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 263: +#line 1926 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(4); } -#line 5170 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6907 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 180: -#line 1369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 264: +#line 1932 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); } -#line 5180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6917 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 181: -#line 1374 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 265: +#line 1937 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt64; + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(3, 3); } -#line 5190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6927 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 182: -#line 1379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 266: +#line 1942 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); } -#line 5200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6937 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 183: -#line 1384 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 267: +#line 1947 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; -#endif + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 2); } -#line 5212 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6947 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 184: -#line 1391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 268: +#line 1952 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; -#endif + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 3); } -#line 5224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6957 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 185: -#line 1398 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 269: +#line 1957 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(2, 4); } -#line 5233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6967 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 186: -#line 1402 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 270: +#line 1962 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(2); + (yyval.interm.type).setMatrix(3, 2); } -#line 5243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6977 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 187: -#line 1407 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 271: +#line 1967 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(3); + (yyval.interm.type).setMatrix(3, 3); } -#line 5253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6987 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 188: -#line 1412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 272: +#line 1972 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).setVector(4); + (yyval.interm.type).setMatrix(3, 4); } -#line 5263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6997 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 189: -#line 1417 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 273: +#line 1977 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 2); } -#line 5274 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 190: -#line 1423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 274: +#line 1982 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 3); } -#line 5285 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 191: -#line 1429 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 275: +#line 1987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - (yyval.interm.type).setVector(4); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).setMatrix(4, 4); } -#line 5296 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7027 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 192: -#line 1435 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 276: +#line 1992 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setVector(2); -#endif + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 2); } -#line 5309 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7038 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 193: -#line 1443 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 277: +#line 1998 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setVector(3); -#endif + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 3); } -#line 5322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7049 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 194: -#line 1451 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 278: +#line 2004 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setVector(4); -#endif + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); } -#line 5335 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7060 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 195: -#line 1459 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 279: +#line 2010 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 2); } -#line 5345 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7071 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 196: -#line 1464 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 280: +#line 2016 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 3); } -#line 5355 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7082 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 197: -#line 1469 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 281: +#line 2022 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - (yyval.interm.type).setVector(4); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 4); } -#line 5365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 198: -#line 1474 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 282: +#line 2028 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 2); } -#line 5375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7104 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 199: -#line 1479 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 283: +#line 2034 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 3); } -#line 5385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7115 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 200: -#line 1484 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 284: +#line 2040 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(4); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 4); } -#line 5395 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7126 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 201: -#line 1489 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 285: +#line 2046 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt64; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 2); } -#line 5406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7137 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 202: -#line 1495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 286: +#line 2052 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt64; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 3); } -#line 5417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7148 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 203: -#line 1501 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 287: +#line 2058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt64; - (yyval.interm.type).setVector(4); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); } -#line 5428 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 204: -#line 1507 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 288: +#line 2064 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; - (yyval.interm.type).setVector(2); -#endif + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 2); } -#line 5441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7170 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 205: -#line 1515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 289: +#line 2070 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; - (yyval.interm.type).setVector(3); -#endif + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 3); } -#line 5454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7181 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 206: -#line 1523 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 290: +#line 2076 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt16; - (yyval.interm.type).setVector(4); -#endif + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 4); } -#line 5467 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7192 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 207: -#line 1531 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 291: +#line 2082 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 2); } -#line 5478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7203 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 208: -#line 1537 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 292: +#line 2088 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 3); } -#line 5489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7214 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 209: -#line 1543 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 293: +#line 2094 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).setVector(4); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(2, 4); } -#line 5500 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 210: -#line 1549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 294: +#line 2100 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint64; - (yyval.interm.type).setVector(2); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 2); } -#line 5511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7236 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 211: -#line 1555 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 295: +#line 2106 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint64; - (yyval.interm.type).setVector(3); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 3); } -#line 5522 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7247 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 212: -#line 1561 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 296: +#line 2112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint64; - (yyval.interm.type).setVector(4); + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(3, 4); } -#line 5533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7258 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 213: -#line 1567 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 297: +#line 2118 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; - (yyval.interm.type).setVector(2); -#endif + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 2); } -#line 5546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7269 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 214: -#line 1575 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 298: +#line 2124 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; - (yyval.interm.type).setVector(3); -#endif + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 3); } -#line 5559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 215: -#line 1583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 299: +#line 2130 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.int16Check((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtUint16; - (yyval.interm.type).setVector(4); -#endif + (yyval.interm.type).basicType = EbtFloat16; + (yyval.interm.type).setMatrix(4, 4); } -#line 5572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 216: -#line 1591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 300: +#line 2136 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 5582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7302 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 217: -#line 1596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 301: +#line 2142 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 5592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 218: -#line 1601 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 302: +#line 2148 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 5602 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 219: -#line 1606 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 303: +#line 2154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 5612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7335 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 220: -#line 1611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 304: +#line 2160 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 5622 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7346 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 221: -#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 305: +#line 2166 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 5632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 222: -#line 1621 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 306: +#line 2172 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 5642 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7368 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 223: -#line 1626 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 307: +#line 2178 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 5652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7379 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 224: -#line 1631 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 308: +#line 2184 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 5662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7390 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 225: -#line 1636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 309: +#line 2190 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 5672 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 226: -#line 1641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 310: +#line 2196 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 5682 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7412 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 227: -#line 1646 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 311: +#line 2202 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 5692 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7423 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 228: -#line 1651 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 312: +#line 2208 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 5703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7434 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 229: -#line 1657 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 313: +#line 2214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 5714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7445 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 230: -#line 1663 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 314: +#line 2220 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 5725 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 231: -#line 1669 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 315: +#line 2226 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 5736 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7467 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 232: -#line 1675 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 316: +#line 2232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 5747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 233: -#line 1681 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 317: +#line 2238 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 5758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 234: -#line 1687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 318: +#line 2244 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 5769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7500 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 235: -#line 1693 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 319: +#line 2250 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 5780 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 236: -#line 1699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 320: +#line 2256 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 5791 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7522 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 237: -#line 1705 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 321: +#line 2262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 5802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 238: -#line 1711 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 322: +#line 2268 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 5813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7544 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 239: -#line 1717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 323: +#line 2274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 5824 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7555 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 240: -#line 1723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 324: +#line 2280 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef NV_EXTENSIONS + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtAccStructNV; +#endif + } +#line 7566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 325: +#line 2286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtAtomicUint; + } +#line 7576 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 326: +#line 2291 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D); + } +#line 7586 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 327: +#line 2296 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D); + } +#line 7596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 328: +#line 2301 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd3D); + } +#line 7606 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 329: +#line 2306 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube); + } +#line 7616 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 330: +#line 2311 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); + } +#line 7626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 331: +#line 2316 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); + } +#line 7636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 332: +#line 2321 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); + } +#line 7646 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 333: +#line 2326 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); + } +#line 7656 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 334: +#line 2331 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); + } +#line 7666 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 335: +#line 2336 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); + } +#line 7676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 336: +#line 2341 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); + } +#line 7686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 337: +#line 2346 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); + } +#line 7696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 338: +#line 2351 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { -#ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 2); -#endif + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); } -#line 5837 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7706 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 241: -#line 1731 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 339: +#line 2356 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd1D); #endif } -#line 5850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7719 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 242: -#line 1739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 340: +#line 2364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D); #endif } -#line 5863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 243: -#line 1747 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 341: +#line 2372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd3D); #endif } -#line 5876 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7745 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 244: -#line 1755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 342: +#line 2380 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 3); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, EsdCube); #endif } -#line 5889 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 245: -#line 1763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 343: +#line 2388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(2, 4); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, false, true); #endif } -#line 5902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 246: -#line 1771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 344: +#line 2396 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 2); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, true); #endif } -#line 5915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7784 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 247: -#line 1779 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 345: +#line 2404 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, false, true); #endif } -#line 5928 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7797 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 248: -#line 1787 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 346: +#line 2412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(3, 4); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true); #endif } -#line 5941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 249: -#line 1795 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 347: +#line 2420 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 2); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true); #endif } -#line 5954 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 250: -#line 1803 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 348: +#line 2428 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 3); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true, true); #endif } -#line 5967 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7836 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 251: -#line 1811 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 349: +#line 2436 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef AMD_EXTENSIONS - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtFloat16; - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, true); #endif } -#line 5980 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7849 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 252: -#line 1819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 350: +#line 2444 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtAtomicUint; + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true); +#endif } -#line 5990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 253: -#line 1824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 351: +#line 2452 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D); + (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true, true); +#endif } -#line 6000 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 254: -#line 1829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 352: +#line 2460 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D); + (yyval.interm.type).sampler.set(EbtInt, Esd1D); } -#line 6010 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 255: -#line 1834 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 353: +#line 2465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd3D); + (yyval.interm.type).sampler.set(EbtInt, Esd2D); } -#line 6020 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 256: -#line 1839 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 354: +#line 2470 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdCube); + (yyval.interm.type).sampler.set(EbtInt, Esd3D); } -#line 6030 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7905 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 257: -#line 1844 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 355: +#line 2475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); + (yyval.interm.type).sampler.set(EbtInt, EsdCube); } -#line 6040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 258: -#line 1849 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 356: +#line 2480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); + (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); } -#line 6050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 259: -#line 1854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 357: +#line 2485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); + (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); } -#line 6060 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7935 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 260: -#line 1859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 358: +#line 2490 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); + (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); } -#line 6070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7945 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 261: -#line 1864 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 359: +#line 2495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); + (yyval.interm.type).sampler.set(EbtUint, Esd1D); } -#line 6080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7955 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 262: -#line 1869 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 360: +#line 2500 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); + (yyval.interm.type).sampler.set(EbtUint, Esd2D); } -#line 6090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7965 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 263: -#line 1874 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 361: +#line 2505 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); + (yyval.interm.type).sampler.set(EbtUint, Esd3D); } -#line 6100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7975 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 264: -#line 1879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 362: +#line 2510 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); + (yyval.interm.type).sampler.set(EbtUint, EsdCube); } -#line 6110 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 265: -#line 1884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 363: +#line 2515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); + (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); } -#line 6120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 266: -#line 1889 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 364: +#line 2520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd1D); + (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); } -#line 6130 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8005 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 267: -#line 1894 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 365: +#line 2525 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd2D); + (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); } -#line 6140 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8015 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 268: -#line 1899 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 366: +#line 2530 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd3D); + (yyval.interm.type).sampler.set(EbtFloat, EsdRect); } -#line 6150 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8025 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 269: -#line 1904 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 367: +#line 2535 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdCube); + (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); } -#line 6160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 270: -#line 1909 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 368: +#line 2540 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); + (yyval.interm.type).sampler.set(EbtFloat16, EsdRect); +#endif } -#line 6170 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 271: -#line 1914 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 369: +#line 2548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); + (yyval.interm.type).sampler.set(EbtFloat16, EsdRect, false, true); +#endif } -#line 6180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8061 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 272: -#line 1919 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 370: +#line 2556 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); + (yyval.interm.type).sampler.set(EbtInt, EsdRect); } -#line 6190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8071 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 273: -#line 1924 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 371: +#line 2561 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd1D); + (yyval.interm.type).sampler.set(EbtUint, EsdRect); } -#line 6200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8081 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 274: -#line 1929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 372: +#line 2566 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D); + (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); } -#line 6210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8091 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 275: -#line 1934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 373: +#line 2571 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd3D); + (yyval.interm.type).sampler.set(EbtFloat16, EsdBuffer); +#endif } -#line 6220 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8104 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 276: -#line 1939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 374: +#line 2579 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, EsdCube); + (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); } -#line 6230 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8114 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 277: -#line 1944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 375: +#line 2584 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); + (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); } -#line 6240 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8124 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 278: -#line 1949 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 376: +#line 2589 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); } -#line 6250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8134 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 279: -#line 1954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 377: +#line 2594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, false, true); +#endif } -#line 6260 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 280: -#line 1959 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 378: +#line 2602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdRect); + (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); } -#line 6270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 281: -#line 1964 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 379: +#line 2607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); + (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); } -#line 6280 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 282: -#line 1969 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 380: +#line 2612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdRect); + (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); } -#line 6290 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8177 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 283: -#line 1974 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 381: +#line 2617 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, EsdRect); + (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, false, true); +#endif } -#line 6300 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 284: -#line 1979 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 382: +#line 2625 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); + (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); } -#line 6310 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 285: -#line 1984 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 383: +#line 2630 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); + (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); } -#line 6320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 286: -#line 1989 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 384: +#line 2635 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); + (yyval.interm.type).sampler.setPureSampler(false); } -#line 6330 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8220 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 287: -#line 1994 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 385: +#line 2640 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); + (yyval.interm.type).sampler.setPureSampler(true); } -#line 6340 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8230 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 288: -#line 1999 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 386: +#line 2645 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); } -#line 6350 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8240 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 289: -#line 2004 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 387: +#line 2650 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D); +#endif } -#line 6360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 290: -#line 2009 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 388: +#line 2658 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); } -#line 6370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 291: -#line 2014 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 389: +#line 2663 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D); +#endif } -#line 6380 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 292: -#line 2019 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 390: +#line 2671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); } -#line 6390 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8286 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 293: -#line 2024 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 391: +#line 2676 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setPureSampler(false); + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd3D); +#endif } -#line 6400 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8299 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 294: -#line 2029 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 392: +#line 2684 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setPureSampler(true); + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); } -#line 6410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8309 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 295: -#line 2034 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 393: +#line 2689 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); + (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube); +#endif } -#line 6420 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 296: -#line 2039 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 394: +#line 2697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); } -#line 6430 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8332 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 297: -#line 2044 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 395: +#line 2702 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D, true); +#endif } -#line 6440 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8345 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 298: -#line 2049 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 396: +#line 2710 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); + (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); } -#line 6450 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8355 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 299: -#line 2054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 397: +#line 2715 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true); +#endif } -#line 6460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8368 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 300: -#line 2059 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 398: +#line 2723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); + (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); } -#line 6470 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8378 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 301: -#line 2064 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 399: +#line 2728 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); + (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube, true); +#endif } -#line 6480 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 302: -#line 2069 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 400: +#line 2736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); } -#line 6490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 303: -#line 2074 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 401: +#line 2741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); } -#line 6500 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8411 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 304: -#line 2079 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 402: +#line 2746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); } -#line 6510 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 305: -#line 2084 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 403: +#line 2751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); } -#line 6520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8431 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 306: -#line 2089 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 404: +#line 2756 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); } -#line 6530 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 307: -#line 2094 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 405: +#line 2761 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); } -#line 6540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 308: -#line 2099 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 406: +#line 2766 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube, true); } -#line 6550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8461 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 309: -#line 2104 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 407: +#line 2771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); } -#line 6560 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 310: -#line 2109 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 408: +#line 2776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); } -#line 6570 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8481 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 311: -#line 2114 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 409: +#line 2781 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); } -#line 6580 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8491 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 312: -#line 2119 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 410: +#line 2786 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); } -#line 6590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8501 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 313: -#line 2124 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 411: +#line 2791 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); } -#line 6600 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 314: -#line 2129 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 412: +#line 2796 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); } -#line 6610 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8521 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 315: -#line 2134 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 413: +#line 2801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube, true); } -#line 6620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8531 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 316: -#line 2139 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 414: +#line 2806 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdRect); } -#line 6630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8541 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 317: -#line 2144 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 415: +#line 2811 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdRect); +#endif + } +#line 8554 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 416: +#line 2819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdRect); } -#line 6640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8564 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 318: -#line 2149 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 417: +#line 2824 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdRect); } -#line 6650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8574 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 319: -#line 2154 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 418: +#line 2829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdBuffer); } -#line 6660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8584 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 320: -#line 2159 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 419: +#line 2834 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdBuffer); +#endif + } +#line 8597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 420: +#line 2842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdBuffer); } -#line 6670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8607 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 321: -#line 2164 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 421: +#line 2847 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdBuffer); } -#line 6680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8617 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 322: -#line 2169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 422: +#line 2852 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, false, false, true); } -#line 6690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8627 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 323: -#line 2174 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 423: +#line 2857 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, false, false, true); +#endif + } +#line 8640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 424: +#line 2865 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, false, false, true); } -#line 6700 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 324: -#line 2179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 425: +#line 2870 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, false, false, true); } -#line 6710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 325: -#line 2184 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 426: +#line 2875 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true, false, true); } -#line 6720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8670 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 326: -#line 2189 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 427: +#line 2880 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true, false, true); +#endif + } +#line 8683 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 428: +#line 2888 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true, false, true); } -#line 6730 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 327: -#line 2194 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 429: +#line 2893 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true, false, true); } -#line 6740 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 328: -#line 2199 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 430: +#line 2898 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D); } -#line 6750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8713 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 329: -#line 2204 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 431: +#line 2903 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D); +#endif + } +#line 8726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 432: +#line 2911 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D); } -#line 6760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8736 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 330: -#line 2209 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 433: +#line 2916 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D); } -#line 6770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8746 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 331: -#line 2214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 434: +#line 2921 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D); } -#line 6780 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 332: -#line 2219 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 435: +#line 2926 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D); +#endif + } +#line 8769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 436: +#line 2934 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D); } -#line 6790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 333: -#line 2224 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 437: +#line 2939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D); } -#line 6800 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8789 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 334: -#line 2229 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 438: +#line 2944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd3D); } -#line 6810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8799 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 335: -#line 2234 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 439: +#line 2949 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd3D); +#endif + } +#line 8812 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 440: +#line 2957 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd3D); } -#line 6820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8822 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 336: -#line 2239 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 441: +#line 2962 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd3D); } -#line 6830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8832 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 337: -#line 2244 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 442: +#line 2967 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdRect); } -#line 6840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 338: -#line 2249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 443: +#line 2972 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, EsdRect); +#endif + } +#line 8855 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 444: +#line 2980 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdRect); } -#line 6850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8865 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 339: -#line 2254 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 445: +#line 2985 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdRect); } -#line 6860 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 340: -#line 2259 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 446: +#line 2990 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube); } -#line 6870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 341: -#line 2264 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 447: +#line 2995 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube); +#endif + } +#line 8898 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 448: +#line 3003 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube); } -#line 6880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8908 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 342: -#line 2269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 449: +#line 3008 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube); } -#line 6890 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 450: +#line 3013 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); + } +#line 8928 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 343: -#line 2274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 451: +#line 3018 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; - (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); + (yyval.interm.type).sampler.setImage(EbtFloat16, EsdBuffer); +#endif } -#line 6900 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 344: -#line 2279 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 452: +#line 3026 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdBuffer); } -#line 6910 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8951 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 345: -#line 2284 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 453: +#line 3031 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdBuffer); } -#line 6920 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8961 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 346: -#line 2289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 454: +#line 3036 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D, true); } -#line 6930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8971 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 347: -#line 2294 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 455: +#line 3041 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D, true); +#endif + } +#line 8984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 456: +#line 3049 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D, true); } -#line 6940 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8994 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 348: -#line 2299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 457: +#line 3054 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D, true); } -#line 6950 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 349: -#line 2304 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 458: +#line 3059 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true); } -#line 6960 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9014 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 350: -#line 2309 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 459: +#line 3064 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true); +#endif + } +#line 9027 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 460: +#line 3072 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true); } -#line 6970 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9037 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 351: -#line 2314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 461: +#line 3077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true); } -#line 6980 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9047 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 352: -#line 2319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 462: +#line 3082 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube, true); } -#line 6990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9057 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 353: -#line 2324 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 463: +#line 3087 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube, true); +#endif + } +#line 9070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 464: +#line 3095 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube, true); } -#line 7000 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 354: -#line 2329 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 465: +#line 3100 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube, true); } -#line 7010 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 355: -#line 2334 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 466: +#line 3105 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, false, false, true); } -#line 7020 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 356: -#line 2339 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 467: +#line 3110 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, false, false, true); +#endif + } +#line 9113 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 468: +#line 3118 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, false, false, true); } -#line 7030 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 357: -#line 2344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 469: +#line 3123 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, false, false, true); } -#line 7040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 358: -#line 2349 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 470: +#line 3128 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true, false, true); } -#line 7050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9143 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 359: -#line 2354 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 471: +#line 3133 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true, false, true); +#endif + } +#line 9156 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 472: +#line 3141 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true, false, true); } -#line 7060 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 360: -#line 2359 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 473: +#line 3146 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true, false, true); } -#line 7070 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9176 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 361: -#line 2364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 474: +#line 3151 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // GL_OES_EGL_image_external (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.external = true; } -#line 7081 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9187 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 362: -#line 2370 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 475: +#line 3157 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { // GL_EXT_YUV_target + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.set(EbtFloat, Esd2D); + (yyval.interm.type).sampler.yuv = true; + } +#line 9198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 476: +#line 3163 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat); } -#line 7092 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 363: -#line 2376 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 477: +#line 3169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat, true); } -#line 7103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9220 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 364: -#line 2382 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 478: +#line 3175 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtFloat16); +#endif + } +#line 9234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 479: +#line 3184 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { +#ifdef AMD_EXTENSIONS + parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setSubpass(EbtFloat16, true); +#endif + } +#line 9248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 480: +#line 3193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt); } -#line 7114 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 365: -#line 2388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 481: +#line 3199 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt, true); } -#line 7125 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 366: -#line 2394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 482: +#line 3205 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint); } -#line 7136 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 367: -#line 2400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 483: +#line 3211 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint, true); } -#line 7147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9292 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 368: -#line 2406 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 484: +#line 3217 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.fcoopmatCheck((yyvsp[0].lex).loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtFloat; + (yyval.interm.type).coopmat = true; + } +#line 9303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 485: +#line 3223 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); (yyval.interm.type).qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; parseContext.structTypeCheck((yyval.interm.type).loc, (yyval.interm.type)); } -#line 7157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 369: -#line 2411 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 486: +#line 3228 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // This is for user defined type names. The lexical phase looked up the @@ -7171,47 +9327,47 @@ } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 7175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9331 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 370: -#line 2427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 487: +#line 3244 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "highp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqHigh); } -#line 7185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9341 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 371: -#line 2432 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 488: +#line 3249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "mediump precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqMedium); } -#line 7195 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9351 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 372: -#line 2437 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 489: +#line 3254 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "lowp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqLow); } -#line 7205 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9361 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 373: -#line 2445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 490: +#line 3262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 7211 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9367 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 374: -#line 2445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 491: +#line 3262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TType* structure = new TType((yyvsp[-1].interm.typeList), *(yyvsp[-4].lex).string); parseContext.structArrayCheck((yyvsp[-4].lex).loc, *structure); @@ -7223,17 +9379,17 @@ (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 7227 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9383 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 375: -#line 2456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 492: +#line 3273 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 7233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9389 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 376: -#line 2456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 493: +#line 3273 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); (yyval.interm.type).init((yyvsp[-4].lex).loc); @@ -7241,19 +9397,19 @@ (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 7245 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 377: -#line 2466 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 494: +#line 3283 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 7253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9409 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 378: -#line 2469 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 495: +#line 3286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); for (unsigned int i = 0; i < (yyvsp[0].interm.typeList)->size(); ++i) { @@ -7264,11 +9420,11 @@ (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 7268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 379: -#line 2482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 496: +#line 3299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -7283,17 +9439,20 @@ parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier); for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) { - parseContext.arrayDimCheck((yyvsp[-2].interm.type).loc, (*(yyval.interm.typeList))[i].type, (yyvsp[-2].interm.type).arraySizes); - (*(yyval.interm.typeList))[i].type->mergeType((yyvsp[-2].interm.type)); + TType type((yyvsp[-2].interm.type)); + type.setFieldName((*(yyval.interm.typeList))[i].type->getFieldName()); + type.transferArraySizes((*(yyval.interm.typeList))[i].type->getArraySizes()); + type.copyArrayInnerSizes((yyvsp[-2].interm.type).arraySizes); + parseContext.arrayOfArrayVersionCheck((*(yyval.interm.typeList))[i].loc, type.getArraySizes()); + (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 7291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 380: -#line 2500 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 497: +#line 3321 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalQualifierFixCheck((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier); if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[-2].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); @@ -7303,269 +9462,273 @@ (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); - parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); + parseContext.memberQualifierCheck((yyvsp[-3].interm.type)); parseContext.voidErrorCheck((yyvsp[-2].interm.type).loc, (*(yyvsp[-1].interm.typeList))[0].type->getFieldName(), (yyvsp[-2].interm.type).basicType); parseContext.mergeQualifiers((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, (yyvsp[-3].interm.type).qualifier, true); parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier); for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) { - parseContext.arrayDimCheck((yyvsp[-3].interm.type).loc, (*(yyval.interm.typeList))[i].type, (yyvsp[-2].interm.type).arraySizes); - (*(yyval.interm.typeList))[i].type->mergeType((yyvsp[-2].interm.type)); + TType type((yyvsp[-2].interm.type)); + type.setFieldName((*(yyval.interm.typeList))[i].type->getFieldName()); + type.transferArraySizes((*(yyval.interm.typeList))[i].type->getArraySizes()); + type.copyArrayInnerSizes((yyvsp[-2].interm.type).arraySizes); + parseContext.arrayOfArrayVersionCheck((*(yyval.interm.typeList))[i].loc, type.getArraySizes()); + (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 7317 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9480 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 381: -#line 2524 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 498: +#line 3348 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 7326 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9489 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 382: -#line 2528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 499: +#line 3352 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 7334 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 383: -#line 2534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 500: +#line 3358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeLine).type = new TType(EbtVoid); (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc; (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string); } -#line 7344 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 384: -#line 2539 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 501: +#line 3363 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.arrayDimCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes, 0); + parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); (yyval.interm.typeLine).type = new TType(EbtVoid); (yyval.interm.typeLine).loc = (yyvsp[-1].lex).loc; (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); - (yyval.interm.typeLine).type->newArraySizes(*(yyvsp[0].interm).arraySizes); + (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 7357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 385: -#line 2550 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 502: +#line 3374 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 7365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9528 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 386: -#line 2553 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 503: +#line 3377 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); } -#line 7376 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9539 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 387: -#line 2559 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 504: +#line 3383 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 7387 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 388: -#line 2568 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 505: +#line 3392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); } -#line 7395 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9558 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 389: -#line 2571 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 506: +#line 3395 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); } -#line 7403 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 390: -#line 2577 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 507: +#line 3401 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7409 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 391: -#line 2581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 508: +#line 3405 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7415 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 392: -#line 2582 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 509: +#line 3406 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9584 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 393: -#line 2588 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 510: +#line 3412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 394: -#line 2589 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 511: +#line 3413 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7433 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 395: -#line 2590 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 512: +#line 3414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9602 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 396: -#line 2591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 513: +#line 3415 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7445 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 397: -#line 2592 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 514: +#line 3416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7451 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9614 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 398: -#line 2593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 515: +#line 3417 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 399: -#line 2594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 516: +#line 3418 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 400: -#line 2598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 517: +#line 3422 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 7469 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 401: -#line 2599 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 518: +#line 3423 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 7478 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9641 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 402: -#line 2603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 519: +#line 3427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 7487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 403: -#line 2607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 520: +#line 3431 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate()) (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode); } -#line 7497 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 404: -#line 2615 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 521: +#line 3439 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7503 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9666 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 405: -#line 2616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 522: +#line 3440 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7509 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9672 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 406: -#line 2620 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 523: +#line 3444 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.controlFlowNestingLevel; } -#line 7517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 407: -#line 2623 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 524: +#line 3447 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 408: -#line 2627 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 525: +#line 3451 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 7536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9699 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 409: -#line 2632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 526: +#line 3456 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 410: -#line 2641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 527: +#line 3465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 7555 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9718 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 411: -#line 2644 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 528: +#line 3468 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate()) (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode); } -#line 7565 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 412: -#line 2652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 529: +#line 3476 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || @@ -7574,11 +9737,11 @@ (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 7578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 413: -#line 2660 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 530: +#line 3484 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { @@ -7587,59 +9750,76 @@ } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 7591 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 414: -#line 2671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 531: +#line 3495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 7597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 415: -#line 2672 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 532: +#line 3496 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 7603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9766 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 416: -#line 2676 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 533: +#line 3500 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 9774 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 534: +#line 3503 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 9783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 535: +#line 3509 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc); } -#line 7612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 417: -#line 2683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 536: +#line 3516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); } -#line 7621 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9801 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 418: -#line 2687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 537: +#line 3520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 7630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 419: -#line 2695 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 538: +#line 3528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)); } -#line 7639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9819 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 420: -#line 2699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 539: +#line 3532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); @@ -7650,11 +9830,28 @@ else (yyval.interm.intermTypedNode) = 0; } -#line 7654 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9834 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 421: -#line 2712 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 540: +#line 3545 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 9842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 541: +#line 3548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 9851 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 542: +#line 3554 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; @@ -7663,11 +9860,11 @@ parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 7667 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 422: -#line 2720 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 543: +#line 3562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0); delete parseContext.switchSequenceStack.back(); @@ -7677,27 +9874,27 @@ --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 7681 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9878 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 423: -#line 2732 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 544: +#line 3574 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 7689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9886 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 424: -#line 2735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 545: +#line 3577 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7697 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9894 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 425: -#line 2741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 546: +#line 3583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -7710,11 +9907,11 @@ (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 7714 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 426: -#line 2753 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 547: +#line 3595 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -7724,11 +9921,28 @@ else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 7728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 427: -#line 2765 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 548: +#line 3607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 9933 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 549: +#line 3610 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); + (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); + } +#line 9942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 550: +#line 3616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); @@ -7737,11 +9951,11 @@ ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 7741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9955 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 428: -#line 2773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 551: +#line 3624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc); @@ -7749,21 +9963,21 @@ --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 7753 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9967 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 429: -#line 2780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 552: +#line 3631 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 7763 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9977 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 430: -#line 2785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 553: +#line 3636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -7775,22 +9989,22 @@ --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 7779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9993 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 431: -#line 2796 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 554: +#line 3647 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 7790 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 432: -#line 2802 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 555: +#line 3653 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc); @@ -7803,81 +10017,81 @@ --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 7807 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10021 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 433: -#line 2817 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 556: +#line 3668 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7815 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10029 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 434: -#line 2820 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 557: +#line 3671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10037 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 435: -#line 2826 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 558: +#line 3677 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 7831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10045 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 436: -#line 2829 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 559: +#line 3680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = 0; } -#line 7839 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 437: -#line 2835 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 560: +#line 3686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 7848 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 438: -#line 2839 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 561: +#line 3690 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); } -#line 7857 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10071 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 439: -#line 2846 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 562: +#line 3697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (parseContext.loopNestingLevel <= 0) parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc); } -#line 7867 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10081 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 440: -#line 2851 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 563: +#line 3702 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc); } -#line 7877 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10091 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 441: -#line 2856 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 564: +#line 3707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) @@ -7885,83 +10099,83 @@ if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 7889 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 442: -#line 2863 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 565: +#line 3714 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 7897 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 443: -#line 2866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 566: +#line 3717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc); } -#line 7906 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10120 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 444: -#line 2875 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 567: +#line 3726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 7915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 445: -#line 2879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 568: +#line 3730 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[0].interm.intermNode) != nullptr) { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } } -#line 7926 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10140 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 446: -#line 2888 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 569: +#line 3739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7934 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10148 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 447: -#line 2891 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 570: +#line 3742 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 7942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10156 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 448: -#line 2894 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 571: +#line 3745 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon"); parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); (yyval.interm.intermNode) = nullptr; } -#line 7952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 449: -#line 2902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 572: +#line 3753 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */); (yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function); } -#line 7961 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 450: -#line 2906 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 573: +#line 3757 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) @@ -7977,11 +10191,52 @@ (yyval.interm.intermNode)->getAsAggregate()->setDebug(parseContext.contextPragma.debug); (yyval.interm.intermNode)->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); } -#line 7981 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10195 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; + case 574: +#line 3775 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.attributes) = (yyvsp[-2].interm.attributes); + parseContext.requireExtensions((yyvsp[-4].lex).loc, 1, &E_GL_EXT_control_flow_attributes, "attribute"); + } +#line 10204 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; -#line 7985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + case 575: +#line 3781 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.attributes) = (yyvsp[0].interm.attributes); + } +#line 10212 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 576: +#line 3784 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); + } +#line 10220 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 577: +#line 3789 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); + } +#line 10228 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 578: +#line 3792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); + } +#line 10236 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + +#line 10240 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -8209,5 +10464,5 @@ #endif return yyresult; } -#line 2923 "MachineIndependent/glslang.y" /* yacc.c:1906 */ +#line 3796 "MachineIndependent/glslang.y" /* yacc.c:1906 */ diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -47,308 +47,418 @@ { ATTRIBUTE = 258, VARYING = 259, - CONST = 260, - BOOL = 261, - FLOAT = 262, + FLOAT16_T = 260, + FLOAT = 261, + FLOAT32_T = 262, DOUBLE = 263, - INT = 264, - UINT = 265, - INT64_T = 266, - UINT64_T = 267, - INT16_T = 268, - UINT16_T = 269, - FLOAT16_T = 270, - BREAK = 271, - CONTINUE = 272, - DO = 273, - ELSE = 274, - FOR = 275, - IF = 276, - DISCARD = 277, - RETURN = 278, - SWITCH = 279, - CASE = 280, - DEFAULT = 281, - SUBROUTINE = 282, - BVEC2 = 283, - BVEC3 = 284, - BVEC4 = 285, - IVEC2 = 286, - IVEC3 = 287, - IVEC4 = 288, - I64VEC2 = 289, - I64VEC3 = 290, - I64VEC4 = 291, - UVEC2 = 292, - UVEC3 = 293, - UVEC4 = 294, - U64VEC2 = 295, - U64VEC3 = 296, - U64VEC4 = 297, - VEC2 = 298, - VEC3 = 299, - VEC4 = 300, - MAT2 = 301, - MAT3 = 302, - MAT4 = 303, - CENTROID = 304, - IN = 305, - OUT = 306, - INOUT = 307, - UNIFORM = 308, - PATCH = 309, - SAMPLE = 310, - BUFFER = 311, - SHARED = 312, - COHERENT = 313, - VOLATILE = 314, - RESTRICT = 315, - READONLY = 316, - WRITEONLY = 317, - DVEC2 = 318, - DVEC3 = 319, - DVEC4 = 320, - DMAT2 = 321, - DMAT3 = 322, - DMAT4 = 323, - F16VEC2 = 324, - F16VEC3 = 325, - F16VEC4 = 326, - F16MAT2 = 327, - F16MAT3 = 328, - F16MAT4 = 329, - I16VEC2 = 330, - I16VEC3 = 331, - I16VEC4 = 332, - U16VEC2 = 333, - U16VEC3 = 334, - U16VEC4 = 335, - NOPERSPECTIVE = 336, - FLAT = 337, - SMOOTH = 338, - LAYOUT = 339, - __EXPLICITINTERPAMD = 340, - MAT2X2 = 341, - MAT2X3 = 342, - MAT2X4 = 343, - MAT3X2 = 344, - MAT3X3 = 345, - MAT3X4 = 346, - MAT4X2 = 347, - MAT4X3 = 348, - MAT4X4 = 349, - DMAT2X2 = 350, - DMAT2X3 = 351, - DMAT2X4 = 352, - DMAT3X2 = 353, - DMAT3X3 = 354, - DMAT3X4 = 355, - DMAT4X2 = 356, - DMAT4X3 = 357, - DMAT4X4 = 358, - F16MAT2X2 = 359, - F16MAT2X3 = 360, - F16MAT2X4 = 361, - F16MAT3X2 = 362, - F16MAT3X3 = 363, - F16MAT3X4 = 364, - F16MAT4X2 = 365, - F16MAT4X3 = 366, - F16MAT4X4 = 367, - ATOMIC_UINT = 368, - SAMPLER1D = 369, - SAMPLER2D = 370, - SAMPLER3D = 371, - SAMPLERCUBE = 372, - SAMPLER1DSHADOW = 373, - SAMPLER2DSHADOW = 374, - SAMPLERCUBESHADOW = 375, - SAMPLER1DARRAY = 376, - SAMPLER2DARRAY = 377, - SAMPLER1DARRAYSHADOW = 378, - SAMPLER2DARRAYSHADOW = 379, - ISAMPLER1D = 380, - ISAMPLER2D = 381, - ISAMPLER3D = 382, - ISAMPLERCUBE = 383, - ISAMPLER1DARRAY = 384, - ISAMPLER2DARRAY = 385, - USAMPLER1D = 386, - USAMPLER2D = 387, - USAMPLER3D = 388, - USAMPLERCUBE = 389, - USAMPLER1DARRAY = 390, - USAMPLER2DARRAY = 391, - SAMPLER2DRECT = 392, - SAMPLER2DRECTSHADOW = 393, - ISAMPLER2DRECT = 394, - USAMPLER2DRECT = 395, - SAMPLERBUFFER = 396, - ISAMPLERBUFFER = 397, - USAMPLERBUFFER = 398, - SAMPLERCUBEARRAY = 399, - SAMPLERCUBEARRAYSHADOW = 400, - ISAMPLERCUBEARRAY = 401, - USAMPLERCUBEARRAY = 402, - SAMPLER2DMS = 403, - ISAMPLER2DMS = 404, - USAMPLER2DMS = 405, - SAMPLER2DMSARRAY = 406, - ISAMPLER2DMSARRAY = 407, - USAMPLER2DMSARRAY = 408, - SAMPLEREXTERNALOES = 409, - SAMPLER = 410, - SAMPLERSHADOW = 411, - TEXTURE1D = 412, - TEXTURE2D = 413, - TEXTURE3D = 414, - TEXTURECUBE = 415, - TEXTURE1DARRAY = 416, - TEXTURE2DARRAY = 417, - ITEXTURE1D = 418, - ITEXTURE2D = 419, - ITEXTURE3D = 420, - ITEXTURECUBE = 421, - ITEXTURE1DARRAY = 422, - ITEXTURE2DARRAY = 423, - UTEXTURE1D = 424, - UTEXTURE2D = 425, - UTEXTURE3D = 426, - UTEXTURECUBE = 427, - UTEXTURE1DARRAY = 428, - UTEXTURE2DARRAY = 429, - TEXTURE2DRECT = 430, - ITEXTURE2DRECT = 431, - UTEXTURE2DRECT = 432, - TEXTUREBUFFER = 433, - ITEXTUREBUFFER = 434, - UTEXTUREBUFFER = 435, - TEXTURECUBEARRAY = 436, - ITEXTURECUBEARRAY = 437, - UTEXTURECUBEARRAY = 438, - TEXTURE2DMS = 439, - ITEXTURE2DMS = 440, - UTEXTURE2DMS = 441, - TEXTURE2DMSARRAY = 442, - ITEXTURE2DMSARRAY = 443, - UTEXTURE2DMSARRAY = 444, - SUBPASSINPUT = 445, - SUBPASSINPUTMS = 446, - ISUBPASSINPUT = 447, - ISUBPASSINPUTMS = 448, - USUBPASSINPUT = 449, - USUBPASSINPUTMS = 450, - IMAGE1D = 451, - IIMAGE1D = 452, - UIMAGE1D = 453, - IMAGE2D = 454, - IIMAGE2D = 455, - UIMAGE2D = 456, - IMAGE3D = 457, - IIMAGE3D = 458, - UIMAGE3D = 459, - IMAGE2DRECT = 460, - IIMAGE2DRECT = 461, - UIMAGE2DRECT = 462, - IMAGECUBE = 463, - IIMAGECUBE = 464, - UIMAGECUBE = 465, - IMAGEBUFFER = 466, - IIMAGEBUFFER = 467, - UIMAGEBUFFER = 468, - IMAGE1DARRAY = 469, - IIMAGE1DARRAY = 470, - UIMAGE1DARRAY = 471, - IMAGE2DARRAY = 472, - IIMAGE2DARRAY = 473, - UIMAGE2DARRAY = 474, - IMAGECUBEARRAY = 475, - IIMAGECUBEARRAY = 476, - UIMAGECUBEARRAY = 477, - IMAGE2DMS = 478, - IIMAGE2DMS = 479, - UIMAGE2DMS = 480, - IMAGE2DMSARRAY = 481, - IIMAGE2DMSARRAY = 482, - UIMAGE2DMSARRAY = 483, - STRUCT = 484, - VOID = 485, - WHILE = 486, - IDENTIFIER = 487, - TYPE_NAME = 488, - FLOATCONSTANT = 489, - DOUBLECONSTANT = 490, - INTCONSTANT = 491, - UINTCONSTANT = 492, - INT64CONSTANT = 493, - UINT64CONSTANT = 494, - INT16CONSTANT = 495, - UINT16CONSTANT = 496, - BOOLCONSTANT = 497, - FLOAT16CONSTANT = 498, - LEFT_OP = 499, - RIGHT_OP = 500, - INC_OP = 501, - DEC_OP = 502, - LE_OP = 503, - GE_OP = 504, - EQ_OP = 505, - NE_OP = 506, - AND_OP = 507, - OR_OP = 508, - XOR_OP = 509, - MUL_ASSIGN = 510, - DIV_ASSIGN = 511, - ADD_ASSIGN = 512, - MOD_ASSIGN = 513, - LEFT_ASSIGN = 514, - RIGHT_ASSIGN = 515, - AND_ASSIGN = 516, - XOR_ASSIGN = 517, - OR_ASSIGN = 518, - SUB_ASSIGN = 519, - LEFT_PAREN = 520, - RIGHT_PAREN = 521, - LEFT_BRACKET = 522, - RIGHT_BRACKET = 523, - LEFT_BRACE = 524, - RIGHT_BRACE = 525, - DOT = 526, - COMMA = 527, - COLON = 528, - EQUAL = 529, - SEMICOLON = 530, - BANG = 531, - DASH = 532, - TILDE = 533, - PLUS = 534, - STAR = 535, - SLASH = 536, - PERCENT = 537, - LEFT_ANGLE = 538, - RIGHT_ANGLE = 539, - VERTICAL_BAR = 540, - CARET = 541, - AMPERSAND = 542, - QUESTION = 543, - INVARIANT = 544, - PRECISE = 545, - HIGH_PRECISION = 546, - MEDIUM_PRECISION = 547, - LOW_PRECISION = 548, - PRECISION = 549, - PACKED = 550, - RESOURCE = 551, - SUPERP = 552 + FLOAT64_T = 264, + CONST = 265, + BOOL = 266, + INT = 267, + UINT = 268, + INT64_T = 269, + UINT64_T = 270, + INT32_T = 271, + UINT32_T = 272, + INT16_T = 273, + UINT16_T = 274, + INT8_T = 275, + UINT8_T = 276, + BREAK = 277, + CONTINUE = 278, + DO = 279, + ELSE = 280, + FOR = 281, + IF = 282, + DISCARD = 283, + RETURN = 284, + SWITCH = 285, + CASE = 286, + DEFAULT = 287, + SUBROUTINE = 288, + BVEC2 = 289, + BVEC3 = 290, + BVEC4 = 291, + IVEC2 = 292, + IVEC3 = 293, + IVEC4 = 294, + UVEC2 = 295, + UVEC3 = 296, + UVEC4 = 297, + I64VEC2 = 298, + I64VEC3 = 299, + I64VEC4 = 300, + U64VEC2 = 301, + U64VEC3 = 302, + U64VEC4 = 303, + I32VEC2 = 304, + I32VEC3 = 305, + I32VEC4 = 306, + U32VEC2 = 307, + U32VEC3 = 308, + U32VEC4 = 309, + I16VEC2 = 310, + I16VEC3 = 311, + I16VEC4 = 312, + U16VEC2 = 313, + U16VEC3 = 314, + U16VEC4 = 315, + I8VEC2 = 316, + I8VEC3 = 317, + I8VEC4 = 318, + U8VEC2 = 319, + U8VEC3 = 320, + U8VEC4 = 321, + VEC2 = 322, + VEC3 = 323, + VEC4 = 324, + MAT2 = 325, + MAT3 = 326, + MAT4 = 327, + CENTROID = 328, + IN = 329, + OUT = 330, + INOUT = 331, + UNIFORM = 332, + PATCH = 333, + SAMPLE = 334, + BUFFER = 335, + SHARED = 336, + NONUNIFORM = 337, + PAYLOADNV = 338, + PAYLOADINNV = 339, + HITATTRNV = 340, + CALLDATANV = 341, + CALLDATAINNV = 342, + COHERENT = 343, + VOLATILE = 344, + RESTRICT = 345, + READONLY = 346, + WRITEONLY = 347, + DEVICECOHERENT = 348, + QUEUEFAMILYCOHERENT = 349, + WORKGROUPCOHERENT = 350, + SUBGROUPCOHERENT = 351, + NONPRIVATE = 352, + DVEC2 = 353, + DVEC3 = 354, + DVEC4 = 355, + DMAT2 = 356, + DMAT3 = 357, + DMAT4 = 358, + F16VEC2 = 359, + F16VEC3 = 360, + F16VEC4 = 361, + F16MAT2 = 362, + F16MAT3 = 363, + F16MAT4 = 364, + F32VEC2 = 365, + F32VEC3 = 366, + F32VEC4 = 367, + F32MAT2 = 368, + F32MAT3 = 369, + F32MAT4 = 370, + F64VEC2 = 371, + F64VEC3 = 372, + F64VEC4 = 373, + F64MAT2 = 374, + F64MAT3 = 375, + F64MAT4 = 376, + NOPERSPECTIVE = 377, + FLAT = 378, + SMOOTH = 379, + LAYOUT = 380, + EXPLICITINTERPAMD = 381, + PERVERTEXNV = 382, + PERPRIMITIVENV = 383, + PERVIEWNV = 384, + PERTASKNV = 385, + MAT2X2 = 386, + MAT2X3 = 387, + MAT2X4 = 388, + MAT3X2 = 389, + MAT3X3 = 390, + MAT3X4 = 391, + MAT4X2 = 392, + MAT4X3 = 393, + MAT4X4 = 394, + DMAT2X2 = 395, + DMAT2X3 = 396, + DMAT2X4 = 397, + DMAT3X2 = 398, + DMAT3X3 = 399, + DMAT3X4 = 400, + DMAT4X2 = 401, + DMAT4X3 = 402, + DMAT4X4 = 403, + F16MAT2X2 = 404, + F16MAT2X3 = 405, + F16MAT2X4 = 406, + F16MAT3X2 = 407, + F16MAT3X3 = 408, + F16MAT3X4 = 409, + F16MAT4X2 = 410, + F16MAT4X3 = 411, + F16MAT4X4 = 412, + F32MAT2X2 = 413, + F32MAT2X3 = 414, + F32MAT2X4 = 415, + F32MAT3X2 = 416, + F32MAT3X3 = 417, + F32MAT3X4 = 418, + F32MAT4X2 = 419, + F32MAT4X3 = 420, + F32MAT4X4 = 421, + F64MAT2X2 = 422, + F64MAT2X3 = 423, + F64MAT2X4 = 424, + F64MAT3X2 = 425, + F64MAT3X3 = 426, + F64MAT3X4 = 427, + F64MAT4X2 = 428, + F64MAT4X3 = 429, + F64MAT4X4 = 430, + ATOMIC_UINT = 431, + ACCSTRUCTNV = 432, + FCOOPMATNV = 433, + SAMPLER1D = 434, + SAMPLER2D = 435, + SAMPLER3D = 436, + SAMPLERCUBE = 437, + SAMPLER1DSHADOW = 438, + SAMPLER2DSHADOW = 439, + SAMPLERCUBESHADOW = 440, + SAMPLER1DARRAY = 441, + SAMPLER2DARRAY = 442, + SAMPLER1DARRAYSHADOW = 443, + SAMPLER2DARRAYSHADOW = 444, + ISAMPLER1D = 445, + ISAMPLER2D = 446, + ISAMPLER3D = 447, + ISAMPLERCUBE = 448, + ISAMPLER1DARRAY = 449, + ISAMPLER2DARRAY = 450, + USAMPLER1D = 451, + USAMPLER2D = 452, + USAMPLER3D = 453, + USAMPLERCUBE = 454, + USAMPLER1DARRAY = 455, + USAMPLER2DARRAY = 456, + SAMPLER2DRECT = 457, + SAMPLER2DRECTSHADOW = 458, + ISAMPLER2DRECT = 459, + USAMPLER2DRECT = 460, + SAMPLERBUFFER = 461, + ISAMPLERBUFFER = 462, + USAMPLERBUFFER = 463, + SAMPLERCUBEARRAY = 464, + SAMPLERCUBEARRAYSHADOW = 465, + ISAMPLERCUBEARRAY = 466, + USAMPLERCUBEARRAY = 467, + SAMPLER2DMS = 468, + ISAMPLER2DMS = 469, + USAMPLER2DMS = 470, + SAMPLER2DMSARRAY = 471, + ISAMPLER2DMSARRAY = 472, + USAMPLER2DMSARRAY = 473, + SAMPLEREXTERNALOES = 474, + SAMPLEREXTERNAL2DY2YEXT = 475, + F16SAMPLER1D = 476, + F16SAMPLER2D = 477, + F16SAMPLER3D = 478, + F16SAMPLER2DRECT = 479, + F16SAMPLERCUBE = 480, + F16SAMPLER1DARRAY = 481, + F16SAMPLER2DARRAY = 482, + F16SAMPLERCUBEARRAY = 483, + F16SAMPLERBUFFER = 484, + F16SAMPLER2DMS = 485, + F16SAMPLER2DMSARRAY = 486, + F16SAMPLER1DSHADOW = 487, + F16SAMPLER2DSHADOW = 488, + F16SAMPLER1DARRAYSHADOW = 489, + F16SAMPLER2DARRAYSHADOW = 490, + F16SAMPLER2DRECTSHADOW = 491, + F16SAMPLERCUBESHADOW = 492, + F16SAMPLERCUBEARRAYSHADOW = 493, + SAMPLER = 494, + SAMPLERSHADOW = 495, + TEXTURE1D = 496, + TEXTURE2D = 497, + TEXTURE3D = 498, + TEXTURECUBE = 499, + TEXTURE1DARRAY = 500, + TEXTURE2DARRAY = 501, + ITEXTURE1D = 502, + ITEXTURE2D = 503, + ITEXTURE3D = 504, + ITEXTURECUBE = 505, + ITEXTURE1DARRAY = 506, + ITEXTURE2DARRAY = 507, + UTEXTURE1D = 508, + UTEXTURE2D = 509, + UTEXTURE3D = 510, + UTEXTURECUBE = 511, + UTEXTURE1DARRAY = 512, + UTEXTURE2DARRAY = 513, + TEXTURE2DRECT = 514, + ITEXTURE2DRECT = 515, + UTEXTURE2DRECT = 516, + TEXTUREBUFFER = 517, + ITEXTUREBUFFER = 518, + UTEXTUREBUFFER = 519, + TEXTURECUBEARRAY = 520, + ITEXTURECUBEARRAY = 521, + UTEXTURECUBEARRAY = 522, + TEXTURE2DMS = 523, + ITEXTURE2DMS = 524, + UTEXTURE2DMS = 525, + TEXTURE2DMSARRAY = 526, + ITEXTURE2DMSARRAY = 527, + UTEXTURE2DMSARRAY = 528, + F16TEXTURE1D = 529, + F16TEXTURE2D = 530, + F16TEXTURE3D = 531, + F16TEXTURE2DRECT = 532, + F16TEXTURECUBE = 533, + F16TEXTURE1DARRAY = 534, + F16TEXTURE2DARRAY = 535, + F16TEXTURECUBEARRAY = 536, + F16TEXTUREBUFFER = 537, + F16TEXTURE2DMS = 538, + F16TEXTURE2DMSARRAY = 539, + SUBPASSINPUT = 540, + SUBPASSINPUTMS = 541, + ISUBPASSINPUT = 542, + ISUBPASSINPUTMS = 543, + USUBPASSINPUT = 544, + USUBPASSINPUTMS = 545, + F16SUBPASSINPUT = 546, + F16SUBPASSINPUTMS = 547, + IMAGE1D = 548, + IIMAGE1D = 549, + UIMAGE1D = 550, + IMAGE2D = 551, + IIMAGE2D = 552, + UIMAGE2D = 553, + IMAGE3D = 554, + IIMAGE3D = 555, + UIMAGE3D = 556, + IMAGE2DRECT = 557, + IIMAGE2DRECT = 558, + UIMAGE2DRECT = 559, + IMAGECUBE = 560, + IIMAGECUBE = 561, + UIMAGECUBE = 562, + IMAGEBUFFER = 563, + IIMAGEBUFFER = 564, + UIMAGEBUFFER = 565, + IMAGE1DARRAY = 566, + IIMAGE1DARRAY = 567, + UIMAGE1DARRAY = 568, + IMAGE2DARRAY = 569, + IIMAGE2DARRAY = 570, + UIMAGE2DARRAY = 571, + IMAGECUBEARRAY = 572, + IIMAGECUBEARRAY = 573, + UIMAGECUBEARRAY = 574, + IMAGE2DMS = 575, + IIMAGE2DMS = 576, + UIMAGE2DMS = 577, + IMAGE2DMSARRAY = 578, + IIMAGE2DMSARRAY = 579, + UIMAGE2DMSARRAY = 580, + F16IMAGE1D = 581, + F16IMAGE2D = 582, + F16IMAGE3D = 583, + F16IMAGE2DRECT = 584, + F16IMAGECUBE = 585, + F16IMAGE1DARRAY = 586, + F16IMAGE2DARRAY = 587, + F16IMAGECUBEARRAY = 588, + F16IMAGEBUFFER = 589, + F16IMAGE2DMS = 590, + F16IMAGE2DMSARRAY = 591, + STRUCT = 592, + VOID = 593, + WHILE = 594, + IDENTIFIER = 595, + TYPE_NAME = 596, + FLOATCONSTANT = 597, + DOUBLECONSTANT = 598, + INT16CONSTANT = 599, + UINT16CONSTANT = 600, + INT32CONSTANT = 601, + UINT32CONSTANT = 602, + INTCONSTANT = 603, + UINTCONSTANT = 604, + INT64CONSTANT = 605, + UINT64CONSTANT = 606, + BOOLCONSTANT = 607, + FLOAT16CONSTANT = 608, + LEFT_OP = 609, + RIGHT_OP = 610, + INC_OP = 611, + DEC_OP = 612, + LE_OP = 613, + GE_OP = 614, + EQ_OP = 615, + NE_OP = 616, + AND_OP = 617, + OR_OP = 618, + XOR_OP = 619, + MUL_ASSIGN = 620, + DIV_ASSIGN = 621, + ADD_ASSIGN = 622, + MOD_ASSIGN = 623, + LEFT_ASSIGN = 624, + RIGHT_ASSIGN = 625, + AND_ASSIGN = 626, + XOR_ASSIGN = 627, + OR_ASSIGN = 628, + SUB_ASSIGN = 629, + LEFT_PAREN = 630, + RIGHT_PAREN = 631, + LEFT_BRACKET = 632, + RIGHT_BRACKET = 633, + LEFT_BRACE = 634, + RIGHT_BRACE = 635, + DOT = 636, + COMMA = 637, + COLON = 638, + EQUAL = 639, + SEMICOLON = 640, + BANG = 641, + DASH = 642, + TILDE = 643, + PLUS = 644, + STAR = 645, + SLASH = 646, + PERCENT = 647, + LEFT_ANGLE = 648, + RIGHT_ANGLE = 649, + VERTICAL_BAR = 650, + CARET = 651, + AMPERSAND = 652, + QUESTION = 653, + INVARIANT = 654, + PRECISE = 655, + HIGH_PRECISION = 656, + MEDIUM_PRECISION = 657, + LOW_PRECISION = 658, + PRECISION = 659, + PACKED = 660, + RESOURCE = 661, + SUPERP = 662 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; + union YYSTYPE { -#line 68 "MachineIndependent/glslang.y" /* yacc.c:1909 */ +#line 71 "MachineIndependent/glslang.y" /* yacc.c:1909 */ struct { glslang::TSourceLoc loc; @@ -370,6 +480,7 @@ TIntermNode* intermNode; glslang::TIntermNodePair nodePair; glslang::TIntermTyped* intermTypedNode; + glslang::TAttributes* attributes; }; union { glslang::TPublicType type; @@ -380,10 +491,13 @@ glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; -#line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ +#line 498 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ }; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/gl_types.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/gl_types.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/gl_types.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/gl_types.h 2019-10-27 13:44:49.000000000 +0000 @@ -117,6 +117,40 @@ #define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D +#ifdef AMD_EXTENSIONS +#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE +#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF +#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0 +#define GL_FLOAT16_SAMPLER_CUBE_AMD 0x91D1 +#define GL_FLOAT16_SAMPLER_2D_RECT_AMD 0x91D2 +#define GL_FLOAT16_SAMPLER_1D_ARRAY_AMD 0x91D3 +#define GL_FLOAT16_SAMPLER_2D_ARRAY_AMD 0x91D4 +#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD 0x91D5 +#define GL_FLOAT16_SAMPLER_BUFFER_AMD 0x91D6 +#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD 0x91D7 +#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD 0x91D8 + +#define GL_FLOAT16_SAMPLER_1D_SHADOW_AMD 0x91D9 +#define GL_FLOAT16_SAMPLER_2D_SHADOW_AMD 0x91DA +#define GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD 0x91DB +#define GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD 0x91DC +#define GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD 0x91DD +#define GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD 0x91DE +#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD 0x91DF + +#define GL_FLOAT16_IMAGE_1D_AMD 0x91E0 +#define GL_FLOAT16_IMAGE_2D_AMD 0x91E1 +#define GL_FLOAT16_IMAGE_3D_AMD 0x91E2 +#define GL_FLOAT16_IMAGE_2D_RECT_AMD 0x91E3 +#define GL_FLOAT16_IMAGE_CUBE_AMD 0x91E4 +#define GL_FLOAT16_IMAGE_1D_ARRAY_AMD 0x91E5 +#define GL_FLOAT16_IMAGE_2D_ARRAY_AMD 0x91E6 +#define GL_FLOAT16_IMAGE_CUBE_MAP_ARRAY_AMD 0x91E7 +#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8 +#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9 +#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA +#endif + #define GL_INT_SAMPLER_1D 0x8DC9 #define GL_INT_SAMPLER_2D 0x8DCA #define GL_INT_SAMPLER_3D 0x8DCB diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. -// Copyright (C) 2015-2017 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -83,6 +84,13 @@ // Set up textual representations for making all the permutations // of texturing/imaging functions. prefixes[EbtFloat] = ""; +#ifdef AMD_EXTENSIONS + prefixes[EbtFloat16] = "f16"; +#endif + prefixes[EbtInt8] = "i8"; + prefixes[EbtUint8] = "u8"; + prefixes[EbtInt16] = "i16"; + prefixes[EbtUint16] = "u16"; prefixes[EbtInt] = "i"; prefixes[EbtUint] = "u"; postfixes[2] = "2"; @@ -116,6 +124,158 @@ { //============================================================================ // + // Prototypes for built-in functions used repeatly by different shaders + // + //============================================================================ + + // + // Derivatives Functions. + // + TString derivatives ( + "float dFdx(float p);" + "vec2 dFdx(vec2 p);" + "vec3 dFdx(vec3 p);" + "vec4 dFdx(vec4 p);" + + "float dFdy(float p);" + "vec2 dFdy(vec2 p);" + "vec3 dFdy(vec3 p);" + "vec4 dFdy(vec4 p);" + + "float fwidth(float p);" + "vec2 fwidth(vec2 p);" + "vec3 fwidth(vec3 p);" + "vec4 fwidth(vec4 p);" + ); + + TString derivativeControls ( + "float dFdxFine(float p);" + "vec2 dFdxFine(vec2 p);" + "vec3 dFdxFine(vec3 p);" + "vec4 dFdxFine(vec4 p);" + + "float dFdyFine(float p);" + "vec2 dFdyFine(vec2 p);" + "vec3 dFdyFine(vec3 p);" + "vec4 dFdyFine(vec4 p);" + + "float fwidthFine(float p);" + "vec2 fwidthFine(vec2 p);" + "vec3 fwidthFine(vec3 p);" + "vec4 fwidthFine(vec4 p);" + + "float dFdxCoarse(float p);" + "vec2 dFdxCoarse(vec2 p);" + "vec3 dFdxCoarse(vec3 p);" + "vec4 dFdxCoarse(vec4 p);" + + "float dFdyCoarse(float p);" + "vec2 dFdyCoarse(vec2 p);" + "vec3 dFdyCoarse(vec3 p);" + "vec4 dFdyCoarse(vec4 p);" + + "float fwidthCoarse(float p);" + "vec2 fwidthCoarse(vec2 p);" + "vec3 fwidthCoarse(vec3 p);" + "vec4 fwidthCoarse(vec4 p);" + ); + + TString derivativesAndControl16bits ( + "float16_t dFdx(float16_t);" + "f16vec2 dFdx(f16vec2);" + "f16vec3 dFdx(f16vec3);" + "f16vec4 dFdx(f16vec4);" + + "float16_t dFdy(float16_t);" + "f16vec2 dFdy(f16vec2);" + "f16vec3 dFdy(f16vec3);" + "f16vec4 dFdy(f16vec4);" + + "float16_t dFdxFine(float16_t);" + "f16vec2 dFdxFine(f16vec2);" + "f16vec3 dFdxFine(f16vec3);" + "f16vec4 dFdxFine(f16vec4);" + + "float16_t dFdyFine(float16_t);" + "f16vec2 dFdyFine(f16vec2);" + "f16vec3 dFdyFine(f16vec3);" + "f16vec4 dFdyFine(f16vec4);" + + "float16_t dFdxCoarse(float16_t);" + "f16vec2 dFdxCoarse(f16vec2);" + "f16vec3 dFdxCoarse(f16vec3);" + "f16vec4 dFdxCoarse(f16vec4);" + + "float16_t dFdyCoarse(float16_t);" + "f16vec2 dFdyCoarse(f16vec2);" + "f16vec3 dFdyCoarse(f16vec3);" + "f16vec4 dFdyCoarse(f16vec4);" + + "float16_t fwidth(float16_t);" + "f16vec2 fwidth(f16vec2);" + "f16vec3 fwidth(f16vec3);" + "f16vec4 fwidth(f16vec4);" + + "float16_t fwidthFine(float16_t);" + "f16vec2 fwidthFine(f16vec2);" + "f16vec3 fwidthFine(f16vec3);" + "f16vec4 fwidthFine(f16vec4);" + + "float16_t fwidthCoarse(float16_t);" + "f16vec2 fwidthCoarse(f16vec2);" + "f16vec3 fwidthCoarse(f16vec3);" + "f16vec4 fwidthCoarse(f16vec4);" + ); + + TString derivativesAndControl64bits ( + "float64_t dFdx(float64_t);" + "f64vec2 dFdx(f64vec2);" + "f64vec3 dFdx(f64vec3);" + "f64vec4 dFdx(f64vec4);" + + "float64_t dFdy(float64_t);" + "f64vec2 dFdy(f64vec2);" + "f64vec3 dFdy(f64vec3);" + "f64vec4 dFdy(f64vec4);" + + "float64_t dFdxFine(float64_t);" + "f64vec2 dFdxFine(f64vec2);" + "f64vec3 dFdxFine(f64vec3);" + "f64vec4 dFdxFine(f64vec4);" + + "float64_t dFdyFine(float64_t);" + "f64vec2 dFdyFine(f64vec2);" + "f64vec3 dFdyFine(f64vec3);" + "f64vec4 dFdyFine(f64vec4);" + + "float64_t dFdxCoarse(float64_t);" + "f64vec2 dFdxCoarse(f64vec2);" + "f64vec3 dFdxCoarse(f64vec3);" + "f64vec4 dFdxCoarse(f64vec4);" + + "float64_t dFdyCoarse(float64_t);" + "f64vec2 dFdyCoarse(f64vec2);" + "f64vec3 dFdyCoarse(f64vec3);" + "f64vec4 dFdyCoarse(f64vec4);" + + "float64_t fwidth(float64_t);" + "f64vec2 fwidth(f64vec2);" + "f64vec3 fwidth(f64vec3);" + "f64vec4 fwidth(f64vec4);" + + "float64_t fwidthFine(float64_t);" + "f64vec2 fwidthFine(f64vec2);" + "f64vec3 fwidthFine(f64vec3);" + "f64vec4 fwidthFine(f64vec4);" + + "float64_t fwidthCoarse(float64_t);" + "f64vec2 fwidthCoarse(f64vec2);" + "f64vec3 fwidthCoarse(f64vec3);" + "f64vec4 fwidthCoarse(f64vec4);" + ); + + //============================================================================ + // // Prototypes for built-in functions seen by both vertex and fragment shaders. // //============================================================================ @@ -799,7 +959,6 @@ "bvec3 notEqual(u64vec3, u64vec3);" "bvec4 notEqual(u64vec4, u64vec4);" -#ifdef AMD_EXTENSIONS "int findLSB(int64_t);" "ivec2 findLSB(i64vec2);" "ivec3 findLSB(i64vec3);" @@ -819,7 +978,7 @@ "ivec2 findMSB(u64vec2);" "ivec3 findMSB(u64vec3);" "ivec4 findMSB(u64vec4);" -#endif + "\n" ); } @@ -888,6 +1047,36 @@ "f16vec3 mid3(f16vec3, f16vec3, f16vec3);" "f16vec4 mid3(f16vec4, f16vec4, f16vec4);" + "int16_t min3(int16_t, int16_t, int16_t);" + "i16vec2 min3(i16vec2, i16vec2, i16vec2);" + "i16vec3 min3(i16vec3, i16vec3, i16vec3);" + "i16vec4 min3(i16vec4, i16vec4, i16vec4);" + + "int16_t max3(int16_t, int16_t, int16_t);" + "i16vec2 max3(i16vec2, i16vec2, i16vec2);" + "i16vec3 max3(i16vec3, i16vec3, i16vec3);" + "i16vec4 max3(i16vec4, i16vec4, i16vec4);" + + "int16_t mid3(int16_t, int16_t, int16_t);" + "i16vec2 mid3(i16vec2, i16vec2, i16vec2);" + "i16vec3 mid3(i16vec3, i16vec3, i16vec3);" + "i16vec4 mid3(i16vec4, i16vec4, i16vec4);" + + "uint16_t min3(uint16_t, uint16_t, uint16_t);" + "u16vec2 min3(u16vec2, u16vec2, u16vec2);" + "u16vec3 min3(u16vec3, u16vec3, u16vec3);" + "u16vec4 min3(u16vec4, u16vec4, u16vec4);" + + "uint16_t max3(uint16_t, uint16_t, uint16_t);" + "u16vec2 max3(u16vec2, u16vec2, u16vec2);" + "u16vec3 max3(u16vec3, u16vec3, u16vec3);" + "u16vec4 max3(u16vec4, u16vec4, u16vec4);" + + "uint16_t mid3(uint16_t, uint16_t, uint16_t);" + "u16vec2 mid3(u16vec2, u16vec2, u16vec2);" + "u16vec3 mid3(u16vec3, u16vec3, u16vec3);" + "u16vec4 mid3(u16vec4, u16vec4, u16vec4);" + "\n" ); } @@ -898,56 +1087,102 @@ commonBuiltins.append( "uint atomicAdd(coherent volatile inout uint, uint);" " int atomicAdd(coherent volatile inout int, int);" + "uint atomicAdd(coherent volatile inout uint, uint, int, int, int);" + " int atomicAdd(coherent volatile inout int, int, int, int, int);" "uint atomicMin(coherent volatile inout uint, uint);" " int atomicMin(coherent volatile inout int, int);" + "uint atomicMin(coherent volatile inout uint, uint, int, int, int);" + " int atomicMin(coherent volatile inout int, int, int, int, int);" "uint atomicMax(coherent volatile inout uint, uint);" " int atomicMax(coherent volatile inout int, int);" + "uint atomicMax(coherent volatile inout uint, uint, int, int, int);" + " int atomicMax(coherent volatile inout int, int, int, int, int);" "uint atomicAnd(coherent volatile inout uint, uint);" " int atomicAnd(coherent volatile inout int, int);" + "uint atomicAnd(coherent volatile inout uint, uint, int, int, int);" + " int atomicAnd(coherent volatile inout int, int, int, int, int);" "uint atomicOr (coherent volatile inout uint, uint);" " int atomicOr (coherent volatile inout int, int);" + "uint atomicOr (coherent volatile inout uint, uint, int, int, int);" + " int atomicOr (coherent volatile inout int, int, int, int, int);" "uint atomicXor(coherent volatile inout uint, uint);" " int atomicXor(coherent volatile inout int, int);" + "uint atomicXor(coherent volatile inout uint, uint, int, int, int);" + " int atomicXor(coherent volatile inout int, int, int, int, int);" "uint atomicExchange(coherent volatile inout uint, uint);" " int atomicExchange(coherent volatile inout int, int);" + "uint atomicExchange(coherent volatile inout uint, uint, int, int, int);" + " int atomicExchange(coherent volatile inout int, int, int, int, int);" "uint atomicCompSwap(coherent volatile inout uint, uint, uint);" " int atomicCompSwap(coherent volatile inout int, int, int);" + "uint atomicCompSwap(coherent volatile inout uint, uint, uint, int, int, int, int, int);" + " int atomicCompSwap(coherent volatile inout int, int, int, int, int, int, int, int);" + + "uint atomicLoad(coherent volatile in uint, int, int, int);" + " int atomicLoad(coherent volatile in int, int, int, int);" + + "void atomicStore(coherent volatile out uint, uint, int, int, int);" + "void atomicStore(coherent volatile out int, int, int, int, int);" "\n"); } -#ifdef NV_EXTENSIONS if (profile != EEsProfile && version >= 440) { commonBuiltins.append( "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicMin(coherent volatile inout int64_t, int64_t);" + "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicMin(coherent volatile inout int64_t, int64_t, int, int, int);" "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicMax(coherent volatile inout int64_t, int64_t);" + "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicMax(coherent volatile inout int64_t, int64_t, int, int, int);" "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicAnd(coherent volatile inout int64_t, int64_t);" + "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicAnd(coherent volatile inout int64_t, int64_t, int, int, int);" "uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t);" " int64_t atomicOr (coherent volatile inout int64_t, int64_t);" + "uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicOr (coherent volatile inout int64_t, int64_t, int, int, int);" "uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t);" " int64_t atomicXor(coherent volatile inout int64_t, int64_t);" + "uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicXor(coherent volatile inout int64_t, int64_t, int, int, int);" - " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" - " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" - " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);" + "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" + "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);" + + "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);" + " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" + "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);" + " int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);" + + "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);" + " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);" + "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t, int, int, int, int, int);" + " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t, int, int, int, int, int);" + "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);" + " int64_t atomicLoad(coherent volatile in int64_t, int, int, int);" + + "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);" + "void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);" "\n"); } -#endif if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 450)) { @@ -1375,6 +1610,16 @@ "\n"); } commonBuiltins.append( + "highp ivec2 textureSize(__samplerExternal2DY2YEXT, int lod);" // GL_EXT_YUV_target + "vec4 texture(__samplerExternal2DY2YEXT, vec2);" // GL_EXT_YUV_target + "vec4 texture(__samplerExternal2DY2YEXT, vec2, float bias);" // GL_EXT_YUV_target + "vec4 textureProj(__samplerExternal2DY2YEXT, vec3);" // GL_EXT_YUV_target + "vec4 textureProj(__samplerExternal2DY2YEXT, vec3, float bias);" // GL_EXT_YUV_target + "vec4 textureProj(__samplerExternal2DY2YEXT, vec4);" // GL_EXT_YUV_target + "vec4 textureProj(__samplerExternal2DY2YEXT, vec4, float bias);" // GL_EXT_YUV_target + "vec4 texelFetch(__samplerExternal2DY2YEXT sampler, ivec2, int lod);" // GL_EXT_YUV_target + "\n"); + commonBuiltins.append( "vec4 texture2DGradEXT(sampler2D, vec2, vec2, vec2);" // GL_EXT_shader_texture_lod "vec4 texture2DProjGradEXT(sampler2D, vec3, vec2, vec2);" // GL_EXT_shader_texture_lod "vec4 texture2DProjGradEXT(sampler2D, vec4, vec2, vec2);" // GL_EXT_shader_texture_lod @@ -1633,6 +1878,1098 @@ "\n"); } + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + commonBuiltins.append( + "void subgroupBarrier();" + "void subgroupMemoryBarrier();" + "void subgroupMemoryBarrierBuffer();" + "void subgroupMemoryBarrierImage();" + "bool subgroupElect();" + + "bool subgroupAll(bool);\n" + "bool subgroupAny(bool);\n" + + "bool subgroupAllEqual(float);\n" + "bool subgroupAllEqual(vec2);\n" + "bool subgroupAllEqual(vec3);\n" + "bool subgroupAllEqual(vec4);\n" + "bool subgroupAllEqual(int);\n" + "bool subgroupAllEqual(ivec2);\n" + "bool subgroupAllEqual(ivec3);\n" + "bool subgroupAllEqual(ivec4);\n" + "bool subgroupAllEqual(uint);\n" + "bool subgroupAllEqual(uvec2);\n" + "bool subgroupAllEqual(uvec3);\n" + "bool subgroupAllEqual(uvec4);\n" + "bool subgroupAllEqual(bool);\n" + "bool subgroupAllEqual(bvec2);\n" + "bool subgroupAllEqual(bvec3);\n" + "bool subgroupAllEqual(bvec4);\n" + + "float subgroupBroadcast(float, uint);\n" + "vec2 subgroupBroadcast(vec2, uint);\n" + "vec3 subgroupBroadcast(vec3, uint);\n" + "vec4 subgroupBroadcast(vec4, uint);\n" + "int subgroupBroadcast(int, uint);\n" + "ivec2 subgroupBroadcast(ivec2, uint);\n" + "ivec3 subgroupBroadcast(ivec3, uint);\n" + "ivec4 subgroupBroadcast(ivec4, uint);\n" + "uint subgroupBroadcast(uint, uint);\n" + "uvec2 subgroupBroadcast(uvec2, uint);\n" + "uvec3 subgroupBroadcast(uvec3, uint);\n" + "uvec4 subgroupBroadcast(uvec4, uint);\n" + "bool subgroupBroadcast(bool, uint);\n" + "bvec2 subgroupBroadcast(bvec2, uint);\n" + "bvec3 subgroupBroadcast(bvec3, uint);\n" + "bvec4 subgroupBroadcast(bvec4, uint);\n" + + "float subgroupBroadcastFirst(float);\n" + "vec2 subgroupBroadcastFirst(vec2);\n" + "vec3 subgroupBroadcastFirst(vec3);\n" + "vec4 subgroupBroadcastFirst(vec4);\n" + "int subgroupBroadcastFirst(int);\n" + "ivec2 subgroupBroadcastFirst(ivec2);\n" + "ivec3 subgroupBroadcastFirst(ivec3);\n" + "ivec4 subgroupBroadcastFirst(ivec4);\n" + "uint subgroupBroadcastFirst(uint);\n" + "uvec2 subgroupBroadcastFirst(uvec2);\n" + "uvec3 subgroupBroadcastFirst(uvec3);\n" + "uvec4 subgroupBroadcastFirst(uvec4);\n" + "bool subgroupBroadcastFirst(bool);\n" + "bvec2 subgroupBroadcastFirst(bvec2);\n" + "bvec3 subgroupBroadcastFirst(bvec3);\n" + "bvec4 subgroupBroadcastFirst(bvec4);\n" + + "uvec4 subgroupBallot(bool);\n" + "bool subgroupInverseBallot(uvec4);\n" + "bool subgroupBallotBitExtract(uvec4, uint);\n" + "uint subgroupBallotBitCount(uvec4);\n" + "uint subgroupBallotInclusiveBitCount(uvec4);\n" + "uint subgroupBallotExclusiveBitCount(uvec4);\n" + "uint subgroupBallotFindLSB(uvec4);\n" + "uint subgroupBallotFindMSB(uvec4);\n" + + "float subgroupShuffle(float, uint);\n" + "vec2 subgroupShuffle(vec2, uint);\n" + "vec3 subgroupShuffle(vec3, uint);\n" + "vec4 subgroupShuffle(vec4, uint);\n" + "int subgroupShuffle(int, uint);\n" + "ivec2 subgroupShuffle(ivec2, uint);\n" + "ivec3 subgroupShuffle(ivec3, uint);\n" + "ivec4 subgroupShuffle(ivec4, uint);\n" + "uint subgroupShuffle(uint, uint);\n" + "uvec2 subgroupShuffle(uvec2, uint);\n" + "uvec3 subgroupShuffle(uvec3, uint);\n" + "uvec4 subgroupShuffle(uvec4, uint);\n" + "bool subgroupShuffle(bool, uint);\n" + "bvec2 subgroupShuffle(bvec2, uint);\n" + "bvec3 subgroupShuffle(bvec3, uint);\n" + "bvec4 subgroupShuffle(bvec4, uint);\n" + + "float subgroupShuffleXor(float, uint);\n" + "vec2 subgroupShuffleXor(vec2, uint);\n" + "vec3 subgroupShuffleXor(vec3, uint);\n" + "vec4 subgroupShuffleXor(vec4, uint);\n" + "int subgroupShuffleXor(int, uint);\n" + "ivec2 subgroupShuffleXor(ivec2, uint);\n" + "ivec3 subgroupShuffleXor(ivec3, uint);\n" + "ivec4 subgroupShuffleXor(ivec4, uint);\n" + "uint subgroupShuffleXor(uint, uint);\n" + "uvec2 subgroupShuffleXor(uvec2, uint);\n" + "uvec3 subgroupShuffleXor(uvec3, uint);\n" + "uvec4 subgroupShuffleXor(uvec4, uint);\n" + "bool subgroupShuffleXor(bool, uint);\n" + "bvec2 subgroupShuffleXor(bvec2, uint);\n" + "bvec3 subgroupShuffleXor(bvec3, uint);\n" + "bvec4 subgroupShuffleXor(bvec4, uint);\n" + + "float subgroupShuffleUp(float, uint delta);\n" + "vec2 subgroupShuffleUp(vec2, uint delta);\n" + "vec3 subgroupShuffleUp(vec3, uint delta);\n" + "vec4 subgroupShuffleUp(vec4, uint delta);\n" + "int subgroupShuffleUp(int, uint delta);\n" + "ivec2 subgroupShuffleUp(ivec2, uint delta);\n" + "ivec3 subgroupShuffleUp(ivec3, uint delta);\n" + "ivec4 subgroupShuffleUp(ivec4, uint delta);\n" + "uint subgroupShuffleUp(uint, uint delta);\n" + "uvec2 subgroupShuffleUp(uvec2, uint delta);\n" + "uvec3 subgroupShuffleUp(uvec3, uint delta);\n" + "uvec4 subgroupShuffleUp(uvec4, uint delta);\n" + "bool subgroupShuffleUp(bool, uint delta);\n" + "bvec2 subgroupShuffleUp(bvec2, uint delta);\n" + "bvec3 subgroupShuffleUp(bvec3, uint delta);\n" + "bvec4 subgroupShuffleUp(bvec4, uint delta);\n" + + "float subgroupShuffleDown(float, uint delta);\n" + "vec2 subgroupShuffleDown(vec2, uint delta);\n" + "vec3 subgroupShuffleDown(vec3, uint delta);\n" + "vec4 subgroupShuffleDown(vec4, uint delta);\n" + "int subgroupShuffleDown(int, uint delta);\n" + "ivec2 subgroupShuffleDown(ivec2, uint delta);\n" + "ivec3 subgroupShuffleDown(ivec3, uint delta);\n" + "ivec4 subgroupShuffleDown(ivec4, uint delta);\n" + "uint subgroupShuffleDown(uint, uint delta);\n" + "uvec2 subgroupShuffleDown(uvec2, uint delta);\n" + "uvec3 subgroupShuffleDown(uvec3, uint delta);\n" + "uvec4 subgroupShuffleDown(uvec4, uint delta);\n" + "bool subgroupShuffleDown(bool, uint delta);\n" + "bvec2 subgroupShuffleDown(bvec2, uint delta);\n" + "bvec3 subgroupShuffleDown(bvec3, uint delta);\n" + "bvec4 subgroupShuffleDown(bvec4, uint delta);\n" + + "float subgroupAdd(float);\n" + "vec2 subgroupAdd(vec2);\n" + "vec3 subgroupAdd(vec3);\n" + "vec4 subgroupAdd(vec4);\n" + "int subgroupAdd(int);\n" + "ivec2 subgroupAdd(ivec2);\n" + "ivec3 subgroupAdd(ivec3);\n" + "ivec4 subgroupAdd(ivec4);\n" + "uint subgroupAdd(uint);\n" + "uvec2 subgroupAdd(uvec2);\n" + "uvec3 subgroupAdd(uvec3);\n" + "uvec4 subgroupAdd(uvec4);\n" + + "float subgroupMul(float);\n" + "vec2 subgroupMul(vec2);\n" + "vec3 subgroupMul(vec3);\n" + "vec4 subgroupMul(vec4);\n" + "int subgroupMul(int);\n" + "ivec2 subgroupMul(ivec2);\n" + "ivec3 subgroupMul(ivec3);\n" + "ivec4 subgroupMul(ivec4);\n" + "uint subgroupMul(uint);\n" + "uvec2 subgroupMul(uvec2);\n" + "uvec3 subgroupMul(uvec3);\n" + "uvec4 subgroupMul(uvec4);\n" + + "float subgroupMin(float);\n" + "vec2 subgroupMin(vec2);\n" + "vec3 subgroupMin(vec3);\n" + "vec4 subgroupMin(vec4);\n" + "int subgroupMin(int);\n" + "ivec2 subgroupMin(ivec2);\n" + "ivec3 subgroupMin(ivec3);\n" + "ivec4 subgroupMin(ivec4);\n" + "uint subgroupMin(uint);\n" + "uvec2 subgroupMin(uvec2);\n" + "uvec3 subgroupMin(uvec3);\n" + "uvec4 subgroupMin(uvec4);\n" + + "float subgroupMax(float);\n" + "vec2 subgroupMax(vec2);\n" + "vec3 subgroupMax(vec3);\n" + "vec4 subgroupMax(vec4);\n" + "int subgroupMax(int);\n" + "ivec2 subgroupMax(ivec2);\n" + "ivec3 subgroupMax(ivec3);\n" + "ivec4 subgroupMax(ivec4);\n" + "uint subgroupMax(uint);\n" + "uvec2 subgroupMax(uvec2);\n" + "uvec3 subgroupMax(uvec3);\n" + "uvec4 subgroupMax(uvec4);\n" + + "int subgroupAnd(int);\n" + "ivec2 subgroupAnd(ivec2);\n" + "ivec3 subgroupAnd(ivec3);\n" + "ivec4 subgroupAnd(ivec4);\n" + "uint subgroupAnd(uint);\n" + "uvec2 subgroupAnd(uvec2);\n" + "uvec3 subgroupAnd(uvec3);\n" + "uvec4 subgroupAnd(uvec4);\n" + "bool subgroupAnd(bool);\n" + "bvec2 subgroupAnd(bvec2);\n" + "bvec3 subgroupAnd(bvec3);\n" + "bvec4 subgroupAnd(bvec4);\n" + + "int subgroupOr(int);\n" + "ivec2 subgroupOr(ivec2);\n" + "ivec3 subgroupOr(ivec3);\n" + "ivec4 subgroupOr(ivec4);\n" + "uint subgroupOr(uint);\n" + "uvec2 subgroupOr(uvec2);\n" + "uvec3 subgroupOr(uvec3);\n" + "uvec4 subgroupOr(uvec4);\n" + "bool subgroupOr(bool);\n" + "bvec2 subgroupOr(bvec2);\n" + "bvec3 subgroupOr(bvec3);\n" + "bvec4 subgroupOr(bvec4);\n" + + "int subgroupXor(int);\n" + "ivec2 subgroupXor(ivec2);\n" + "ivec3 subgroupXor(ivec3);\n" + "ivec4 subgroupXor(ivec4);\n" + "uint subgroupXor(uint);\n" + "uvec2 subgroupXor(uvec2);\n" + "uvec3 subgroupXor(uvec3);\n" + "uvec4 subgroupXor(uvec4);\n" + "bool subgroupXor(bool);\n" + "bvec2 subgroupXor(bvec2);\n" + "bvec3 subgroupXor(bvec3);\n" + "bvec4 subgroupXor(bvec4);\n" + + "float subgroupInclusiveAdd(float);\n" + "vec2 subgroupInclusiveAdd(vec2);\n" + "vec3 subgroupInclusiveAdd(vec3);\n" + "vec4 subgroupInclusiveAdd(vec4);\n" + "int subgroupInclusiveAdd(int);\n" + "ivec2 subgroupInclusiveAdd(ivec2);\n" + "ivec3 subgroupInclusiveAdd(ivec3);\n" + "ivec4 subgroupInclusiveAdd(ivec4);\n" + "uint subgroupInclusiveAdd(uint);\n" + "uvec2 subgroupInclusiveAdd(uvec2);\n" + "uvec3 subgroupInclusiveAdd(uvec3);\n" + "uvec4 subgroupInclusiveAdd(uvec4);\n" + + "float subgroupInclusiveMul(float);\n" + "vec2 subgroupInclusiveMul(vec2);\n" + "vec3 subgroupInclusiveMul(vec3);\n" + "vec4 subgroupInclusiveMul(vec4);\n" + "int subgroupInclusiveMul(int);\n" + "ivec2 subgroupInclusiveMul(ivec2);\n" + "ivec3 subgroupInclusiveMul(ivec3);\n" + "ivec4 subgroupInclusiveMul(ivec4);\n" + "uint subgroupInclusiveMul(uint);\n" + "uvec2 subgroupInclusiveMul(uvec2);\n" + "uvec3 subgroupInclusiveMul(uvec3);\n" + "uvec4 subgroupInclusiveMul(uvec4);\n" + + "float subgroupInclusiveMin(float);\n" + "vec2 subgroupInclusiveMin(vec2);\n" + "vec3 subgroupInclusiveMin(vec3);\n" + "vec4 subgroupInclusiveMin(vec4);\n" + "int subgroupInclusiveMin(int);\n" + "ivec2 subgroupInclusiveMin(ivec2);\n" + "ivec3 subgroupInclusiveMin(ivec3);\n" + "ivec4 subgroupInclusiveMin(ivec4);\n" + "uint subgroupInclusiveMin(uint);\n" + "uvec2 subgroupInclusiveMin(uvec2);\n" + "uvec3 subgroupInclusiveMin(uvec3);\n" + "uvec4 subgroupInclusiveMin(uvec4);\n" + + "float subgroupInclusiveMax(float);\n" + "vec2 subgroupInclusiveMax(vec2);\n" + "vec3 subgroupInclusiveMax(vec3);\n" + "vec4 subgroupInclusiveMax(vec4);\n" + "int subgroupInclusiveMax(int);\n" + "ivec2 subgroupInclusiveMax(ivec2);\n" + "ivec3 subgroupInclusiveMax(ivec3);\n" + "ivec4 subgroupInclusiveMax(ivec4);\n" + "uint subgroupInclusiveMax(uint);\n" + "uvec2 subgroupInclusiveMax(uvec2);\n" + "uvec3 subgroupInclusiveMax(uvec3);\n" + "uvec4 subgroupInclusiveMax(uvec4);\n" + + "int subgroupInclusiveAnd(int);\n" + "ivec2 subgroupInclusiveAnd(ivec2);\n" + "ivec3 subgroupInclusiveAnd(ivec3);\n" + "ivec4 subgroupInclusiveAnd(ivec4);\n" + "uint subgroupInclusiveAnd(uint);\n" + "uvec2 subgroupInclusiveAnd(uvec2);\n" + "uvec3 subgroupInclusiveAnd(uvec3);\n" + "uvec4 subgroupInclusiveAnd(uvec4);\n" + "bool subgroupInclusiveAnd(bool);\n" + "bvec2 subgroupInclusiveAnd(bvec2);\n" + "bvec3 subgroupInclusiveAnd(bvec3);\n" + "bvec4 subgroupInclusiveAnd(bvec4);\n" + + "int subgroupInclusiveOr(int);\n" + "ivec2 subgroupInclusiveOr(ivec2);\n" + "ivec3 subgroupInclusiveOr(ivec3);\n" + "ivec4 subgroupInclusiveOr(ivec4);\n" + "uint subgroupInclusiveOr(uint);\n" + "uvec2 subgroupInclusiveOr(uvec2);\n" + "uvec3 subgroupInclusiveOr(uvec3);\n" + "uvec4 subgroupInclusiveOr(uvec4);\n" + "bool subgroupInclusiveOr(bool);\n" + "bvec2 subgroupInclusiveOr(bvec2);\n" + "bvec3 subgroupInclusiveOr(bvec3);\n" + "bvec4 subgroupInclusiveOr(bvec4);\n" + + "int subgroupInclusiveXor(int);\n" + "ivec2 subgroupInclusiveXor(ivec2);\n" + "ivec3 subgroupInclusiveXor(ivec3);\n" + "ivec4 subgroupInclusiveXor(ivec4);\n" + "uint subgroupInclusiveXor(uint);\n" + "uvec2 subgroupInclusiveXor(uvec2);\n" + "uvec3 subgroupInclusiveXor(uvec3);\n" + "uvec4 subgroupInclusiveXor(uvec4);\n" + "bool subgroupInclusiveXor(bool);\n" + "bvec2 subgroupInclusiveXor(bvec2);\n" + "bvec3 subgroupInclusiveXor(bvec3);\n" + "bvec4 subgroupInclusiveXor(bvec4);\n" + + "float subgroupExclusiveAdd(float);\n" + "vec2 subgroupExclusiveAdd(vec2);\n" + "vec3 subgroupExclusiveAdd(vec3);\n" + "vec4 subgroupExclusiveAdd(vec4);\n" + "int subgroupExclusiveAdd(int);\n" + "ivec2 subgroupExclusiveAdd(ivec2);\n" + "ivec3 subgroupExclusiveAdd(ivec3);\n" + "ivec4 subgroupExclusiveAdd(ivec4);\n" + "uint subgroupExclusiveAdd(uint);\n" + "uvec2 subgroupExclusiveAdd(uvec2);\n" + "uvec3 subgroupExclusiveAdd(uvec3);\n" + "uvec4 subgroupExclusiveAdd(uvec4);\n" + + "float subgroupExclusiveMul(float);\n" + "vec2 subgroupExclusiveMul(vec2);\n" + "vec3 subgroupExclusiveMul(vec3);\n" + "vec4 subgroupExclusiveMul(vec4);\n" + "int subgroupExclusiveMul(int);\n" + "ivec2 subgroupExclusiveMul(ivec2);\n" + "ivec3 subgroupExclusiveMul(ivec3);\n" + "ivec4 subgroupExclusiveMul(ivec4);\n" + "uint subgroupExclusiveMul(uint);\n" + "uvec2 subgroupExclusiveMul(uvec2);\n" + "uvec3 subgroupExclusiveMul(uvec3);\n" + "uvec4 subgroupExclusiveMul(uvec4);\n" + + "float subgroupExclusiveMin(float);\n" + "vec2 subgroupExclusiveMin(vec2);\n" + "vec3 subgroupExclusiveMin(vec3);\n" + "vec4 subgroupExclusiveMin(vec4);\n" + "int subgroupExclusiveMin(int);\n" + "ivec2 subgroupExclusiveMin(ivec2);\n" + "ivec3 subgroupExclusiveMin(ivec3);\n" + "ivec4 subgroupExclusiveMin(ivec4);\n" + "uint subgroupExclusiveMin(uint);\n" + "uvec2 subgroupExclusiveMin(uvec2);\n" + "uvec3 subgroupExclusiveMin(uvec3);\n" + "uvec4 subgroupExclusiveMin(uvec4);\n" + + "float subgroupExclusiveMax(float);\n" + "vec2 subgroupExclusiveMax(vec2);\n" + "vec3 subgroupExclusiveMax(vec3);\n" + "vec4 subgroupExclusiveMax(vec4);\n" + "int subgroupExclusiveMax(int);\n" + "ivec2 subgroupExclusiveMax(ivec2);\n" + "ivec3 subgroupExclusiveMax(ivec3);\n" + "ivec4 subgroupExclusiveMax(ivec4);\n" + "uint subgroupExclusiveMax(uint);\n" + "uvec2 subgroupExclusiveMax(uvec2);\n" + "uvec3 subgroupExclusiveMax(uvec3);\n" + "uvec4 subgroupExclusiveMax(uvec4);\n" + + "int subgroupExclusiveAnd(int);\n" + "ivec2 subgroupExclusiveAnd(ivec2);\n" + "ivec3 subgroupExclusiveAnd(ivec3);\n" + "ivec4 subgroupExclusiveAnd(ivec4);\n" + "uint subgroupExclusiveAnd(uint);\n" + "uvec2 subgroupExclusiveAnd(uvec2);\n" + "uvec3 subgroupExclusiveAnd(uvec3);\n" + "uvec4 subgroupExclusiveAnd(uvec4);\n" + "bool subgroupExclusiveAnd(bool);\n" + "bvec2 subgroupExclusiveAnd(bvec2);\n" + "bvec3 subgroupExclusiveAnd(bvec3);\n" + "bvec4 subgroupExclusiveAnd(bvec4);\n" + + "int subgroupExclusiveOr(int);\n" + "ivec2 subgroupExclusiveOr(ivec2);\n" + "ivec3 subgroupExclusiveOr(ivec3);\n" + "ivec4 subgroupExclusiveOr(ivec4);\n" + "uint subgroupExclusiveOr(uint);\n" + "uvec2 subgroupExclusiveOr(uvec2);\n" + "uvec3 subgroupExclusiveOr(uvec3);\n" + "uvec4 subgroupExclusiveOr(uvec4);\n" + "bool subgroupExclusiveOr(bool);\n" + "bvec2 subgroupExclusiveOr(bvec2);\n" + "bvec3 subgroupExclusiveOr(bvec3);\n" + "bvec4 subgroupExclusiveOr(bvec4);\n" + + "int subgroupExclusiveXor(int);\n" + "ivec2 subgroupExclusiveXor(ivec2);\n" + "ivec3 subgroupExclusiveXor(ivec3);\n" + "ivec4 subgroupExclusiveXor(ivec4);\n" + "uint subgroupExclusiveXor(uint);\n" + "uvec2 subgroupExclusiveXor(uvec2);\n" + "uvec3 subgroupExclusiveXor(uvec3);\n" + "uvec4 subgroupExclusiveXor(uvec4);\n" + "bool subgroupExclusiveXor(bool);\n" + "bvec2 subgroupExclusiveXor(bvec2);\n" + "bvec3 subgroupExclusiveXor(bvec3);\n" + "bvec4 subgroupExclusiveXor(bvec4);\n" + + "float subgroupClusteredAdd(float, uint);\n" + "vec2 subgroupClusteredAdd(vec2, uint);\n" + "vec3 subgroupClusteredAdd(vec3, uint);\n" + "vec4 subgroupClusteredAdd(vec4, uint);\n" + "int subgroupClusteredAdd(int, uint);\n" + "ivec2 subgroupClusteredAdd(ivec2, uint);\n" + "ivec3 subgroupClusteredAdd(ivec3, uint);\n" + "ivec4 subgroupClusteredAdd(ivec4, uint);\n" + "uint subgroupClusteredAdd(uint, uint);\n" + "uvec2 subgroupClusteredAdd(uvec2, uint);\n" + "uvec3 subgroupClusteredAdd(uvec3, uint);\n" + "uvec4 subgroupClusteredAdd(uvec4, uint);\n" + + "float subgroupClusteredMul(float, uint);\n" + "vec2 subgroupClusteredMul(vec2, uint);\n" + "vec3 subgroupClusteredMul(vec3, uint);\n" + "vec4 subgroupClusteredMul(vec4, uint);\n" + "int subgroupClusteredMul(int, uint);\n" + "ivec2 subgroupClusteredMul(ivec2, uint);\n" + "ivec3 subgroupClusteredMul(ivec3, uint);\n" + "ivec4 subgroupClusteredMul(ivec4, uint);\n" + "uint subgroupClusteredMul(uint, uint);\n" + "uvec2 subgroupClusteredMul(uvec2, uint);\n" + "uvec3 subgroupClusteredMul(uvec3, uint);\n" + "uvec4 subgroupClusteredMul(uvec4, uint);\n" + + "float subgroupClusteredMin(float, uint);\n" + "vec2 subgroupClusteredMin(vec2, uint);\n" + "vec3 subgroupClusteredMin(vec3, uint);\n" + "vec4 subgroupClusteredMin(vec4, uint);\n" + "int subgroupClusteredMin(int, uint);\n" + "ivec2 subgroupClusteredMin(ivec2, uint);\n" + "ivec3 subgroupClusteredMin(ivec3, uint);\n" + "ivec4 subgroupClusteredMin(ivec4, uint);\n" + "uint subgroupClusteredMin(uint, uint);\n" + "uvec2 subgroupClusteredMin(uvec2, uint);\n" + "uvec3 subgroupClusteredMin(uvec3, uint);\n" + "uvec4 subgroupClusteredMin(uvec4, uint);\n" + + "float subgroupClusteredMax(float, uint);\n" + "vec2 subgroupClusteredMax(vec2, uint);\n" + "vec3 subgroupClusteredMax(vec3, uint);\n" + "vec4 subgroupClusteredMax(vec4, uint);\n" + "int subgroupClusteredMax(int, uint);\n" + "ivec2 subgroupClusteredMax(ivec2, uint);\n" + "ivec3 subgroupClusteredMax(ivec3, uint);\n" + "ivec4 subgroupClusteredMax(ivec4, uint);\n" + "uint subgroupClusteredMax(uint, uint);\n" + "uvec2 subgroupClusteredMax(uvec2, uint);\n" + "uvec3 subgroupClusteredMax(uvec3, uint);\n" + "uvec4 subgroupClusteredMax(uvec4, uint);\n" + + "int subgroupClusteredAnd(int, uint);\n" + "ivec2 subgroupClusteredAnd(ivec2, uint);\n" + "ivec3 subgroupClusteredAnd(ivec3, uint);\n" + "ivec4 subgroupClusteredAnd(ivec4, uint);\n" + "uint subgroupClusteredAnd(uint, uint);\n" + "uvec2 subgroupClusteredAnd(uvec2, uint);\n" + "uvec3 subgroupClusteredAnd(uvec3, uint);\n" + "uvec4 subgroupClusteredAnd(uvec4, uint);\n" + "bool subgroupClusteredAnd(bool, uint);\n" + "bvec2 subgroupClusteredAnd(bvec2, uint);\n" + "bvec3 subgroupClusteredAnd(bvec3, uint);\n" + "bvec4 subgroupClusteredAnd(bvec4, uint);\n" + + "int subgroupClusteredOr(int, uint);\n" + "ivec2 subgroupClusteredOr(ivec2, uint);\n" + "ivec3 subgroupClusteredOr(ivec3, uint);\n" + "ivec4 subgroupClusteredOr(ivec4, uint);\n" + "uint subgroupClusteredOr(uint, uint);\n" + "uvec2 subgroupClusteredOr(uvec2, uint);\n" + "uvec3 subgroupClusteredOr(uvec3, uint);\n" + "uvec4 subgroupClusteredOr(uvec4, uint);\n" + "bool subgroupClusteredOr(bool, uint);\n" + "bvec2 subgroupClusteredOr(bvec2, uint);\n" + "bvec3 subgroupClusteredOr(bvec3, uint);\n" + "bvec4 subgroupClusteredOr(bvec4, uint);\n" + + "int subgroupClusteredXor(int, uint);\n" + "ivec2 subgroupClusteredXor(ivec2, uint);\n" + "ivec3 subgroupClusteredXor(ivec3, uint);\n" + "ivec4 subgroupClusteredXor(ivec4, uint);\n" + "uint subgroupClusteredXor(uint, uint);\n" + "uvec2 subgroupClusteredXor(uvec2, uint);\n" + "uvec3 subgroupClusteredXor(uvec3, uint);\n" + "uvec4 subgroupClusteredXor(uvec4, uint);\n" + "bool subgroupClusteredXor(bool, uint);\n" + "bvec2 subgroupClusteredXor(bvec2, uint);\n" + "bvec3 subgroupClusteredXor(bvec3, uint);\n" + "bvec4 subgroupClusteredXor(bvec4, uint);\n" + + "float subgroupQuadBroadcast(float, uint);\n" + "vec2 subgroupQuadBroadcast(vec2, uint);\n" + "vec3 subgroupQuadBroadcast(vec3, uint);\n" + "vec4 subgroupQuadBroadcast(vec4, uint);\n" + "int subgroupQuadBroadcast(int, uint);\n" + "ivec2 subgroupQuadBroadcast(ivec2, uint);\n" + "ivec3 subgroupQuadBroadcast(ivec3, uint);\n" + "ivec4 subgroupQuadBroadcast(ivec4, uint);\n" + "uint subgroupQuadBroadcast(uint, uint);\n" + "uvec2 subgroupQuadBroadcast(uvec2, uint);\n" + "uvec3 subgroupQuadBroadcast(uvec3, uint);\n" + "uvec4 subgroupQuadBroadcast(uvec4, uint);\n" + "bool subgroupQuadBroadcast(bool, uint);\n" + "bvec2 subgroupQuadBroadcast(bvec2, uint);\n" + "bvec3 subgroupQuadBroadcast(bvec3, uint);\n" + "bvec4 subgroupQuadBroadcast(bvec4, uint);\n" + + "float subgroupQuadSwapHorizontal(float);\n" + "vec2 subgroupQuadSwapHorizontal(vec2);\n" + "vec3 subgroupQuadSwapHorizontal(vec3);\n" + "vec4 subgroupQuadSwapHorizontal(vec4);\n" + "int subgroupQuadSwapHorizontal(int);\n" + "ivec2 subgroupQuadSwapHorizontal(ivec2);\n" + "ivec3 subgroupQuadSwapHorizontal(ivec3);\n" + "ivec4 subgroupQuadSwapHorizontal(ivec4);\n" + "uint subgroupQuadSwapHorizontal(uint);\n" + "uvec2 subgroupQuadSwapHorizontal(uvec2);\n" + "uvec3 subgroupQuadSwapHorizontal(uvec3);\n" + "uvec4 subgroupQuadSwapHorizontal(uvec4);\n" + "bool subgroupQuadSwapHorizontal(bool);\n" + "bvec2 subgroupQuadSwapHorizontal(bvec2);\n" + "bvec3 subgroupQuadSwapHorizontal(bvec3);\n" + "bvec4 subgroupQuadSwapHorizontal(bvec4);\n" + + "float subgroupQuadSwapVertical(float);\n" + "vec2 subgroupQuadSwapVertical(vec2);\n" + "vec3 subgroupQuadSwapVertical(vec3);\n" + "vec4 subgroupQuadSwapVertical(vec4);\n" + "int subgroupQuadSwapVertical(int);\n" + "ivec2 subgroupQuadSwapVertical(ivec2);\n" + "ivec3 subgroupQuadSwapVertical(ivec3);\n" + "ivec4 subgroupQuadSwapVertical(ivec4);\n" + "uint subgroupQuadSwapVertical(uint);\n" + "uvec2 subgroupQuadSwapVertical(uvec2);\n" + "uvec3 subgroupQuadSwapVertical(uvec3);\n" + "uvec4 subgroupQuadSwapVertical(uvec4);\n" + "bool subgroupQuadSwapVertical(bool);\n" + "bvec2 subgroupQuadSwapVertical(bvec2);\n" + "bvec3 subgroupQuadSwapVertical(bvec3);\n" + "bvec4 subgroupQuadSwapVertical(bvec4);\n" + + "float subgroupQuadSwapDiagonal(float);\n" + "vec2 subgroupQuadSwapDiagonal(vec2);\n" + "vec3 subgroupQuadSwapDiagonal(vec3);\n" + "vec4 subgroupQuadSwapDiagonal(vec4);\n" + "int subgroupQuadSwapDiagonal(int);\n" + "ivec2 subgroupQuadSwapDiagonal(ivec2);\n" + "ivec3 subgroupQuadSwapDiagonal(ivec3);\n" + "ivec4 subgroupQuadSwapDiagonal(ivec4);\n" + "uint subgroupQuadSwapDiagonal(uint);\n" + "uvec2 subgroupQuadSwapDiagonal(uvec2);\n" + "uvec3 subgroupQuadSwapDiagonal(uvec3);\n" + "uvec4 subgroupQuadSwapDiagonal(uvec4);\n" + "bool subgroupQuadSwapDiagonal(bool);\n" + "bvec2 subgroupQuadSwapDiagonal(bvec2);\n" + "bvec3 subgroupQuadSwapDiagonal(bvec3);\n" + "bvec4 subgroupQuadSwapDiagonal(bvec4);\n" + +#ifdef NV_EXTENSIONS + "uvec4 subgroupPartitionNV(float);\n" + "uvec4 subgroupPartitionNV(vec2);\n" + "uvec4 subgroupPartitionNV(vec3);\n" + "uvec4 subgroupPartitionNV(vec4);\n" + "uvec4 subgroupPartitionNV(int);\n" + "uvec4 subgroupPartitionNV(ivec2);\n" + "uvec4 subgroupPartitionNV(ivec3);\n" + "uvec4 subgroupPartitionNV(ivec4);\n" + "uvec4 subgroupPartitionNV(uint);\n" + "uvec4 subgroupPartitionNV(uvec2);\n" + "uvec4 subgroupPartitionNV(uvec3);\n" + "uvec4 subgroupPartitionNV(uvec4);\n" + "uvec4 subgroupPartitionNV(bool);\n" + "uvec4 subgroupPartitionNV(bvec2);\n" + "uvec4 subgroupPartitionNV(bvec3);\n" + "uvec4 subgroupPartitionNV(bvec4);\n" + + "float subgroupPartitionedAddNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedAddNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedAddNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedAddNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedAddNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedAddNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedAddNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedAddNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedAddNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedAddNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedAddNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedAddNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedMulNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedMulNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedMulNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedMulNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedMulNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedMulNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedMulNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedMulNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedMulNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedMulNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedMulNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedMulNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedMinNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedMinNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedMinNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedMinNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedMinNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedMinNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedMinNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedMinNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedMinNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedMinNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedMinNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedMinNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedMaxNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedMaxNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedMaxNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedMaxNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedMaxNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedMaxNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedMaxNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedMaxNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedMaxNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedMaxNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedMaxNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedMaxNV(uvec4, uvec4 ballot);\n" + + "int subgroupPartitionedAndNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedAndNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedAndNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedAndNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedAndNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedAndNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedAndNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedAndNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedAndNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedAndNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedAndNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedAndNV(bvec4, uvec4 ballot);\n" + + "int subgroupPartitionedOrNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedOrNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedOrNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedOrNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedOrNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedOrNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedOrNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedOrNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedOrNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedOrNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedOrNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedOrNV(bvec4, uvec4 ballot);\n" + + "int subgroupPartitionedXorNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedXorNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedXorNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedXorNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedXorNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedXorNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedXorNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedXorNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedXorNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedXorNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedXorNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedXorNV(bvec4, uvec4 ballot);\n" + + "float subgroupPartitionedInclusiveAddNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedInclusiveAddNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedInclusiveAddNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedInclusiveAddNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedInclusiveAddNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveAddNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveAddNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveAddNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveAddNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveAddNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveAddNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveAddNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedInclusiveMulNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedInclusiveMulNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedInclusiveMulNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedInclusiveMulNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedInclusiveMulNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveMulNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveMulNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveMulNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveMulNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveMulNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveMulNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveMulNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedInclusiveMinNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedInclusiveMinNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedInclusiveMinNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedInclusiveMinNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedInclusiveMinNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveMinNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveMinNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveMinNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveMinNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveMinNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveMinNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveMinNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedInclusiveMaxNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedInclusiveMaxNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedInclusiveMaxNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedInclusiveMaxNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedInclusiveMaxNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveMaxNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveMaxNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveMaxNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveMaxNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveMaxNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveMaxNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveMaxNV(uvec4, uvec4 ballot);\n" + + "int subgroupPartitionedInclusiveAndNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveAndNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveAndNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveAndNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveAndNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveAndNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveAndNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveAndNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedInclusiveAndNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedInclusiveAndNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedInclusiveAndNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedInclusiveAndNV(bvec4, uvec4 ballot);\n" + + "int subgroupPartitionedInclusiveOrNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveOrNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveOrNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveOrNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveOrNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveOrNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveOrNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveOrNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedInclusiveOrNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedInclusiveOrNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedInclusiveOrNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedInclusiveOrNV(bvec4, uvec4 ballot);\n" + + "int subgroupPartitionedInclusiveXorNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedInclusiveXorNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedInclusiveXorNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedInclusiveXorNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedInclusiveXorNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedInclusiveXorNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedInclusiveXorNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedInclusiveXorNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedInclusiveXorNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedInclusiveXorNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedInclusiveXorNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedInclusiveXorNV(bvec4, uvec4 ballot);\n" + + "float subgroupPartitionedExclusiveAddNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedExclusiveAddNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedExclusiveAddNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedExclusiveAddNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedExclusiveAddNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveAddNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveAddNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveAddNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveAddNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveAddNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveAddNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveAddNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedExclusiveMulNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedExclusiveMulNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedExclusiveMulNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedExclusiveMulNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedExclusiveMulNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveMulNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveMulNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveMulNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveMulNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveMulNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveMulNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveMulNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedExclusiveMinNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedExclusiveMinNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedExclusiveMinNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedExclusiveMinNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedExclusiveMinNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveMinNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveMinNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveMinNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveMinNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveMinNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveMinNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveMinNV(uvec4, uvec4 ballot);\n" + + "float subgroupPartitionedExclusiveMaxNV(float, uvec4 ballot);\n" + "vec2 subgroupPartitionedExclusiveMaxNV(vec2, uvec4 ballot);\n" + "vec3 subgroupPartitionedExclusiveMaxNV(vec3, uvec4 ballot);\n" + "vec4 subgroupPartitionedExclusiveMaxNV(vec4, uvec4 ballot);\n" + "int subgroupPartitionedExclusiveMaxNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveMaxNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveMaxNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveMaxNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveMaxNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveMaxNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveMaxNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveMaxNV(uvec4, uvec4 ballot);\n" + + "int subgroupPartitionedExclusiveAndNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveAndNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveAndNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveAndNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveAndNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveAndNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveAndNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveAndNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedExclusiveAndNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedExclusiveAndNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedExclusiveAndNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedExclusiveAndNV(bvec4, uvec4 ballot);\n" + + "int subgroupPartitionedExclusiveOrNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveOrNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveOrNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveOrNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveOrNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveOrNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveOrNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveOrNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedExclusiveOrNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedExclusiveOrNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedExclusiveOrNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedExclusiveOrNV(bvec4, uvec4 ballot);\n" + + "int subgroupPartitionedExclusiveXorNV(int, uvec4 ballot);\n" + "ivec2 subgroupPartitionedExclusiveXorNV(ivec2, uvec4 ballot);\n" + "ivec3 subgroupPartitionedExclusiveXorNV(ivec3, uvec4 ballot);\n" + "ivec4 subgroupPartitionedExclusiveXorNV(ivec4, uvec4 ballot);\n" + "uint subgroupPartitionedExclusiveXorNV(uint, uvec4 ballot);\n" + "uvec2 subgroupPartitionedExclusiveXorNV(uvec2, uvec4 ballot);\n" + "uvec3 subgroupPartitionedExclusiveXorNV(uvec3, uvec4 ballot);\n" + "uvec4 subgroupPartitionedExclusiveXorNV(uvec4, uvec4 ballot);\n" + "bool subgroupPartitionedExclusiveXorNV(bool, uvec4 ballot);\n" + "bvec2 subgroupPartitionedExclusiveXorNV(bvec2, uvec4 ballot);\n" + "bvec3 subgroupPartitionedExclusiveXorNV(bvec3, uvec4 ballot);\n" + "bvec4 subgroupPartitionedExclusiveXorNV(bvec4, uvec4 ballot);\n" +#endif + + "\n"); + + if (profile != EEsProfile && version >= 400) { + commonBuiltins.append( + "bool subgroupAllEqual(double);\n" + "bool subgroupAllEqual(dvec2);\n" + "bool subgroupAllEqual(dvec3);\n" + "bool subgroupAllEqual(dvec4);\n" + + "double subgroupBroadcast(double, uint);\n" + "dvec2 subgroupBroadcast(dvec2, uint);\n" + "dvec3 subgroupBroadcast(dvec3, uint);\n" + "dvec4 subgroupBroadcast(dvec4, uint);\n" + + "double subgroupBroadcastFirst(double);\n" + "dvec2 subgroupBroadcastFirst(dvec2);\n" + "dvec3 subgroupBroadcastFirst(dvec3);\n" + "dvec4 subgroupBroadcastFirst(dvec4);\n" + + "double subgroupShuffle(double, uint);\n" + "dvec2 subgroupShuffle(dvec2, uint);\n" + "dvec3 subgroupShuffle(dvec3, uint);\n" + "dvec4 subgroupShuffle(dvec4, uint);\n" + + "double subgroupShuffleXor(double, uint);\n" + "dvec2 subgroupShuffleXor(dvec2, uint);\n" + "dvec3 subgroupShuffleXor(dvec3, uint);\n" + "dvec4 subgroupShuffleXor(dvec4, uint);\n" + + "double subgroupShuffleUp(double, uint delta);\n" + "dvec2 subgroupShuffleUp(dvec2, uint delta);\n" + "dvec3 subgroupShuffleUp(dvec3, uint delta);\n" + "dvec4 subgroupShuffleUp(dvec4, uint delta);\n" + + "double subgroupShuffleDown(double, uint delta);\n" + "dvec2 subgroupShuffleDown(dvec2, uint delta);\n" + "dvec3 subgroupShuffleDown(dvec3, uint delta);\n" + "dvec4 subgroupShuffleDown(dvec4, uint delta);\n" + + "double subgroupAdd(double);\n" + "dvec2 subgroupAdd(dvec2);\n" + "dvec3 subgroupAdd(dvec3);\n" + "dvec4 subgroupAdd(dvec4);\n" + + "double subgroupMul(double);\n" + "dvec2 subgroupMul(dvec2);\n" + "dvec3 subgroupMul(dvec3);\n" + "dvec4 subgroupMul(dvec4);\n" + + "double subgroupMin(double);\n" + "dvec2 subgroupMin(dvec2);\n" + "dvec3 subgroupMin(dvec3);\n" + "dvec4 subgroupMin(dvec4);\n" + + "double subgroupMax(double);\n" + "dvec2 subgroupMax(dvec2);\n" + "dvec3 subgroupMax(dvec3);\n" + "dvec4 subgroupMax(dvec4);\n" + + "double subgroupInclusiveAdd(double);\n" + "dvec2 subgroupInclusiveAdd(dvec2);\n" + "dvec3 subgroupInclusiveAdd(dvec3);\n" + "dvec4 subgroupInclusiveAdd(dvec4);\n" + + "double subgroupInclusiveMul(double);\n" + "dvec2 subgroupInclusiveMul(dvec2);\n" + "dvec3 subgroupInclusiveMul(dvec3);\n" + "dvec4 subgroupInclusiveMul(dvec4);\n" + + "double subgroupInclusiveMin(double);\n" + "dvec2 subgroupInclusiveMin(dvec2);\n" + "dvec3 subgroupInclusiveMin(dvec3);\n" + "dvec4 subgroupInclusiveMin(dvec4);\n" + + "double subgroupInclusiveMax(double);\n" + "dvec2 subgroupInclusiveMax(dvec2);\n" + "dvec3 subgroupInclusiveMax(dvec3);\n" + "dvec4 subgroupInclusiveMax(dvec4);\n" + + "double subgroupExclusiveAdd(double);\n" + "dvec2 subgroupExclusiveAdd(dvec2);\n" + "dvec3 subgroupExclusiveAdd(dvec3);\n" + "dvec4 subgroupExclusiveAdd(dvec4);\n" + + "double subgroupExclusiveMul(double);\n" + "dvec2 subgroupExclusiveMul(dvec2);\n" + "dvec3 subgroupExclusiveMul(dvec3);\n" + "dvec4 subgroupExclusiveMul(dvec4);\n" + + "double subgroupExclusiveMin(double);\n" + "dvec2 subgroupExclusiveMin(dvec2);\n" + "dvec3 subgroupExclusiveMin(dvec3);\n" + "dvec4 subgroupExclusiveMin(dvec4);\n" + + "double subgroupExclusiveMax(double);\n" + "dvec2 subgroupExclusiveMax(dvec2);\n" + "dvec3 subgroupExclusiveMax(dvec3);\n" + "dvec4 subgroupExclusiveMax(dvec4);\n" + + "double subgroupClusteredAdd(double, uint);\n" + "dvec2 subgroupClusteredAdd(dvec2, uint);\n" + "dvec3 subgroupClusteredAdd(dvec3, uint);\n" + "dvec4 subgroupClusteredAdd(dvec4, uint);\n" + + "double subgroupClusteredMul(double, uint);\n" + "dvec2 subgroupClusteredMul(dvec2, uint);\n" + "dvec3 subgroupClusteredMul(dvec3, uint);\n" + "dvec4 subgroupClusteredMul(dvec4, uint);\n" + + "double subgroupClusteredMin(double, uint);\n" + "dvec2 subgroupClusteredMin(dvec2, uint);\n" + "dvec3 subgroupClusteredMin(dvec3, uint);\n" + "dvec4 subgroupClusteredMin(dvec4, uint);\n" + + "double subgroupClusteredMax(double, uint);\n" + "dvec2 subgroupClusteredMax(dvec2, uint);\n" + "dvec3 subgroupClusteredMax(dvec3, uint);\n" + "dvec4 subgroupClusteredMax(dvec4, uint);\n" + + "double subgroupQuadBroadcast(double, uint);\n" + "dvec2 subgroupQuadBroadcast(dvec2, uint);\n" + "dvec3 subgroupQuadBroadcast(dvec3, uint);\n" + "dvec4 subgroupQuadBroadcast(dvec4, uint);\n" + + "double subgroupQuadSwapHorizontal(double);\n" + "dvec2 subgroupQuadSwapHorizontal(dvec2);\n" + "dvec3 subgroupQuadSwapHorizontal(dvec3);\n" + "dvec4 subgroupQuadSwapHorizontal(dvec4);\n" + + "double subgroupQuadSwapVertical(double);\n" + "dvec2 subgroupQuadSwapVertical(dvec2);\n" + "dvec3 subgroupQuadSwapVertical(dvec3);\n" + "dvec4 subgroupQuadSwapVertical(dvec4);\n" + + "double subgroupQuadSwapDiagonal(double);\n" + "dvec2 subgroupQuadSwapDiagonal(dvec2);\n" + "dvec3 subgroupQuadSwapDiagonal(dvec3);\n" + "dvec4 subgroupQuadSwapDiagonal(dvec4);\n" + + +#ifdef NV_EXTENSIONS + "uvec4 subgroupPartitionNV(double);\n" + "uvec4 subgroupPartitionNV(dvec2);\n" + "uvec4 subgroupPartitionNV(dvec3);\n" + "uvec4 subgroupPartitionNV(dvec4);\n" + + "double subgroupPartitionedAddNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedAddNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedAddNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedAddNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedMulNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedMulNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedMulNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedMulNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedMinNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedMinNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedMinNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedMinNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedMaxNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedMaxNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedMaxNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedMaxNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedInclusiveAddNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedInclusiveAddNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedInclusiveAddNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedInclusiveAddNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedInclusiveMulNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedInclusiveMulNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedInclusiveMulNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedInclusiveMulNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedInclusiveMinNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedInclusiveMinNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedInclusiveMinNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedInclusiveMinNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedInclusiveMaxNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedInclusiveMaxNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedInclusiveMaxNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedInclusiveMaxNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedExclusiveAddNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedExclusiveAddNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedExclusiveAddNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedExclusiveAddNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedExclusiveMulNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedExclusiveMulNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedExclusiveMulNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedExclusiveMulNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedExclusiveMinNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedExclusiveMinNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedExclusiveMinNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedExclusiveMinNV(dvec4, uvec4 ballot);\n" + + "double subgroupPartitionedExclusiveMaxNV(double, uvec4 ballot);\n" + "dvec2 subgroupPartitionedExclusiveMaxNV(dvec2, uvec4 ballot);\n" + "dvec3 subgroupPartitionedExclusiveMaxNV(dvec3, uvec4 ballot);\n" + "dvec4 subgroupPartitionedExclusiveMaxNV(dvec4, uvec4 ballot);\n" +#endif + + "\n"); + } + + stageBuiltins[EShLangCompute].append( + "void subgroupMemoryBarrierShared();" + + "\n" + ); +#ifdef NV_EXTENSIONS + stageBuiltins[EShLangMeshNV].append( + "void subgroupMemoryBarrierShared();" + "\n" + ); + stageBuiltins[EShLangTaskNV].append( + "void subgroupMemoryBarrierShared();" + "\n" + ); +#endif + } + if (profile != EEsProfile && version >= 460) { commonBuiltins.append( "bool anyInvocation(bool);" @@ -1681,6 +3018,16 @@ "f16vec3 minInvocationsAMD(f16vec3);" "f16vec4 minInvocationsAMD(f16vec4);" + "int16_t minInvocationsAMD(int16_t);" + "i16vec2 minInvocationsAMD(i16vec2);" + "i16vec3 minInvocationsAMD(i16vec3);" + "i16vec4 minInvocationsAMD(i16vec4);" + + "uint16_t minInvocationsAMD(uint16_t);" + "u16vec2 minInvocationsAMD(u16vec2);" + "u16vec3 minInvocationsAMD(u16vec3);" + "u16vec4 minInvocationsAMD(u16vec4);" + "float minInvocationsInclusiveScanAMD(float);" "vec2 minInvocationsInclusiveScanAMD(vec2);" "vec3 minInvocationsInclusiveScanAMD(vec3);" @@ -1716,6 +3063,16 @@ "f16vec3 minInvocationsInclusiveScanAMD(f16vec3);" "f16vec4 minInvocationsInclusiveScanAMD(f16vec4);" + "int16_t minInvocationsInclusiveScanAMD(int16_t);" + "i16vec2 minInvocationsInclusiveScanAMD(i16vec2);" + "i16vec3 minInvocationsInclusiveScanAMD(i16vec3);" + "i16vec4 minInvocationsInclusiveScanAMD(i16vec4);" + + "uint16_t minInvocationsInclusiveScanAMD(uint16_t);" + "u16vec2 minInvocationsInclusiveScanAMD(u16vec2);" + "u16vec3 minInvocationsInclusiveScanAMD(u16vec3);" + "u16vec4 minInvocationsInclusiveScanAMD(u16vec4);" + "float minInvocationsExclusiveScanAMD(float);" "vec2 minInvocationsExclusiveScanAMD(vec2);" "vec3 minInvocationsExclusiveScanAMD(vec3);" @@ -1751,6 +3108,16 @@ "f16vec3 minInvocationsExclusiveScanAMD(f16vec3);" "f16vec4 minInvocationsExclusiveScanAMD(f16vec4);" + "int16_t minInvocationsExclusiveScanAMD(int16_t);" + "i16vec2 minInvocationsExclusiveScanAMD(i16vec2);" + "i16vec3 minInvocationsExclusiveScanAMD(i16vec3);" + "i16vec4 minInvocationsExclusiveScanAMD(i16vec4);" + + "uint16_t minInvocationsExclusiveScanAMD(uint16_t);" + "u16vec2 minInvocationsExclusiveScanAMD(u16vec2);" + "u16vec3 minInvocationsExclusiveScanAMD(u16vec3);" + "u16vec4 minInvocationsExclusiveScanAMD(u16vec4);" + "float maxInvocationsAMD(float);" "vec2 maxInvocationsAMD(vec2);" "vec3 maxInvocationsAMD(vec3);" @@ -1786,6 +3153,16 @@ "f16vec3 maxInvocationsAMD(f16vec3);" "f16vec4 maxInvocationsAMD(f16vec4);" + "int16_t maxInvocationsAMD(int16_t);" + "i16vec2 maxInvocationsAMD(i16vec2);" + "i16vec3 maxInvocationsAMD(i16vec3);" + "i16vec4 maxInvocationsAMD(i16vec4);" + + "uint16_t maxInvocationsAMD(uint16_t);" + "u16vec2 maxInvocationsAMD(u16vec2);" + "u16vec3 maxInvocationsAMD(u16vec3);" + "u16vec4 maxInvocationsAMD(u16vec4);" + "float maxInvocationsInclusiveScanAMD(float);" "vec2 maxInvocationsInclusiveScanAMD(vec2);" "vec3 maxInvocationsInclusiveScanAMD(vec3);" @@ -1821,6 +3198,16 @@ "f16vec3 maxInvocationsInclusiveScanAMD(f16vec3);" "f16vec4 maxInvocationsInclusiveScanAMD(f16vec4);" + "int16_t maxInvocationsInclusiveScanAMD(int16_t);" + "i16vec2 maxInvocationsInclusiveScanAMD(i16vec2);" + "i16vec3 maxInvocationsInclusiveScanAMD(i16vec3);" + "i16vec4 maxInvocationsInclusiveScanAMD(i16vec4);" + + "uint16_t maxInvocationsInclusiveScanAMD(uint16_t);" + "u16vec2 maxInvocationsInclusiveScanAMD(u16vec2);" + "u16vec3 maxInvocationsInclusiveScanAMD(u16vec3);" + "u16vec4 maxInvocationsInclusiveScanAMD(u16vec4);" + "float maxInvocationsExclusiveScanAMD(float);" "vec2 maxInvocationsExclusiveScanAMD(vec2);" "vec3 maxInvocationsExclusiveScanAMD(vec3);" @@ -1856,6 +3243,16 @@ "f16vec3 maxInvocationsExclusiveScanAMD(f16vec3);" "f16vec4 maxInvocationsExclusiveScanAMD(f16vec4);" + "int16_t maxInvocationsExclusiveScanAMD(int16_t);" + "i16vec2 maxInvocationsExclusiveScanAMD(i16vec2);" + "i16vec3 maxInvocationsExclusiveScanAMD(i16vec3);" + "i16vec4 maxInvocationsExclusiveScanAMD(i16vec4);" + + "uint16_t maxInvocationsExclusiveScanAMD(uint16_t);" + "u16vec2 maxInvocationsExclusiveScanAMD(u16vec2);" + "u16vec3 maxInvocationsExclusiveScanAMD(u16vec3);" + "u16vec4 maxInvocationsExclusiveScanAMD(u16vec4);" + "float addInvocationsAMD(float);" "vec2 addInvocationsAMD(vec2);" "vec3 addInvocationsAMD(vec3);" @@ -1891,6 +3288,16 @@ "f16vec3 addInvocationsAMD(f16vec3);" "f16vec4 addInvocationsAMD(f16vec4);" + "int16_t addInvocationsAMD(int16_t);" + "i16vec2 addInvocationsAMD(i16vec2);" + "i16vec3 addInvocationsAMD(i16vec3);" + "i16vec4 addInvocationsAMD(i16vec4);" + + "uint16_t addInvocationsAMD(uint16_t);" + "u16vec2 addInvocationsAMD(u16vec2);" + "u16vec3 addInvocationsAMD(u16vec3);" + "u16vec4 addInvocationsAMD(u16vec4);" + "float addInvocationsInclusiveScanAMD(float);" "vec2 addInvocationsInclusiveScanAMD(vec2);" "vec3 addInvocationsInclusiveScanAMD(vec3);" @@ -1926,6 +3333,16 @@ "f16vec3 addInvocationsInclusiveScanAMD(f16vec3);" "f16vec4 addInvocationsInclusiveScanAMD(f16vec4);" + "int16_t addInvocationsInclusiveScanAMD(int16_t);" + "i16vec2 addInvocationsInclusiveScanAMD(i16vec2);" + "i16vec3 addInvocationsInclusiveScanAMD(i16vec3);" + "i16vec4 addInvocationsInclusiveScanAMD(i16vec4);" + + "uint16_t addInvocationsInclusiveScanAMD(uint16_t);" + "u16vec2 addInvocationsInclusiveScanAMD(u16vec2);" + "u16vec3 addInvocationsInclusiveScanAMD(u16vec3);" + "u16vec4 addInvocationsInclusiveScanAMD(u16vec4);" + "float addInvocationsExclusiveScanAMD(float);" "vec2 addInvocationsExclusiveScanAMD(vec2);" "vec3 addInvocationsExclusiveScanAMD(vec3);" @@ -1961,6 +3378,16 @@ "f16vec3 addInvocationsExclusiveScanAMD(f16vec3);" "f16vec4 addInvocationsExclusiveScanAMD(f16vec4);" + "int16_t addInvocationsExclusiveScanAMD(int16_t);" + "i16vec2 addInvocationsExclusiveScanAMD(i16vec2);" + "i16vec3 addInvocationsExclusiveScanAMD(i16vec3);" + "i16vec4 addInvocationsExclusiveScanAMD(i16vec4);" + + "uint16_t addInvocationsExclusiveScanAMD(uint16_t);" + "u16vec2 addInvocationsExclusiveScanAMD(u16vec2);" + "u16vec3 addInvocationsExclusiveScanAMD(u16vec3);" + "u16vec4 addInvocationsExclusiveScanAMD(u16vec4);" + "float minInvocationsNonUniformAMD(float);" "vec2 minInvocationsNonUniformAMD(vec2);" "vec3 minInvocationsNonUniformAMD(vec3);" @@ -1996,6 +3423,16 @@ "f16vec3 minInvocationsNonUniformAMD(f16vec3);" "f16vec4 minInvocationsNonUniformAMD(f16vec4);" + "int16_t minInvocationsNonUniformAMD(int16_t);" + "i16vec2 minInvocationsNonUniformAMD(i16vec2);" + "i16vec3 minInvocationsNonUniformAMD(i16vec3);" + "i16vec4 minInvocationsNonUniformAMD(i16vec4);" + + "uint16_t minInvocationsNonUniformAMD(uint16_t);" + "u16vec2 minInvocationsNonUniformAMD(u16vec2);" + "u16vec3 minInvocationsNonUniformAMD(u16vec3);" + "u16vec4 minInvocationsNonUniformAMD(u16vec4);" + "float minInvocationsInclusiveScanNonUniformAMD(float);" "vec2 minInvocationsInclusiveScanNonUniformAMD(vec2);" "vec3 minInvocationsInclusiveScanNonUniformAMD(vec3);" @@ -2031,6 +3468,16 @@ "f16vec3 minInvocationsInclusiveScanNonUniformAMD(f16vec3);" "f16vec4 minInvocationsInclusiveScanNonUniformAMD(f16vec4);" + "int16_t minInvocationsInclusiveScanNonUniformAMD(int16_t);" + "i16vec2 minInvocationsInclusiveScanNonUniformAMD(i16vec2);" + "i16vec3 minInvocationsInclusiveScanNonUniformAMD(i16vec3);" + "i16vec4 minInvocationsInclusiveScanNonUniformAMD(i16vec4);" + + "uint16_t minInvocationsInclusiveScanNonUniformAMD(uint16_t);" + "u16vec2 minInvocationsInclusiveScanNonUniformAMD(u16vec2);" + "u16vec3 minInvocationsInclusiveScanNonUniformAMD(u16vec3);" + "u16vec4 minInvocationsInclusiveScanNonUniformAMD(u16vec4);" + "float minInvocationsExclusiveScanNonUniformAMD(float);" "vec2 minInvocationsExclusiveScanNonUniformAMD(vec2);" "vec3 minInvocationsExclusiveScanNonUniformAMD(vec3);" @@ -2066,6 +3513,16 @@ "f16vec3 minInvocationsExclusiveScanNonUniformAMD(f16vec3);" "f16vec4 minInvocationsExclusiveScanNonUniformAMD(f16vec4);" + "int16_t minInvocationsExclusiveScanNonUniformAMD(int16_t);" + "i16vec2 minInvocationsExclusiveScanNonUniformAMD(i16vec2);" + "i16vec3 minInvocationsExclusiveScanNonUniformAMD(i16vec3);" + "i16vec4 minInvocationsExclusiveScanNonUniformAMD(i16vec4);" + + "uint16_t minInvocationsExclusiveScanNonUniformAMD(uint16_t);" + "u16vec2 minInvocationsExclusiveScanNonUniformAMD(u16vec2);" + "u16vec3 minInvocationsExclusiveScanNonUniformAMD(u16vec3);" + "u16vec4 minInvocationsExclusiveScanNonUniformAMD(u16vec4);" + "float maxInvocationsNonUniformAMD(float);" "vec2 maxInvocationsNonUniformAMD(vec2);" "vec3 maxInvocationsNonUniformAMD(vec3);" @@ -2101,6 +3558,16 @@ "f16vec3 maxInvocationsNonUniformAMD(f16vec3);" "f16vec4 maxInvocationsNonUniformAMD(f16vec4);" + "int16_t maxInvocationsNonUniformAMD(int16_t);" + "i16vec2 maxInvocationsNonUniformAMD(i16vec2);" + "i16vec3 maxInvocationsNonUniformAMD(i16vec3);" + "i16vec4 maxInvocationsNonUniformAMD(i16vec4);" + + "uint16_t maxInvocationsNonUniformAMD(uint16_t);" + "u16vec2 maxInvocationsNonUniformAMD(u16vec2);" + "u16vec3 maxInvocationsNonUniformAMD(u16vec3);" + "u16vec4 maxInvocationsNonUniformAMD(u16vec4);" + "float maxInvocationsInclusiveScanNonUniformAMD(float);" "vec2 maxInvocationsInclusiveScanNonUniformAMD(vec2);" "vec3 maxInvocationsInclusiveScanNonUniformAMD(vec3);" @@ -2136,6 +3603,16 @@ "f16vec3 maxInvocationsInclusiveScanNonUniformAMD(f16vec3);" "f16vec4 maxInvocationsInclusiveScanNonUniformAMD(f16vec4);" + "int16_t maxInvocationsInclusiveScanNonUniformAMD(int16_t);" + "i16vec2 maxInvocationsInclusiveScanNonUniformAMD(i16vec2);" + "i16vec3 maxInvocationsInclusiveScanNonUniformAMD(i16vec3);" + "i16vec4 maxInvocationsInclusiveScanNonUniformAMD(i16vec4);" + + "uint16_t maxInvocationsInclusiveScanNonUniformAMD(uint16_t);" + "u16vec2 maxInvocationsInclusiveScanNonUniformAMD(u16vec2);" + "u16vec3 maxInvocationsInclusiveScanNonUniformAMD(u16vec3);" + "u16vec4 maxInvocationsInclusiveScanNonUniformAMD(u16vec4);" + "float maxInvocationsExclusiveScanNonUniformAMD(float);" "vec2 maxInvocationsExclusiveScanNonUniformAMD(vec2);" "vec3 maxInvocationsExclusiveScanNonUniformAMD(vec3);" @@ -2171,6 +3648,16 @@ "f16vec3 maxInvocationsExclusiveScanNonUniformAMD(f16vec3);" "f16vec4 maxInvocationsExclusiveScanNonUniformAMD(f16vec4);" + "int16_t maxInvocationsExclusiveScanNonUniformAMD(int16_t);" + "i16vec2 maxInvocationsExclusiveScanNonUniformAMD(i16vec2);" + "i16vec3 maxInvocationsExclusiveScanNonUniformAMD(i16vec3);" + "i16vec4 maxInvocationsExclusiveScanNonUniformAMD(i16vec4);" + + "uint16_t maxInvocationsExclusiveScanNonUniformAMD(uint16_t);" + "u16vec2 maxInvocationsExclusiveScanNonUniformAMD(u16vec2);" + "u16vec3 maxInvocationsExclusiveScanNonUniformAMD(u16vec3);" + "u16vec4 maxInvocationsExclusiveScanNonUniformAMD(u16vec4);" + "float addInvocationsNonUniformAMD(float);" "vec2 addInvocationsNonUniformAMD(vec2);" "vec3 addInvocationsNonUniformAMD(vec3);" @@ -2206,6 +3693,16 @@ "f16vec3 addInvocationsNonUniformAMD(f16vec3);" "f16vec4 addInvocationsNonUniformAMD(f16vec4);" + "int16_t addInvocationsNonUniformAMD(int16_t);" + "i16vec2 addInvocationsNonUniformAMD(i16vec2);" + "i16vec3 addInvocationsNonUniformAMD(i16vec3);" + "i16vec4 addInvocationsNonUniformAMD(i16vec4);" + + "uint16_t addInvocationsNonUniformAMD(uint16_t);" + "u16vec2 addInvocationsNonUniformAMD(u16vec2);" + "u16vec3 addInvocationsNonUniformAMD(u16vec3);" + "u16vec4 addInvocationsNonUniformAMD(u16vec4);" + "float addInvocationsInclusiveScanNonUniformAMD(float);" "vec2 addInvocationsInclusiveScanNonUniformAMD(vec2);" "vec3 addInvocationsInclusiveScanNonUniformAMD(vec3);" @@ -2241,6 +3738,16 @@ "f16vec3 addInvocationsInclusiveScanNonUniformAMD(f16vec3);" "f16vec4 addInvocationsInclusiveScanNonUniformAMD(f16vec4);" + "int16_t addInvocationsInclusiveScanNonUniformAMD(int16_t);" + "i16vec2 addInvocationsInclusiveScanNonUniformAMD(i16vec2);" + "i16vec3 addInvocationsInclusiveScanNonUniformAMD(i16vec3);" + "i16vec4 addInvocationsInclusiveScanNonUniformAMD(i16vec4);" + + "uint16_t addInvocationsInclusiveScanNonUniformAMD(uint16_t);" + "u16vec2 addInvocationsInclusiveScanNonUniformAMD(u16vec2);" + "u16vec3 addInvocationsInclusiveScanNonUniformAMD(u16vec3);" + "u16vec4 addInvocationsInclusiveScanNonUniformAMD(u16vec4);" + "float addInvocationsExclusiveScanNonUniformAMD(float);" "vec2 addInvocationsExclusiveScanNonUniformAMD(vec2);" "vec3 addInvocationsExclusiveScanNonUniformAMD(vec3);" @@ -2276,6 +3783,16 @@ "f16vec3 addInvocationsExclusiveScanNonUniformAMD(f16vec3);" "f16vec4 addInvocationsExclusiveScanNonUniformAMD(f16vec4);" + "int16_t addInvocationsExclusiveScanNonUniformAMD(int16_t);" + "i16vec2 addInvocationsExclusiveScanNonUniformAMD(i16vec2);" + "i16vec3 addInvocationsExclusiveScanNonUniformAMD(i16vec3);" + "i16vec4 addInvocationsExclusiveScanNonUniformAMD(i16vec4);" + + "uint16_t addInvocationsExclusiveScanNonUniformAMD(uint16_t);" + "u16vec2 addInvocationsExclusiveScanNonUniformAMD(u16vec2);" + "u16vec3 addInvocationsExclusiveScanNonUniformAMD(u16vec3);" + "u16vec4 addInvocationsExclusiveScanNonUniformAMD(u16vec4);" + "float swizzleInvocationsAMD(float, uvec4);" "vec2 swizzleInvocationsAMD(vec2, uvec4);" "vec3 swizzleInvocationsAMD(vec3, uvec4);" @@ -2336,7 +3853,67 @@ "\n"); } - // GL_AMD_gpu_shader_half_float + // GL_AMD_shader_fragment_mask + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uint fragmentMaskFetchAMD(sampler2DMS, ivec2);" + "uint fragmentMaskFetchAMD(isampler2DMS, ivec2);" + "uint fragmentMaskFetchAMD(usampler2DMS, ivec2);" + + "uint fragmentMaskFetchAMD(sampler2DMSArray, ivec3);" + "uint fragmentMaskFetchAMD(isampler2DMSArray, ivec3);" + "uint fragmentMaskFetchAMD(usampler2DMSArray, ivec3);" + + "vec4 fragmentFetchAMD(sampler2DMS, ivec2, uint);" + "ivec4 fragmentFetchAMD(isampler2DMS, ivec2, uint);" + "uvec4 fragmentFetchAMD(usampler2DMS, ivec2, uint);" + + "vec4 fragmentFetchAMD(sampler2DMSArray, ivec3, uint);" + "ivec4 fragmentFetchAMD(isampler2DMSArray, ivec3, uint);" + "uvec4 fragmentFetchAMD(usampler2DMSArray, ivec3, uint);" + + "\n"); + } + +#endif // AMD_EXTENSIONS + + +#ifdef NV_EXTENSIONS + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 320)) { + commonBuiltins.append( + "struct gl_TextureFootprint2DNV {" + "uvec2 anchor;" + "uvec2 offset;" + "uvec2 mask;" + "uint lod;" + "uint granularity;" + "};" + + "struct gl_TextureFootprint3DNV {" + "uvec3 anchor;" + "uvec3 offset;" + "uvec2 mask;" + "uint lod;" + "uint granularity;" + "};" + "bool textureFootprintNV(sampler2D, vec2, int, bool, out gl_TextureFootprint2DNV);" + "bool textureFootprintNV(sampler3D, vec3, int, bool, out gl_TextureFootprint3DNV);" + "bool textureFootprintNV(sampler2D, vec2, int, bool, out gl_TextureFootprint2DNV, float);" + "bool textureFootprintNV(sampler3D, vec3, int, bool, out gl_TextureFootprint3DNV, float);" + "bool textureFootprintClampNV(sampler2D, vec2, float, int, bool, out gl_TextureFootprint2DNV);" + "bool textureFootprintClampNV(sampler3D, vec3, float, int, bool, out gl_TextureFootprint3DNV);" + "bool textureFootprintClampNV(sampler2D, vec2, float, int, bool, out gl_TextureFootprint2DNV, float);" + "bool textureFootprintClampNV(sampler3D, vec3, float, int, bool, out gl_TextureFootprint3DNV, float);" + "bool textureFootprintLodNV(sampler2D, vec2, float, int, bool, out gl_TextureFootprint2DNV);" + "bool textureFootprintLodNV(sampler3D, vec3, float, int, bool, out gl_TextureFootprint3DNV);" + "bool textureFootprintGradNV(sampler2D, vec2, vec2, vec2, int, bool, out gl_TextureFootprint2DNV);" + "bool textureFootprintGradClampNV(sampler2D, vec2, vec2, vec2, float, int, bool, out gl_TextureFootprint2DNV);" + "\n"); + } + +#endif // NV_EXTENSIONS + // GL_AMD_gpu_shader_half_float/Explicit types if (profile != EEsProfile && version >= 450) { commonBuiltins.append( "float16_t radians(float16_t);" @@ -2684,9 +4261,168 @@ "\n"); } - // GL_AMD_gpu_shader_int16 + // Explicit types if (profile != EEsProfile && version >= 450) { commonBuiltins.append( + "int8_t abs(int8_t);" + "i8vec2 abs(i8vec2);" + "i8vec3 abs(i8vec3);" + "i8vec4 abs(i8vec4);" + + "int8_t sign(int8_t);" + "i8vec2 sign(i8vec2);" + "i8vec3 sign(i8vec3);" + "i8vec4 sign(i8vec4);" + + "int8_t min(int8_t x, int8_t y);" + "i8vec2 min(i8vec2 x, int8_t y);" + "i8vec3 min(i8vec3 x, int8_t y);" + "i8vec4 min(i8vec4 x, int8_t y);" + "i8vec2 min(i8vec2 x, i8vec2 y);" + "i8vec3 min(i8vec3 x, i8vec3 y);" + "i8vec4 min(i8vec4 x, i8vec4 y);" + + "uint8_t min(uint8_t x, uint8_t y);" + "u8vec2 min(u8vec2 x, uint8_t y);" + "u8vec3 min(u8vec3 x, uint8_t y);" + "u8vec4 min(u8vec4 x, uint8_t y);" + "u8vec2 min(u8vec2 x, u8vec2 y);" + "u8vec3 min(u8vec3 x, u8vec3 y);" + "u8vec4 min(u8vec4 x, u8vec4 y);" + + "int8_t max(int8_t x, int8_t y);" + "i8vec2 max(i8vec2 x, int8_t y);" + "i8vec3 max(i8vec3 x, int8_t y);" + "i8vec4 max(i8vec4 x, int8_t y);" + "i8vec2 max(i8vec2 x, i8vec2 y);" + "i8vec3 max(i8vec3 x, i8vec3 y);" + "i8vec4 max(i8vec4 x, i8vec4 y);" + + "uint8_t max(uint8_t x, uint8_t y);" + "u8vec2 max(u8vec2 x, uint8_t y);" + "u8vec3 max(u8vec3 x, uint8_t y);" + "u8vec4 max(u8vec4 x, uint8_t y);" + "u8vec2 max(u8vec2 x, u8vec2 y);" + "u8vec3 max(u8vec3 x, u8vec3 y);" + "u8vec4 max(u8vec4 x, u8vec4 y);" + + "int8_t clamp(int8_t x, int8_t minVal, int8_t maxVal);" + "i8vec2 clamp(i8vec2 x, int8_t minVal, int8_t maxVal);" + "i8vec3 clamp(i8vec3 x, int8_t minVal, int8_t maxVal);" + "i8vec4 clamp(i8vec4 x, int8_t minVal, int8_t maxVal);" + "i8vec2 clamp(i8vec2 x, i8vec2 minVal, i8vec2 maxVal);" + "i8vec3 clamp(i8vec3 x, i8vec3 minVal, i8vec3 maxVal);" + "i8vec4 clamp(i8vec4 x, i8vec4 minVal, i8vec4 maxVal);" + + "uint8_t clamp(uint8_t x, uint8_t minVal, uint8_t maxVal);" + "u8vec2 clamp(u8vec2 x, uint8_t minVal, uint8_t maxVal);" + "u8vec3 clamp(u8vec3 x, uint8_t minVal, uint8_t maxVal);" + "u8vec4 clamp(u8vec4 x, uint8_t minVal, uint8_t maxVal);" + "u8vec2 clamp(u8vec2 x, u8vec2 minVal, u8vec2 maxVal);" + "u8vec3 clamp(u8vec3 x, u8vec3 minVal, u8vec3 maxVal);" + "u8vec4 clamp(u8vec4 x, u8vec4 minVal, u8vec4 maxVal);" + + "int8_t mix(int8_t, int8_t, bool);" + "i8vec2 mix(i8vec2, i8vec2, bvec2);" + "i8vec3 mix(i8vec3, i8vec3, bvec3);" + "i8vec4 mix(i8vec4, i8vec4, bvec4);" + "uint8_t mix(uint8_t, uint8_t, bool);" + "u8vec2 mix(u8vec2, u8vec2, bvec2);" + "u8vec3 mix(u8vec3, u8vec3, bvec3);" + "u8vec4 mix(u8vec4, u8vec4, bvec4);" + + "bvec2 lessThan(i8vec2, i8vec2);" + "bvec3 lessThan(i8vec3, i8vec3);" + "bvec4 lessThan(i8vec4, i8vec4);" + "bvec2 lessThan(u8vec2, u8vec2);" + "bvec3 lessThan(u8vec3, u8vec3);" + "bvec4 lessThan(u8vec4, u8vec4);" + + "bvec2 lessThanEqual(i8vec2, i8vec2);" + "bvec3 lessThanEqual(i8vec3, i8vec3);" + "bvec4 lessThanEqual(i8vec4, i8vec4);" + "bvec2 lessThanEqual(u8vec2, u8vec2);" + "bvec3 lessThanEqual(u8vec3, u8vec3);" + "bvec4 lessThanEqual(u8vec4, u8vec4);" + + "bvec2 greaterThan(i8vec2, i8vec2);" + "bvec3 greaterThan(i8vec3, i8vec3);" + "bvec4 greaterThan(i8vec4, i8vec4);" + "bvec2 greaterThan(u8vec2, u8vec2);" + "bvec3 greaterThan(u8vec3, u8vec3);" + "bvec4 greaterThan(u8vec4, u8vec4);" + + "bvec2 greaterThanEqual(i8vec2, i8vec2);" + "bvec3 greaterThanEqual(i8vec3, i8vec3);" + "bvec4 greaterThanEqual(i8vec4, i8vec4);" + "bvec2 greaterThanEqual(u8vec2, u8vec2);" + "bvec3 greaterThanEqual(u8vec3, u8vec3);" + "bvec4 greaterThanEqual(u8vec4, u8vec4);" + + "bvec2 equal(i8vec2, i8vec2);" + "bvec3 equal(i8vec3, i8vec3);" + "bvec4 equal(i8vec4, i8vec4);" + "bvec2 equal(u8vec2, u8vec2);" + "bvec3 equal(u8vec3, u8vec3);" + "bvec4 equal(u8vec4, u8vec4);" + + "bvec2 notEqual(i8vec2, i8vec2);" + "bvec3 notEqual(i8vec3, i8vec3);" + "bvec4 notEqual(i8vec4, i8vec4);" + "bvec2 notEqual(u8vec2, u8vec2);" + "bvec3 notEqual(u8vec3, u8vec3);" + "bvec4 notEqual(u8vec4, u8vec4);" + + " int8_t bitfieldExtract( int8_t, int8_t, int8_t);" + "i8vec2 bitfieldExtract(i8vec2, int8_t, int8_t);" + "i8vec3 bitfieldExtract(i8vec3, int8_t, int8_t);" + "i8vec4 bitfieldExtract(i8vec4, int8_t, int8_t);" + + " uint8_t bitfieldExtract( uint8_t, int8_t, int8_t);" + "u8vec2 bitfieldExtract(u8vec2, int8_t, int8_t);" + "u8vec3 bitfieldExtract(u8vec3, int8_t, int8_t);" + "u8vec4 bitfieldExtract(u8vec4, int8_t, int8_t);" + + " int8_t bitfieldInsert( int8_t base, int8_t, int8_t, int8_t);" + "i8vec2 bitfieldInsert(i8vec2 base, i8vec2, int8_t, int8_t);" + "i8vec3 bitfieldInsert(i8vec3 base, i8vec3, int8_t, int8_t);" + "i8vec4 bitfieldInsert(i8vec4 base, i8vec4, int8_t, int8_t);" + + " uint8_t bitfieldInsert( uint8_t base, uint8_t, int8_t, int8_t);" + "u8vec2 bitfieldInsert(u8vec2 base, u8vec2, int8_t, int8_t);" + "u8vec3 bitfieldInsert(u8vec3 base, u8vec3, int8_t, int8_t);" + "u8vec4 bitfieldInsert(u8vec4 base, u8vec4, int8_t, int8_t);" + + " int8_t bitCount( int8_t);" + "i8vec2 bitCount(i8vec2);" + "i8vec3 bitCount(i8vec3);" + "i8vec4 bitCount(i8vec4);" + + " int8_t bitCount( uint8_t);" + "i8vec2 bitCount(u8vec2);" + "i8vec3 bitCount(u8vec3);" + "i8vec4 bitCount(u8vec4);" + + " int8_t findLSB( int8_t);" + "i8vec2 findLSB(i8vec2);" + "i8vec3 findLSB(i8vec3);" + "i8vec4 findLSB(i8vec4);" + + " int8_t findLSB( uint8_t);" + "i8vec2 findLSB(u8vec2);" + "i8vec3 findLSB(u8vec3);" + "i8vec4 findLSB(u8vec4);" + + " int8_t findMSB( int8_t);" + "i8vec2 findMSB(i8vec2);" + "i8vec3 findMSB(i8vec3);" + "i8vec4 findMSB(i8vec4);" + + " int8_t findMSB( uint8_t);" + "i8vec2 findMSB(u8vec2);" + "i8vec3 findMSB(u8vec3);" + "i8vec4 findMSB(u8vec4);" + "int16_t abs(int16_t);" "i16vec2 abs(i16vec2);" "i16vec3 abs(i16vec3);" @@ -2697,50 +4433,53 @@ "i16vec3 sign(i16vec3);" "i16vec4 sign(i16vec4);" - "int16_t min(int16_t, int16_t);" - "i16vec2 min(i16vec2, int16_t);" - "i16vec3 min(i16vec3, int16_t);" - "i16vec4 min(i16vec4, int16_t);" - "i16vec2 min(i16vec2, i16vec2);" - "i16vec3 min(i16vec3, i16vec3);" - "i16vec4 min(i16vec4, i16vec4);" - "uint16_t min(uint16_t, uint16_t);" - "u16vec2 min(u16vec2, uint16_t);" - "u16vec3 min(u16vec3, uint16_t);" - "u16vec4 min(u16vec4, uint16_t);" - "u16vec2 min(u16vec2, u16vec2);" - "u16vec3 min(u16vec3, u16vec3);" - "u16vec4 min(u16vec4, u16vec4);" - - "int16_t max(int16_t, int16_t);" - "i16vec2 max(i16vec2, int16_t);" - "i16vec3 max(i16vec3, int16_t);" - "i16vec4 max(i16vec4, int16_t);" - "i16vec2 max(i16vec2, i16vec2);" - "i16vec3 max(i16vec3, i16vec3);" - "i16vec4 max(i16vec4, i16vec4);" - "uint16_t max(uint16_t, uint16_t);" - "u16vec2 max(u16vec2, uint16_t);" - "u16vec3 max(u16vec3, uint16_t);" - "u16vec4 max(u16vec4, uint16_t);" - "u16vec2 max(u16vec2, u16vec2);" - "u16vec3 max(u16vec3, u16vec3);" - "u16vec4 max(u16vec4, u16vec4);" - - "int16_t clamp(int16_t, int16_t, int16_t);" - "i16vec2 clamp(i16vec2, int16_t, int16_t);" - "i16vec3 clamp(i16vec3, int16_t, int16_t);" - "i16vec4 clamp(i16vec4, int16_t, int16_t);" - "i16vec2 clamp(i16vec2, i16vec2, i16vec2);" - "i16vec3 clamp(i16vec3, i16vec3, i16vec3);" - "i16vec4 clamp(i16vec4, i16vec4, i16vec4);" - "uint16_t clamp(uint16_t, uint16_t, uint16_t);" - "u16vec2 clamp(u16vec2, uint16_t, uint16_t);" - "u16vec3 clamp(u16vec3, uint16_t, uint16_t);" - "u16vec4 clamp(u16vec4, uint16_t, uint16_t);" - "u16vec2 clamp(u16vec2, u16vec2, u16vec2);" - "u16vec3 clamp(u16vec3, u16vec3, u16vec3);" - "u16vec4 clamp(u16vec4, u16vec4, u16vec4);" + "int16_t min(int16_t x, int16_t y);" + "i16vec2 min(i16vec2 x, int16_t y);" + "i16vec3 min(i16vec3 x, int16_t y);" + "i16vec4 min(i16vec4 x, int16_t y);" + "i16vec2 min(i16vec2 x, i16vec2 y);" + "i16vec3 min(i16vec3 x, i16vec3 y);" + "i16vec4 min(i16vec4 x, i16vec4 y);" + + "uint16_t min(uint16_t x, uint16_t y);" + "u16vec2 min(u16vec2 x, uint16_t y);" + "u16vec3 min(u16vec3 x, uint16_t y);" + "u16vec4 min(u16vec4 x, uint16_t y);" + "u16vec2 min(u16vec2 x, u16vec2 y);" + "u16vec3 min(u16vec3 x, u16vec3 y);" + "u16vec4 min(u16vec4 x, u16vec4 y);" + + "int16_t max(int16_t x, int16_t y);" + "i16vec2 max(i16vec2 x, int16_t y);" + "i16vec3 max(i16vec3 x, int16_t y);" + "i16vec4 max(i16vec4 x, int16_t y);" + "i16vec2 max(i16vec2 x, i16vec2 y);" + "i16vec3 max(i16vec3 x, i16vec3 y);" + "i16vec4 max(i16vec4 x, i16vec4 y);" + + "uint16_t max(uint16_t x, uint16_t y);" + "u16vec2 max(u16vec2 x, uint16_t y);" + "u16vec3 max(u16vec3 x, uint16_t y);" + "u16vec4 max(u16vec4 x, uint16_t y);" + "u16vec2 max(u16vec2 x, u16vec2 y);" + "u16vec3 max(u16vec3 x, u16vec3 y);" + "u16vec4 max(u16vec4 x, u16vec4 y);" + + "int16_t clamp(int16_t x, int16_t minVal, int16_t maxVal);" + "i16vec2 clamp(i16vec2 x, int16_t minVal, int16_t maxVal);" + "i16vec3 clamp(i16vec3 x, int16_t minVal, int16_t maxVal);" + "i16vec4 clamp(i16vec4 x, int16_t minVal, int16_t maxVal);" + "i16vec2 clamp(i16vec2 x, i16vec2 minVal, i16vec2 maxVal);" + "i16vec3 clamp(i16vec3 x, i16vec3 minVal, i16vec3 maxVal);" + "i16vec4 clamp(i16vec4 x, i16vec4 minVal, i16vec4 maxVal);" + + "uint16_t clamp(uint16_t x, uint16_t minVal, uint16_t maxVal);" + "u16vec2 clamp(u16vec2 x, uint16_t minVal, uint16_t maxVal);" + "u16vec3 clamp(u16vec3 x, uint16_t minVal, uint16_t maxVal);" + "u16vec4 clamp(u16vec4 x, uint16_t minVal, uint16_t maxVal);" + "u16vec2 clamp(u16vec2 x, u16vec2 minVal, u16vec2 maxVal);" + "u16vec3 clamp(u16vec3 x, u16vec3 minVal, u16vec3 maxVal);" + "u16vec4 clamp(u16vec4 x, u16vec4 minVal, u16vec4 maxVal);" "int16_t mix(int16_t, int16_t, bool);" "i16vec2 mix(i16vec2, i16vec2, bvec2);" @@ -2761,6 +4500,16 @@ "f16vec3 ldexp(f16vec3, i16vec3);" "f16vec4 ldexp(f16vec4, i16vec4);" + "int16_t halfBitsToInt16(float16_t);" + "i16vec2 halfBitsToInt16(f16vec2);" + "i16vec3 halhBitsToInt16(f16vec3);" + "i16vec4 halfBitsToInt16(f16vec4);" + + "uint16_t halfBitsToUint16(float16_t);" + "u16vec2 halfBitsToUint16(f16vec2);" + "u16vec3 halfBitsToUint16(f16vec3);" + "u16vec4 halfBitsToUint16(f16vec4);" + "int16_t float16BitsToInt16(float16_t);" "i16vec2 float16BitsToInt16(f16vec2);" "i16vec3 float16BitsToInt16(f16vec3);" @@ -2781,6 +4530,16 @@ "f16vec3 uint16BitsToFloat16(u16vec3);" "f16vec4 uint16BitsToFloat16(u16vec4);" + "float16_t int16BitsToHalf(int16_t);" + "f16vec2 int16BitsToHalf(i16vec2);" + "f16vec3 int16BitsToHalf(i16vec3);" + "f16vec4 int16BitsToHalf(i16vec4);" + + "float16_t uint16BitsToHalf(uint16_t);" + "f16vec2 uint16BitsToHalf(u16vec2);" + "f16vec3 uint16BitsToHalf(u16vec3);" + "f16vec4 uint16BitsToHalf(u16vec4);" + "int packInt2x16(i16vec2);" "uint packUint2x16(u16vec2);" "int64_t packInt4x16(i16vec4);" @@ -2832,33 +4591,201 @@ "bvec3 notEqual(u16vec3, u16vec3);" "bvec4 notEqual(u16vec4, u16vec4);" + " int16_t bitfieldExtract( int16_t, int16_t, int16_t);" + "i16vec2 bitfieldExtract(i16vec2, int16_t, int16_t);" + "i16vec3 bitfieldExtract(i16vec3, int16_t, int16_t);" + "i16vec4 bitfieldExtract(i16vec4, int16_t, int16_t);" + + " uint16_t bitfieldExtract( uint16_t, int16_t, int16_t);" + "u16vec2 bitfieldExtract(u16vec2, int16_t, int16_t);" + "u16vec3 bitfieldExtract(u16vec3, int16_t, int16_t);" + "u16vec4 bitfieldExtract(u16vec4, int16_t, int16_t);" + + " int16_t bitfieldInsert( int16_t base, int16_t, int16_t, int16_t);" + "i16vec2 bitfieldInsert(i16vec2 base, i16vec2, int16_t, int16_t);" + "i16vec3 bitfieldInsert(i16vec3 base, i16vec3, int16_t, int16_t);" + "i16vec4 bitfieldInsert(i16vec4 base, i16vec4, int16_t, int16_t);" + + " uint16_t bitfieldInsert( uint16_t base, uint16_t, int16_t, int16_t);" + "u16vec2 bitfieldInsert(u16vec2 base, u16vec2, int16_t, int16_t);" + "u16vec3 bitfieldInsert(u16vec3 base, u16vec3, int16_t, int16_t);" + "u16vec4 bitfieldInsert(u16vec4 base, u16vec4, int16_t, int16_t);" + + " int16_t bitCount( int16_t);" + "i16vec2 bitCount(i16vec2);" + "i16vec3 bitCount(i16vec3);" + "i16vec4 bitCount(i16vec4);" + + " int16_t bitCount( uint16_t);" + "i16vec2 bitCount(u16vec2);" + "i16vec3 bitCount(u16vec3);" + "i16vec4 bitCount(u16vec4);" + + " int16_t findLSB( int16_t);" + "i16vec2 findLSB(i16vec2);" + "i16vec3 findLSB(i16vec3);" + "i16vec4 findLSB(i16vec4);" + + " int16_t findLSB( uint16_t);" + "i16vec2 findLSB(u16vec2);" + "i16vec3 findLSB(u16vec3);" + "i16vec4 findLSB(u16vec4);" + + " int16_t findMSB( int16_t);" + "i16vec2 findMSB(i16vec2);" + "i16vec3 findMSB(i16vec3);" + "i16vec4 findMSB(i16vec4);" + + " int16_t findMSB( uint16_t);" + "i16vec2 findMSB(u16vec2);" + "i16vec3 findMSB(u16vec3);" + "i16vec4 findMSB(u16vec4);" + + "int16_t pack16(i8vec2);" + "uint16_t pack16(u8vec2);" + "int32_t pack32(i8vec4);" + "uint32_t pack32(u8vec4);" + "int32_t pack32(i16vec2);" + "uint32_t pack32(u16vec2);" + "int64_t pack64(i16vec4);" + "uint64_t pack64(u16vec4);" + "int64_t pack64(i32vec2);" + "uint64_t pack64(u32vec2);" + + "i8vec2 unpack8(int16_t);" + "u8vec2 unpack8(uint16_t);" + "i8vec4 unpack8(int32_t);" + "u8vec4 unpack8(uint32_t);" + "i16vec2 unpack16(int32_t);" + "u16vec2 unpack16(uint32_t);" + "i16vec4 unpack16(int64_t);" + "u16vec4 unpack16(uint64_t);" + "i32vec2 unpack32(int64_t);" + "u32vec2 unpack32(uint64_t);" + + "float64_t radians(float64_t);" + "f64vec2 radians(f64vec2);" + "f64vec3 radians(f64vec3);" + "f64vec4 radians(f64vec4);" + + "float64_t degrees(float64_t);" + "f64vec2 degrees(f64vec2);" + "f64vec3 degrees(f64vec3);" + "f64vec4 degrees(f64vec4);" + + "float64_t sin(float64_t);" + "f64vec2 sin(f64vec2);" + "f64vec3 sin(f64vec3);" + "f64vec4 sin(f64vec4);" + + "float64_t cos(float64_t);" + "f64vec2 cos(f64vec2);" + "f64vec3 cos(f64vec3);" + "f64vec4 cos(f64vec4);" + + "float64_t tan(float64_t);" + "f64vec2 tan(f64vec2);" + "f64vec3 tan(f64vec3);" + "f64vec4 tan(f64vec4);" + + "float64_t asin(float64_t);" + "f64vec2 asin(f64vec2);" + "f64vec3 asin(f64vec3);" + "f64vec4 asin(f64vec4);" + + "float64_t acos(float64_t);" + "f64vec2 acos(f64vec2);" + "f64vec3 acos(f64vec3);" + "f64vec4 acos(f64vec4);" + + "float64_t atan(float64_t, float64_t);" + "f64vec2 atan(f64vec2, f64vec2);" + "f64vec3 atan(f64vec3, f64vec3);" + "f64vec4 atan(f64vec4, f64vec4);" + + "float64_t atan(float64_t);" + "f64vec2 atan(f64vec2);" + "f64vec3 atan(f64vec3);" + "f64vec4 atan(f64vec4);" + + "float64_t sinh(float64_t);" + "f64vec2 sinh(f64vec2);" + "f64vec3 sinh(f64vec3);" + "f64vec4 sinh(f64vec4);" + + "float64_t cosh(float64_t);" + "f64vec2 cosh(f64vec2);" + "f64vec3 cosh(f64vec3);" + "f64vec4 cosh(f64vec4);" + + "float64_t tanh(float64_t);" + "f64vec2 tanh(f64vec2);" + "f64vec3 tanh(f64vec3);" + "f64vec4 tanh(f64vec4);" + + "float64_t asinh(float64_t);" + "f64vec2 asinh(f64vec2);" + "f64vec3 asinh(f64vec3);" + "f64vec4 asinh(f64vec4);" + + "float64_t acosh(float64_t);" + "f64vec2 acosh(f64vec2);" + "f64vec3 acosh(f64vec3);" + "f64vec4 acosh(f64vec4);" + + "float64_t atanh(float64_t);" + "f64vec2 atanh(f64vec2);" + "f64vec3 atanh(f64vec3);" + "f64vec4 atanh(f64vec4);" + + "float64_t pow(float64_t, float64_t);" + "f64vec2 pow(f64vec2, f64vec2);" + "f64vec3 pow(f64vec3, f64vec3);" + "f64vec4 pow(f64vec4, f64vec4);" + + "float64_t exp(float64_t);" + "f64vec2 exp(f64vec2);" + "f64vec3 exp(f64vec3);" + "f64vec4 exp(f64vec4);" + + "float64_t log(float64_t);" + "f64vec2 log(f64vec2);" + "f64vec3 log(f64vec3);" + "f64vec4 log(f64vec4);" + + "float64_t exp2(float64_t);" + "f64vec2 exp2(f64vec2);" + "f64vec3 exp2(f64vec3);" + "f64vec4 exp2(f64vec4);" + + "float64_t log2(float64_t);" + "f64vec2 log2(f64vec2);" + "f64vec3 log2(f64vec3);" + "f64vec4 log2(f64vec4);" "\n"); - } - - // GL_AMD_shader_fragment_mask - if (profile != EEsProfile && version >= 450) { - commonBuiltins.append( - "uint fragmentMaskFetchAMD(sampler2DMS, ivec2);" - "uint fragmentMaskFetchAMD(isampler2DMS, ivec2);" - "uint fragmentMaskFetchAMD(usampler2DMS, ivec2);" - - "uint fragmentMaskFetchAMD(sampler2DMSArray, ivec3);" - "uint fragmentMaskFetchAMD(isampler2DMSArray, ivec3);" - "uint fragmentMaskFetchAMD(usampler2DMSArray, ivec3);" - - "vec4 fragmentFetchAMD(sampler2DMS, ivec2, uint);" - "ivec4 fragmentFetchAMD(isampler2DMS, ivec2, uint);" - "uvec4 fragmentFetchAMD(usampler2DMS, ivec2, uint);" + } + if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); + stageBuiltins[EShLangFragment].append( + "float64_t interpolateAtCentroid(float64_t);" + "f64vec2 interpolateAtCentroid(f64vec2);" + "f64vec3 interpolateAtCentroid(f64vec3);" + "f64vec4 interpolateAtCentroid(f64vec4);" + + "float64_t interpolateAtSample(float64_t, int);" + "f64vec2 interpolateAtSample(f64vec2, int);" + "f64vec3 interpolateAtSample(f64vec3, int);" + "f64vec4 interpolateAtSample(f64vec4, int);" + + "float64_t interpolateAtOffset(float64_t, f64vec2);" + "f64vec2 interpolateAtOffset(f64vec2, f64vec2);" + "f64vec3 interpolateAtOffset(f64vec3, f64vec2);" + "f64vec4 interpolateAtOffset(f64vec4, f64vec2);" - "vec4 fragmentFetchAMD(sampler2DMSArray, ivec3, uint);" - "ivec4 fragmentFetchAMD(isampler2DMSArray, ivec3, uint);" - "uvec4 fragmentFetchAMD(usampler2DMSArray, ivec3, uint);" + "\n"); - "\n"); } -#endif - //============================================================================ // // Prototypes for built-in functions seen by vertex shaders only. @@ -2973,6 +4900,16 @@ stageBuiltins[EShLangCompute].append( "void barrier();" ); +#ifdef NV_EXTENSIONS + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + stageBuiltins[EShLangMeshNV].append( + "void barrier();" + ); + stageBuiltins[EShLangTaskNV].append( + "void barrier();" + ); + } +#endif if ((profile != EEsProfile && version >= 130) || esBarrier) commonBuiltins.append( "void memoryBarrier();" @@ -2988,6 +4925,49 @@ "void groupMemoryBarrier();" ); } +#ifdef NV_EXTENSIONS + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + stageBuiltins[EShLangMeshNV].append( + "void memoryBarrierShared();" + "void groupMemoryBarrier();" + ); + stageBuiltins[EShLangTaskNV].append( + "void memoryBarrierShared();" + "void groupMemoryBarrier();" + ); + } +#endif + + commonBuiltins.append("void controlBarrier(int, int, int, int);\n" + "void memoryBarrier(int, int, int);\n"); + + if (profile != EEsProfile && version >= 450) { + // coopMatStoreNV perhaps ought to have "out" on the buf parameter, but + // adding it introduces undesirable tempArgs on the stack. What we want + // is more like "buf" thought of as a pointer value being an in parameter. + stageBuiltins[EShLangCompute].append( + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent float16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent float[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out fcoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatStoreNV(fcoopmatNV m, volatile coherent float16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent float[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent float64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(fcoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "fcoopmatNV coopMatMulAddNV(fcoopmatNV A, fcoopmatNV B, fcoopmatNV C);\n" + ); + } //============================================================================ // @@ -3034,61 +5014,13 @@ "\n"); } - stageBuiltins[EShLangFragment].append( - "float dFdx(float p);" - "vec2 dFdx(vec2 p);" - "vec3 dFdx(vec3 p);" - "vec4 dFdx(vec4 p);" - - "float dFdy(float p);" - "vec2 dFdy(vec2 p);" - "vec3 dFdy(vec3 p);" - "vec4 dFdy(vec4 p);" - - "float fwidth(float p);" - "vec2 fwidth(vec2 p);" - "vec3 fwidth(vec3 p);" - "vec4 fwidth(vec4 p);" - - "\n"); + stageBuiltins[EShLangFragment].append(derivatives); + stageBuiltins[EShLangFragment].append("\n"); // GL_ARB_derivative_control if (profile != EEsProfile && version >= 400) { - stageBuiltins[EShLangFragment].append( - "float dFdxFine(float p);" - "vec2 dFdxFine(vec2 p);" - "vec3 dFdxFine(vec3 p);" - "vec4 dFdxFine(vec4 p);" - - "float dFdyFine(float p);" - "vec2 dFdyFine(vec2 p);" - "vec3 dFdyFine(vec3 p);" - "vec4 dFdyFine(vec4 p);" - - "float fwidthFine(float p);" - "vec2 fwidthFine(vec2 p);" - "vec3 fwidthFine(vec3 p);" - "vec4 fwidthFine(vec4 p);" - - "\n"); - - stageBuiltins[EShLangFragment].append( - "float dFdxCoarse(float p);" - "vec2 dFdxCoarse(vec2 p);" - "vec3 dFdxCoarse(vec3 p);" - "vec4 dFdxCoarse(vec4 p);" - - "float dFdyCoarse(float p);" - "vec2 dFdyCoarse(vec2 p);" - "vec3 dFdyCoarse(vec3 p);" - "vec4 dFdyCoarse(vec4 p);" - - "float fwidthCoarse(float p);" - "vec2 fwidthCoarse(vec2 p);" - "vec3 fwidthCoarse(vec3 p);" - "vec4 fwidthCoarse(vec4 p);" - - "\n"); + stageBuiltins[EShLangFragment].append(derivativeControls); + stageBuiltins[EShLangFragment].append("\n"); } // GL_OES_shader_multisample_interpolation @@ -3142,52 +5074,10 @@ // GL_AMD_gpu_shader_half_float if (profile != EEsProfile && version >= 450) { - stageBuiltins[EShLangFragment].append( - "float16_t dFdx(float16_t);" - "f16vec2 dFdx(f16vec2);" - "f16vec3 dFdx(f16vec3);" - "f16vec4 dFdx(f16vec4);" - - "float16_t dFdy(float16_t);" - "f16vec2 dFdy(f16vec2);" - "f16vec3 dFdy(f16vec3);" - "f16vec4 dFdy(f16vec4);" - - "float16_t dFdxFine(float16_t);" - "f16vec2 dFdxFine(f16vec2);" - "f16vec3 dFdxFine(f16vec3);" - "f16vec4 dFdxFine(f16vec4);" - - "float16_t dFdyFine(float16_t);" - "f16vec2 dFdyFine(f16vec2);" - "f16vec3 dFdyFine(f16vec3);" - "f16vec4 dFdyFine(f16vec4);" - - "float16_t dFdxCoarse(float16_t);" - "f16vec2 dFdxCoarse(f16vec2);" - "f16vec3 dFdxCoarse(f16vec3);" - "f16vec4 dFdxCoarse(f16vec4);" - - "float16_t dFdyCoarse(float16_t);" - "f16vec2 dFdyCoarse(f16vec2);" - "f16vec3 dFdyCoarse(f16vec3);" - "f16vec4 dFdyCoarse(f16vec4);" - - "float16_t fwidth(float16_t);" - "f16vec2 fwidth(f16vec2);" - "f16vec3 fwidth(f16vec3);" - "f16vec4 fwidth(f16vec4);" - - "float16_t fwidthFine(float16_t);" - "f16vec2 fwidthFine(f16vec2);" - "f16vec3 fwidthFine(f16vec3);" - "f16vec4 fwidthFine(f16vec4);" - - "float16_t fwidthCoarse(float16_t);" - "f16vec2 fwidthCoarse(f16vec2);" - "f16vec3 fwidthCoarse(f16vec3);" - "f16vec4 fwidthCoarse(f16vec4);" + stageBuiltins[EShLangFragment].append(derivativesAndControl16bits); + stageBuiltins[EShLangFragment].append("\n"); + stageBuiltins[EShLangFragment].append( "float16_t interpolateAtCentroid(float16_t);" "f16vec2 interpolateAtCentroid(f16vec2);" "f16vec3 interpolateAtCentroid(f16vec3);" @@ -3207,7 +5097,7 @@ } // GL_AMD_shader_fragment_mask - if (profile != EEsProfile && version >= 450 && spvVersion.vulkan >= 100) { + if (profile != EEsProfile && version >= 450 && spvVersion.vulkan > 0) { stageBuiltins[EShLangFragment].append( "uint fragmentMaskFetchAMD(subpassInputMS);" "uint fragmentMaskFetchAMD(isubpassInputMS);" @@ -3221,6 +5111,56 @@ } #endif +#ifdef NV_EXTENSIONS + + // Builtins for GL_NV_ray_tracing + if (profile != EEsProfile && version >= 460) { + stageBuiltins[EShLangRayGenNV].append( + "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void executeCallableNV(uint, int);" + "\n"); + stageBuiltins[EShLangIntersectNV].append( + "bool reportIntersectionNV(float, uint);" + "\n"); + stageBuiltins[EShLangAnyHitNV].append( + "void ignoreIntersectionNV();" + "void terminateRayNV();" + "\n"); + stageBuiltins[EShLangClosestHitNV].append( + "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void executeCallableNV(uint, int);" + "\n"); + stageBuiltins[EShLangMissNV].append( + "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void executeCallableNV(uint, int);" + "\n"); + stageBuiltins[EShLangCallableNV].append( + "void executeCallableNV(uint, int);" + "\n"); + } + + //E_SPV_NV_compute_shader_derivatives + + stageBuiltins[EShLangCompute].append(derivatives); + stageBuiltins[EShLangCompute].append(derivativeControls); + stageBuiltins[EShLangCompute].append("\n"); + + + if (profile != EEsProfile && version >= 450) { + + stageBuiltins[EShLangCompute].append(derivativesAndControl16bits); + stageBuiltins[EShLangCompute].append(derivativesAndControl64bits); + stageBuiltins[EShLangCompute].append("\n"); + } + + // Builtins for GL_NV_mesh_shader + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + stageBuiltins[EShLangMeshNV].append( + "void writePackedPrimitiveIndices4x8NV(uint, uint);" + "\n"); + } +#endif + //============================================================================ // // Standard Uniforms @@ -3400,49 +5340,139 @@ "\n"); } +#ifdef NV_EXTENSIONS //============================================================================ // - // Define the interface to the vertex shader. + // Define the interface to the mesh/task shader. // //============================================================================ - if (profile != EEsProfile) { - if (version < 130) { - stageBuiltins[EShLangVertex].append( - "attribute vec4 gl_Color;" - "attribute vec4 gl_SecondaryColor;" - "attribute vec3 gl_Normal;" - "attribute vec4 gl_Vertex;" - "attribute vec4 gl_MultiTexCoord0;" - "attribute vec4 gl_MultiTexCoord1;" - "attribute vec4 gl_MultiTexCoord2;" - "attribute vec4 gl_MultiTexCoord3;" - "attribute vec4 gl_MultiTexCoord4;" - "attribute vec4 gl_MultiTexCoord5;" - "attribute vec4 gl_MultiTexCoord6;" - "attribute vec4 gl_MultiTexCoord7;" - "attribute float gl_FogCoord;" - "\n"); - } else if (IncludeLegacy(version, profile, spvVersion)) { - stageBuiltins[EShLangVertex].append( - "in vec4 gl_Color;" - "in vec4 gl_SecondaryColor;" - "in vec3 gl_Normal;" - "in vec4 gl_Vertex;" - "in vec4 gl_MultiTexCoord0;" - "in vec4 gl_MultiTexCoord1;" - "in vec4 gl_MultiTexCoord2;" - "in vec4 gl_MultiTexCoord3;" - "in vec4 gl_MultiTexCoord4;" - "in vec4 gl_MultiTexCoord5;" - "in vec4 gl_MultiTexCoord6;" - "in vec4 gl_MultiTexCoord7;" - "in float gl_FogCoord;" - "\n"); - } + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + // per-vertex attributes + stageBuiltins[EShLangMeshNV].append( + "out gl_MeshPerVertexNV {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + "float gl_CullDistance[];" + "perviewNV vec4 gl_PositionPerViewNV[];" + "perviewNV float gl_ClipDistancePerViewNV[][];" + "perviewNV float gl_CullDistancePerViewNV[][];" + "} gl_MeshVerticesNV[];" + ); - if (version < 150) { - if (version < 130) { + // per-primitive attributes + stageBuiltins[EShLangMeshNV].append( + "perprimitiveNV out gl_MeshPerPrimitiveNV {" + "int gl_PrimitiveID;" + "int gl_Layer;" + "int gl_ViewportIndex;" + "int gl_ViewportMask[];" + "perviewNV int gl_LayerPerViewNV[];" + "perviewNV int gl_ViewportMaskPerViewNV[][];" + "} gl_MeshPrimitivesNV[];" + ); + + stageBuiltins[EShLangMeshNV].append( + "out uint gl_PrimitiveCountNV;" + "out uint gl_PrimitiveIndicesNV[];" + + "in uint gl_MeshViewCountNV;" + "in uint gl_MeshViewIndicesNV[4];" + + "const highp uvec3 gl_WorkGroupSize = uvec3(1,1,1);" + + "in highp uvec3 gl_WorkGroupID;" + "in highp uvec3 gl_LocalInvocationID;" + + "in highp uvec3 gl_GlobalInvocationID;" + "in highp uint gl_LocalInvocationIndex;" + + "\n"); + + stageBuiltins[EShLangTaskNV].append( + "out uint gl_TaskCountNV;" + + "const highp uvec3 gl_WorkGroupSize = uvec3(1,1,1);" + + "in highp uvec3 gl_WorkGroupID;" + "in highp uvec3 gl_LocalInvocationID;" + + "in highp uvec3 gl_GlobalInvocationID;" + "in highp uint gl_LocalInvocationIndex;" + + "in uint gl_MeshViewCountNV;" + "in uint gl_MeshViewIndicesNV[4];" + + "\n"); + } + + if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangMeshNV].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters + "\n"); + + stageBuiltins[EShLangTaskNV].append( + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters + "\n"); + + if (version >= 460) { + stageBuiltins[EShLangMeshNV].append( + "in int gl_DrawID;" + "\n"); + + stageBuiltins[EShLangTaskNV].append( + "in int gl_DrawID;" + "\n"); + } + } +#endif + + //============================================================================ + // + // Define the interface to the vertex shader. + // + //============================================================================ + + if (profile != EEsProfile) { + if (version < 130) { + stageBuiltins[EShLangVertex].append( + "attribute vec4 gl_Color;" + "attribute vec4 gl_SecondaryColor;" + "attribute vec3 gl_Normal;" + "attribute vec4 gl_Vertex;" + "attribute vec4 gl_MultiTexCoord0;" + "attribute vec4 gl_MultiTexCoord1;" + "attribute vec4 gl_MultiTexCoord2;" + "attribute vec4 gl_MultiTexCoord3;" + "attribute vec4 gl_MultiTexCoord4;" + "attribute vec4 gl_MultiTexCoord5;" + "attribute vec4 gl_MultiTexCoord6;" + "attribute vec4 gl_MultiTexCoord7;" + "attribute float gl_FogCoord;" + "\n"); + } else if (IncludeLegacy(version, profile, spvVersion)) { + stageBuiltins[EShLangVertex].append( + "in vec4 gl_Color;" + "in vec4 gl_SecondaryColor;" + "in vec3 gl_Normal;" + "in vec4 gl_Vertex;" + "in vec4 gl_MultiTexCoord0;" + "in vec4 gl_MultiTexCoord1;" + "in vec4 gl_MultiTexCoord2;" + "in vec4 gl_MultiTexCoord3;" + "in vec4 gl_MultiTexCoord4;" + "in vec4 gl_MultiTexCoord5;" + "in vec4 gl_MultiTexCoord6;" + "in vec4 gl_MultiTexCoord7;" + "in float gl_FogCoord;" + "\n"); + } + + if (version < 150) { + if (version < 130) { stageBuiltins[EShLangVertex].append( " vec4 gl_ClipVertex;" // needs qualifier fixed later "varying vec4 gl_FrontColor;" @@ -3506,7 +5536,7 @@ stageBuiltins[EShLangVertex].append( "int gl_InstanceID;" // needs qualifier fixed later ); - if (spvVersion.vulkan >= 100 && version >= 140) + if (spvVersion.vulkan > 0 && version >= 140) stageBuiltins[EShLangVertex].append( "in int gl_VertexIndex;" "in int gl_InstanceIndex;" @@ -3556,7 +5586,7 @@ "in highp int gl_VertexID;" // needs qualifier fixed later "in highp int gl_InstanceID;" // needs qualifier fixed later ); - if (spvVersion.vulkan >= 100) + if (spvVersion.vulkan > 0) stageBuiltins[EShLangVertex].append( "in highp int gl_VertexIndex;" "in highp int gl_InstanceIndex;" @@ -3780,7 +5810,14 @@ "patch out highp float gl_TessLevelOuter[4];" "patch out highp float gl_TessLevelInner[2];" "patch out highp vec4 gl_BoundingBoxOES[2];" + "patch out highp vec4 gl_BoundingBoxEXT[2];" "\n"); + if (profile == EEsProfile && version >= 320) { + stageBuiltins[EShLangTessControl].append( + "patch out highp vec4 gl_BoundingBox[2];" + "\n" + ); + } } if ((profile != EEsProfile && version >= 140) || @@ -3966,6 +6003,12 @@ "bool gl_HelperInvocation;" // needs qualifier fixed later ); + if (version >= 450) + stageBuiltins[EShLangFragment].append( // GL_EXT_fragment_invocation_density + "flat in ivec2 gl_FragSizeEXT;" + "flat in int gl_FragInvocationCountEXT;" + ); + #ifdef AMD_EXTENSIONS if (version >= 450) stageBuiltins[EShLangFragment].append( @@ -3984,6 +6027,14 @@ stageBuiltins[EShLangFragment].append( "in bool gl_FragFullyCoveredNV;" ); + if (version >= 450) + stageBuiltins[EShLangFragment].append( + "flat in ivec2 gl_FragmentSizeNV;" // GL_NV_shading_rate_image + "flat in int gl_InvocationsPerPixelNV;" + "in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric + "in vec3 gl_BaryCoordNoPerspNV;" + ); + #endif } else { // ES profile @@ -4025,6 +6076,25 @@ stageBuiltins[EShLangFragment].append( "highp float gl_FragDepthEXT;" // GL_EXT_frag_depth ); + + if (version >= 310) + stageBuiltins[EShLangFragment].append( // GL_EXT_fragment_invocation_density + "flat in ivec2 gl_FragSizeEXT;" + "flat in int gl_FragInvocationCountEXT;" + ); +#ifdef NV_EXTENSIONS + if (version >= 320) + stageBuiltins[EShLangFragment].append( // GL_NV_shading_rate_image + "flat in ivec2 gl_FragmentSizeNV;" + "flat in int gl_InvocationsPerPixelNV;" + ); + if (version >= 320) + stageBuiltins[EShLangFragment].append( + "in vec3 gl_BaryCoordNV;" + "in vec3 gl_BaryCoordNoPerspNV;" + ); +#endif + } stageBuiltins[EShLangFragment].append("\n"); @@ -4033,17 +6103,34 @@ // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { - commonBuiltins.append( + const char* ballotDecls = "uniform uint gl_SubGroupSizeARB;" - "in uint gl_SubGroupInvocationARB;" "in uint64_t gl_SubGroupEqMaskARB;" "in uint64_t gl_SubGroupGeMaskARB;" "in uint64_t gl_SubGroupGtMaskARB;" "in uint64_t gl_SubGroupLeMaskARB;" "in uint64_t gl_SubGroupLtMaskARB;" - - "\n"); + "\n"; + const char* fragmentBallotDecls = + "uniform uint gl_SubGroupSizeARB;" + "flat in uint gl_SubGroupInvocationARB;" + "flat in uint64_t gl_SubGroupEqMaskARB;" + "flat in uint64_t gl_SubGroupGeMaskARB;" + "flat in uint64_t gl_SubGroupGtMaskARB;" + "flat in uint64_t gl_SubGroupLeMaskARB;" + "flat in uint64_t gl_SubGroupLtMaskARB;" + "\n"; + stageBuiltins[EShLangVertex] .append(ballotDecls); + stageBuiltins[EShLangTessControl] .append(ballotDecls); + stageBuiltins[EShLangTessEvaluation].append(ballotDecls); + stageBuiltins[EShLangGeometry] .append(ballotDecls); + stageBuiltins[EShLangCompute] .append(ballotDecls); + stageBuiltins[EShLangFragment] .append(fragmentBallotDecls); +#ifdef NV_EXTENSIONS + stageBuiltins[EShLangMeshNV] .append(ballotDecls); + stageBuiltins[EShLangTaskNV] .append(ballotDecls); +#endif } if ((profile != EEsProfile && version >= 140) || @@ -4054,12 +6141,184 @@ "\n"); } + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + const char* ballotDecls = + "in mediump uint gl_SubgroupSize;" + "in mediump uint gl_SubgroupInvocationID;" + "in highp uvec4 gl_SubgroupEqMask;" + "in highp uvec4 gl_SubgroupGeMask;" + "in highp uvec4 gl_SubgroupGtMask;" + "in highp uvec4 gl_SubgroupLeMask;" + "in highp uvec4 gl_SubgroupLtMask;" + "\n"; + const char* fragmentBallotDecls = + "flat in mediump uint gl_SubgroupSize;" + "flat in mediump uint gl_SubgroupInvocationID;" + "flat in highp uvec4 gl_SubgroupEqMask;" + "flat in highp uvec4 gl_SubgroupGeMask;" + "flat in highp uvec4 gl_SubgroupGtMask;" + "flat in highp uvec4 gl_SubgroupLeMask;" + "flat in highp uvec4 gl_SubgroupLtMask;" + "\n"; + stageBuiltins[EShLangVertex] .append(ballotDecls); + stageBuiltins[EShLangTessControl] .append(ballotDecls); + stageBuiltins[EShLangTessEvaluation].append(ballotDecls); + stageBuiltins[EShLangGeometry] .append(ballotDecls); + stageBuiltins[EShLangCompute] .append(ballotDecls); + stageBuiltins[EShLangFragment] .append(fragmentBallotDecls); +#ifdef NV_EXTENSIONS + stageBuiltins[EShLangMeshNV] .append(ballotDecls); + stageBuiltins[EShLangTaskNV] .append(ballotDecls); +#endif + + stageBuiltins[EShLangCompute].append( + "highp in uint gl_NumSubgroups;" + "highp in uint gl_SubgroupID;" + "\n"); +#ifdef NV_EXTENSIONS + stageBuiltins[EShLangMeshNV].append( + "highp in uint gl_NumSubgroups;" + "highp in uint gl_SubgroupID;" + "\n"); + stageBuiltins[EShLangTaskNV].append( + "highp in uint gl_NumSubgroups;" + "highp in uint gl_SubgroupID;" + "\n"); +#endif + } + +#ifdef NV_EXTENSIONS + // GL_NV_ray_tracing + if (profile != EEsProfile && version >= 460) { + + const char *constRayFlags = + "const uint gl_RayFlagsNoneNV = 0U;" + "const uint gl_RayFlagsOpaqueNV = 1U;" + "const uint gl_RayFlagsNoOpaqueNV = 2U;" + "const uint gl_RayFlagsTerminateOnFirstHitNV = 4U;" + "const uint gl_RayFlagsSkipClosestHitShaderNV = 8U;" + "const uint gl_RayFlagsCullBackFacingTrianglesNV = 16U;" + "const uint gl_RayFlagsCullFrontFacingTrianglesNV = 32U;" + "const uint gl_RayFlagsCullOpaqueNV = 64U;" + "const uint gl_RayFlagsCullNoOpaqueNV = 128U;" + "\n"; + const char *rayGenDecls = + "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchSizeNV;" + "\n"; + const char *intersectDecls = + "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchSizeNV;" + "in int gl_PrimitiveID;" + "in int gl_InstanceID;" + "in int gl_InstanceCustomIndexNV;" + "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayDirectionNV;" + "in float gl_RayTminNV;" + "in float gl_RayTmaxNV;" + "in mat4x3 gl_ObjectToWorldNV;" + "in mat4x3 gl_WorldToObjectNV;" + "in uint gl_IncomingRayFlagsNV;" + "\n"; + const char *hitDecls = + "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchSizeNV;" + "in int gl_PrimitiveID;" + "in int gl_InstanceID;" + "in int gl_InstanceCustomIndexNV;" + "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayDirectionNV;" + "in float gl_RayTminNV;" + "in float gl_RayTmaxNV;" + "in float gl_HitTNV;" + "in uint gl_HitKindNV;" + "in mat4x3 gl_ObjectToWorldNV;" + "in mat4x3 gl_WorldToObjectNV;" + "in uint gl_IncomingRayFlagsNV;" + "\n"; + const char *missDecls = + "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchSizeNV;" + "in vec3 gl_WorldRayOriginNV;" + "in vec3 gl_WorldRayDirectionNV;" + "in vec3 gl_ObjectRayOriginNV;" + "in vec3 gl_ObjectRayDirectionNV;" + "in float gl_RayTminNV;" + "in float gl_RayTmaxNV;" + "in uint gl_IncomingRayFlagsNV;" + "\n"; + + const char *callableDecls = + "in uvec3 gl_LaunchIDNV;" + "in uvec3 gl_LaunchSizeNV;" + "\n"; + + stageBuiltins[EShLangRayGenNV].append(rayGenDecls); + stageBuiltins[EShLangRayGenNV].append(constRayFlags); + + stageBuiltins[EShLangIntersectNV].append(intersectDecls); + stageBuiltins[EShLangIntersectNV].append(constRayFlags); + + stageBuiltins[EShLangAnyHitNV].append(hitDecls); + stageBuiltins[EShLangAnyHitNV].append(constRayFlags); + + stageBuiltins[EShLangClosestHitNV].append(hitDecls); + stageBuiltins[EShLangClosestHitNV].append(constRayFlags); + + stageBuiltins[EShLangMissNV].append(missDecls); + stageBuiltins[EShLangMissNV].append(constRayFlags); + + stageBuiltins[EShLangCallableNV].append(callableDecls); + stageBuiltins[EShLangCallableNV].append(constRayFlags); + + } + if ((profile != EEsProfile && version >= 140)) { + const char *deviceIndex = + "in highp int gl_DeviceIndex;" // GL_EXT_device_group + "\n"; + + stageBuiltins[EShLangRayGenNV].append(deviceIndex); + stageBuiltins[EShLangIntersectNV].append(deviceIndex); + stageBuiltins[EShLangAnyHitNV].append(deviceIndex); + stageBuiltins[EShLangClosestHitNV].append(deviceIndex); + stageBuiltins[EShLangMissNV].append(deviceIndex); + } +#endif + if (version >= 300 /* both ES and non-ES */) { stageBuiltins[EShLangFragment].append( "flat in highp uint gl_ViewID_OVR;" // GL_OVR_multiview, GL_OVR_multiview2 "\n"); } + if ((profile != EEsProfile && version >= 420) || + (profile == EEsProfile && version >= 310)) { + commonBuiltins.append("const int gl_ScopeDevice = 1;\n"); + commonBuiltins.append("const int gl_ScopeWorkgroup = 2;\n"); + commonBuiltins.append("const int gl_ScopeSubgroup = 3;\n"); + commonBuiltins.append("const int gl_ScopeInvocation = 4;\n"); + commonBuiltins.append("const int gl_ScopeQueueFamily = 5;\n"); + + commonBuiltins.append("const int gl_SemanticsRelaxed = 0x0;\n"); + commonBuiltins.append("const int gl_SemanticsAcquire = 0x2;\n"); + commonBuiltins.append("const int gl_SemanticsRelease = 0x4;\n"); + commonBuiltins.append("const int gl_SemanticsAcquireRelease = 0x8;\n"); + commonBuiltins.append("const int gl_SemanticsMakeAvailable = 0x2000;\n"); + commonBuiltins.append("const int gl_SemanticsMakeVisible = 0x4000;\n"); + + commonBuiltins.append("const int gl_StorageSemanticsNone = 0x0;\n"); + commonBuiltins.append("const int gl_StorageSemanticsBuffer = 0x40;\n"); + commonBuiltins.append("const int gl_StorageSemanticsShared = 0x100;\n"); + commonBuiltins.append("const int gl_StorageSemanticsImage = 0x800;\n"); + commonBuiltins.append("const int gl_StorageSemanticsOutput = 0x1000;\n"); + } + // printf("%s\n", commonBuiltins.c_str()); // printf("%s\n", stageBuiltins[EShLangFragment].c_str()); } @@ -4074,8 +6333,11 @@ // In this function proper, enumerate the types, then calls the next set of functions // to enumerate all the uses for that type. // - +#ifdef AMD_EXTENSIONS + TBasicType bTypes[4] = { EbtFloat, EbtFloat16, EbtInt, EbtUint }; +#else TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint }; +#endif bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); @@ -4115,12 +6377,20 @@ continue; if (ms && arrayed && profile == EEsProfile && version < 310) continue; +#ifdef AMD_EXTENSIONS + for (int bType = 0; bType < 4; ++bType) { // float, float16, int, uint results + if (shadow && bType > 1) + continue; + + if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile ||version < 450)) + continue; +#else for (int bType = 0; bType < 3; ++bType) { // float, int, uint results if (shadow && bType > 0) continue; - +#endif if (dim == EsdRect && version < 140 && bType > 0) continue; @@ -4156,15 +6426,19 @@ addSamplingFunctions(sampler, typeName, version, profile); addGatherFunctions(sampler, typeName, version, profile); - if (spvVersion.vulkan > 0 && sampler.dim == EsdBuffer && sampler.isCombined()) { - // Vulkan wants a textureBuffer to allow texelFetch() -- - // a sampled image with no sampler. - // So, add sampling functions for both the - // samplerBuffer and textureBuffer types. + if (spvVersion.vulkan > 0 && sampler.isCombined() && !sampler.shadow) { + // Base Vulkan allows texelFetch() for + // textureBuffer (i.e. without sampler). + // + // GL_EXT_samplerless_texture_functions + // allows texelFetch() and query functions + // (other than textureQueryLod()) for all + // texture types. sampler.setTexture(sampler.type, sampler.dim, sampler.arrayed, sampler.shadow, sampler.ms); TString textureTypeName = sampler.getString(); addSamplingFunctions(sampler, textureTypeName, version, profile); + addQueryFunctions(sampler, textureTypeName, version, profile); } } } @@ -4237,16 +6511,50 @@ // textureQueryLod(), fragment stage only // - if (profile != EEsProfile && version >= 400 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { - stageBuiltins[EShLangFragment].append("vec2 textureQueryLod("); - stageBuiltins[EShLangFragment].append(typeName); + if (profile != EEsProfile && version >= 400 && sampler.combined && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { +#ifdef AMD_EXTENSIONS + for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) { + if (f16TexAddr && sampler.type != EbtFloat16) + continue; +#endif + stageBuiltins[EShLangFragment].append("vec2 textureQueryLod("); + stageBuiltins[EShLangFragment].append(typeName); + if (dimMap[sampler.dim] == 1) +#ifdef AMD_EXTENSIONS + if (f16TexAddr) + stageBuiltins[EShLangFragment].append(", float16_t"); + else + stageBuiltins[EShLangFragment].append(", float"); +#else + stageBuiltins[EShLangFragment].append(", float"); +#endif + else { +#ifdef AMD_EXTENSIONS + if (f16TexAddr) + stageBuiltins[EShLangFragment].append(", f16vec"); + else + stageBuiltins[EShLangFragment].append(", vec"); +#else + stageBuiltins[EShLangFragment].append(", vec"); +#endif + stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]); + } + stageBuiltins[EShLangFragment].append(");\n"); +#ifdef AMD_EXTENSIONS + } +#endif + +#ifdef NV_EXTENSIONS + stageBuiltins[EShLangCompute].append("vec2 textureQueryLod("); + stageBuiltins[EShLangCompute].append(typeName); if (dimMap[sampler.dim] == 1) - stageBuiltins[EShLangFragment].append(", float"); + stageBuiltins[EShLangCompute].append(", float"); else { - stageBuiltins[EShLangFragment].append(", vec"); - stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]); + stageBuiltins[EShLangCompute].append(", vec"); + stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]); } - stageBuiltins[EShLangFragment].append(");\n"); + stageBuiltins[EShLangCompute].append(");\n"); +#endif } // @@ -4322,23 +6630,44 @@ " imageAtomicExchange(volatile coherent " }; - for (size_t i = 0; i < numBuiltins; ++i) { + // Loop twice to add prototypes with/without scope/semantics + for (int j = 0; j < 2; ++j) { + for (size_t i = 0; i < numBuiltins; ++i) { + commonBuiltins.append(dataType); + commonBuiltins.append(atomicFunc[i]); + commonBuiltins.append(imageParams); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + if (j == 1) { + commonBuiltins.append(", int, int, int"); + } + commonBuiltins.append(");\n"); + } + commonBuiltins.append(dataType); - commonBuiltins.append(atomicFunc[i]); + commonBuiltins.append(" imageAtomicCompSwap(volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", "); commonBuiltins.append(dataType); + commonBuiltins.append(", "); + commonBuiltins.append(dataType); + if (j == 1) { + commonBuiltins.append(", int, int, int, int, int"); + } commonBuiltins.append(");\n"); } commonBuiltins.append(dataType); - commonBuiltins.append(" imageAtomicCompSwap(volatile coherent "); + commonBuiltins.append(" imageAtomicLoad(volatile coherent "); + commonBuiltins.append(imageParams); + commonBuiltins.append(", int, int, int);\n"); + + commonBuiltins.append("void imageAtomicStore(volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", "); commonBuiltins.append(dataType); - commonBuiltins.append(", "); - commonBuiltins.append(dataType); - commonBuiltins.append(");\n"); + commonBuiltins.append(", int, int, int);\n"); + } else { // not int or uint // GL_ARB_ES3_1_compatibility @@ -4420,12 +6749,12 @@ // for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not - if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms)) + if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms || !sampler.combined)) continue; for (int lod = 0; lod <= 1; ++lod) { - if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms)) + if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms || !sampler.combined)) continue; if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) continue; @@ -4434,9 +6763,9 @@ for (int bias = 0; bias <= 1; ++bias) { - if (bias && (lod || sampler.ms)) + if (bias && (lod || sampler.ms || !sampler.combined)) continue; - if (bias && sampler.dim == Esd2D && sampler.shadow && sampler.arrayed) + if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed) continue; if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) continue; @@ -4456,12 +6785,12 @@ continue; if (fetch && (sampler.shadow || sampler.dim == EsdCube)) continue; - if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer)) + if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer || !sampler.combined)) continue; for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not - if (grad && (lod || bias || sampler.ms)) + if (grad && (lod || bias || sampler.ms || !sampler.combined)) continue; if (grad && sampler.dim == EsdBuffer) continue; @@ -4483,151 +6812,242 @@ if (extraProj && ! proj) continue; - if (extraProj && (sampler.dim == Esd3D || sampler.shadow)) + if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.combined)) continue; +#ifdef AMD_EXTENSIONS + for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing - for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) { // loop over "bool" lod clamp - - if (lodClamp && (profile == EEsProfile || version < 450)) + if (f16TexAddr && sampler.type != EbtFloat16) continue; - if (lodClamp && (proj || lod || fetch)) - continue; - - for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not + if (f16TexAddr && sampler.shadow && ! compare) { + compare = true; // compare argument is always present + totalDims--; + } +#endif + for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) { // loop over "bool" lod clamp - if (sparse && (profile == EEsProfile || version < 450)) + if (lodClamp && (profile == EEsProfile || version < 450)) continue; - // Sparse sampling is not for 1D/1D array texture, buffer texture, and projective texture - if (sparse && (sampler.dim == Esd1D || sampler.dim == EsdBuffer || proj)) + if (lodClamp && (proj || lod || fetch)) continue; - TString s; + for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not - // return type - if (sparse) - s.append("int "); - else { - if (sampler.shadow) - s.append("float "); + if (sparse && (profile == EEsProfile || version < 450)) + continue; + // Sparse sampling is not for 1D/1D array texture, buffer texture, and projective texture + if (sparse && (sampler.dim == Esd1D || sampler.dim == EsdBuffer || proj)) + continue; + + TString s; + + // return type + if (sparse) + s.append("int "); else { - s.append(prefixes[sampler.type]); - s.append("vec4 "); + if (sampler.shadow) +#ifdef AMD_EXTENSIONS + if (sampler.type == EbtFloat16) + s.append("float16_t "); + else + s.append("float "); +#else + s.append("float "); +#endif + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } } - } - // name - if (sparse) { - if (fetch) - s.append("sparseTexel"); - else - s.append("sparseTexture"); - } else { - if (fetch) - s.append("texel"); - else - s.append("texture"); - } - if (proj) - s.append("Proj"); - if (lod) - s.append("Lod"); - if (grad) - s.append("Grad"); - if (fetch) - s.append("Fetch"); - if (offset) - s.append("Offset"); - if (lodClamp) - s.append("Clamp"); - if (lodClamp || sparse) - s.append("ARB"); - s.append("("); - - // sampler type - s.append(typeName); - - // P coordinate - if (extraProj) - s.append(",vec4"); - else { - s.append(","); - TBasicType t = fetch ? EbtInt : EbtFloat; - if (totalDims == 1) - s.append(TType::getBasicString(t)); + // name + if (sparse) { + if (fetch) + s.append("sparseTexel"); + else + s.append("sparseTexture"); + } else { - s.append(prefixes[t]); - s.append("vec"); - s.append(postfixes[totalDims]); + if (fetch) + s.append("texel"); + else + s.append("texture"); } - } - - if (bias && compare) - continue; + if (proj) + s.append("Proj"); + if (lod) + s.append("Lod"); + if (grad) + s.append("Grad"); + if (fetch) + s.append("Fetch"); + if (offset) + s.append("Offset"); + if (lodClamp) + s.append("Clamp"); + if (lodClamp || sparse) + s.append("ARB"); + s.append("("); - // non-optional lod argument (lod that's not driven by lod loop) or sample - if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || - (sampler.ms && fetch)) - s.append(",int"); - - // non-optional lod - if (lod) - s.append(",float"); - - // gradient arguments - if (grad) { - if (dimMap[sampler.dim] == 1) - s.append(",float,float"); + // sampler type + s.append(typeName); +#ifdef AMD_EXTENSIONS + // P coordinate + if (extraProj) { + if (f16TexAddr) + s.append(",f16vec4"); + else + s.append(",vec4"); + } else { + s.append(","); + TBasicType t = fetch ? EbtInt : (f16TexAddr ? EbtFloat16 : EbtFloat); + if (totalDims == 1) + s.append(TType::getBasicString(t)); + else { + s.append(prefixes[t]); + s.append("vec"); + s.append(postfixes[totalDims]); + } + } +#else + // P coordinate + if (extraProj) + s.append(",vec4"); else { - s.append(",vec"); - s.append(postfixes[dimMap[sampler.dim]]); - s.append(",vec"); - s.append(postfixes[dimMap[sampler.dim]]); + s.append(","); + TBasicType t = fetch ? EbtInt : EbtFloat; + if (totalDims == 1) + s.append(TType::getBasicString(t)); + else { + s.append(prefixes[t]); + s.append("vec"); + s.append(postfixes[totalDims]); + } } - } - - // offset - if (offset) { - if (dimMap[sampler.dim] == 1) +#endif + // non-optional compare + if (compare) + s.append(",float"); + + // non-optional lod argument (lod that's not driven by lod loop) or sample + if ((fetch && sampler.dim != EsdBuffer && sampler.dim != EsdRect && !sampler.ms) || + (sampler.ms && fetch)) s.append(",int"); - else { - s.append(",ivec"); - s.append(postfixes[dimMap[sampler.dim]]); +#ifdef AMD_EXTENSIONS + // non-optional lod + if (lod) { + if (f16TexAddr) + s.append(",float16_t"); + else + s.append(",float"); } - } - // non-optional compare - if (compare) - s.append(",float"); - - // lod clamp - if (lodClamp) - s.append(",float"); - - // texel out (for sparse texture) - if (sparse) { - s.append(",out "); - if (sampler.shadow) - s.append("float "); - else { - s.append(prefixes[sampler.type]); - s.append("vec4 "); + // gradient arguments + if (grad) { + if (dimMap[sampler.dim] == 1) { + if (f16TexAddr) + s.append(",float16_t,float16_t"); + else + s.append(",float,float"); + } else { + if (f16TexAddr) + s.append(",f16vec"); + else + s.append(",vec"); + s.append(postfixes[dimMap[sampler.dim]]); + if (f16TexAddr) + s.append(",f16vec"); + else + s.append(",vec"); + s.append(postfixes[dimMap[sampler.dim]]); + } + } +#else + // non-optional lod + if (lod) + s.append(",float"); + + // gradient arguments + if (grad) { + if (dimMap[sampler.dim] == 1) + s.append(",float,float"); + else { + s.append(",vec"); + s.append(postfixes[dimMap[sampler.dim]]); + s.append(",vec"); + s.append(postfixes[dimMap[sampler.dim]]); + } + } +#endif + // offset + if (offset) { + if (dimMap[sampler.dim] == 1) + s.append(",int"); + else { + s.append(",ivec"); + s.append(postfixes[dimMap[sampler.dim]]); + } } - } - // optional bias - if (bias) - s.append(",float"); - - s.append(");\n"); - - // Add to the per-language set of built-ins - - if (bias || lodClamp) - stageBuiltins[EShLangFragment].append(s); - else - commonBuiltins.append(s); +#ifdef AMD_EXTENSIONS + // lod clamp + if (lodClamp) { + if (f16TexAddr) + s.append(",float16_t"); + else + s.append(",float"); + } +#else + // lod clamp + if (lodClamp) + s.append(",float"); +#endif + // texel out (for sparse texture) + if (sparse) { + s.append(",out "); + if (sampler.shadow) +#ifdef AMD_EXTENSIONS + if (sampler.type == EbtFloat16) + s.append("float16_t"); + else + s.append("float"); +#else + s.append("float"); +#endif + else { + s.append(prefixes[sampler.type]); + s.append("vec4"); + } + } +#ifdef AMD_EXTENSIONS + // optional bias + if (bias) { + if (f16TexAddr) + s.append(",float16_t"); + else + s.append(",float"); + } +#else + // optional bias + if (bias) + s.append(",float"); +#endif + s.append(");\n"); + + // Add to the per-language set of built-ins + if (bias || lodClamp) { + stageBuiltins[EShLangFragment].append(s); +#ifdef NV_EXTENSIONS + stageBuiltins[EShLangCompute].append(s); +#endif + } else + commonBuiltins.append(s); + + } } +#ifdef AMD_EXTENSIONS } +#endif } } } @@ -4660,81 +7080,97 @@ if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) return; - for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets +#ifdef AMD_EXTENSIONS + for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing - for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument + if (f16TexAddr && sampler.type != EbtFloat16) + continue; +#endif + for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets - if (comp > 0 && sampler.shadow) - continue; + for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument - if (offset > 0 && sampler.dim == EsdCube) - continue; + if (comp > 0 && sampler.shadow) + continue; - for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not - if (sparse && (profile == EEsProfile || version < 450)) + if (offset > 0 && sampler.dim == EsdCube) continue; - TString s; + for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not + if (sparse && (profile == EEsProfile || version < 450)) + continue; - // return type - if (sparse) - s.append("int "); - else { - s.append(prefixes[sampler.type]); - s.append("vec4 "); - } + TString s; - // name - if (sparse) - s.append("sparseTextureGather"); - else - s.append("textureGather"); - switch (offset) { - case 1: - s.append("Offset"); - break; - case 2: - s.append("Offsets"); - default: - break; - } + // return type + if (sparse) + s.append("int "); + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } - if (sparse) - s.append("ARB"); - s.append("("); - - // sampler type argument - s.append(typeName); - - // P coordinate argument - s.append(",vec"); - int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); - s.append(postfixes[totalDims]); - - // refZ argument - if (sampler.shadow) - s.append(",float"); - - // offset argument - if (offset > 0) { - s.append(",ivec2"); - if (offset == 2) - s.append("[4]"); - } + // name + if (sparse) + s.append("sparseTextureGather"); + else + s.append("textureGather"); + switch (offset) { + case 1: + s.append("Offset"); + break; + case 2: + s.append("Offsets"); + break; + default: + break; + } + if (sparse) + s.append("ARB"); + s.append("("); - // texel out (for sparse texture) - if (sparse) { - s.append(",out "); - s.append(prefixes[sampler.type]); - s.append("vec4 "); - } + // sampler type argument + s.append(typeName); + + // P coordinate argument +#ifdef AMD_EXTENSIONS + if (f16TexAddr) + s.append(",f16vec"); + else + s.append(",vec"); +#else + s.append(",vec"); +#endif + int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); + s.append(postfixes[totalDims]); - // comp argument - if (comp) - s.append(",int"); + // refZ argument + if (sampler.shadow) + s.append(",float"); + + // offset argument + if (offset > 0) { + s.append(",ivec2"); + if (offset == 2) + s.append("[4]"); + } + + // texel out (for sparse texture) + if (sparse) { + s.append(",out "); + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } + + // comp argument + if (comp) + s.append(",int"); - s.append(");\n"); - commonBuiltins.append(s); + s.append(");\n"); + commonBuiltins.append(s); +#ifdef AMD_EXTENSIONS + } +#endif } } } @@ -4753,95 +7189,113 @@ if ((lod && bias) || (lod == 0 && bias == 0)) continue; - for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets + for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing - for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument + if (f16TexAddr && sampler.type != EbtFloat16) + continue; - if (comp == 0 && bias) - continue; + for (int offset = 0; offset < 3; ++offset) { // loop over three forms of offset in the call name: none, Offset, and Offsets - if (offset > 0 && sampler.dim == EsdCube) - continue; + for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument - for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not - if (sparse && (profile == EEsProfile || version < 450)) + if (comp == 0 && bias) continue; - TString s; + if (offset > 0 && sampler.dim == EsdCube) + continue; - // return type - if (sparse) - s.append("int "); - else { - s.append(prefixes[sampler.type]); - s.append("vec4 "); - } + for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not + if (sparse && (profile == EEsProfile || version < 450)) + continue; - // name - if (sparse) - s.append("sparseTextureGather"); - else - s.append("textureGather"); - - if (lod) - s.append("Lod"); - - switch (offset) { - case 1: - s.append("Offset"); - break; - case 2: - s.append("Offsets"); - default: - break; - } + TString s; - if (lod) - s.append("AMD"); - else if (sparse) - s.append("ARB"); + // return type + if (sparse) + s.append("int "); + else { + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } - s.append("("); + // name + if (sparse) + s.append("sparseTextureGather"); + else + s.append("textureGather"); + + if (lod) + s.append("Lod"); + + switch (offset) { + case 1: + s.append("Offset"); + break; + case 2: + s.append("Offsets"); + break; + default: + break; + } - // sampler type argument - s.append(typeName); + if (lod) + s.append("AMD"); + else if (sparse) + s.append("ARB"); + + s.append("("); + + // sampler type argument + s.append(typeName); + + // P coordinate argument + if (f16TexAddr) + s.append(",f16vec"); + else + s.append(",vec"); + int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); + s.append(postfixes[totalDims]); + + // lod argument + if (lod) { + if (f16TexAddr) + s.append(",float16_t"); + else + s.append(",float"); + } - // P coordinate argument - s.append(",vec"); - int totalDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0); - s.append(postfixes[totalDims]); + // offset argument + if (offset > 0) { + s.append(",ivec2"); + if (offset == 2) + s.append("[4]"); + } - // lod argument - if (lod) - s.append(",float"); - - // offset argument - if (offset > 0) { - s.append(",ivec2"); - if (offset == 2) - s.append("[4]"); - } + // texel out (for sparse texture) + if (sparse) { + s.append(",out "); + s.append(prefixes[sampler.type]); + s.append("vec4 "); + } - // texel out (for sparse texture) - if (sparse) { - s.append(",out "); - s.append(prefixes[sampler.type]); - s.append("vec4 "); - } + // comp argument + if (comp) + s.append(",int"); + + // bias argument + if (bias) { + if (f16TexAddr) + s.append(",float16_t"); + else + s.append(",float"); + } - // comp argument - if (comp) - s.append(",int"); - - // bias argument - if (bias) - s.append(",float"); - - s.append(");\n"); - if (bias) - stageBuiltins[EShLangFragment].append(s); - else - commonBuiltins.append(s); + s.append(");\n"); + if (bias) + stageBuiltins[EShLangFragment].append(s); + else + commonBuiltins.append(s); + } } } } @@ -5303,6 +7757,31 @@ } #endif +#ifdef NV_EXTENSIONS + // SPV_NV_mesh_shader + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + snprintf(builtInConstant, maxSize, "const int gl_MaxMeshOutputVerticesNV = %d;", resources.maxMeshOutputVerticesNV); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxMeshOutputPrimitivesNV = %d;", resources.maxMeshOutputPrimitivesNV); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxMeshWorkGroupSizeNV = ivec3(%d,%d,%d);", resources.maxMeshWorkGroupSizeX_NV, + resources.maxMeshWorkGroupSizeY_NV, + resources.maxMeshWorkGroupSizeZ_NV); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxTaskWorkGroupSizeNV = ivec3(%d,%d,%d);", resources.maxTaskWorkGroupSizeX_NV, + resources.maxTaskWorkGroupSizeY_NV, + resources.maxTaskWorkGroupSizeZ_NV); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxMeshViewCountNV = %d;", resources.maxMeshViewCountNV); + s.append(builtInConstant); + + s.append("\n"); + } +#endif + s.append("\n"); } @@ -5322,11 +7801,12 @@ static void SpecialQualifier(const char* name, TStorageQualifier qualifier, TBuiltInVariable builtIn, TSymbolTable& symbolTable) { TSymbol* symbol = symbolTable.find(name); - if (symbol) { - TQualifier& symQualifier = symbol->getWritableType().getQualifier(); - symQualifier.storage = qualifier; - symQualifier.builtIn = builtIn; - } + if (symbol == nullptr) + return; + + TQualifier& symQualifier = symbol->getWritableType().getQualifier(); + symQualifier.storage = qualifier; + symQualifier.builtIn = builtIn; } // @@ -5342,7 +7822,7 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable) { TSymbol* symbol = symbolTable.find(name); - if (! symbol) + if (symbol == nullptr) return; TQualifier& symQualifier = symbol->getWritableType().getQualifier(); @@ -5359,7 +7839,7 @@ static void BuiltInVariable(const char* blockName, const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable) { TSymbol* symbol = symbolTable.find(blockName); - if (! symbol) + if (symbol == nullptr) return; TTypeList& structure = *symbol->getWritableType().getWritableStruct(); @@ -5428,9 +7908,11 @@ BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan >= 100) + if (spvVersion.vulkan > 0) // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); if (version >= 430) { symbolTable.setFunctionExtensions("anyInvocationARB", 1, &E_GL_ARB_shader_group_vote); @@ -5484,6 +7966,13 @@ } #endif +#ifdef NV_EXTENSIONS + symbolTable.setFunctionExtensions("textureFootprintNV", 1, &E_GL_NV_shader_texture_footprint); + symbolTable.setFunctionExtensions("textureFootprintClampNV", 1, &E_GL_NV_shader_texture_footprint); + symbolTable.setFunctionExtensions("textureFootprintLodNV", 1, &E_GL_NV_shader_texture_footprint); + symbolTable.setFunctionExtensions("textureFootprintGradNV", 1, &E_GL_NV_shader_texture_footprint); + symbolTable.setFunctionExtensions("textureFootprintGradClampNV", 1, &E_GL_NV_shader_texture_footprint); +#endif // Compatibility variables, vertex only if (spvVersion.spv == 0) { BuiltInVariable("gl_Color", EbvColor, symbolTable); @@ -5529,7 +8018,7 @@ SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); } - if (spvVersion.vulkan >= 100) { + if (spvVersion.vulkan > 0) { BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); } @@ -5548,10 +8037,16 @@ case EShLangTessControl: if (profile == EEsProfile && version >= 310) { + BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable); + symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1, + &E_GL_EXT_primitive_bounding_box); BuiltInVariable("gl_BoundingBoxOES", EbvBoundingBox, symbolTable); - if (version < 320) - symbolTable.setVariableExtensions("gl_BoundingBoxOES", Num_AEP_primitive_bounding_box, - AEP_primitive_bounding_box); + symbolTable.setVariableExtensions("gl_BoundingBoxOES", 1, + &E_GL_OES_primitive_bounding_box); + + if (version >= 320) { + BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable); + } } // Fall through @@ -5606,9 +8101,18 @@ BuiltInVariable("gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); if (language != EShLangVertex) { + symbolTable.setVariableExtensions("gl_in", "gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); + symbolTable.setVariableExtensions("gl_in", "gl_PositionPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); + BuiltInVariable("gl_in", "gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable); BuiltInVariable("gl_in", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); } + symbolTable.setVariableExtensions("gl_out", "gl_ViewportMask", 1, &E_GL_NV_viewport_array2); + symbolTable.setVariableExtensions("gl_out", "gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); + symbolTable.setVariableExtensions("gl_out", "gl_SecondaryViewportMaskNV", 1, &E_GL_NV_stereo_view_rendering); + symbolTable.setVariableExtensions("gl_out", "gl_PositionPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); + symbolTable.setVariableExtensions("gl_out", "gl_ViewportMaskPerViewNV", 1, &E_GL_NVX_multiview_per_view_attributes); + BuiltInVariable("gl_out", "gl_ViewportMask", EbvViewportMaskNV, symbolTable); BuiltInVariable("gl_out", "gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable); BuiltInVariable("gl_out", "gl_SecondaryViewportMaskNV", EbvSecondaryViewportMaskNV, symbolTable); @@ -5652,15 +8156,16 @@ // gl_PointSize, when it needs to be tied to an extension, is always a member of a block. // (Sometimes with an instance name, sometimes anonymous). - // However, the current automatic extension scheme does not work per block member, - // so for now check when parsing. - // - // if (profile == EEsProfile) { - // if (language == EShLangGeometry) - // symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_geometry_point_size, AEP_geometry_point_size); - // else if (language == EShLangTessEvaluation || language == EShLangTessControl) - // symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); - //} + if (profile == EEsProfile) { + if (language == EShLangGeometry) { + symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_geometry_point_size, AEP_geometry_point_size); + symbolTable.setVariableExtensions("gl_in", "gl_PointSize", Num_AEP_geometry_point_size, AEP_geometry_point_size); + } else if (language == EShLangTessEvaluation || language == EShLangTessControl) { + // gl_in tessellation settings of gl_PointSize are in the context-dependent paths + symbolTable.setVariableExtensions("gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); + symbolTable.setVariableExtensions("gl_out", "gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); + } + } if ((profile != EEsProfile && version >= 140) || (profile == EEsProfile && version >= 310)) { @@ -5669,6 +8174,26 @@ symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); } + + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + + BuiltInVariable("gl_SubgroupSize", EbvSubgroupSize2, symbolTable); + BuiltInVariable("gl_SubgroupInvocationID", EbvSubgroupInvocation2, symbolTable); + BuiltInVariable("gl_SubgroupEqMask", EbvSubgroupEqMask2, symbolTable); + BuiltInVariable("gl_SubgroupGeMask", EbvSubgroupGeMask2, symbolTable); + BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); + BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); + BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + } break; @@ -5906,8 +8431,40 @@ symbolTable.setVariableExtensions("gl_FragFullyCoveredNV", 1, &E_GL_NV_conservative_raster_underestimation); BuiltInVariable("gl_FragFullyCoveredNV", EbvFragFullyCoveredNV, symbolTable); } + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 320)) { + symbolTable.setVariableExtensions("gl_FragmentSizeNV", 1, &E_GL_NV_shading_rate_image); + symbolTable.setVariableExtensions("gl_InvocationsPerPixelNV", 1, &E_GL_NV_shading_rate_image); + BuiltInVariable("gl_FragmentSizeNV", EbvFragmentSizeNV, symbolTable); + BuiltInVariable("gl_InvocationsPerPixelNV", EbvInvocationsPerPixelNV, symbolTable); + symbolTable.setVariableExtensions("gl_BaryCoordNV", 1, &E_GL_NV_fragment_shader_barycentric); + symbolTable.setVariableExtensions("gl_BaryCoordNoPerspNV", 1, &E_GL_NV_fragment_shader_barycentric); + BuiltInVariable("gl_BaryCoordNV", EbvBaryCoordNV, symbolTable); + BuiltInVariable("gl_BaryCoordNoPerspNV", EbvBaryCoordNoPerspNV, symbolTable); + } + if (((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 320)) && + language == EShLangCompute) { + symbolTable.setFunctionExtensions("dFdx", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("fwidth", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdyFine", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("fwidthFine", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdxCoarse", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("dFdyCoarse", 1, &E_GL_NV_compute_shader_derivatives); + symbolTable.setFunctionExtensions("fwidthCoarse", 1, &E_GL_NV_compute_shader_derivatives); + } #endif + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 310)) { + symbolTable.setVariableExtensions("gl_FragSizeEXT", 1, &E_GL_EXT_fragment_invocation_density); + symbolTable.setVariableExtensions("gl_FragInvocationCountEXT", 1, &E_GL_EXT_fragment_invocation_density); + BuiltInVariable("gl_FragSizeEXT", EbvFragSizeEXT, symbolTable); + BuiltInVariable("gl_FragInvocationCountEXT", EbvFragInvocationCountEXT, symbolTable); + } + symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &E_GL_EXT_frag_depth); if (profile == EEsProfile && version < 320) { @@ -5935,10 +8492,155 @@ BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable); } + // GL_ARB_shader_ballot + if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan > 0) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + } + + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + + BuiltInVariable("gl_SubgroupSize", EbvSubgroupSize2, symbolTable); + BuiltInVariable("gl_SubgroupInvocationID", EbvSubgroupInvocation2, symbolTable); + BuiltInVariable("gl_SubgroupEqMask", EbvSubgroupEqMask2, symbolTable); + BuiltInVariable("gl_SubgroupGeMask", EbvSubgroupGeMask2, symbolTable); + BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); + BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); + BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + + symbolTable.setFunctionExtensions("subgroupBarrier", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setFunctionExtensions("subgroupMemoryBarrier", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setFunctionExtensions("subgroupMemoryBarrierBuffer", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setFunctionExtensions("subgroupMemoryBarrierImage", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setFunctionExtensions("subgroupElect", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setFunctionExtensions("subgroupAll", 1, &E_GL_KHR_shader_subgroup_vote); + symbolTable.setFunctionExtensions("subgroupAny", 1, &E_GL_KHR_shader_subgroup_vote); + symbolTable.setFunctionExtensions("subgroupAllEqual", 1, &E_GL_KHR_shader_subgroup_vote); + symbolTable.setFunctionExtensions("subgroupBroadcast", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBroadcastFirst", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallot", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupInverseBallot", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallotBitExtract", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallotBitCount", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallotInclusiveBitCount", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallotExclusiveBitCount", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallotFindLSB", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupBallotFindMSB", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setFunctionExtensions("subgroupShuffle", 1, &E_GL_KHR_shader_subgroup_shuffle); + symbolTable.setFunctionExtensions("subgroupShuffleXor", 1, &E_GL_KHR_shader_subgroup_shuffle); + symbolTable.setFunctionExtensions("subgroupShuffleUp", 1, &E_GL_KHR_shader_subgroup_shuffle_relative); + symbolTable.setFunctionExtensions("subgroupShuffleDown", 1, &E_GL_KHR_shader_subgroup_shuffle_relative); + symbolTable.setFunctionExtensions("subgroupAdd", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupMul", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupMin", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupMax", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupAnd", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupOr", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupXor", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveAdd", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveMul", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveMin", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveMax", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveAnd", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveOr", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupInclusiveXor", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveAdd", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveMul", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveMin", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveMax", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveAnd", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveOr", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupExclusiveXor", 1, &E_GL_KHR_shader_subgroup_arithmetic); + symbolTable.setFunctionExtensions("subgroupClusteredAdd", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupClusteredMul", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupClusteredMin", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupClusteredMax", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupClusteredAnd", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupClusteredOr", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupClusteredXor", 1, &E_GL_KHR_shader_subgroup_clustered); + symbolTable.setFunctionExtensions("subgroupQuadBroadcast", 1, &E_GL_KHR_shader_subgroup_quad); + symbolTable.setFunctionExtensions("subgroupQuadSwapHorizontal", 1, &E_GL_KHR_shader_subgroup_quad); + symbolTable.setFunctionExtensions("subgroupQuadSwapVertical", 1, &E_GL_KHR_shader_subgroup_quad); + symbolTable.setFunctionExtensions("subgroupQuadSwapDiagonal", 1, &E_GL_KHR_shader_subgroup_quad); + +#ifdef NV_EXTENSIONS + symbolTable.setFunctionExtensions("subgroupPartitionNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedAddNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedMulNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedMinNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedMaxNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedAndNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedOrNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedXorNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveAddNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveMulNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveMinNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveMaxNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveAndNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveOrNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedInclusiveXorNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveAddNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveMulNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveMinNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveMaxNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveAndNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveOrNV", 1, &E_GL_NV_shader_subgroup_partitioned); + symbolTable.setFunctionExtensions("subgroupPartitionedExclusiveXorNV", 1, &E_GL_NV_shader_subgroup_partitioned); +#endif + + } + if (profile == EEsProfile) { symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); } + + if (spvVersion.vulkan > 0) { + symbolTable.setVariableExtensions("gl_ScopeDevice", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_ScopeWorkgroup", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_ScopeSubgroup", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_ScopeInvocation", 1, &E_GL_KHR_memory_scope_semantics); + + symbolTable.setVariableExtensions("gl_SemanticsRelaxed", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsAcquire", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsRelease", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsAcquireRelease", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsMakeAvailable", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsMakeVisible", 1, &E_GL_KHR_memory_scope_semantics); + + symbolTable.setVariableExtensions("gl_StorageSemanticsNone", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_StorageSemanticsBuffer", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_StorageSemanticsShared", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_StorageSemanticsImage", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_StorageSemanticsOutput", 1, &E_GL_KHR_memory_scope_semantics); + } break; case EShLangCompute: @@ -5973,6 +8675,52 @@ symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader); } + symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics); + + // GL_ARB_shader_ballot + if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan > 0) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + } + + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + + BuiltInVariable("gl_SubgroupSize", EbvSubgroupSize2, symbolTable); + BuiltInVariable("gl_SubgroupInvocationID", EbvSubgroupInvocation2, symbolTable); + BuiltInVariable("gl_SubgroupEqMask", EbvSubgroupEqMask2, symbolTable); + BuiltInVariable("gl_SubgroupGeMask", EbvSubgroupGeMask2, symbolTable); + BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); + BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); + BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + } + if ((profile != EEsProfile && version >= 140) || (profile == EEsProfile && version >= 310)) { symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); @@ -5981,7 +8729,293 @@ BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); } + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); + + BuiltInVariable("gl_NumSubgroups", EbvNumSubgroups, symbolTable); + BuiltInVariable("gl_SubgroupID", EbvSubgroupID, symbolTable); + + symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); + } + + symbolTable.setFunctionExtensions("coopMatLoadNV", 1, &E_GL_NV_cooperative_matrix); + symbolTable.setFunctionExtensions("coopMatStoreNV", 1, &E_GL_NV_cooperative_matrix); + symbolTable.setFunctionExtensions("coopMatMulAddNV", 1, &E_GL_NV_cooperative_matrix); + + break; +#ifdef NV_EXTENSIONS + case EShLangRayGenNV: + case EShLangIntersectNV: + case EShLangAnyHitNV: + case EShLangClosestHitNV: + case EShLangMissNV: + case EShLangCallableNV: + if (profile != EEsProfile && version >= 460) { + symbolTable.setVariableExtensions("gl_LaunchIDNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_LaunchSizeNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_PrimitiveID", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_InstanceCustomIndexNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldRayOriginNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldRayDirectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectRayOriginNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectRayDirectionNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_RayTminNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_RayTmaxNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_HitTNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_HitKindNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_ObjectToWorldNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_WorldToObjectNV", 1, &E_GL_NV_ray_tracing); + symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing); + + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + + BuiltInVariable("gl_LaunchIDNV", EbvLaunchIdNV, symbolTable); + BuiltInVariable("gl_LaunchSizeNV", EbvLaunchSizeNV, symbolTable); + BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_InstanceID", EbvInstanceId, symbolTable); + BuiltInVariable("gl_InstanceCustomIndexNV", EbvInstanceCustomIndexNV,symbolTable); + BuiltInVariable("gl_WorldRayOriginNV", EbvWorldRayOriginNV, symbolTable); + BuiltInVariable("gl_WorldRayDirectionNV", EbvWorldRayDirectionNV, symbolTable); + BuiltInVariable("gl_ObjectRayOriginNV", EbvObjectRayOriginNV, symbolTable); + BuiltInVariable("gl_ObjectRayDirectionNV", EbvObjectRayDirectionNV, symbolTable); + BuiltInVariable("gl_RayTminNV", EbvRayTminNV, symbolTable); + BuiltInVariable("gl_RayTmaxNV", EbvRayTmaxNV, symbolTable); + BuiltInVariable("gl_HitTNV", EbvHitTNV, symbolTable); + BuiltInVariable("gl_HitKindNV", EbvHitKindNV, symbolTable); + BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorldNV, symbolTable); + BuiltInVariable("gl_WorldToObjectNV", EbvWorldToObjectNV, symbolTable); + BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlagsNV, symbolTable); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + } break; + case EShLangMeshNV: + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + // per-vertex builtins + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_Position", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_PointSize", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_ClipDistance", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_CullDistance", 1, &E_GL_NV_mesh_shader); + + BuiltInVariable("gl_MeshVerticesNV", "gl_Position", EbvPosition, symbolTable); + BuiltInVariable("gl_MeshVerticesNV", "gl_PointSize", EbvPointSize, symbolTable); + BuiltInVariable("gl_MeshVerticesNV", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_MeshVerticesNV", "gl_CullDistance", EbvCullDistance, symbolTable); + + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_PositionPerViewNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_ClipDistancePerViewNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_CullDistancePerViewNV", 1, &E_GL_NV_mesh_shader); + + BuiltInVariable("gl_MeshVerticesNV", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); + BuiltInVariable("gl_MeshVerticesNV", "gl_ClipDistancePerViewNV", EbvClipDistancePerViewNV, symbolTable); + BuiltInVariable("gl_MeshVerticesNV", "gl_CullDistancePerViewNV", EbvCullDistancePerViewNV, symbolTable); + + // per-primitive builtins + symbolTable.setVariableExtensions("gl_MeshPrimitivesNV", "gl_PrimitiveID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesNV", "gl_Layer", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesNV", "gl_ViewportIndex", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesNV", "gl_ViewportMask", 1, &E_GL_NV_mesh_shader); + + BuiltInVariable("gl_MeshPrimitivesNV", "gl_PrimitiveID", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_MeshPrimitivesNV", "gl_Layer", EbvLayer, symbolTable); + BuiltInVariable("gl_MeshPrimitivesNV", "gl_ViewportIndex", EbvViewportIndex, symbolTable); + BuiltInVariable("gl_MeshPrimitivesNV", "gl_ViewportMask", EbvViewportMaskNV, symbolTable); + + // per-view per-primitive builtins + symbolTable.setVariableExtensions("gl_MeshPrimitivesNV", "gl_LayerPerViewNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesNV", "gl_ViewportMaskPerViewNV", 1, &E_GL_NV_mesh_shader); + + BuiltInVariable("gl_MeshPrimitivesNV", "gl_LayerPerViewNV", EbvLayerPerViewNV, symbolTable); + BuiltInVariable("gl_MeshPrimitivesNV", "gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); + + // other builtins + symbolTable.setVariableExtensions("gl_PrimitiveCountNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_PrimitiveIndicesNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshViewCountNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshViewIndicesNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader); + + BuiltInVariable("gl_PrimitiveCountNV", EbvPrimitiveCountNV, symbolTable); + BuiltInVariable("gl_PrimitiveIndicesNV", EbvPrimitiveIndicesNV, symbolTable); + BuiltInVariable("gl_MeshViewCountNV", EbvMeshViewCountNV, symbolTable); + BuiltInVariable("gl_MeshViewIndicesNV", EbvMeshViewIndicesNV, symbolTable); + BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable); + BuiltInVariable("gl_WorkGroupID", EbvWorkGroupId, symbolTable); + BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); + BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); + BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); + + // builtin constants + symbolTable.setVariableExtensions("gl_MaxMeshOutputVerticesNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MaxMeshOutputPrimitivesNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MaxMeshWorkGroupSizeNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV", 1, &E_GL_NV_mesh_shader); + + // builtin functions + symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader); + } + + if (profile != EEsProfile && version >= 450) { + // GL_EXT_device_group + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + + // GL_ARB_shader_draw_parameters + symbolTable.setVariableExtensions("gl_DrawIDARB", 1, &E_GL_ARB_shader_draw_parameters); + BuiltInVariable("gl_DrawIDARB", EbvDrawId, symbolTable); + if (version >= 460) { + BuiltInVariable("gl_DrawID", EbvDrawId, symbolTable); + } + + // GL_ARB_shader_ballot + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan > 0) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + } + + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + + BuiltInVariable("gl_NumSubgroups", EbvNumSubgroups, symbolTable); + BuiltInVariable("gl_SubgroupID", EbvSubgroupID, symbolTable); + BuiltInVariable("gl_SubgroupSize", EbvSubgroupSize2, symbolTable); + BuiltInVariable("gl_SubgroupInvocationID", EbvSubgroupInvocation2, symbolTable); + BuiltInVariable("gl_SubgroupEqMask", EbvSubgroupEqMask2, symbolTable); + BuiltInVariable("gl_SubgroupGeMask", EbvSubgroupGeMask2, symbolTable); + BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); + BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); + BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + + symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); + } + break; + + case EShLangTaskNV: + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + symbolTable.setVariableExtensions("gl_TaskCountNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshViewCountNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshViewIndicesNV", 1, &E_GL_NV_mesh_shader); + + BuiltInVariable("gl_TaskCountNV", EbvTaskCountNV, symbolTable); + BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable); + BuiltInVariable("gl_WorkGroupID", EbvWorkGroupId, symbolTable); + BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); + BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); + BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); + BuiltInVariable("gl_MeshViewCountNV", EbvMeshViewCountNV, symbolTable); + BuiltInVariable("gl_MeshViewIndicesNV", EbvMeshViewIndicesNV, symbolTable); + + symbolTable.setVariableExtensions("gl_MaxTaskWorkGroupSizeNV", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV", 1, &E_GL_NV_mesh_shader); + + symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader); + } + + if (profile != EEsProfile && version >= 450) { + // GL_EXT_device_group + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + + // GL_ARB_shader_draw_parameters + symbolTable.setVariableExtensions("gl_DrawIDARB", 1, &E_GL_ARB_shader_draw_parameters); + BuiltInVariable("gl_DrawIDARB", EbvDrawId, symbolTable); + if (version >= 460) { + BuiltInVariable("gl_DrawID", EbvDrawId, symbolTable); + } + + // GL_ARB_shader_ballot + symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupEqMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupGtMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLeMaskARB", 1, &E_GL_ARB_shader_ballot); + symbolTable.setVariableExtensions("gl_SubGroupLtMaskARB", 1, &E_GL_ARB_shader_ballot); + + BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); + BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); + BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); + BuiltInVariable("gl_SubGroupGtMaskARB", EbvSubGroupGtMask, symbolTable); + BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); + BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); + + if (spvVersion.vulkan > 0) + // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan + SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + else + BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); + } + + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setVariableExtensions("gl_NumSubgroups", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupSize", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupInvocationID", 1, &E_GL_KHR_shader_subgroup_basic); + symbolTable.setVariableExtensions("gl_SubgroupEqMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupGtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLeMask", 1, &E_GL_KHR_shader_subgroup_ballot); + symbolTable.setVariableExtensions("gl_SubgroupLtMask", 1, &E_GL_KHR_shader_subgroup_ballot); + + BuiltInVariable("gl_NumSubgroups", EbvNumSubgroups, symbolTable); + BuiltInVariable("gl_SubgroupID", EbvSubgroupID, symbolTable); + BuiltInVariable("gl_SubgroupSize", EbvSubgroupSize2, symbolTable); + BuiltInVariable("gl_SubgroupInvocationID", EbvSubgroupInvocation2, symbolTable); + BuiltInVariable("gl_SubgroupEqMask", EbvSubgroupEqMask2, symbolTable); + BuiltInVariable("gl_SubgroupGeMask", EbvSubgroupGeMask2, symbolTable); + BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); + BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); + BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); + + symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); + } + break; +#endif default: assert(false && "Language not supported"); @@ -6066,12 +9100,15 @@ symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64); symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble); symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble); -#ifdef AMD_EXTENSIONS + symbolTable.relateToOperator("halfBitsToInt16", EOpFloat16BitsToInt16); + symbolTable.relateToOperator("halfBitsToUint16", EOpFloat16BitsToUint16); symbolTable.relateToOperator("float16BitsToInt16", EOpFloat16BitsToInt16); symbolTable.relateToOperator("float16BitsToUint16", EOpFloat16BitsToUint16); symbolTable.relateToOperator("int16BitsToFloat16", EOpInt16BitsToFloat16); symbolTable.relateToOperator("uint16BitsToFloat16", EOpUint16BitsToFloat16); -#endif + + symbolTable.relateToOperator("int16BitsToHalf", EOpInt16BitsToFloat16); + symbolTable.relateToOperator("uint16BitsToHalf", EOpUint16BitsToFloat16); symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16); symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16); @@ -6094,7 +9131,6 @@ symbolTable.relateToOperator("packUint2x32", EOpPackUint2x32); symbolTable.relateToOperator("unpackUint2x32", EOpUnpackUint2x32); -#ifdef AMD_EXTENSIONS symbolTable.relateToOperator("packInt2x16", EOpPackInt2x16); symbolTable.relateToOperator("unpackInt2x16", EOpUnpackInt2x16); symbolTable.relateToOperator("packUint2x16", EOpPackUint2x16); @@ -6104,10 +9140,16 @@ symbolTable.relateToOperator("unpackInt4x16", EOpUnpackInt4x16); symbolTable.relateToOperator("packUint4x16", EOpPackUint4x16); symbolTable.relateToOperator("unpackUint4x16", EOpUnpackUint4x16); - symbolTable.relateToOperator("packFloat2x16", EOpPackFloat2x16); symbolTable.relateToOperator("unpackFloat2x16", EOpUnpackFloat2x16); -#endif + + symbolTable.relateToOperator("pack16", EOpPack16); + symbolTable.relateToOperator("pack32", EOpPack32); + symbolTable.relateToOperator("pack64", EOpPack64); + + symbolTable.relateToOperator("unpack32", EOpUnpack32); + symbolTable.relateToOperator("unpack16", EOpUnpack16); + symbolTable.relateToOperator("unpack8", EOpUnpack8); symbolTable.relateToOperator("length", EOpLength); symbolTable.relateToOperator("distance", EOpDistance); @@ -6122,6 +9164,7 @@ symbolTable.relateToOperator("all", EOpAll); symbolTable.relateToOperator("barrier", EOpBarrier); + symbolTable.relateToOperator("controlBarrier", EOpBarrier); symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier); symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer); @@ -6135,6 +9178,8 @@ symbolTable.relateToOperator("atomicXor", EOpAtomicXor); symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange); symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap); + symbolTable.relateToOperator("atomicLoad", EOpAtomicLoad); + symbolTable.relateToOperator("atomicStore", EOpAtomicStore); symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement); symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement); @@ -6179,6 +9224,8 @@ symbolTable.relateToOperator("imageAtomicXor", EOpImageAtomicXor); symbolTable.relateToOperator("imageAtomicExchange", EOpImageAtomicExchange); symbolTable.relateToOperator("imageAtomicCompSwap", EOpImageAtomicCompSwap); + symbolTable.relateToOperator("imageAtomicLoad", EOpImageAtomicLoad); + symbolTable.relateToOperator("imageAtomicStore", EOpImageAtomicStore); symbolTable.relateToOperator("subpassLoad", EOpSubpassLoad); symbolTable.relateToOperator("subpassLoadMS", EOpSubpassLoadMS); @@ -6210,6 +9257,14 @@ symbolTable.relateToOperator("noise3", EOpNoise); symbolTable.relateToOperator("noise4", EOpNoise); +#ifdef NV_EXTENSIONS + symbolTable.relateToOperator("textureFootprintNV", EOpImageSampleFootprintNV); + symbolTable.relateToOperator("textureFootprintClampNV", EOpImageSampleFootprintClampNV); + symbolTable.relateToOperator("textureFootprintLodNV", EOpImageSampleFootprintLodNV); + symbolTable.relateToOperator("textureFootprintGradNV", EOpImageSampleFootprintGradNV); + symbolTable.relateToOperator("textureFootprintGradClampNV", EOpImageSampleFootprintGradClampNV); +#endif + if (spvVersion.spv == 0 && (IncludeLegacy(version, profile, spvVersion) || (profile == EEsProfile && version == 100))) { symbolTable.relateToOperator("ftransform", EOpFtransform); @@ -6360,6 +9415,91 @@ symbolTable.relateToOperator("fragmentFetchAMD", EOpFragmentFetch); #endif } + + // GL_KHR_shader_subgroup + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.relateToOperator("subgroupBarrier", EOpSubgroupBarrier); + symbolTable.relateToOperator("subgroupMemoryBarrier", EOpSubgroupMemoryBarrier); + symbolTable.relateToOperator("subgroupMemoryBarrierBuffer", EOpSubgroupMemoryBarrierBuffer); + symbolTable.relateToOperator("subgroupMemoryBarrierImage", EOpSubgroupMemoryBarrierImage); + symbolTable.relateToOperator("subgroupElect", EOpSubgroupElect); + symbolTable.relateToOperator("subgroupAll", EOpSubgroupAll); + symbolTable.relateToOperator("subgroupAny", EOpSubgroupAny); + symbolTable.relateToOperator("subgroupAllEqual", EOpSubgroupAllEqual); + symbolTable.relateToOperator("subgroupBroadcast", EOpSubgroupBroadcast); + symbolTable.relateToOperator("subgroupBroadcastFirst", EOpSubgroupBroadcastFirst); + symbolTable.relateToOperator("subgroupBallot", EOpSubgroupBallot); + symbolTable.relateToOperator("subgroupInverseBallot", EOpSubgroupInverseBallot); + symbolTable.relateToOperator("subgroupBallotBitExtract", EOpSubgroupBallotBitExtract); + symbolTable.relateToOperator("subgroupBallotBitCount", EOpSubgroupBallotBitCount); + symbolTable.relateToOperator("subgroupBallotInclusiveBitCount", EOpSubgroupBallotInclusiveBitCount); + symbolTable.relateToOperator("subgroupBallotExclusiveBitCount", EOpSubgroupBallotExclusiveBitCount); + symbolTable.relateToOperator("subgroupBallotFindLSB", EOpSubgroupBallotFindLSB); + symbolTable.relateToOperator("subgroupBallotFindMSB", EOpSubgroupBallotFindMSB); + symbolTable.relateToOperator("subgroupShuffle", EOpSubgroupShuffle); + symbolTable.relateToOperator("subgroupShuffleXor", EOpSubgroupShuffleXor); + symbolTable.relateToOperator("subgroupShuffleUp", EOpSubgroupShuffleUp); + symbolTable.relateToOperator("subgroupShuffleDown", EOpSubgroupShuffleDown); + symbolTable.relateToOperator("subgroupAdd", EOpSubgroupAdd); + symbolTable.relateToOperator("subgroupMul", EOpSubgroupMul); + symbolTable.relateToOperator("subgroupMin", EOpSubgroupMin); + symbolTable.relateToOperator("subgroupMax", EOpSubgroupMax); + symbolTable.relateToOperator("subgroupAnd", EOpSubgroupAnd); + symbolTable.relateToOperator("subgroupOr", EOpSubgroupOr); + symbolTable.relateToOperator("subgroupXor", EOpSubgroupXor); + symbolTable.relateToOperator("subgroupInclusiveAdd", EOpSubgroupInclusiveAdd); + symbolTable.relateToOperator("subgroupInclusiveMul", EOpSubgroupInclusiveMul); + symbolTable.relateToOperator("subgroupInclusiveMin", EOpSubgroupInclusiveMin); + symbolTable.relateToOperator("subgroupInclusiveMax", EOpSubgroupInclusiveMax); + symbolTable.relateToOperator("subgroupInclusiveAnd", EOpSubgroupInclusiveAnd); + symbolTable.relateToOperator("subgroupInclusiveOr", EOpSubgroupInclusiveOr); + symbolTable.relateToOperator("subgroupInclusiveXor", EOpSubgroupInclusiveXor); + symbolTable.relateToOperator("subgroupExclusiveAdd", EOpSubgroupExclusiveAdd); + symbolTable.relateToOperator("subgroupExclusiveMul", EOpSubgroupExclusiveMul); + symbolTable.relateToOperator("subgroupExclusiveMin", EOpSubgroupExclusiveMin); + symbolTable.relateToOperator("subgroupExclusiveMax", EOpSubgroupExclusiveMax); + symbolTable.relateToOperator("subgroupExclusiveAnd", EOpSubgroupExclusiveAnd); + symbolTable.relateToOperator("subgroupExclusiveOr", EOpSubgroupExclusiveOr); + symbolTable.relateToOperator("subgroupExclusiveXor", EOpSubgroupExclusiveXor); + symbolTable.relateToOperator("subgroupClusteredAdd", EOpSubgroupClusteredAdd); + symbolTable.relateToOperator("subgroupClusteredMul", EOpSubgroupClusteredMul); + symbolTable.relateToOperator("subgroupClusteredMin", EOpSubgroupClusteredMin); + symbolTable.relateToOperator("subgroupClusteredMax", EOpSubgroupClusteredMax); + symbolTable.relateToOperator("subgroupClusteredAnd", EOpSubgroupClusteredAnd); + symbolTable.relateToOperator("subgroupClusteredOr", EOpSubgroupClusteredOr); + symbolTable.relateToOperator("subgroupClusteredXor", EOpSubgroupClusteredXor); + symbolTable.relateToOperator("subgroupQuadBroadcast", EOpSubgroupQuadBroadcast); + symbolTable.relateToOperator("subgroupQuadSwapHorizontal", EOpSubgroupQuadSwapHorizontal); + symbolTable.relateToOperator("subgroupQuadSwapVertical", EOpSubgroupQuadSwapVertical); + symbolTable.relateToOperator("subgroupQuadSwapDiagonal", EOpSubgroupQuadSwapDiagonal); + +#ifdef NV_EXTENSIONS + symbolTable.relateToOperator("subgroupPartitionNV", EOpSubgroupPartition); + symbolTable.relateToOperator("subgroupPartitionedAddNV", EOpSubgroupPartitionedAdd); + symbolTable.relateToOperator("subgroupPartitionedMulNV", EOpSubgroupPartitionedMul); + symbolTable.relateToOperator("subgroupPartitionedMinNV", EOpSubgroupPartitionedMin); + symbolTable.relateToOperator("subgroupPartitionedMaxNV", EOpSubgroupPartitionedMax); + symbolTable.relateToOperator("subgroupPartitionedAndNV", EOpSubgroupPartitionedAnd); + symbolTable.relateToOperator("subgroupPartitionedOrNV", EOpSubgroupPartitionedOr); + symbolTable.relateToOperator("subgroupPartitionedXorNV", EOpSubgroupPartitionedXor); + symbolTable.relateToOperator("subgroupPartitionedInclusiveAddNV", EOpSubgroupPartitionedInclusiveAdd); + symbolTable.relateToOperator("subgroupPartitionedInclusiveMulNV", EOpSubgroupPartitionedInclusiveMul); + symbolTable.relateToOperator("subgroupPartitionedInclusiveMinNV", EOpSubgroupPartitionedInclusiveMin); + symbolTable.relateToOperator("subgroupPartitionedInclusiveMaxNV", EOpSubgroupPartitionedInclusiveMax); + symbolTable.relateToOperator("subgroupPartitionedInclusiveAndNV", EOpSubgroupPartitionedInclusiveAnd); + symbolTable.relateToOperator("subgroupPartitionedInclusiveOrNV", EOpSubgroupPartitionedInclusiveOr); + symbolTable.relateToOperator("subgroupPartitionedInclusiveXorNV", EOpSubgroupPartitionedInclusiveXor); + symbolTable.relateToOperator("subgroupPartitionedExclusiveAddNV", EOpSubgroupPartitionedExclusiveAdd); + symbolTable.relateToOperator("subgroupPartitionedExclusiveMulNV", EOpSubgroupPartitionedExclusiveMul); + symbolTable.relateToOperator("subgroupPartitionedExclusiveMinNV", EOpSubgroupPartitionedExclusiveMin); + symbolTable.relateToOperator("subgroupPartitionedExclusiveMaxNV", EOpSubgroupPartitionedExclusiveMax); + symbolTable.relateToOperator("subgroupPartitionedExclusiveAndNV", EOpSubgroupPartitionedExclusiveAnd); + symbolTable.relateToOperator("subgroupPartitionedExclusiveOrNV", EOpSubgroupPartitionedExclusiveOr); + symbolTable.relateToOperator("subgroupPartitionedExclusiveXorNV", EOpSubgroupPartitionedExclusiveXor); +#endif + } + if (profile == EEsProfile) { symbolTable.relateToOperator("shadow2DEXT", EOpTexture); symbolTable.relateToOperator("shadow2DProjEXT", EOpTextureProj); @@ -6400,14 +9540,69 @@ #ifdef AMD_EXTENSIONS if (profile != EEsProfile) symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex); - break; #endif + break; case EShLangCompute: - symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); - symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); + symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); +#ifdef NV_EXTENSIONS + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 320)) { + symbolTable.relateToOperator("dFdx", EOpDPdx); + symbolTable.relateToOperator("dFdy", EOpDPdy); + symbolTable.relateToOperator("fwidth", EOpFwidth); + symbolTable.relateToOperator("dFdxFine", EOpDPdxFine); + symbolTable.relateToOperator("dFdyFine", EOpDPdyFine); + symbolTable.relateToOperator("fwidthFine", EOpFwidthFine); + symbolTable.relateToOperator("dFdxCoarse", EOpDPdxCoarse); + symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); + symbolTable.relateToOperator("fwidthCoarse",EOpFwidthCoarse); + } +#endif + symbolTable.relateToOperator("coopMatLoadNV", EOpCooperativeMatrixLoad); + symbolTable.relateToOperator("coopMatStoreNV", EOpCooperativeMatrixStore); + symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAdd); break; +#ifdef NV_EXTENSIONS + case EShLangRayGenNV: + case EShLangClosestHitNV: + case EShLangMissNV: + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("traceNV", EOpTraceNV); + symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); + } + break; + case EShLangIntersectNV: + if (profile != EEsProfile && version >= 460) + symbolTable.relateToOperator("reportIntersectionNV", EOpReportIntersectionNV); + break; + case EShLangAnyHitNV: + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("ignoreIntersectionNV", EOpIgnoreIntersectionNV); + symbolTable.relateToOperator("terminateRayNV", EOpTerminateRayNV); + } + break; + case EShLangCallableNV: + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); + } + break; + case EShLangMeshNV: + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + symbolTable.relateToOperator("writePackedPrimitiveIndices4x8NV", EOpWritePackedPrimitiveIndices4x8NV); + } + // fall through + case EShLangTaskNV: + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); + symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + } + break; +#endif + default: assert(false && "Language not supported"); } @@ -6441,9 +9636,9 @@ if (version == 100 || IncludeLegacy(version, profile, spvVersion) || (! ForwardCompatibility && profile != EEsProfile && version < 420)) { TPrecisionQualifier pq = profile == EEsProfile ? EpqMedium : EpqNone; TType fragData(EbtFloat, EvqFragColor, pq, 4); - TArraySizes& arraySizes = *new TArraySizes; - arraySizes.addInnerSize(resources.maxDrawBuffers); - fragData.newArraySizes(arraySizes); + TArraySizes* arraySizes = new TArraySizes; + arraySizes->addInnerSize(resources.maxDrawBuffers); + fragData.transferArraySizes(arraySizes); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable); } @@ -6468,6 +9663,12 @@ BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + + // extension requirements + if (profile == EEsProfile) { + symbolTable.setVariableExtensions("gl_in", "gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); + } + break; default: diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Initialize.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/Initialize.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Initialize.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Initialize.h 2019-10-27 13:44:49.000000000 +0000 @@ -67,7 +67,6 @@ virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; } virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0; - virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0; protected: @@ -89,7 +88,6 @@ void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage); void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable); - void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources); protected: diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2015 LunarG, Inc. -// Copyright (C) 2015-2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -46,6 +47,7 @@ #include #include +#include namespace glslang { @@ -117,18 +119,70 @@ if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) return nullptr; - // Try converting the children's base types to compatible types. - TIntermTyped* child = addConversion(op, left->getType(), right); - if (child) - right = child; - else { - child = addConversion(op, right->getType(), left); - if (child) - left = child; - else + // Convert "reference +/- int" and "reference - reference" to integer math + if ((op == EOpAdd || op == EOpSub) && extensionRequested(E_GL_EXT_buffer_reference2)) { + + // No addressing math on struct with unsized array. + if ((left->getBasicType() == EbtReference && left->getType().getReferentType()->containsUnsizedArray()) || + (right->getBasicType() == EbtReference && right->getType().getReferentType()->containsUnsizedArray())) { + return nullptr; + } + + if (left->getBasicType() == EbtReference && isTypeInt(right->getBasicType())) { + const TType& referenceType = left->getType(); + TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(left->getType()), loc, true); + left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64)); + + right = createConversion(EbtInt64, right); + right = addBinaryMath(EOpMul, right, size, loc); + + TIntermTyped *node = addBinaryMath(op, left, right, loc); + node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); + return node; + } + + if (op == EOpAdd && right->getBasicType() == EbtReference && isTypeInt(left->getBasicType())) { + const TType& referenceType = right->getType(); + TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true); + right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); + + left = createConversion(EbtInt64, left); + left = addBinaryMath(EOpMul, left, size, loc); + + TIntermTyped *node = addBinaryMath(op, left, right, loc); + node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType); + return node; + } + + if (op == EOpSub && left->getBasicType() == EbtReference && right->getBasicType() == EbtReference) { + TIntermConstantUnion* size = addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true); + + left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64)); + right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64)); + + left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64)); + right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64)); + + left = addBinaryMath(EOpSub, left, right, loc); + + TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc); + return node; + } + + // No other math operators supported on references + if (left->getBasicType() == EbtReference || right->getBasicType() == EbtReference) { return nullptr; + } } + // Try converting the children's base types to compatible types. + auto children = addConversion(op, left, right); + left = std::get<0>(children); + right = std::get<1>(children); + + if (left == nullptr || right == nullptr) + return nullptr; + // Convert the children's type shape to be compatible. addBiShapeConversion(op, left, right); if (left == nullptr || right == nullptr) @@ -161,6 +215,11 @@ if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node)) node->getWritableType().getQualifier().makeSpecConstant(); + // If must propagate nonuniform, make a nonuniform. + if ((node->getLeft()->getQualifier().nonUniform || node->getRight()->getQualifier().nonUniform) && + isNonuniformPropagating(node->getOp())) + node->getWritableType().getQualifier().nonUniform = true; + return node; } @@ -228,6 +287,26 @@ if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) return nullptr; + // Convert "reference += int" to "reference = reference + int". We need this because the + // "reference + int" calculation involves a cast back to the original type, which makes it + // not an lvalue. + if ((op == EOpAddAssign || op == EOpSubAssign) && left->getBasicType() == EbtReference && + extensionRequested(E_GL_EXT_buffer_reference2)) { + + if (!(right->getType().isScalar() && right->getType().isIntegerDomain())) + return nullptr; + + TIntermTyped* node = addBinaryMath(op == EOpAddAssign ? EOpAdd : EOpSub, left, right, loc); + if (!node) + return nullptr; + + TIntermSymbol* symbol = left->getAsSymbolNode(); + left = addSymbol(*symbol); + + node = addAssign(EOpAssign, left, node, loc); + return node; + } + // // Like adding binary math, except the conversion can only go // from right to left. @@ -304,20 +383,18 @@ // TBasicType newType = EbtVoid; switch (op) { + case EOpConstructInt8: newType = EbtInt8; break; + case EOpConstructUint8: newType = EbtUint8; break; + case EOpConstructInt16: newType = EbtInt16; break; + case EOpConstructUint16: newType = EbtUint16; break; case EOpConstructInt: newType = EbtInt; break; case EOpConstructUint: newType = EbtUint; break; case EOpConstructInt64: newType = EbtInt64; break; case EOpConstructUint64: newType = EbtUint64; break; -#ifdef AMD_EXTENSIONS - case EOpConstructInt16: newType = EbtInt16; break; - case EOpConstructUint16: newType = EbtUint16; break; -#endif case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; case EOpConstructDouble: newType = EbtDouble; break; -#ifdef AMD_EXTENSIONS case EOpConstructFloat16: newType = EbtFloat16; break; -#endif default: break; // some compilers want this } @@ -336,20 +413,18 @@ // TODO: but, did this bypass constant folding? // switch (op) { + case EOpConstructInt8: + case EOpConstructUint8: + case EOpConstructInt16: + case EOpConstructUint16: case EOpConstructInt: case EOpConstructUint: case EOpConstructInt64: case EOpConstructUint64: -#ifdef AMD_EXTENSIONS - case EOpConstructInt16: - case EOpConstructUint16: -#endif case EOpConstructBool: case EOpConstructFloat: case EOpConstructDouble: -#ifdef AMD_EXTENSIONS case EOpConstructFloat16: -#endif return child; default: break; // some compilers want this } @@ -373,10 +448,15 @@ if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node)) node->getWritableType().getQualifier().makeSpecConstant(); + // If must propagate nonuniform, make a nonuniform. + if (node->getOperand()->getQualifier().nonUniform && isNonuniformPropagating(node->getOp())) + node->getWritableType().getQualifier().nonUniform = true; + return node; } -TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType) +TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, + TIntermNode* childNode, const TType& returnType) { if (unary) { // @@ -406,7 +486,7 @@ // // This is the safe way to change the operator on an aggregate, as it // does lots of error checking and fixing. Especially for establishing -// a function call's operation on it's set of parameters. Sequences +// a function call's operation on its set of parameters. Sequences // of instructions are also aggregates, but they just directly set // their operator to EOpSequence. // @@ -420,7 +500,7 @@ // // Make sure we have an aggregate. If not turn it into one. // - if (node) { + if (node != nullptr) { aggNode = node->getAsAggregate(); if (aggNode == nullptr || aggNode->getOp() != EOpNull) { // @@ -446,29 +526,19 @@ return fold(aggNode); } -// -// Convert the node's type to the given type, as allowed by the operation involved: 'op'. -// For implicit conversions, 'op' is not the requested conversion, it is the explicit -// operation requiring the implicit conversion. -// -// Returns a node representing the conversion, which could be the same -// node passed in if no conversion was needed. -// -// Generally, this is focused on basic type conversion, not shape conversion. -// See addShapeConversion(). -// -// Return nullptr if a conversion can't be done. -// -TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const +bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const { // // Does the base type even allow the operation? // switch (node->getBasicType()) { case EbtVoid: - return nullptr; + return false; case EbtAtomicUint: case EbtSampler: +#ifdef NV_EXTENSIONS + case EbtAccStructNV: +#endif // opaque types can be passed to functions if (op == EOpFunction) break; @@ -484,239 +554,119 @@ break; // otherwise, opaque types can't even be operated on, let alone converted - return nullptr; + return false; default: break; } - // Otherwise, if types are identical, no problem - if (type == node->getType()) - return node; - - // If one's a structure, then no conversions. - if (type.isStruct() || node->isStruct()) - return nullptr; - - // If one's an array, then no conversions. - if (type.isArray() || node->getType().isArray()) - return nullptr; - - // Note: callers are responsible for other aspects of shape, - // like vector and matrix sizes. - - TBasicType promoteTo; - - switch (op) { - // - // Explicit conversions (unary operations) - // - case EOpConstructBool: - promoteTo = EbtBool; - break; - case EOpConstructFloat: - promoteTo = EbtFloat; - break; - case EOpConstructDouble: - promoteTo = EbtDouble; - break; -#ifdef AMD_EXTENSIONS - case EOpConstructFloat16: - promoteTo = EbtFloat16; - break; -#endif - case EOpConstructInt: - promoteTo = EbtInt; - break; - case EOpConstructUint: - promoteTo = EbtUint; - break; - case EOpConstructInt64: - promoteTo = EbtInt64; - break; - case EOpConstructUint64: - promoteTo = EbtUint64; - break; -#ifdef AMD_EXTENSIONS - case EOpConstructInt16: - promoteTo = EbtInt16; - break; - case EOpConstructUint16: - promoteTo = EbtUint16; - break; -#endif + return true; +} +// This is 'mechanism' here, it does any conversion told. +// It is about basic type, not about shape. +// The policy comes from the shader or the calling code. +TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const +{ // - // List all the binary ops that can implicitly convert one operand to the other's type; - // This implements the 'policy' for implicit type conversion. + // Add a new newNode for the conversion. // - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - case EOpEqual: - case EOpNotEqual: - - case EOpAdd: - case EOpSub: - case EOpMul: - case EOpDiv: - case EOpMod: + TIntermUnary* newNode = nullptr; - case EOpVectorTimesScalar: - case EOpVectorTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: + TOperator newOp = EOpNull; - case EOpAnd: - case EOpInclusiveOr: - case EOpExclusiveOr: - case EOpAndAssign: - case EOpInclusiveOrAssign: - case EOpExclusiveOrAssign: - case EOpLogicalNot: - case EOpLogicalAnd: - case EOpLogicalOr: - case EOpLogicalXor: + // Certain explicit conversions are allowed conditionally + bool arithemeticInt8Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); +#ifdef AMD_EXTENSIONS + bool arithemeticInt16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) || + extensionRequested(E_GL_AMD_gpu_shader_int16); + + bool arithemeticFloat16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) || + extensionRequested(E_GL_AMD_gpu_shader_half_float); +#else + bool arithemeticInt16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); - case EOpFunctionCall: - case EOpReturn: - case EOpAssign: - case EOpAddAssign: - case EOpSubAssign: - case EOpMulAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpDivAssign: - case EOpModAssign: + bool arithemeticFloat16Enabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); +#endif + bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 || + convertTo == EbtInt16 || convertTo == EbtUint16 || + convertTo == EbtInt || convertTo == EbtUint || + convertTo == EbtInt64 || convertTo == EbtUint64); - case EOpAtan: - case EOpClamp: - case EOpCross: - case EOpDistance: - case EOpDot: - case EOpDst: - case EOpFaceForward: - case EOpFma: - case EOpFrexp: - case EOpLdexp: - case EOpMix: - case EOpLit: - case EOpMax: - case EOpMin: - case EOpModf: - case EOpPow: - case EOpReflect: - case EOpRefract: - case EOpSmoothStep: - case EOpStep: + bool convertFromIntTypes = (node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8 || + node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16 || + node->getBasicType() == EbtInt || node->getBasicType() == EbtUint || + node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64); - case EOpSequence: - case EOpConstructStruct: + bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble); - if (type.getBasicType() == node->getType().getBasicType()) - return node; + bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 || + node->getBasicType() == EbtFloat || + node->getBasicType() == EbtDouble); - if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType(), op)) - promoteTo = type.getBasicType(); - else + if (! arithemeticInt8Enabled) { + if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) return nullptr; + } - break; - - // Shifts can have mixed types as long as they are integer, without converting. - // It's the left operand's type that determines the resulting type, so no issue - // with assign shift ops either. - case EOpLeftShift: - case EOpRightShift: - case EOpLeftShiftAssign: - case EOpRightShiftAssign: - if ((type.getBasicType() == EbtInt || - type.getBasicType() == EbtUint || -#ifdef AMD_EXTENSIONS - type.getBasicType() == EbtInt16 || - type.getBasicType() == EbtUint16 || -#endif - type.getBasicType() == EbtInt64 || - type.getBasicType() == EbtUint64) && - (node->getType().getBasicType() == EbtInt || - node->getType().getBasicType() == EbtUint || -#ifdef AMD_EXTENSIONS - node->getType().getBasicType() == EbtInt16 || - node->getType().getBasicType() == EbtUint16 || -#endif - node->getType().getBasicType() == EbtInt64 || - node->getType().getBasicType() == EbtUint64)) - - return node; - else if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) { - promoteTo = type.getBasicType(); - break; - } else + if (! arithemeticInt16Enabled) { + if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) return nullptr; + } - default: - // default is to require a match; all exceptions should have case statements above - - if (type.getBasicType() == node->getType().getBasicType()) - return node; - else + if (! arithemeticFloat16Enabled) { + if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) || + (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) return nullptr; } - if (node->getAsConstantUnion()) - return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); - - // - // Add a new newNode for the conversion. - // - TIntermUnary* newNode = nullptr; - - TOperator newOp = EOpNull; - - // This is 'mechanism' here, it does any conversion told. The policy comes - // from the shader or the above code. - switch (promoteTo) { + switch (convertTo) { case EbtDouble: switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToDouble; break; - case EbtUint: newOp = EOpConvUintToDouble; break; - case EbtBool: newOp = EOpConvBoolToDouble; break; - case EbtFloat: newOp = EOpConvFloatToDouble; break; -#ifdef AMD_EXTENSIONS + case EbtInt8: newOp = EOpConvInt8ToDouble; break; + case EbtUint8: newOp = EOpConvUint8ToDouble; break; + case EbtInt16: newOp = EOpConvInt16ToDouble; break; + case EbtUint16: newOp = EOpConvUint16ToDouble; break; + case EbtInt: newOp = EOpConvIntToDouble; break; + case EbtUint: newOp = EOpConvUintToDouble; break; + case EbtBool: newOp = EOpConvBoolToDouble; break; + case EbtFloat: newOp = EOpConvFloatToDouble; break; case EbtFloat16: newOp = EOpConvFloat16ToDouble; break; -#endif - case EbtInt64: newOp = EOpConvInt64ToDouble; break; - case EbtUint64: newOp = EOpConvUint64ToDouble; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToDouble; break; - case EbtUint16: newOp = EOpConvUint16ToDouble; break; -#endif + case EbtInt64: newOp = EOpConvInt64ToDouble; break; + case EbtUint64: newOp = EOpConvUint64ToDouble; break; default: return nullptr; } break; case EbtFloat: switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToFloat; break; - case EbtUint: newOp = EOpConvUintToFloat; break; - case EbtBool: newOp = EOpConvBoolToFloat; break; - case EbtDouble: newOp = EOpConvDoubleToFloat; break; -#ifdef AMD_EXTENSIONS + case EbtInt8: newOp = EOpConvInt8ToFloat; break; + case EbtUint8: newOp = EOpConvUint8ToFloat; break; + case EbtInt16: newOp = EOpConvInt16ToFloat; break; + case EbtUint16: newOp = EOpConvUint16ToFloat; break; + case EbtInt: newOp = EOpConvIntToFloat; break; + case EbtUint: newOp = EOpConvUintToFloat; break; + case EbtBool: newOp = EOpConvBoolToFloat; break; + case EbtDouble: newOp = EOpConvDoubleToFloat; break; case EbtFloat16: newOp = EOpConvFloat16ToFloat; break; -#endif - case EbtInt64: newOp = EOpConvInt64ToFloat; break; - case EbtUint64: newOp = EOpConvUint64ToFloat; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToFloat; break; - case EbtUint16: newOp = EOpConvUint16ToFloat; break; -#endif + case EbtInt64: newOp = EOpConvInt64ToFloat; break; + case EbtUint64: newOp = EOpConvUint64ToFloat; break; default: return nullptr; } break; -#ifdef AMD_EXTENSIONS case EbtFloat16: switch (node->getBasicType()) { + case EbtInt8: newOp = EOpConvInt8ToFloat16; break; + case EbtUint8: newOp = EOpConvUint8ToFloat16; break; + case EbtInt16: newOp = EOpConvInt16ToFloat16; break; + case EbtUint16: newOp = EOpConvUint16ToFloat16; break; case EbtInt: newOp = EOpConvIntToFloat16; break; case EbtUint: newOp = EOpConvUintToFloat16; break; case EbtBool: newOp = EOpConvBoolToFloat16; break; @@ -724,148 +674,177 @@ case EbtDouble: newOp = EOpConvDoubleToFloat16; break; case EbtInt64: newOp = EOpConvInt64ToFloat16; break; case EbtUint64: newOp = EOpConvUint64ToFloat16; break; - case EbtInt16: newOp = EOpConvInt16ToFloat16; break; - case EbtUint16: newOp = EOpConvUint16ToFloat16; break; default: return nullptr; } break; -#endif case EbtBool: switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToBool; break; - case EbtUint: newOp = EOpConvUintToBool; break; - case EbtFloat: newOp = EOpConvFloatToBool; break; - case EbtDouble: newOp = EOpConvDoubleToBool; break; -#ifdef AMD_EXTENSIONS + case EbtInt8: newOp = EOpConvInt8ToBool; break; + case EbtUint8: newOp = EOpConvUint8ToBool; break; + case EbtInt16: newOp = EOpConvInt16ToBool; break; + case EbtUint16: newOp = EOpConvUint16ToBool; break; + case EbtInt: newOp = EOpConvIntToBool; break; + case EbtUint: newOp = EOpConvUintToBool; break; + case EbtFloat: newOp = EOpConvFloatToBool; break; + case EbtDouble: newOp = EOpConvDoubleToBool; break; case EbtFloat16: newOp = EOpConvFloat16ToBool; break; -#endif - case EbtInt64: newOp = EOpConvInt64ToBool; break; - case EbtUint64: newOp = EOpConvUint64ToBool; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToBool; break; - case EbtUint16: newOp = EOpConvUint16ToBool; break; -#endif + case EbtInt64: newOp = EOpConvInt64ToBool; break; + case EbtUint64: newOp = EOpConvUint64ToBool; break; default: return nullptr; } break; - case EbtInt: + case EbtInt8: switch (node->getBasicType()) { - case EbtUint: newOp = EOpConvUintToInt; break; - case EbtBool: newOp = EOpConvBoolToInt; break; - case EbtFloat: newOp = EOpConvFloatToInt; break; - case EbtDouble: newOp = EOpConvDoubleToInt; break; -#ifdef AMD_EXTENSIONS - case EbtFloat16: newOp = EOpConvFloat16ToInt; break; -#endif - case EbtInt64: newOp = EOpConvInt64ToInt; break; - case EbtUint64: newOp = EOpConvUint64ToInt; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToInt; break; - case EbtUint16: newOp = EOpConvUint16ToInt; break; -#endif + case EbtUint8: newOp = EOpConvUint8ToInt8; break; + case EbtInt16: newOp = EOpConvInt16ToInt8; break; + case EbtUint16: newOp = EOpConvUint16ToInt8; break; + case EbtInt: newOp = EOpConvIntToInt8; break; + case EbtUint: newOp = EOpConvUintToInt8; break; + case EbtInt64: newOp = EOpConvInt64ToInt8; break; + case EbtUint64: newOp = EOpConvUint64ToInt8; break; + case EbtBool: newOp = EOpConvBoolToInt8; break; + case EbtFloat: newOp = EOpConvFloatToInt8; break; + case EbtDouble: newOp = EOpConvDoubleToInt8; break; + case EbtFloat16: newOp = EOpConvFloat16ToInt8; break; default: return nullptr; } break; - case EbtUint: + case EbtUint8: switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToUint; break; - case EbtBool: newOp = EOpConvBoolToUint; break; - case EbtFloat: newOp = EOpConvFloatToUint; break; - case EbtDouble: newOp = EOpConvDoubleToUint; break; -#ifdef AMD_EXTENSIONS - case EbtFloat16: newOp = EOpConvFloat16ToUint; break; -#endif - case EbtInt64: newOp = EOpConvInt64ToUint; break; - case EbtUint64: newOp = EOpConvUint64ToUint; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToUint; break; - case EbtUint16: newOp = EOpConvUint16ToUint; break; -#endif - default: - return nullptr; - } - break; - case EbtInt64: - switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToInt64; break; - case EbtUint: newOp = EOpConvUintToInt64; break; - case EbtBool: newOp = EOpConvBoolToInt64; break; - case EbtFloat: newOp = EOpConvFloatToInt64; break; - case EbtDouble: newOp = EOpConvDoubleToInt64; break; -#ifdef AMD_EXTENSIONS - case EbtFloat16: newOp = EOpConvFloat16ToInt64; break; -#endif - case EbtUint64: newOp = EOpConvUint64ToInt64; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToInt64; break; - case EbtUint16: newOp = EOpConvUint16ToInt64; break; -#endif - default: - return nullptr; - } - break; - case EbtUint64: - switch (node->getBasicType()) { - case EbtInt: newOp = EOpConvIntToUint64; break; - case EbtUint: newOp = EOpConvUintToUint64; break; - case EbtBool: newOp = EOpConvBoolToUint64; break; - case EbtFloat: newOp = EOpConvFloatToUint64; break; - case EbtDouble: newOp = EOpConvDoubleToUint64; break; -#ifdef AMD_EXTENSIONS - case EbtFloat16: newOp = EOpConvFloat16ToUint64; break; -#endif - case EbtInt64: newOp = EOpConvInt64ToUint64; break; -#ifdef AMD_EXTENSIONS - case EbtInt16: newOp = EOpConvInt16ToUint64; break; - case EbtUint16: newOp = EOpConvUint16ToUint64; break; -#endif + case EbtInt8: newOp = EOpConvInt8ToUint8; break; + case EbtInt16: newOp = EOpConvInt16ToUint8; break; + case EbtUint16: newOp = EOpConvUint16ToUint8; break; + case EbtInt: newOp = EOpConvIntToUint8; break; + case EbtUint: newOp = EOpConvUintToUint8; break; + case EbtInt64: newOp = EOpConvInt64ToUint8; break; + case EbtUint64: newOp = EOpConvUint64ToUint8; break; + case EbtBool: newOp = EOpConvBoolToUint8; break; + case EbtFloat: newOp = EOpConvFloatToUint8; break; + case EbtDouble: newOp = EOpConvDoubleToUint8; break; + case EbtFloat16: newOp = EOpConvFloat16ToUint8; break; default: return nullptr; } break; -#ifdef AMD_EXTENSIONS + case EbtInt16: switch (node->getBasicType()) { + case EbtUint8: newOp = EOpConvUint8ToInt16; break; + case EbtInt8: newOp = EOpConvInt8ToInt16; break; + case EbtUint16: newOp = EOpConvUint16ToInt16; break; case EbtInt: newOp = EOpConvIntToInt16; break; case EbtUint: newOp = EOpConvUintToInt16; break; + case EbtInt64: newOp = EOpConvInt64ToInt16; break; + case EbtUint64: newOp = EOpConvUint64ToInt16; break; case EbtBool: newOp = EOpConvBoolToInt16; break; case EbtFloat: newOp = EOpConvFloatToInt16; break; case EbtDouble: newOp = EOpConvDoubleToInt16; break; case EbtFloat16: newOp = EOpConvFloat16ToInt16; break; - case EbtInt64: newOp = EOpConvInt64ToInt16; break; - case EbtUint64: newOp = EOpConvUint64ToInt16; break; - case EbtUint16: newOp = EOpConvUint16ToInt16; break; default: return nullptr; } break; case EbtUint16: switch (node->getBasicType()) { + case EbtInt8: newOp = EOpConvInt8ToUint16; break; + case EbtUint8: newOp = EOpConvUint8ToUint16; break; + case EbtInt16: newOp = EOpConvInt16ToUint16; break; case EbtInt: newOp = EOpConvIntToUint16; break; case EbtUint: newOp = EOpConvUintToUint16; break; + case EbtInt64: newOp = EOpConvInt64ToUint16; break; + case EbtUint64: newOp = EOpConvUint64ToUint16; break; case EbtBool: newOp = EOpConvBoolToUint16; break; case EbtFloat: newOp = EOpConvFloatToUint16; break; case EbtDouble: newOp = EOpConvDoubleToUint16; break; case EbtFloat16: newOp = EOpConvFloat16ToUint16; break; - case EbtInt64: newOp = EOpConvInt64ToUint16; break; - case EbtUint64: newOp = EOpConvUint64ToUint16; break; - case EbtInt16: newOp = EOpConvInt16ToUint16; break; default: return nullptr; } break; -#endif + + case EbtInt: + switch (node->getBasicType()) { + case EbtInt8: newOp = EOpConvInt8ToInt; break; + case EbtUint8: newOp = EOpConvUint8ToInt; break; + case EbtInt16: newOp = EOpConvInt16ToInt; break; + case EbtUint16: newOp = EOpConvUint16ToInt; break; + case EbtUint: newOp = EOpConvUintToInt; break; + case EbtBool: newOp = EOpConvBoolToInt; break; + case EbtFloat: newOp = EOpConvFloatToInt; break; + case EbtDouble: newOp = EOpConvDoubleToInt; break; + case EbtFloat16: newOp = EOpConvFloat16ToInt; break; + case EbtInt64: newOp = EOpConvInt64ToInt; break; + case EbtUint64: newOp = EOpConvUint64ToInt; break; + default: + return nullptr; + } + break; + case EbtUint: + switch (node->getBasicType()) { + case EbtInt8: newOp = EOpConvInt8ToUint; break; + case EbtUint8: newOp = EOpConvUint8ToUint; break; + case EbtInt16: newOp = EOpConvInt16ToUint; break; + case EbtUint16: newOp = EOpConvUint16ToUint; break; + case EbtInt: newOp = EOpConvIntToUint; break; + case EbtBool: newOp = EOpConvBoolToUint; break; + case EbtFloat: newOp = EOpConvFloatToUint; break; + case EbtDouble: newOp = EOpConvDoubleToUint; break; + case EbtFloat16: newOp = EOpConvFloat16ToUint; break; + case EbtInt64: newOp = EOpConvInt64ToUint; break; + case EbtUint64: newOp = EOpConvUint64ToUint; break; + default: + return nullptr; + } + break; + case EbtInt64: + switch (node->getBasicType()) { + case EbtInt8: newOp = EOpConvInt8ToInt64; break; + case EbtUint8: newOp = EOpConvUint8ToInt64; break; + case EbtInt16: newOp = EOpConvInt16ToInt64; break; + case EbtUint16: newOp = EOpConvUint16ToInt64; break; + case EbtInt: newOp = EOpConvIntToInt64; break; + case EbtUint: newOp = EOpConvUintToInt64; break; + case EbtBool: newOp = EOpConvBoolToInt64; break; + case EbtFloat: newOp = EOpConvFloatToInt64; break; + case EbtDouble: newOp = EOpConvDoubleToInt64; break; + case EbtFloat16: newOp = EOpConvFloat16ToInt64; break; + case EbtUint64: newOp = EOpConvUint64ToInt64; break; + default: + return nullptr; + } + break; + case EbtUint64: + switch (node->getBasicType()) { + case EbtInt8: newOp = EOpConvInt8ToUint64; break; + case EbtUint8: newOp = EOpConvUint8ToUint64; break; + case EbtInt16: newOp = EOpConvInt16ToUint64; break; + case EbtUint16: newOp = EOpConvUint16ToUint64; break; + case EbtInt: newOp = EOpConvIntToUint64; break; + case EbtUint: newOp = EOpConvUintToUint64; break; + case EbtBool: newOp = EOpConvBoolToUint64; break; + case EbtFloat: newOp = EOpConvFloatToUint64; break; + case EbtDouble: newOp = EOpConvDoubleToUint64; break; + case EbtFloat16: newOp = EOpConvFloat16ToUint64; break; + case EbtInt64: newOp = EOpConvInt64ToUint64; break; + default: + return nullptr; + } + break; default: return nullptr; } - TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); + TType newType(convertTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); newNode = addUnaryNode(newOp, node, node->getLoc(), newType); - // TODO: it seems that some unary folding operations should occur here, but are not + if (node->getAsConstantUnion()) { + TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType); + if (folded) + return folded; + } // Propagate specialization-constant-ness, if allowed if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode)) @@ -874,6 +853,329 @@ return newNode; } +TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const +{ + return createConversion(convertTo, node); +} + +// For converting a pair of operands to a binary operation to compatible +// types with each other, relative to the operation in 'op'. +// This does not cover assignment operations, which is asymmetric in that the +// left type is not changeable. +// See addConversion(op, type, node) for assignments and unary operation +// conversions. +// +// Generally, this is focused on basic type conversion, not shape conversion. +// See addShapeConversion() for shape conversions. +// +// Returns the converted pair of nodes. +// Returns when there is no conversion. +std::tuple +TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) +{ + if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1)) + return std::make_tuple(nullptr, nullptr); + + if (node0->getType() != node1->getType()) { + // If differing structure, then no conversions. + if (node0->isStruct() || node1->isStruct()) + return std::make_tuple(nullptr, nullptr); + + // If differing arrays, then no conversions. + if (node0->getType().isArray() || node1->getType().isArray()) + return std::make_tuple(nullptr, nullptr); + + // No implicit conversions for operations involving cooperative matrices + if (node0->getType().isCoopMat() || node1->getType().isCoopMat()) + return std::make_tuple(node0, node1); + } + + auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes); + + switch (op) { + // + // List all the binary ops that can implicitly convert one operand to the other's type; + // This implements the 'policy' for implicit type conversion. + // + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + case EOpEqual: + case EOpNotEqual: + + case EOpAdd: + case EOpSub: + case EOpMul: + case EOpDiv: + case EOpMod: + + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + + case EOpSequence: // used by ?: + + if (node0->getBasicType() == node1->getBasicType()) + return std::make_tuple(node0, node1); + + promoteTo = getConversionDestinatonType(node0->getBasicType(), node1->getBasicType(), op); + if (std::get<0>(promoteTo) == EbtNumTypes || std::get<1>(promoteTo) == EbtNumTypes) + return std::make_tuple(nullptr, nullptr); + + break; + + case EOpLogicalAnd: + case EOpLogicalOr: + case EOpLogicalXor: + if (source == EShSourceHlsl) + promoteTo = std::make_tuple(EbtBool, EbtBool); + else + return std::make_tuple(node0, node1); + break; + + // There are no conversions needed for GLSL; the shift amount just needs to be an + // integer type, as does the base. + // HLSL can promote bools to ints to make this work. + case EOpLeftShift: + case EOpRightShift: + if (source == EShSourceHlsl) { + TBasicType node0BasicType = node0->getBasicType(); + if (node0BasicType == EbtBool) + node0BasicType = EbtInt; + if (node1->getBasicType() == EbtBool) + promoteTo = std::make_tuple(node0BasicType, EbtInt); + else + promoteTo = std::make_tuple(node0BasicType, node1->getBasicType()); + } else { + if (isTypeInt(node0->getBasicType()) && isTypeInt(node1->getBasicType())) + return std::make_tuple(node0, node1); + else + return std::make_tuple(nullptr, nullptr); + } + break; + + default: + if (node0->getType() == node1->getType()) + return std::make_tuple(node0, node1); + + return std::make_tuple(nullptr, nullptr); + } + + TIntermTyped* newNode0; + TIntermTyped* newNode1; + + if (std::get<0>(promoteTo) != node0->getType().getBasicType()) { + if (node0->getAsConstantUnion()) + newNode0 = promoteConstantUnion(std::get<0>(promoteTo), node0->getAsConstantUnion()); + else + newNode0 = createConversion(std::get<0>(promoteTo), node0); + } else + newNode0 = node0; + + if (std::get<1>(promoteTo) != node1->getType().getBasicType()) { + if (node1->getAsConstantUnion()) + newNode1 = promoteConstantUnion(std::get<1>(promoteTo), node1->getAsConstantUnion()); + else + newNode1 = createConversion(std::get<1>(promoteTo), node1); + } else + newNode1 = node1; + + return std::make_tuple(newNode0, newNode1); +} + +// +// Convert the node's type to the given type, as allowed by the operation involved: 'op'. +// For implicit conversions, 'op' is not the requested conversion, it is the explicit +// operation requiring the implicit conversion. +// +// Binary operation conversions should be handled by addConversion(op, node, node), not here. +// +// Returns a node representing the conversion, which could be the same +// node passed in if no conversion was needed. +// +// Generally, this is focused on basic type conversion, not shape conversion. +// See addShapeConversion() for shape conversions. +// +// Return nullptr if a conversion can't be done. +// +TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) +{ + if (!isConversionAllowed(op, node)) + return nullptr; + + // Otherwise, if types are identical, no problem + if (type == node->getType()) + return node; + + // If one's a structure, then no conversions. + if (type.isStruct() || node->isStruct()) + return nullptr; + + // If one's an array, then no conversions. + if (type.isArray() || node->getType().isArray()) + return nullptr; + + // Note: callers are responsible for other aspects of shape, + // like vector and matrix sizes. + + TBasicType promoteTo; + // GL_EXT_shader_16bit_storage can't do OpConstantComposite with + // 16-bit types, so disable promotion for those types. + bool canPromoteConstant = true; + + switch (op) { + // + // Explicit conversions (unary operations) + // + case EOpConstructBool: + promoteTo = EbtBool; + break; + case EOpConstructFloat: + promoteTo = EbtFloat; + break; + case EOpConstructDouble: + promoteTo = EbtDouble; + break; + case EOpConstructFloat16: + promoteTo = EbtFloat16; + canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); + break; + case EOpConstructInt8: + promoteTo = EbtInt8; + canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); + break; + case EOpConstructUint8: + promoteTo = EbtUint8; + canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); + break; + case EOpConstructInt16: + promoteTo = EbtInt16; + canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); + break; + case EOpConstructUint16: + promoteTo = EbtUint16; + canPromoteConstant = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); + break; + case EOpConstructInt: + promoteTo = EbtInt; + break; + case EOpConstructUint: + promoteTo = EbtUint; + break; + case EOpConstructInt64: + promoteTo = EbtInt64; + break; + case EOpConstructUint64: + promoteTo = EbtUint64; + break; + + case EOpLogicalNot: + + case EOpFunctionCall: + + case EOpReturn: + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpDivAssign: + case EOpModAssign: + case EOpAndAssign: + case EOpInclusiveOrAssign: + case EOpExclusiveOrAssign: + + case EOpAtan: + case EOpClamp: + case EOpCross: + case EOpDistance: + case EOpDot: + case EOpDst: + case EOpFaceForward: + case EOpFma: + case EOpFrexp: + case EOpLdexp: + case EOpMix: + case EOpLit: + case EOpMax: + case EOpMin: + case EOpModf: + case EOpPow: + case EOpReflect: + case EOpRefract: + case EOpSmoothStep: + case EOpStep: + + case EOpSequence: + case EOpConstructStruct: + case EOpConstructCooperativeMatrix: + + if (type.getBasicType() == EbtReference || node->getType().getBasicType() == EbtReference) { + // types must match to assign a reference + if (type == node->getType()) + return node; + else + return nullptr; + } + + if (type.getBasicType() == node->getType().getBasicType()) + return node; + + if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op)) + promoteTo = type.getBasicType(); + else + return nullptr; + break; + + // For GLSL, there are no conversions needed; the shift amount just needs to be an + // integer type, as do the base/result. + // HLSL can convert the shift from a bool to an int. + case EOpLeftShiftAssign: + case EOpRightShiftAssign: + { + if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) + promoteTo = type.getBasicType(); + else { + if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType())) + return node; + else + return nullptr; + } + break; + } + + default: + // default is to require a match; all exceptions should have case statements above + + if (type.getBasicType() == node->getType().getBasicType()) + return node; + else + return nullptr; + } + + if (canPromoteConstant && node->getAsConstantUnion()) + return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); + + // + // Add a new newNode for the conversion. + // + TIntermTyped* newNode = createConversion(promoteTo, node); + + return newNode; +} + // Convert the node's shape of type for the given type, as allowed by the // operation involved: 'op'. This is for situations where there is only one // direction to consider doing the shape conversion. @@ -967,9 +1269,12 @@ rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode); return; + case EOpMul: + // matrix multiply does not change shapes + if (lhsNode->isMatrix() && rhsNode->isMatrix()) + return; case EOpAdd: case EOpSub: - case EOpMul: case EOpDiv: // want to support vector * scalar native ops in AST and lower, not smear, similarly for // matrix * vector, etc. @@ -1019,12 +1324,11 @@ rhsNode = addShapeConversion(lhsNode->getType(), rhsNode); } -// Convert the node's shape of type for the given type. It's not necessarily -// an error if they are different and not converted, as some operations accept -// mixed types. Promotion will do final shape checking. +// Convert the node's shape of type for the given type, as allowed by the +// operation involved: 'op'. // -// If there is a chance of two nodes, with conversions possible in each direction, -// the policy for what to ask for must be in the caller; this will do what is asked. +// Generally, the AST represents allowed GLSL shapes, so this isn't needed +// for GLSL. Bad shapes are caught in conversion or promotion. // // Return 'node' if no conversion was done. Promotion handles final shape // checking. @@ -1043,9 +1347,19 @@ // The new node that handles the conversion TOperator constructorOp = mapTypeToConstructorOp(type); - // HLSL has custom semantics for scalar->mat shape conversions. if (source == EShSourceHlsl) { - if (node->getType().isScalarOrVec1() && type.isMatrix()) { + // HLSL rules for scalar, vector and matrix conversions: + // 1) scalar can become anything, initializing every component with its value + // 2) vector and matrix can become scalar, first element is used (warning: truncation) + // 3) matrix can become matrix with less rows and/or columns (warning: truncation) + // 4) vector can become vector with less rows size (warning: truncation) + // 5a) vector 4 can become 2x2 matrix (special case) (same packing layout, its a reinterpret) + // 5b) 2x2 matrix can become vector 4 (special case) (same packing layout, its a reinterpret) + + const TType &sourceType = node->getType(); + + // rule 1 for scalar to matrix is special + if (sourceType.isScalarOrVec1() && type.isMatrix()) { // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its // own devices, the constructor from a scalar would populate the diagonal. This forces replication @@ -1053,7 +1367,7 @@ // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here // repeatedly, so we copy it to a temp, then use the temp. - const int matSize = type.getMatrixRows() * type.getMatrixCols(); + const int matSize = type.computeNumComponents(); TIntermAggregate* rhsAggregate = new TIntermAggregate(); const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr); @@ -1061,23 +1375,215 @@ if (!isSimple) { assert(0); // TODO: use node replicator service when available. } - - for (int x=0; xgetSequence().push_back(node); return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc()); } - } - - // scalar -> vector or vec1 -> vector or - // vector -> scalar or - // bigger vector -> smaller vector - if ((node->getType().isScalarOrVec1() && type.isVector()) || - (node->getType().isVector() && type.isScalar()) || - (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize())) - return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); - return node; + // rule 1 and 2 + if ((sourceType.isScalar() && !type.isScalar()) || (!sourceType.isScalar() && type.isScalar())) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + + // rule 3 and 5b + if (sourceType.isMatrix()) { + // rule 3 + if (type.isMatrix()) { + if ((sourceType.getMatrixCols() != type.getMatrixCols() || sourceType.getMatrixRows() != type.getMatrixRows()) && + sourceType.getMatrixCols() >= type.getMatrixCols() && sourceType.getMatrixRows() >= type.getMatrixRows()) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + // rule 5b + } else if (type.isVector()) { + if (type.getVectorSize() == 4 && sourceType.getMatrixCols() == 2 && sourceType.getMatrixRows() == 2) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + } + } + + // rule 4 and 5a + if (sourceType.isVector()) { + // rule 4 + if (type.isVector()) + { + if (sourceType.getVectorSize() > type.getVectorSize()) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + // rule 5a + } else if (type.isMatrix()) { + if (sourceType.getVectorSize() == 4 && type.getMatrixCols() == 2 && type.getMatrixRows() == 2) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + } + } + } + + // scalar -> vector or vec1 -> vector or + // vector -> scalar or + // bigger vector -> smaller vector + if ((node->getType().isScalarOrVec1() && type.isVector()) || + (node->getType().isVector() && type.isScalar()) || + (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize())) + return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); + + return node; +} + +bool TIntermediate::isIntegralPromotion(TBasicType from, TBasicType to) const +{ + // integral promotions + if (to == EbtInt) { + switch(from) { + case EbtInt8: + case EbtInt16: + case EbtUint8: + case EbtUint16: + return true; + default: + break; + } + } + return false; +} + +bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const +{ + // floating-point promotions + if (to == EbtDouble) { + switch(from) { + case EbtFloat16: + case EbtFloat: + return true; + default: + break; + } + } + return false; +} + +bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const +{ + switch (from) { + case EbtInt8: + switch (to) { + case EbtUint8: + case EbtInt16: + case EbtUint16: + case EbtUint: + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtUint8: + switch (to) { + case EbtInt16: + case EbtUint16: + case EbtUint: + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtInt16: + switch(to) { + case EbtUint16: + case EbtUint: + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtUint16: + switch(to) { + case EbtUint: + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtInt: + switch(to) { + case EbtUint: + return version >= 400 || (source == EShSourceHlsl); + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtUint: + switch(to) { + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtInt64: + if (to == EbtUint64) { + return true; + } + break; + default: + break; + } + return false; +} + +bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const +{ + if (to == EbtFloat && from == EbtFloat16) { + return true; + } else { + return false; + } +} + +bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const +{ + switch (from) { + case EbtInt8: + case EbtUint8: + case EbtInt16: + case EbtUint16: + switch (to) { + case EbtFloat16: + case EbtFloat: + case EbtDouble: + return true; + default: + break; + } + break; + case EbtInt: + case EbtUint: + switch(to) { + case EbtFloat: + case EbtDouble: + return true; + default: + break; + } + break; + case EbtInt64: + case EbtUint64: + if (to == EbtDouble) { + return true; + } + break; + + default: + break; + } + return false; } // @@ -1125,120 +1631,350 @@ } } - switch (to) { - case EbtDouble: - switch (from) { - case EbtInt: - case EbtUint: - case EbtInt64: - case EbtUint64: + bool explicitTypesEnabled = extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int32) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int64) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64); + + if (explicitTypesEnabled) { + // integral promotions + if (isIntegralPromotion(from, to)) { + return true; + } + + // floating-point promotions + if (isFPPromotion(from, to)) { + return true; + } + + // integral conversions + if (isIntegralConversion(from, to)) { + return true; + } + + // floating-point conversions + if (isFPConversion(from, to)) { + return true; + } + + // floating-integral conversions + if (isFPIntegralConversion(from, to)) { + return true; + } + + // hlsl supported conversions + if (source == EShSourceHlsl) { + if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) + return true; + } + } else { + switch (to) { + case EbtDouble: + switch (from) { + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: + case EbtFloat: + case EbtDouble: + return true; #ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); + case EbtFloat16: + return extensionRequested(E_GL_AMD_gpu_shader_half_float); #endif + default: + return false; + } case EbtFloat: - case EbtDouble: + switch (from) { + case EbtInt: + case EbtUint: + case EbtFloat: + return true; + case EbtBool: + return (source == EShSourceHlsl); #ifdef AMD_EXTENSIONS - case EbtFloat16: + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); #endif - return true; - default: - return false; - } - case EbtFloat: - switch (from) { - case EbtInt: - case EbtUint: + case EbtFloat16: + return #ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: + extensionRequested(E_GL_AMD_gpu_shader_half_float) || #endif - case EbtFloat: + (source == EShSourceHlsl); + default: + return false; + } + case EbtUint: + switch (from) { + case EbtInt: + return version >= 400 || (source == EShSourceHlsl); + case EbtUint: + return true; + case EbtBool: + return (source == EShSourceHlsl); #ifdef AMD_EXTENSIONS - case EbtFloat16: + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); #endif - return true; - case EbtBool: - return (source == EShSourceHlsl); - default: - return false; - } - case EbtUint: - switch (from) { + default: + return false; + } case EbtInt: - return version >= 400 || (source == EShSourceHlsl); - case EbtUint: + switch (from) { + case EbtInt: + return true; + case EbtBool: + return (source == EShSourceHlsl); #ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: + case EbtInt16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); +#endif + default: + return false; + } + case EbtUint64: + switch (from) { + case EbtInt: + case EbtUint: + case EbtInt64: + case EbtUint64: + return true; +#ifdef AMD_EXTENSIONS + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); +#endif + default: + return false; + } + case EbtInt64: + switch (from) { + case EbtInt: + case EbtInt64: + return true; +#ifdef AMD_EXTENSIONS + case EbtInt16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); +#endif + default: + return false; + } + case EbtFloat16: +#ifdef AMD_EXTENSIONS + switch (from) { + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); + case EbtFloat16: + return extensionRequested(E_GL_AMD_gpu_shader_half_float); + default: + break; + } #endif - return true; - case EbtBool: - return (source == EShSourceHlsl); - default: return false; - } - case EbtInt: - switch (from) { - case EbtInt: + case EbtUint16: #ifdef AMD_EXTENSIONS - case EbtInt16: + switch (from) { + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); + default: + break; + } #endif - return true; - case EbtBool: - return (source == EShSourceHlsl); + return false; default: return false; } - case EbtUint64: - switch (from) { - case EbtInt: + } + + return false; +} + +static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType) { + switch(sintType) { + case EbtInt8: + switch(uintType) { + case EbtUint8: + case EbtUint16: case EbtUint: - case EbtInt64: case EbtUint64: -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: -#endif - return true; + return false; default: + assert(false); return false; } - case EbtInt64: - switch (from) { - case EbtInt: - case EbtInt64: -#ifdef AMD_EXTENSIONS - case EbtInt16: -#endif + break; + case EbtInt16: + switch(uintType) { + case EbtUint8: return true; + case EbtUint16: + case EbtUint: + case EbtUint64: + return false; default: + assert(false); return false; } -#ifdef AMD_EXTENSIONS - case EbtFloat16: - switch (from) { - case EbtInt16: + break; + case EbtInt: + switch(uintType) { + case EbtUint8: case EbtUint16: - case EbtFloat16: return true; + case EbtUint: + return false; default: + assert(false); return false; } - case EbtUint16: - switch (from) { - case EbtInt16: + break; + case EbtInt64: + switch(uintType) { + case EbtUint8: case EbtUint16: + case EbtUint: return true; + case EbtUint64: + return false; default: + assert(false); return false; } -#endif + break; default: + assert(false); return false; } } + +static TBasicType getCorrespondingUnsignedType(TBasicType type) { + switch(type) { + case EbtInt8: + return EbtUint8; + case EbtInt16: + return EbtUint16; + case EbtInt: + return EbtUint; + case EbtInt64: + return EbtUint64; + default: + assert(false); + return EbtNumTypes; + } +} + +// Implements the following rules +// - If either operand has type float64_t or derived from float64_t, +// the other shall be converted to float64_t or derived type. +// - Otherwise, if either operand has type float32_t or derived from +// float32_t, the other shall be converted to float32_t or derived type. +// - Otherwise, if either operand has type float16_t or derived from +// float16_t, the other shall be converted to float16_t or derived type. +// - Otherwise, if both operands have integer types the following rules +// shall be applied to the operands: +// - If both operands have the same type, no further conversion +// is needed. +// - Otherwise, if both operands have signed integer types or both +// have unsigned integer types, the operand with the type of lesser +// integer conversion rank shall be converted to the type of the +// operand with greater rank. +// - Otherwise, if the operand that has unsigned integer type has rank +// greater than or equal to the rank of the type of the other +// operand, the operand with signed integer type shall be converted +// to the type of the operand with unsigned integer type. +// - Otherwise, if the type of the operand with signed integer type can +// represent all of the values of the type of the operand with +// unsigned integer type, the operand with unsigned integer type +// shall be converted to the type of the operand with signed +// integer type. +// - Otherwise, both operands shall be converted to the unsigned +// integer type corresponding to the type of the operand with signed +// integer type. + +std::tuple TIntermediate::getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const +{ + TBasicType res0 = EbtNumTypes; + TBasicType res1 = EbtNumTypes; + + if (profile == EEsProfile || version == 110) + return std::make_tuple(res0, res1);; + + if (source == EShSourceHlsl) { + if (canImplicitlyPromote(type1, type0, op)) { + res0 = type0; + res1 = type0; + } else if (canImplicitlyPromote(type0, type1, op)) { + res0 = type1; + res1 = type1; + } + return std::make_tuple(res0, res1); + } + + if ((type0 == EbtDouble && canImplicitlyPromote(type1, EbtDouble, op)) || + (type1 == EbtDouble && canImplicitlyPromote(type0, EbtDouble, op)) ) { + res0 = EbtDouble; + res1 = EbtDouble; + } else if ((type0 == EbtFloat && canImplicitlyPromote(type1, EbtFloat, op)) || + (type1 == EbtFloat && canImplicitlyPromote(type0, EbtFloat, op)) ) { + res0 = EbtFloat; + res1 = EbtFloat; + } else if ((type0 == EbtFloat16 && canImplicitlyPromote(type1, EbtFloat16, op)) || + (type1 == EbtFloat16 && canImplicitlyPromote(type0, EbtFloat16, op)) ) { + res0 = EbtFloat16; + res1 = EbtFloat16; + } else if (isTypeInt(type0) && isTypeInt(type1) && + (canImplicitlyPromote(type0, type1, op) || canImplicitlyPromote(type1, type0, op))) { + if ((isTypeSignedInt(type0) && isTypeSignedInt(type1)) || + (isTypeUnsignedInt(type0) && isTypeUnsignedInt(type1))) { + if (getTypeRank(type0) < getTypeRank(type1)) { + res0 = type1; + res1 = type1; + } else { + res0 = type0; + res1 = type0; + } + } else if (isTypeUnsignedInt(type0) && (getTypeRank(type0) > getTypeRank(type1))) { + res0 = type0; + res1 = type0; + } else if (isTypeUnsignedInt(type1) && (getTypeRank(type1) > getTypeRank(type0))) { + res0 = type1; + res1 = type1; + } else if (isTypeSignedInt(type0)) { + if (canSignedIntTypeRepresentAllUnsignedValues(type0, type1)) { + res0 = type0; + res1 = type0; + } else { + res0 = getCorrespondingUnsignedType(type0); + res1 = getCorrespondingUnsignedType(type0); + } + } else if (isTypeSignedInt(type1)) { + if (canSignedIntTypeRepresentAllUnsignedValues(type1, type0)) { + res0 = type1; + res1 = type1; + } else { + res0 = getCorrespondingUnsignedType(type1); + res1 = getCorrespondingUnsignedType(type1); + } + } + } + + return std::make_tuple(res0, res1); +} + // // Given a type, find what operation would fully construct it. // @@ -1246,6 +1982,12 @@ { TOperator op = EOpNull; + if (type.getQualifier().nonUniform) + return EOpConstructNonuniform; + + if (type.isCoopMat()) + return EOpConstructCooperativeMatrix; + switch (type.getBasicType()) { case EbtStruct: op = EOpConstructStruct; @@ -1331,7 +2073,6 @@ } } break; -#ifdef AMD_EXTENSIONS case EbtFloat16: if (type.getMatrixCols()) { switch (type.getMatrixCols()) { @@ -1371,7 +2112,42 @@ } } break; -#endif + case EbtInt8: + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt8; break; + case 2: op = EOpConstructI8Vec2; break; + case 3: op = EOpConstructI8Vec3; break; + case 4: op = EOpConstructI8Vec4; break; + default: break; // some compilers want this + } + break; + case EbtUint8: + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint8; break; + case 2: op = EOpConstructU8Vec2; break; + case 3: op = EOpConstructU8Vec3; break; + case 4: op = EOpConstructU8Vec4; break; + default: break; // some compilers want this + } + break; + case EbtInt16: + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt16; break; + case 2: op = EOpConstructI16Vec2; break; + case 3: op = EOpConstructI16Vec3; break; + case 4: op = EOpConstructI16Vec4; break; + default: break; // some compilers want this + } + break; + case EbtUint16: + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint16; break; + case 2: op = EOpConstructU16Vec2; break; + case 3: op = EOpConstructU16Vec3; break; + case 4: op = EOpConstructU16Vec4; break; + default: break; // some compilers want this + } + break; case EbtInt: if (type.getMatrixCols()) { switch (type.getMatrixCols()) { @@ -1461,31 +2237,11 @@ switch(type.getVectorSize()) { case 1: op = EOpConstructUint64; break; case 2: op = EOpConstructU64Vec2; break; - case 3: op = EOpConstructU64Vec3; break; - case 4: op = EOpConstructU64Vec4; break; - default: break; // some compilers want this - } - break; -#ifdef AMD_EXTENSIONS - case EbtInt16: - switch(type.getVectorSize()) { - case 1: op = EOpConstructInt16; break; - case 2: op = EOpConstructI16Vec2; break; - case 3: op = EOpConstructI16Vec3; break; - case 4: op = EOpConstructI16Vec4; break; - default: break; // some compilers want this - } - break; - case EbtUint16: - switch(type.getVectorSize()) { - case 1: op = EOpConstructUint16; break; - case 2: op = EOpConstructU16Vec2; break; - case 3: op = EOpConstructU16Vec3; break; - case 4: op = EOpConstructU16Vec4; break; + case 3: op = EOpConstructU64Vec3; break; + case 4: op = EOpConstructU64Vec4; break; default: break; // some compilers want this } break; -#endif case EbtBool: if (type.getMatrixCols()) { switch (type.getMatrixCols()) { @@ -1524,6 +2280,9 @@ } } break; + case EbtReference: + op = EOpConstructReference; + break; default: break; } @@ -1614,7 +2373,7 @@ // // Returns the selection node created. // -TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control) +TIntermSelection* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc) { // // Don't prune the false path for compile-time constants; it's needed @@ -1623,7 +2382,6 @@ TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); node->setLoc(loc); - node->setSelectionControl(control); return node; } @@ -1666,27 +2424,28 @@ // // Returns the selection node created, or nullptr if one could not be. // -TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control) +TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, + const TSourceLoc& loc) { // If it's void, go to the if-then-else selection() if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) { TIntermNodePair pair = { trueBlock, falseBlock }; - return addSelection(cond, pair, loc, control); + TIntermSelection* selection = addSelection(cond, pair, loc); + if (getSource() == EShSourceHlsl) + selection->setNoShortCircuit(); + + return selection; } // // Get compatible types. // - TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock); - if (child) - falseBlock = child; - else { - child = addConversion(EOpSequence, falseBlock->getType(), trueBlock); - if (child) - trueBlock = child; - else - return nullptr; - } + auto children = addConversion(EOpSequence, trueBlock, falseBlock); + trueBlock = std::get<0>(children); + falseBlock = std::get<1>(children); + + if (trueBlock == nullptr || falseBlock == nullptr) + return nullptr; // Handle a vector condition as a mix if (!cond->getType().isScalarOrVec1()) { @@ -1742,6 +2501,9 @@ else node->getQualifier().makeTemporary(); + if (getSource() == EShSourceHlsl) + node->setNoShortCircuit(); + return node; } @@ -1761,6 +2523,37 @@ return node; } +TIntermConstantUnion* TIntermediate::addConstantUnion(signed char i8, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setI8Const(i8); + + return addConstantUnion(unionArray, TType(EbtInt8, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned char u8, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setUConst(u8); + + return addConstantUnion(unionArray, TType(EbtUint8, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(signed short i16, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setI16Const(i16); + + return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal); +} + +TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const +{ + TConstUnionArray unionArray(1); + unionArray[0].setU16Const(u16); + + return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal); +} TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const { @@ -1794,24 +2587,6 @@ return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal); } -#ifdef AMD_EXTENSIONS -TIntermConstantUnion* TIntermediate::addConstantUnion(short i16, const TSourceLoc& loc, bool literal) const -{ - TConstUnionArray unionArray(1); - unionArray[0].setIConst(i16); - - return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal); -} - -TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const -{ - TConstUnionArray unionArray(1); - unionArray[0].setUConst(u16); - - return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal); -} -#endif - TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const { TConstUnionArray unionArray(1); @@ -1822,11 +2597,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const { -#ifdef AMD_EXTENSIONS assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16); -#else - assert(baseType == EbtFloat || baseType == EbtDouble); -#endif TConstUnionArray unionArray(1); unionArray[0].setDConst(d); @@ -1909,11 +2680,11 @@ // // Create while and do-while loop nodes. // -TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control) +TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, + const TSourceLoc& loc) { TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); node->setLoc(loc); - node->setLoopControl(control); return node; } @@ -1921,11 +2692,11 @@ // // Create a for-loop sequence. // -TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control) +TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, + TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TIntermLoop*& node) { - TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); + node = new TIntermLoop(body, test, terminal, testFirst); node->setLoc(loc); - node->setLoopControl(control); // make a sequence of the initializer and statement, but try to reuse the // aggregate already created for whatever is in the initializer, if there is one @@ -2121,12 +2892,10 @@ case EOpVectorSwizzle: case EOpConvFloatToDouble: case EOpConvDoubleToFloat: -#ifdef AMD_EXTENSIONS case EOpConvFloat16ToFloat: case EOpConvFloatToFloat16: case EOpConvFloat16ToDouble: case EOpConvDoubleToFloat16: -#endif return true; default: return false; @@ -2150,51 +2919,97 @@ case EOpIndexDirectStruct: case EOpVectorSwizzle: - // conversion constructors + // (u)int* -> bool + case EOpConvInt8ToBool: + case EOpConvInt16ToBool: case EOpConvIntToBool: + case EOpConvInt64ToBool: + case EOpConvUint8ToBool: + case EOpConvUint16ToBool: case EOpConvUintToBool: - case EOpConvUintToInt: + case EOpConvUint64ToBool: + + // bool -> (u)int* + case EOpConvBoolToInt8: + case EOpConvBoolToInt16: case EOpConvBoolToInt: - case EOpConvIntToUint: - case EOpConvBoolToUint: - case EOpConvInt64ToBool: case EOpConvBoolToInt64: - case EOpConvUint64ToBool: + case EOpConvBoolToUint8: + case EOpConvBoolToUint16: + case EOpConvBoolToUint: case EOpConvBoolToUint64: - case EOpConvInt64ToInt: - case EOpConvIntToInt64: - case EOpConvUint64ToUint: - case EOpConvUintToUint64: - case EOpConvInt64ToUint64: - case EOpConvUint64ToInt64: - case EOpConvInt64ToUint: - case EOpConvUintToInt64: - case EOpConvUint64ToInt: - case EOpConvIntToUint64: -#ifdef AMD_EXTENSIONS - case EOpConvInt16ToBool: - case EOpConvBoolToInt16: + + // int8_t -> (u)int* + case EOpConvInt8ToInt16: + case EOpConvInt8ToInt: + case EOpConvInt8ToInt64: + case EOpConvInt8ToUint8: + case EOpConvInt8ToUint16: + case EOpConvInt8ToUint: + case EOpConvInt8ToUint64: + + // int16_t -> (u)int* + case EOpConvInt16ToInt8: case EOpConvInt16ToInt: - case EOpConvIntToInt16: - case EOpConvInt16ToUint: - case EOpConvUintToInt16: case EOpConvInt16ToInt64: - case EOpConvInt64ToInt16: + case EOpConvInt16ToUint8: + case EOpConvInt16ToUint16: + case EOpConvInt16ToUint: case EOpConvInt16ToUint64: - case EOpConvUint64ToInt16: - case EOpConvUint16ToBool: - case EOpConvBoolToUint16: - case EOpConvUint16ToInt: + + // int32_t -> (u)int* + case EOpConvIntToInt8: + case EOpConvIntToInt16: + case EOpConvIntToInt64: + case EOpConvIntToUint8: case EOpConvIntToUint16: - case EOpConvUint16ToUint: - case EOpConvUintToUint16: - case EOpConvUint16ToInt64: + case EOpConvIntToUint: + case EOpConvIntToUint64: + + // int64_t -> (u)int* + case EOpConvInt64ToInt8: + case EOpConvInt64ToInt16: + case EOpConvInt64ToInt: + case EOpConvInt64ToUint8: case EOpConvInt64ToUint16: + case EOpConvInt64ToUint: + case EOpConvInt64ToUint64: + + // uint8_t -> (u)int* + case EOpConvUint8ToInt8: + case EOpConvUint8ToInt16: + case EOpConvUint8ToInt: + case EOpConvUint8ToInt64: + case EOpConvUint8ToUint16: + case EOpConvUint8ToUint: + case EOpConvUint8ToUint64: + + // uint16_t -> (u)int* + case EOpConvUint16ToInt8: + case EOpConvUint16ToInt16: + case EOpConvUint16ToInt: + case EOpConvUint16ToInt64: + case EOpConvUint16ToUint8: + case EOpConvUint16ToUint: case EOpConvUint16ToUint64: + + // uint32_t -> (u)int* + case EOpConvUintToInt8: + case EOpConvUintToInt16: + case EOpConvUintToInt: + case EOpConvUintToInt64: + case EOpConvUintToUint8: + case EOpConvUintToUint16: + case EOpConvUintToUint64: + + // uint64_t -> (u)int* + case EOpConvUint64ToInt8: + case EOpConvUint64ToInt16: + case EOpConvUint64ToInt: + case EOpConvUint64ToInt64: + case EOpConvUint64ToUint8: case EOpConvUint64ToUint16: - case EOpConvInt16ToUint16: - case EOpConvUint16ToInt16: -#endif + case EOpConvUint64ToUint: // unary operations case EOpNegative: @@ -2228,6 +3043,64 @@ } } +// Is the operation one that must propagate nonuniform? +bool TIntermediate::isNonuniformPropagating(TOperator op) const +{ + // "* All Operators in Section 5.1 (Operators), except for assignment, + // arithmetic assignment, and sequence + // * Component selection in Section 5.5 + // * Matrix components in Section 5.6 + // * Structure and Array Operations in Section 5.7, except for the length + // method." + switch (op) { + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + + case EOpNegative: + case EOpLogicalNot: + case EOpVectorLogicalNot: + case EOpBitwiseNot: + + case EOpAdd: + case EOpSub: + case EOpMul: + case EOpDiv: + case EOpMod: + case EOpRightShift: + case EOpLeftShift: + case EOpAnd: + case EOpInclusiveOr: + case EOpExclusiveOr: + case EOpEqual: + case EOpNotEqual: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + + case EOpLogicalOr: + case EOpLogicalXor: + case EOpLogicalAnd: + + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpVectorSwizzle: + return true; + + default: + break; + } + + return false; +} + //////////////////////////////////////////////////////////////// // // Member functions of the nodes used for building the tree. @@ -2312,7 +3185,7 @@ // Convert operand to a boolean type if (operand->getBasicType() != EbtBool) { // Add constructor to boolean type. If that fails, we can't do it, so return false. - TIntermTyped* converted = convertToBasicType(op, EbtBool, operand); + TIntermTyped* converted = addConversion(op, TType(EbtBool), operand); if (converted == nullptr) return false; @@ -2321,15 +3194,7 @@ } break; case EOpBitwiseNot: - if (operand->getBasicType() != EbtInt && - operand->getBasicType() != EbtUint && -#ifdef AMD_EXTENSIONS - operand->getBasicType() != EbtInt16 && - operand->getBasicType() != EbtUint16 && -#endif - operand->getBasicType() != EbtInt64 && - operand->getBasicType() != EbtUint64) - + if (!isTypeInt(operand->getBasicType())) return false; break; case EOpNegative: @@ -2337,18 +3202,9 @@ case EOpPostDecrement: case EOpPreIncrement: case EOpPreDecrement: - if (operand->getBasicType() != EbtInt && - operand->getBasicType() != EbtUint && - operand->getBasicType() != EbtInt64 && - operand->getBasicType() != EbtUint64 && -#ifdef AMD_EXTENSIONS - operand->getBasicType() != EbtInt16 && - operand->getBasicType() != EbtUint16 && -#endif + if (!isTypeInt(operand->getBasicType()) && operand->getBasicType() != EbtFloat && -#ifdef AMD_EXTENSIONS operand->getBasicType() != EbtFloat16 && -#endif operand->getBasicType() != EbtDouble) return false; @@ -2368,34 +3224,12 @@ void TIntermUnary::updatePrecision() { -#ifdef AMD_EXTENSIONS if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { -#else - if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { -#endif if (operand->getQualifier().precision > getQualifier().precision) getQualifier().precision = operand->getQualifier().precision; } } -// If it is not already, convert this node to the given basic type. -TIntermTyped* TIntermediate::convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const -{ - if (node == nullptr) - return nullptr; - - // It's already this basic type: nothing needs to be done, so use the node directly. - if (node->getBasicType() == basicType) - return node; - - const TType& type = node->getType(); - const TType newType(basicType, type.getQualifier().storage, - type.getVectorSize(), type.getMatrixCols(), type.getMatrixRows(), type.isVector()); - - // Add constructor to the right vectorness of the right type. If that fails, we can't do it, so return nullptr. - return addConversion(op, newType, node); -} - // // See TIntermediate::promote // @@ -2468,8 +3302,10 @@ case EOpSub: case EOpDiv: case EOpMul: - left = addConversion(op, TType(EbtInt, EvqTemporary, left->getVectorSize()), left); - right = addConversion(op, TType(EbtInt, EvqTemporary, right->getVectorSize()), right); + if (left->getBasicType() == EbtBool) + left = createConversion(EbtInt, left); + if (right->getBasicType() == EbtBool) + right = createConversion(EbtInt, right); if (left == nullptr || right == nullptr) return false; node.setLeft(left); @@ -2520,21 +3356,17 @@ case EOpLogicalAnd: case EOpLogicalOr: case EOpLogicalXor: - if (getSource() == EShSourceHlsl) { - TIntermTyped* convertedL = convertToBasicType(op, EbtBool, left); - TIntermTyped* convertedR = convertToBasicType(op, EbtBool, right); - if (convertedL == nullptr || convertedR == nullptr) + // logical ops operate only on Booleans or vectors of Booleans. + if (left->getBasicType() != EbtBool || left->isMatrix()) return false; - node.setLeft(left = convertedL); // also updates stack variable - node.setRight(right = convertedR); // also updates stack variable - } else { + + if (getSource() == EShSourceGlsl) { // logical ops operate only on scalar Booleans and will promote to scalar Boolean. - if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix()) + if (left->isVector()) return false; } node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize())); - break; case EOpRightShift: @@ -2555,16 +3387,7 @@ break; // Check for integer-only operands. - if ((left->getBasicType() != EbtInt && left->getBasicType() != EbtUint && -#ifdef AMD_EXTENSIONS - left->getBasicType() != EbtInt16 && left->getBasicType() != EbtUint16 && -#endif - left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) || - (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint && -#ifdef AMD_EXTENSIONS - right->getBasicType() != EbtInt16 && right->getBasicType() != EbtUint16 && -#endif - right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64)) + if (!isTypeInt(left->getBasicType()) && !isTypeInt(right->getBasicType())) return false; if (left->isMatrix() || right->isMatrix()) return false; @@ -2637,6 +3460,40 @@ break; } + if (left->getType().isCoopMat() || right->getType().isCoopMat()) { + if (left->getType().isCoopMat() && right->getType().isCoopMat() && + *left->getType().getTypeParameters() != *right->getType().getTypeParameters()) { + return false; + } + switch (op) { + case EOpMul: + case EOpMulAssign: + if (left->getType().isCoopMat() && right->getType().isCoopMat()) { + return false; + } + if (op == EOpMulAssign && right->getType().isCoopMat()) { + return false; + } + node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar); + if (right->getType().isCoopMat()) { + node.setType(right->getType()); + } + return true; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpAssign: + // These require both to be cooperative matrices + if (!left->getType().isCoopMat() || !right->getType().isCoopMat()) { + return false; + } + return true; + default: + break; + } + return false; + } + // Finish handling the case, for all ops, where both operands are scalars. if (left->isScalar() && right->isScalar()) return true; @@ -2705,7 +3562,7 @@ node.setOp(op = EOpMatrixTimesScalarAssign); } } else if (left->isMatrix() && right->isMatrix()) { - if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows()) + if (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows()) return false; node.setOp(op = EOpMatrixTimesMatrixAssign); } else if (!left->isMatrix() && !right->isMatrix()) { @@ -2865,11 +3722,7 @@ void TIntermBinary::updatePrecision() { -#ifdef AMD_EXTENSIONS if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { -#else - if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { -#endif getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); if (getQualifier().precision != EpqNone) { left->propagatePrecision(getQualifier().precision); @@ -2880,11 +3733,7 @@ void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) { -#ifdef AMD_EXTENSIONS if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) -#else - if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat)) -#endif return; getQualifier().precision = newPrecision; @@ -2959,9 +3808,7 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i] = rightUnionArray[i]; break; default: @@ -2987,16 +3834,13 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i] = rightUnionArray[i]; break; default: return node; } break; -#ifdef AMD_EXTENSIONS case EbtFloat16: switch (node->getType().getBasicType()) { case EbtInt: @@ -3023,7 +3867,6 @@ return node; } break; -#endif case EbtInt: switch (node->getType().getBasicType()) { case EbtInt: @@ -3043,9 +3886,7 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getDConst())); break; default: @@ -3071,9 +3912,7 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getDConst())); break; default: @@ -3099,9 +3938,7 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); break; default: @@ -3127,9 +3964,7 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getDConst())); break; default: @@ -3155,9 +3990,7 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getDConst())); break; default: @@ -3200,23 +4033,39 @@ bool visitAggregate(TVisit, TIntermAggregate* ag) override { using namespace std; TIntermSequence& seq = ag->getSequence(); - // remove pure sampler variables - TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) { - TIntermSymbol* symbol = node->getAsSymbolNode(); - if (!symbol) - return false; + TQualifierList& qual = ag->getQualifierList(); - return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()); - }); - seq.erase(newEnd, seq.end()); - // replace constructors with sampler/textures - for_each(seq.begin(), seq.end(), [](TIntermNode*& node) { - TIntermAggregate *constructor = node->getAsAggregate(); + // qual and seq are indexed using the same indices, so we have to modify both in lock-step + assert(seq.size() == qual.size() || qual.empty()); + + size_t write = 0; + for (size_t i = 0; i < seq.size(); ++i) { + TIntermSymbol* symbol = seq[i]->getAsSymbolNode(); + if (symbol && symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()) { + // remove pure sampler variables + continue; + } + + TIntermNode* result = seq[i]; + + // replace constructors with sampler/textures + TIntermAggregate *constructor = seq[i]->getAsAggregate(); if (constructor && constructor->getOp() == EOpConstructTextureSampler) { if (!constructor->getSequence().empty()) - node = constructor->getSequence()[0]; + result = constructor->getSequence()[0]; } - }); + + // write new node & qualifier + seq[write] = result; + if (!qual.empty()) + qual[write] = qual[i]; + write++; + } + + seq.resize(write); + if (!qual.empty()) + qual.resize(write); + return true; } }; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2016 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -42,6 +43,7 @@ #else #include #endif +#include namespace { @@ -92,7 +94,13 @@ // class TOutputTraverser : public TIntermTraverser { public: - TOutputTraverser(TInfoSink& i) : infoSink(i) { } + TOutputTraverser(TInfoSink& i) : infoSink(i), extraOutput(NoExtraOutput) { } + + enum EExtraOutput { + NoExtraOutput, + BinaryDoubleOutput + }; + void setDoubleOutput(EExtraOutput extra) { extraOutput = extra; } virtual bool visitBinary(TVisit, TIntermBinary* node); virtual bool visitUnary(TVisit, TIntermUnary* node); @@ -108,6 +116,8 @@ protected: TOutputTraverser(TOutputTraverser&); TOutputTraverser& operator=(TOutputTraverser&); + + EExtraOutput extraOutput; }; // @@ -163,8 +173,12 @@ case EOpIndexDirect: out.debug << "direct index"; break; case EOpIndexIndirect: out.debug << "indirect index"; break; case EOpIndexDirectStruct: - out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName(); - out.debug << ": direct index for structure"; break; + { + bool reference = node->getLeft()->getType().getBasicType() == EbtReference; + const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct(); + out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName(); + out.debug << ": direct index for structure"; break; + } case EOpVectorSwizzle: out.debug << "vector swizzle"; break; case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break; @@ -223,49 +237,196 @@ case EOpPostDecrement: out.debug << "Post-Decrement"; break; case EOpPreIncrement: out.debug << "Pre-Increment"; break; case EOpPreDecrement: out.debug << "Pre-Decrement"; break; + case EOpCopyObject: out.debug << "copy object"; break; + // * -> bool + case EOpConvInt8ToBool: out.debug << "Convert int8_t to bool"; break; + case EOpConvUint8ToBool: out.debug << "Convert uint8_t to bool"; break; + case EOpConvInt16ToBool: out.debug << "Convert int16_t to bool"; break; + case EOpConvUint16ToBool: out.debug << "Convert uint16_t to bool";break; case EOpConvIntToBool: out.debug << "Convert int to bool"; break; case EOpConvUintToBool: out.debug << "Convert uint to bool"; break; - case EOpConvFloatToBool: out.debug << "Convert float to bool"; break; - case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break; case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break; case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break; - case EOpConvIntToFloat: out.debug << "Convert int to float"; break; - case EOpConvUintToFloat: out.debug << "Convert uint to float"; break; - case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break; - case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break; - case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break; - case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break; - case EOpConvUintToInt: out.debug << "Convert uint to int"; break; - case EOpConvFloatToInt: out.debug << "Convert float to int"; break; - case EOpConvDoubleToInt: out.debug << "Convert double to int"; break; - case EOpConvBoolToInt: out.debug << "Convert bool to int"; break; - case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break; - case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break; - case EOpConvIntToUint: out.debug << "Convert int to uint"; break; - case EOpConvFloatToUint: out.debug << "Convert float to uint"; break; - case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break; + case EOpConvFloat16ToBool: out.debug << "Convert float16_t to bool"; break; + case EOpConvFloatToBool: out.debug << "Convert float to bool"; break; + case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break; + + // bool -> * + case EOpConvBoolToInt8: out.debug << "Convert bool to int8_t"; break; + case EOpConvBoolToUint8: out.debug << "Convert bool to uint8_t"; break; + case EOpConvBoolToInt16: out.debug << "Convert bool to in16t_t"; break; + case EOpConvBoolToUint16: out.debug << "Convert bool to uint16_t";break; + case EOpConvBoolToInt: out.debug << "Convert bool to int" ; break; case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break; - case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break; - case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break; + case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break; + case EOpConvBoolToUint64: out.debug << "Convert bool to uint64";break; + case EOpConvBoolToFloat16: out.debug << "Convert bool to float16_t"; break; + case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break; + case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break; + + // int8_t -> (u)int* + case EOpConvInt8ToInt16: out.debug << "Convert int8_t to int16_t";break; + case EOpConvInt8ToInt: out.debug << "Convert int8_t to int"; break; + case EOpConvInt8ToInt64: out.debug << "Convert int8_t to int64"; break; + case EOpConvInt8ToUint8: out.debug << "Convert int8_t to uint8_t";break; + case EOpConvInt8ToUint16: out.debug << "Convert int8_t to uint16_t";break; + case EOpConvInt8ToUint: out.debug << "Convert int8_t to uint"; break; + case EOpConvInt8ToUint64: out.debug << "Convert int8_t to uint64"; break; + + // uint8_t -> (u)int* + case EOpConvUint8ToInt8: out.debug << "Convert uint8_t to int8_t";break; + case EOpConvUint8ToInt16: out.debug << "Convert uint8_t to int16_t";break; + case EOpConvUint8ToInt: out.debug << "Convert uint8_t to int"; break; + case EOpConvUint8ToInt64: out.debug << "Convert uint8_t to int64"; break; + case EOpConvUint8ToUint16: out.debug << "Convert uint8_t to uint16_t";break; + case EOpConvUint8ToUint: out.debug << "Convert uint8_t to uint"; break; + case EOpConvUint8ToUint64: out.debug << "Convert uint8_t to uint64"; break; + + // int8_t -> float* + case EOpConvInt8ToFloat16: out.debug << "Convert int8_t to float16_t";break; + case EOpConvInt8ToFloat: out.debug << "Convert int8_t to float"; break; + case EOpConvInt8ToDouble: out.debug << "Convert int8_t to double"; break; + + // uint8_t -> float* + case EOpConvUint8ToFloat16: out.debug << "Convert uint8_t to float16_t";break; + case EOpConvUint8ToFloat: out.debug << "Convert uint8_t to float"; break; + case EOpConvUint8ToDouble: out.debug << "Convert uint8_t to double"; break; + + // int16_t -> (u)int* + case EOpConvInt16ToInt8: out.debug << "Convert int16_t to int8_t";break; + case EOpConvInt16ToInt: out.debug << "Convert int16_t to int"; break; + case EOpConvInt16ToInt64: out.debug << "Convert int16_t to int64"; break; + case EOpConvInt16ToUint8: out.debug << "Convert int16_t to uint8_t";break; + case EOpConvInt16ToUint16: out.debug << "Convert int16_t to uint16_t";break; + case EOpConvInt16ToUint: out.debug << "Convert int16_t to uint"; break; + case EOpConvInt16ToUint64: out.debug << "Convert int16_t to uint64"; break; + + // int16_t -> float* + case EOpConvInt16ToFloat16: out.debug << "Convert int16_t to float16_t";break; + case EOpConvInt16ToFloat: out.debug << "Convert int16_t to float"; break; + case EOpConvInt16ToDouble: out.debug << "Convert int16_t to double"; break; + + // uint16_t -> (u)int* + case EOpConvUint16ToInt8: out.debug << "Convert uint16_t to int8_t";break; + case EOpConvUint16ToInt16: out.debug << "Convert uint16_t to int16_t";break; + case EOpConvUint16ToInt: out.debug << "Convert uint16_t to int"; break; + case EOpConvUint16ToInt64: out.debug << "Convert uint16_t to int64"; break; + case EOpConvUint16ToUint8: out.debug << "Convert uint16_t to uint8_t";break; + case EOpConvUint16ToUint: out.debug << "Convert uint16_t to uint"; break; + case EOpConvUint16ToUint64: out.debug << "Convert uint16_t to uint64"; break; + + // uint16_t -> float* + case EOpConvUint16ToFloat16: out.debug << "Convert uint16_t to float16_t";break; + case EOpConvUint16ToFloat: out.debug << "Convert uint16_t to float"; break; + case EOpConvUint16ToDouble: out.debug << "Convert uint16_t to double"; break; + + // int32_t -> (u)int* + case EOpConvIntToInt8: out.debug << "Convert int to int8_t";break; + case EOpConvIntToInt16: out.debug << "Convert int to int16_t";break; + case EOpConvIntToInt64: out.debug << "Convert int to int64"; break; + case EOpConvIntToUint8: out.debug << "Convert int to uint8_t";break; + case EOpConvIntToUint16: out.debug << "Convert int to uint16_t";break; + case EOpConvIntToUint: out.debug << "Convert int to uint"; break; + case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break; + + // int32_t -> float* + case EOpConvIntToFloat16: out.debug << "Convert int to float16_t";break; + case EOpConvIntToFloat: out.debug << "Convert int to float"; break; case EOpConvIntToDouble: out.debug << "Convert int to double"; break; - case EOpConvUintToDouble: out.debug << "Convert uint to double"; break; - case EOpConvFloatToDouble: out.debug << "Convert float to double"; break; - case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break; - case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break; - case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break; - case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break; - case EOpConvIntToInt64: out.debug << "Convert int to int64"; break; + + // uint32_t -> (u)int* + case EOpConvUintToInt8: out.debug << "Convert uint to int8_t";break; + case EOpConvUintToInt16: out.debug << "Convert uint to int16_t";break; + case EOpConvUintToInt: out.debug << "Convert uint to int";break; case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break; - case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break; - case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break; - case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break; - case EOpConvBoolToUint64: out.debug << "Convert bool to uint64"; break; - case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break; - case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break; + case EOpConvUintToUint8: out.debug << "Convert uint to uint8_t";break; + case EOpConvUintToUint16: out.debug << "Convert uint to uint16_t";break; + case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break; + + // uint32_t -> float* + case EOpConvUintToFloat16: out.debug << "Convert uint to float16_t";break; + case EOpConvUintToFloat: out.debug << "Convert uint to float"; break; + case EOpConvUintToDouble: out.debug << "Convert uint to double"; break; + + // int64 -> (u)int* + case EOpConvInt64ToInt8: out.debug << "Convert int64 to int8_t"; break; + case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16_t"; break; + case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break; + case EOpConvInt64ToUint8: out.debug << "Convert int64 to uint8_t";break; + case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16_t";break; + case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break; + case EOpConvInt64ToUint64: out.debug << "Convert int64 to uint64"; break; + + // int64 -> float* + case EOpConvInt64ToFloat16: out.debug << "Convert int64 to float16_t";break; + case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break; + case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break; + + // uint64 -> (u)int* + case EOpConvUint64ToInt8: out.debug << "Convert uint64 to int8_t";break; + case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16_t";break; + case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break; + case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break; + case EOpConvUint64ToUint8: out.debug << "Convert uint64 to uint8_t";break; + case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break; + case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break; + + // uint64 -> float* + case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16_t";break; + case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break; + case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break; + + // float16_t -> int* + case EOpConvFloat16ToInt8: out.debug << "Convert float16_t to int8_t"; break; + case EOpConvFloat16ToInt16: out.debug << "Convert float16_t to int16_t"; break; + case EOpConvFloat16ToInt: out.debug << "Convert float16_t to int"; break; + case EOpConvFloat16ToInt64: out.debug << "Convert float16_t to int64"; break; + + // float16_t -> uint* + case EOpConvFloat16ToUint8: out.debug << "Convert float16_t to uint8_t"; break; + case EOpConvFloat16ToUint16: out.debug << "Convert float16_t to uint16_t"; break; + case EOpConvFloat16ToUint: out.debug << "Convert float16_t to uint"; break; + case EOpConvFloat16ToUint64: out.debug << "Convert float16_t to uint64"; break; + + // float16_t -> float* + case EOpConvFloat16ToFloat: out.debug << "Convert float16_t to float"; break; + case EOpConvFloat16ToDouble: out.debug << "Convert float16_t to double"; break; + + // float32 -> float* + case EOpConvFloatToFloat16: out.debug << "Convert float to float16_t"; break; + case EOpConvFloatToDouble: out.debug << "Convert float to double"; break; + + // float32_t -> int* + case EOpConvFloatToInt8: out.debug << "Convert float to int8_t"; break; + case EOpConvFloatToInt16: out.debug << "Convert float to int16_t"; break; + case EOpConvFloatToInt: out.debug << "Convert float to int"; break; + case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break; + + // float32_t -> uint* + case EOpConvFloatToUint8: out.debug << "Convert float to uint8_t"; break; + case EOpConvFloatToUint16: out.debug << "Convert float to uint16_t"; break; + case EOpConvFloatToUint: out.debug << "Convert float to uint"; break; case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break; + + // double -> float* + case EOpConvDoubleToFloat16: out.debug << "Convert double to float16_t"; break; + case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break; + + // double -> int* + case EOpConvDoubleToInt8: out.debug << "Convert double to int8_t"; break; + case EOpConvDoubleToInt16: out.debug << "Convert double to int16_t"; break; + case EOpConvDoubleToInt: out.debug << "Convert double to int"; break; + case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break; + + // float32_t -> uint* + case EOpConvDoubleToUint8: out.debug << "Convert double to uint8_t"; break; + case EOpConvDoubleToUint16: out.debug << "Convert double to uint16_t"; break; + case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break; case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break; - case EOpConvInt64ToUint64: out.debug << "Convert uint64 to uint64"; break; + + case EOpConvUint64ToPtr: out.debug << "Convert uint64_t to pointer"; break; + case EOpConvPtrToUint64: out.debug << "Convert pointer to uint64_t"; break; case EOpRadians: out.debug << "radians"; break; case EOpDegrees: out.debug << "degrees"; break; @@ -309,12 +470,10 @@ case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break; case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break; case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break; -#ifdef AMD_EXTENSIONS case EOpFloat16BitsToInt16: out.debug << "float16BitsToInt16"; break; case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break; case EOpInt16BitsToFloat16: out.debug << "int16BitsToFloat16"; break; case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break; -#endif case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break; case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break; @@ -322,6 +481,12 @@ case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16"; break; case EOpPackHalf2x16: out.debug << "packHalf2x16"; break; case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16"; break; + case EOpPack16: out.debug << "pack16"; break; + case EOpPack32: out.debug << "pack32"; break; + case EOpPack64: out.debug << "pack64"; break; + case EOpUnpack32: out.debug << "unpack32"; break; + case EOpUnpack16: out.debug << "unpack16"; break; + case EOpUnpack8: out.debug << "unpack8"; break; case EOpPackSnorm4x8: out.debug << "PackSnorm4x8"; break; case EOpUnpackSnorm4x8: out.debug << "UnpackSnorm4x8"; break; @@ -335,7 +500,6 @@ case EOpPackUint2x32: out.debug << "packUint2x32"; break; case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break; -#ifdef AMD_EXTENSIONS case EOpPackInt2x16: out.debug << "packInt2x16"; break; case EOpUnpackInt2x16: out.debug << "unpackInt2x16"; break; case EOpPackUint2x16: out.debug << "packUint2x16"; break; @@ -345,10 +509,8 @@ case EOpUnpackInt4x16: out.debug << "unpackInt4x16"; break; case EOpPackUint4x16: out.debug << "packUint4x16"; break; case EOpUnpackUint4x16: out.debug << "unpackUint4x16"; break; - case EOpPackFloat2x16: out.debug << "packFloat2x16"; break; case EOpUnpackFloat2x16: out.debug << "unpackFloat2x16"; break; -#endif case EOpLength: out.debug << "length"; break; case EOpNormalize: out.debug << "normalize"; break; @@ -402,6 +564,82 @@ case EOpAllInvocations: out.debug << "allInvocations"; break; case EOpAllInvocationsEqual: out.debug << "allInvocationsEqual"; break; + case EOpSubgroupElect: out.debug << "subgroupElect"; break; + case EOpSubgroupAll: out.debug << "subgroupAll"; break; + case EOpSubgroupAny: out.debug << "subgroupAny"; break; + case EOpSubgroupAllEqual: out.debug << "subgroupAllEqual"; break; + case EOpSubgroupBroadcast: out.debug << "subgroupBroadcast"; break; + case EOpSubgroupBroadcastFirst: out.debug << "subgroupBroadcastFirst"; break; + case EOpSubgroupBallot: out.debug << "subgroupBallot"; break; + case EOpSubgroupInverseBallot: out.debug << "subgroupInverseBallot"; break; + case EOpSubgroupBallotBitExtract: out.debug << "subgroupBallotBitExtract"; break; + case EOpSubgroupBallotBitCount: out.debug << "subgroupBallotBitCount"; break; + case EOpSubgroupBallotInclusiveBitCount: out.debug << "subgroupBallotInclusiveBitCount"; break; + case EOpSubgroupBallotExclusiveBitCount: out.debug << "subgroupBallotExclusiveBitCount"; break; + case EOpSubgroupBallotFindLSB: out.debug << "subgroupBallotFindLSB"; break; + case EOpSubgroupBallotFindMSB: out.debug << "subgroupBallotFindMSB"; break; + case EOpSubgroupShuffle: out.debug << "subgroupShuffle"; break; + case EOpSubgroupShuffleXor: out.debug << "subgroupShuffleXor"; break; + case EOpSubgroupShuffleUp: out.debug << "subgroupShuffleUp"; break; + case EOpSubgroupShuffleDown: out.debug << "subgroupShuffleDown"; break; + case EOpSubgroupAdd: out.debug << "subgroupAdd"; break; + case EOpSubgroupMul: out.debug << "subgroupMul"; break; + case EOpSubgroupMin: out.debug << "subgroupMin"; break; + case EOpSubgroupMax: out.debug << "subgroupMax"; break; + case EOpSubgroupAnd: out.debug << "subgroupAnd"; break; + case EOpSubgroupOr: out.debug << "subgroupOr"; break; + case EOpSubgroupXor: out.debug << "subgroupXor"; break; + case EOpSubgroupInclusiveAdd: out.debug << "subgroupInclusiveAdd"; break; + case EOpSubgroupInclusiveMul: out.debug << "subgroupInclusiveMul"; break; + case EOpSubgroupInclusiveMin: out.debug << "subgroupInclusiveMin"; break; + case EOpSubgroupInclusiveMax: out.debug << "subgroupInclusiveMax"; break; + case EOpSubgroupInclusiveAnd: out.debug << "subgroupInclusiveAnd"; break; + case EOpSubgroupInclusiveOr: out.debug << "subgroupInclusiveOr"; break; + case EOpSubgroupInclusiveXor: out.debug << "subgroupInclusiveXor"; break; + case EOpSubgroupExclusiveAdd: out.debug << "subgroupExclusiveAdd"; break; + case EOpSubgroupExclusiveMul: out.debug << "subgroupExclusiveMul"; break; + case EOpSubgroupExclusiveMin: out.debug << "subgroupExclusiveMin"; break; + case EOpSubgroupExclusiveMax: out.debug << "subgroupExclusiveMax"; break; + case EOpSubgroupExclusiveAnd: out.debug << "subgroupExclusiveAnd"; break; + case EOpSubgroupExclusiveOr: out.debug << "subgroupExclusiveOr"; break; + case EOpSubgroupExclusiveXor: out.debug << "subgroupExclusiveXor"; break; + case EOpSubgroupClusteredAdd: out.debug << "subgroupClusteredAdd"; break; + case EOpSubgroupClusteredMul: out.debug << "subgroupClusteredMul"; break; + case EOpSubgroupClusteredMin: out.debug << "subgroupClusteredMin"; break; + case EOpSubgroupClusteredMax: out.debug << "subgroupClusteredMax"; break; + case EOpSubgroupClusteredAnd: out.debug << "subgroupClusteredAnd"; break; + case EOpSubgroupClusteredOr: out.debug << "subgroupClusteredOr"; break; + case EOpSubgroupClusteredXor: out.debug << "subgroupClusteredXor"; break; + case EOpSubgroupQuadBroadcast: out.debug << "subgroupQuadBroadcast"; break; + case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break; + case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break; + case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break; + +#ifdef NV_EXTENSIONS + case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break; + case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break; + case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break; + case EOpSubgroupPartitionedMin: out.debug << "subgroupPartitionedMinNV"; break; + case EOpSubgroupPartitionedMax: out.debug << "subgroupPartitionedMaxNV"; break; + case EOpSubgroupPartitionedAnd: out.debug << "subgroupPartitionedAndNV"; break; + case EOpSubgroupPartitionedOr: out.debug << "subgroupPartitionedOrNV"; break; + case EOpSubgroupPartitionedXor: out.debug << "subgroupPartitionedXorNV"; break; + case EOpSubgroupPartitionedInclusiveAdd: out.debug << "subgroupPartitionedInclusiveAddNV"; break; + case EOpSubgroupPartitionedInclusiveMul: out.debug << "subgroupPartitionedInclusiveMulNV"; break; + case EOpSubgroupPartitionedInclusiveMin: out.debug << "subgroupPartitionedInclusiveMinNV"; break; + case EOpSubgroupPartitionedInclusiveMax: out.debug << "subgroupPartitionedInclusiveMaxNV"; break; + case EOpSubgroupPartitionedInclusiveAnd: out.debug << "subgroupPartitionedInclusiveAndNV"; break; + case EOpSubgroupPartitionedInclusiveOr: out.debug << "subgroupPartitionedInclusiveOrNV"; break; + case EOpSubgroupPartitionedInclusiveXor: out.debug << "subgroupPartitionedInclusiveXorNV"; break; + case EOpSubgroupPartitionedExclusiveAdd: out.debug << "subgroupPartitionedExclusiveAddNV"; break; + case EOpSubgroupPartitionedExclusiveMul: out.debug << "subgroupPartitionedExclusiveMulNV"; break; + case EOpSubgroupPartitionedExclusiveMin: out.debug << "subgroupPartitionedExclusiveMinNV"; break; + case EOpSubgroupPartitionedExclusiveMax: out.debug << "subgroupPartitionedExclusiveMaxNV"; break; + case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break; + case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break; + case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break; +#endif + case EOpClip: out.debug << "clip"; break; case EOpIsFinite: out.debug << "isfinite"; break; case EOpLog10: out.debug << "log10"; break; @@ -434,67 +672,18 @@ case EOpMbcnt: out.debug << "mbcnt"; break; - case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break; - case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break; - case EOpFragmentMaskFetch: out.debug << "fragmentMaskFetchAMD"; break; case EOpFragmentFetch: out.debug << "fragmentFetchAMD"; break; - case EOpConvBoolToFloat16: out.debug << "Convert bool to float16"; break; - case EOpConvIntToFloat16: out.debug << "Convert int to float16"; break; - case EOpConvUintToFloat16: out.debug << "Convert uint to float16"; break; - case EOpConvFloatToFloat16: out.debug << "Convert float to float16"; break; - case EOpConvDoubleToFloat16: out.debug << "Convert double to float16"; break; - case EOpConvInt64ToFloat16: out.debug << "Convert int64 to float16"; break; - case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16"; break; - case EOpConvFloat16ToBool: out.debug << "Convert float16 to bool"; break; - case EOpConvFloat16ToInt: out.debug << "Convert float16 to int"; break; - case EOpConvFloat16ToUint: out.debug << "Convert float16 to uint"; break; - case EOpConvFloat16ToFloat: out.debug << "Convert float16 to float"; break; - case EOpConvFloat16ToDouble: out.debug << "Convert float16 to double"; break; - case EOpConvFloat16ToInt64: out.debug << "Convert float16 to int64"; break; - case EOpConvFloat16ToUint64: out.debug << "Convert float16 to uint64"; break; - - case EOpConvBoolToInt16: out.debug << "Convert bool to int16"; break; - case EOpConvIntToInt16: out.debug << "Convert int to int16"; break; - case EOpConvUintToInt16: out.debug << "Convert uint to int16"; break; - case EOpConvFloatToInt16: out.debug << "Convert float to int16"; break; - case EOpConvDoubleToInt16: out.debug << "Convert double to int16"; break; - case EOpConvFloat16ToInt16: out.debug << "Convert float16 to int16"; break; - case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16"; break; - case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16"; break; - case EOpConvUint16ToInt16: out.debug << "Convert uint16 to int16"; break; - case EOpConvInt16ToBool: out.debug << "Convert int16 to bool"; break; - case EOpConvInt16ToInt: out.debug << "Convert int16 to int"; break; - case EOpConvInt16ToUint: out.debug << "Convert int16 to uint"; break; - case EOpConvInt16ToFloat: out.debug << "Convert int16 to float"; break; - case EOpConvInt16ToDouble: out.debug << "Convert int16 to double"; break; - case EOpConvInt16ToFloat16: out.debug << "Convert int16 to float16"; break; - case EOpConvInt16ToInt64: out.debug << "Convert int16 to int64"; break; - case EOpConvInt16ToUint64: out.debug << "Convert int16 to uint64"; break; - - case EOpConvBoolToUint16: out.debug << "Convert bool to uint16"; break; - case EOpConvIntToUint16: out.debug << "Convert int to uint16"; break; - case EOpConvUintToUint16: out.debug << "Convert uint to uint16"; break; - case EOpConvFloatToUint16: out.debug << "Convert float to uint16"; break; - case EOpConvDoubleToUint16: out.debug << "Convert double to uint16"; break; - case EOpConvFloat16ToUint16: out.debug << "Convert float16 to uint16"; break; - case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16"; break; - case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break; - case EOpConvInt16ToUint16: out.debug << "Convert int16 to uint16"; break; - case EOpConvUint16ToBool: out.debug << "Convert uint16 to bool"; break; - case EOpConvUint16ToInt: out.debug << "Convert uint16 to int"; break; - case EOpConvUint16ToUint: out.debug << "Convert uint16 to uint"; break; - case EOpConvUint16ToFloat: out.debug << "Convert uint16 to float"; break; - case EOpConvUint16ToDouble: out.debug << "Convert uint16 to double"; break; - case EOpConvUint16ToFloat16: out.debug << "Convert uint16 to float16"; break; - case EOpConvUint16ToInt64: out.debug << "Convert uint16 to int64"; break; - case EOpConvUint16ToUint64: out.debug << "Convert uint16 to uint64"; break; + case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break; + case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break; #endif case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; + case EOpConstructReference: out.debug << "Construct reference type"; break; + default: out.debug.message(EPrefixError, "Bad unary op"); } @@ -537,23 +726,30 @@ case EOpConstructBVec2: out.debug << "Construct bvec2"; break; case EOpConstructBVec3: out.debug << "Construct bvec3"; break; case EOpConstructBVec4: out.debug << "Construct bvec4"; break; + case EOpConstructInt8: out.debug << "Construct int8_t"; break; + case EOpConstructI8Vec2: out.debug << "Construct i8vec2"; break; + case EOpConstructI8Vec3: out.debug << "Construct i8vec3"; break; + case EOpConstructI8Vec4: out.debug << "Construct i8vec4"; break; case EOpConstructInt: out.debug << "Construct int"; break; case EOpConstructIVec2: out.debug << "Construct ivec2"; break; case EOpConstructIVec3: out.debug << "Construct ivec3"; break; case EOpConstructIVec4: out.debug << "Construct ivec4"; break; + case EOpConstructUint8: out.debug << "Construct uint8_t"; break; + case EOpConstructU8Vec2: out.debug << "Construct u8vec2"; break; + case EOpConstructU8Vec3: out.debug << "Construct u8vec3"; break; + case EOpConstructU8Vec4: out.debug << "Construct u8vec4"; break; case EOpConstructUint: out.debug << "Construct uint"; break; case EOpConstructUVec2: out.debug << "Construct uvec2"; break; case EOpConstructUVec3: out.debug << "Construct uvec3"; break; case EOpConstructUVec4: out.debug << "Construct uvec4"; break; - case EOpConstructInt64: out.debug << "Construct int64_t"; break; + case EOpConstructInt64: out.debug << "Construct int64"; break; case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break; case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break; case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break; - case EOpConstructUint64: out.debug << "Construct uint64_t"; break; + case EOpConstructUint64: out.debug << "Construct uint64"; break; case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break; case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break; case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break; -#ifdef AMD_EXTENSIONS case EOpConstructInt16: out.debug << "Construct int16_t"; break; case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break; case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break; @@ -562,7 +758,6 @@ case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break; case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break; case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break; -#endif case EOpConstructMat2x2: out.debug << "Construct mat2"; break; case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break; case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break; @@ -608,7 +803,6 @@ case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break; case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break; case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break; -#ifdef AMD_EXTENSIONS case EOpConstructFloat16: out.debug << "Construct float16_t"; break; case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break; case EOpConstructF16Vec3: out.debug << "Construct f16vec3"; break; @@ -622,9 +816,10 @@ case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break; case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break; case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break; -#endif case EOpConstructStruct: out.debug << "Construct structure"; break; case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break; + case EOpConstructReference: out.debug << "Construct reference"; break; + case EOpConstructCooperativeMatrix: out.debug << "Construct cooperative matrix"; break; case EOpLessThan: out.debug << "Compare Less Than"; break; case EOpGreaterThan: out.debug << "Compare Greater Than"; break; @@ -688,6 +883,8 @@ case EOpAtomicXor: out.debug << "AtomicXor"; break; case EOpAtomicExchange: out.debug << "AtomicExchange"; break; case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break; + case EOpAtomicLoad: out.debug << "AtomicLoad"; break; + case EOpAtomicStore: out.debug << "AtomicStore"; break; case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break; case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break; @@ -711,6 +908,8 @@ case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break; case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break; case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break; + case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break; + case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break; #ifdef AMD_EXTENSIONS case EOpImageLoadLod: out.debug << "imageLoadLod"; break; case EOpImageStoreLod: out.debug << "imageStoreLod"; break; @@ -769,7 +968,13 @@ case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break; case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break; #endif - +#ifdef NV_EXTENSIONS + case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break; + case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break; + case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break; + case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break; + case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break; +#endif case EOpAddCarry: out.debug << "addCarry"; break; case EOpSubBorrow: out.debug << "subBorrow"; break; case EOpUMulExtended: out.debug << "uMulExtended"; break; @@ -796,9 +1001,78 @@ case EOpWorkgroupMemoryBarrier: out.debug << "WorkgroupMemoryBarrier"; break; case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break; + case EOpSubgroupBarrier: out.debug << "subgroupBarrier"; break; + case EOpSubgroupMemoryBarrier: out.debug << "subgroupMemoryBarrier"; break; + case EOpSubgroupMemoryBarrierBuffer: out.debug << "subgroupMemoryBarrierBuffer"; break; + case EOpSubgroupMemoryBarrierImage: out.debug << "subgroupMemoryBarrierImage"; break; + case EOpSubgroupMemoryBarrierShared: out.debug << "subgroupMemoryBarrierShared"; break; + case EOpSubgroupElect: out.debug << "subgroupElect"; break; + case EOpSubgroupAll: out.debug << "subgroupAll"; break; + case EOpSubgroupAny: out.debug << "subgroupAny"; break; + case EOpSubgroupAllEqual: out.debug << "subgroupAllEqual"; break; + case EOpSubgroupBroadcast: out.debug << "subgroupBroadcast"; break; + case EOpSubgroupBroadcastFirst: out.debug << "subgroupBroadcastFirst"; break; + case EOpSubgroupBallot: out.debug << "subgroupBallot"; break; + case EOpSubgroupInverseBallot: out.debug << "subgroupInverseBallot"; break; + case EOpSubgroupBallotBitExtract: out.debug << "subgroupBallotBitExtract"; break; + case EOpSubgroupBallotBitCount: out.debug << "subgroupBallotBitCount"; break; + case EOpSubgroupBallotInclusiveBitCount: out.debug << "subgroupBallotInclusiveBitCount"; break; + case EOpSubgroupBallotExclusiveBitCount: out.debug << "subgroupBallotExclusiveBitCount"; break; + case EOpSubgroupBallotFindLSB: out.debug << "subgroupBallotFindLSB"; break; + case EOpSubgroupBallotFindMSB: out.debug << "subgroupBallotFindMSB"; break; + case EOpSubgroupShuffle: out.debug << "subgroupShuffle"; break; + case EOpSubgroupShuffleXor: out.debug << "subgroupShuffleXor"; break; + case EOpSubgroupShuffleUp: out.debug << "subgroupShuffleUp"; break; + case EOpSubgroupShuffleDown: out.debug << "subgroupShuffleDown"; break; + case EOpSubgroupAdd: out.debug << "subgroupAdd"; break; + case EOpSubgroupMul: out.debug << "subgroupMul"; break; + case EOpSubgroupMin: out.debug << "subgroupMin"; break; + case EOpSubgroupMax: out.debug << "subgroupMax"; break; + case EOpSubgroupAnd: out.debug << "subgroupAnd"; break; + case EOpSubgroupOr: out.debug << "subgroupOr"; break; + case EOpSubgroupXor: out.debug << "subgroupXor"; break; + case EOpSubgroupInclusiveAdd: out.debug << "subgroupInclusiveAdd"; break; + case EOpSubgroupInclusiveMul: out.debug << "subgroupInclusiveMul"; break; + case EOpSubgroupInclusiveMin: out.debug << "subgroupInclusiveMin"; break; + case EOpSubgroupInclusiveMax: out.debug << "subgroupInclusiveMax"; break; + case EOpSubgroupInclusiveAnd: out.debug << "subgroupInclusiveAnd"; break; + case EOpSubgroupInclusiveOr: out.debug << "subgroupInclusiveOr"; break; + case EOpSubgroupInclusiveXor: out.debug << "subgroupInclusiveXor"; break; + case EOpSubgroupExclusiveAdd: out.debug << "subgroupExclusiveAdd"; break; + case EOpSubgroupExclusiveMul: out.debug << "subgroupExclusiveMul"; break; + case EOpSubgroupExclusiveMin: out.debug << "subgroupExclusiveMin"; break; + case EOpSubgroupExclusiveMax: out.debug << "subgroupExclusiveMax"; break; + case EOpSubgroupExclusiveAnd: out.debug << "subgroupExclusiveAnd"; break; + case EOpSubgroupExclusiveOr: out.debug << "subgroupExclusiveOr"; break; + case EOpSubgroupExclusiveXor: out.debug << "subgroupExclusiveXor"; break; + case EOpSubgroupClusteredAdd: out.debug << "subgroupClusteredAdd"; break; + case EOpSubgroupClusteredMul: out.debug << "subgroupClusteredMul"; break; + case EOpSubgroupClusteredMin: out.debug << "subgroupClusteredMin"; break; + case EOpSubgroupClusteredMax: out.debug << "subgroupClusteredMax"; break; + case EOpSubgroupClusteredAnd: out.debug << "subgroupClusteredAnd"; break; + case EOpSubgroupClusteredOr: out.debug << "subgroupClusteredOr"; break; + case EOpSubgroupClusteredXor: out.debug << "subgroupClusteredXor"; break; + case EOpSubgroupQuadBroadcast: out.debug << "subgroupQuadBroadcast"; break; + case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break; + case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break; + case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break; + case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; +#ifdef NV_EXTENSIONS + case EOpTraceNV: out.debug << "traceNV"; break; + case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break; + case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break; + case EOpTerminateRayNV: out.debug << "terminateRayNV"; break; + case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break; + case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break; +#endif + + case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break; + case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break; + case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break; + default: out.debug.message(EPrefixError, "Bad aggregation op"); } @@ -817,7 +1091,15 @@ OutputTreeText(out, node, depth); out.debug << "Test condition and select"; - out.debug << " (" << node->getCompleteString() << ")\n"; + out.debug << " (" << node->getCompleteString() << ")"; + + if (node->getShortCircuit() == false) + out.debug << ": no shortcircuit"; + if (node->getFlatten()) + out.debug << ": Flatten"; + if (node->getDontFlatten()) + out.debug << ": DontFlatten"; + out.debug << "\n"; ++depth; @@ -843,7 +1125,64 @@ return false; } -static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth) +// Print infinities and NaNs, and numbers in a portable way. +// Goals: +// - portable (across IEEE 754 platforms) +// - shows all possible IEEE values +// - shows simple numbers in a simple way, e.g., no leading/trailing 0s +// - shows all digits, no premature rounding +static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra) +{ + if (IsInfinity(value)) { + if (value < 0) + out.debug << "-1.#INF"; + else + out.debug << "+1.#INF"; + } else if (IsNan(value)) + out.debug << "1.#IND"; + else { + const int maxSize = 340; + char buf[maxSize]; + const char* format = "%f"; + if (fabs(value) > 0.0 && (fabs(value) < 1e-5 || fabs(value) > 1e12)) + format = "%-.13e"; + int len = snprintf(buf, maxSize, format, value); + assert(len < maxSize); + + // remove a leading zero in the 100s slot in exponent; it is not portable + // pattern: XX...XXXe+0XX or XX...XXXe-0XX + if (len > 5) { + if (buf[len-5] == 'e' && (buf[len-4] == '+' || buf[len-4] == '-') && buf[len-3] == '0') { + buf[len-3] = buf[len-2]; + buf[len-2] = buf[len-1]; + buf[len-1] = '\0'; + } + } + + out.debug << buf; + + switch (extra) { + case TOutputTraverser::BinaryDoubleOutput: + { + uint64_t b; + static_assert(sizeof(b) == sizeof(value), "sizeof(uint64_t) != sizeof(double)"); + memcpy(&b, &value, sizeof(b)); + + out.debug << " : "; + for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) { + out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0"); + b <<= 1; + } + break; + } + default: + break; + } + } +} + +static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, + TOutputTraverser::EExtraOutput extra, int depth) { int size = node->getType().computeNumComponents(); @@ -862,84 +1201,82 @@ break; case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif + OutputDouble(out, constUnion[i].getDConst(), extra); + out.debug << "\n"; + break; + case EbtInt8: { - const double value = constUnion[i].getDConst(); - // Print infinities and NaNs in a portable way. - if (IsInfinity(value)) { - if (value < 0) - out.debug << "-1.#INF\n"; - else - out.debug << "+1.#INF\n"; - } else if (IsNan(value)) - out.debug << "1.#IND\n"; - else { - const int maxSize = 300; - char buf[maxSize]; - snprintf(buf, maxSize, "%f", value); + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%d (%s)", constUnion[i].getI8Const(), "const int8_t"); - out.debug << buf << "\n"; - } + out.debug << buf << "\n"; } break; - case EbtInt: + case EbtUint8: { const int maxSize = 300; char buf[maxSize]; - snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int"); + snprintf(buf, maxSize, "%u (%s)", constUnion[i].getU8Const(), "const uint8_t"); out.debug << buf << "\n"; } break; - case EbtUint: + case EbtInt16: { const int maxSize = 300; char buf[maxSize]; - snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint"); + snprintf(buf, maxSize, "%d (%s)", constUnion[i].getI16Const(), "const int16_t"); out.debug << buf << "\n"; } break; - case EbtInt64: + case EbtUint16: { const int maxSize = 300; char buf[maxSize]; - snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t"); + snprintf(buf, maxSize, "%u (%s)", constUnion[i].getU16Const(), "const uint16_t"); out.debug << buf << "\n"; } break; - case EbtUint64: + case EbtInt: { const int maxSize = 300; char buf[maxSize]; - snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t"); + snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int"); out.debug << buf << "\n"; } break; -#ifdef AMD_EXTENSIONS - case EbtInt16: + case EbtUint: { const int maxSize = 300; char buf[maxSize]; - snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t"); + snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint"); out.debug << buf << "\n"; } break; - case EbtUint16: + case EbtInt64: { const int maxSize = 300; char buf[maxSize]; - snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t"); + snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t"); + + out.debug << buf << "\n"; + } + break; + case EbtUint64: + { + const int maxSize = 300; + char buf[maxSize]; + snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t"); out.debug << buf << "\n"; } break; -#endif default: out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc()); break; @@ -952,7 +1289,7 @@ OutputTreeText(infoSink, node, depth); infoSink.debug << "Constant:\n"; - OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); + OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1); } void TOutputTraverser::visitSymbol(TIntermSymbol* node) @@ -962,7 +1299,7 @@ infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n"; if (! node->getConstArray().empty()) - OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); + OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1); else if (node->getConstSubtree()) { incrementDepth(node); node->getConstSubtree()->traverse(this); @@ -979,7 +1316,17 @@ out.debug << "Loop with condition "; if (! node->testFirst()) out.debug << "not "; - out.debug << "tested first\n"; + out.debug << "tested first"; + + if (node->getUnroll()) + out.debug << ": Unroll"; + if (node->getDontUnroll()) + out.debug << ": DontUnroll"; + if (node->getLoopDependency()) { + out.debug << ": Dependency "; + out.debug << node->getLoopDependency(); + } + out.debug << "\n"; ++depth; @@ -1040,7 +1387,13 @@ TInfoSink& out = infoSink; OutputTreeText(out, node, depth); - out.debug << "switch\n"; + out.debug << "switch"; + + if (node->getFlatten()) + out.debug << ": Flatten"; + if (node->getDontFlatten()) + out.debug << ": DontFlatten"; + out.debug << "\n"; OutputTreeText(out, node, depth); out.debug << "condition\n"; @@ -1126,6 +1479,16 @@ } break; +#ifdef NV_EXTENSIONS + case EShLangMeshNV: + infoSink.debug << "max_vertices = " << vertices << "\n"; + infoSink.debug << "max_primitives = " << primitives << "\n"; + infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n"; + // Fall through + + case EShLangTaskNV: + // Fall through +#endif case EShLangCompute: infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; { @@ -1148,7 +1511,8 @@ return; TOutputTraverser it(infoSink); - + if (getBinaryDoubleOutput()) + it.setDoubleOutput(TOutputTraverser::BinaryDoubleOutput); treeRoot->traverse(&it); } diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -132,7 +132,7 @@ target = &inputList; else if (base->getQualifier().storage == EvqVaryingOut) target = &outputList; - else if (base->getQualifier().isUniformOrBuffer()) + else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().layoutPushConstant) target = &uniformList; if (target) { @@ -331,8 +331,14 @@ ent.symbol->getType(), ent.live); } else { - TString errorMsg = "Invalid shader In/Out variable semantic: "; - errorMsg += ent.symbol->getType().getQualifier().semanticName; + TString errorMsg; + if (ent.symbol->getType().getQualifier().semanticName != nullptr) { + errorMsg = "Invalid shader In/Out variable semantic: "; + errorMsg += ent.symbol->getType().getQualifier().semanticName; + } else { + errorMsg = "Invalid shader In/Out variable: "; + errorMsg += ent.symbol->getName(); + } infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); error = true; } @@ -353,7 +359,9 @@ { TDefaultIoResolverBase(const TIntermediate &intermediate) : intermediate(intermediate), - nextUniformLocation(0) + nextUniformLocation(intermediate.getUniformLocationBase()), + nextInputLocation(0), + nextOutputLocation(0) { } int getBaseBinding(TResourceType res, unsigned int set) const { @@ -381,29 +389,34 @@ return !(at != slots[set].end() && *at == slot); } - int reserveSlot(int set, int slot) + int reserveSlot(int set, int slot, int size = 1) { TSlotSet::iterator at = findSlot(set, slot); // tolerate aliasing, by not double-recording aliases // (policy about appropriateness of the alias is higher up) - if (at == slots[set].end() || *at != slot) - slots[set].insert(at, slot); + for (int i = 0; i < size; i++) { + if (at == slots[set].end() || *at != slot + i) + at = slots[set].insert(at, slot + i); + ++at; + } return slot; } - int getFreeSlot(int set, int base) + int getFreeSlot(int set, int base, int size = 1) { TSlotSet::iterator at = findSlot(set, base); if (at == slots[set].end()) - return reserveSlot(set, base); + return reserveSlot(set, base, size); - // look in locksteps, if they not match, then there is a free slot - for (; at != slots[set].end(); ++at, ++base) - if (*at != base) + // look for a big enough gap + for (; at != slots[set].end(); ++at) { + if (*at - base >= size) break; - return reserveSlot(set, base); + base = *at + 1; + } + return reserveSlot(set, base, size); } virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0; @@ -421,7 +434,7 @@ return 0; } - int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override + int resolveUniformLocation(EShLanguage /*stage*/, const char* name, const glslang::TType& type, bool /*is_live*/) override { // kick out of not doing this if (!doAutoLocationMapping()) @@ -429,7 +442,9 @@ // no locations added if already present, a built-in variable, a block, or an opaque if (type.getQualifier().hasLocation() || type.isBuiltIn() || - type.getBasicType() == EbtBlock || type.containsOpaque()) + type.getBasicType() == EbtBlock || + type.getBasicType() == EbtAtomicUint || + (type.containsOpaque() && intermediate.getSpv().openGl == 0)) return -1; // no locations on blocks of built-in variables @@ -440,13 +455,21 @@ return -1; } - return nextUniformLocation++; + int location = intermediate.getUniformLocationOverride(name); + if (location != -1) + return location; + + location = nextUniformLocation; + + nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type); + + return location; } bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override { return true; } - int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override + int resolveInOutLocation(EShLanguage stage, const char* /*name*/, const TType& type, bool /*is_live*/) override { // kick out of not doing this if (!doAutoLocationMapping()) @@ -464,14 +487,24 @@ return -1; } - // Placeholder. - // TODO: It would be nice to flesh this out using - // intermediate->computeTypeLocationSize(type), or functions that call it like - // intermediate->addUsedLocation() - // These in turn would want the intermediate, which is not available here, but - // is available in many places, and a lot of copying from it could be saved if - // it were just available. - return 0; + // point to the right input or output location counter + int& nextLocation = type.getQualifier().isPipeInput() ? nextInputLocation : nextOutputLocation; + + // Placeholder. This does not do proper cross-stage lining up, nor + // work with mixed location/no-location declarations. + int location = nextLocation; + int typeLocationSize; + // Don’t take into account the outer-most array if the stage’s + // interface is automatically an array. + if (type.getQualifier().isArrayedIo(stage)) { + TType elementType(type, 0); + typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage); + } else { + typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage); + } + nextLocation += typeLocationSize; + + return location; } int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override { @@ -490,8 +523,13 @@ void endResolve(EShLanguage) override {} protected: + TDefaultIoResolverBase(TDefaultIoResolverBase&); + TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&); + const TIntermediate &intermediate; int nextUniformLocation; + int nextInputLocation; + int nextOutputLocation; // Return descriptor set specific base if there is one, and the generic base otherwise. int selectBaseBinding(int base, int descriptorSetBase) const { @@ -541,40 +579,42 @@ int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override { const int set = getLayoutSet(type); + // On OpenGL arrays of opaque types take a seperate binding for each element + int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; if (type.getQualifier().hasBinding()) { if (isImageType(type)) - return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding); + return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding, numBindings); if (isTextureType(type)) - return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); + return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding, numBindings); if (isSsboType(type)) - return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding); + return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding, numBindings); if (isSamplerType(type)) - return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); + return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding, numBindings); if (isUboType(type)) - return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); + return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding, numBindings); } else if (is_live && doAutoBindingMapping()) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one if (isImageType(type)) - return getFreeSlot(set, getBaseBinding(EResImage, set)); + return getFreeSlot(set, getBaseBinding(EResImage, set), numBindings); if (isTextureType(type)) - return getFreeSlot(set, getBaseBinding(EResTexture, set)); + return getFreeSlot(set, getBaseBinding(EResTexture, set), numBindings); if (isSsboType(type)) - return getFreeSlot(set, getBaseBinding(EResSsbo, set)); + return getFreeSlot(set, getBaseBinding(EResSsbo, set), numBindings); if (isSamplerType(type)) - return getFreeSlot(set, getBaseBinding(EResSampler, set)); + return getFreeSlot(set, getBaseBinding(EResSampler, set), numBindings); if (isUboType(type)) - return getFreeSlot(set, getBaseBinding(EResUbo, set)); + return getFreeSlot(set, getBaseBinding(EResUbo, set), numBindings); } return -1; @@ -593,7 +633,7 @@ /******************************************************************************** The following IO resolver maps types in HLSL register space, as follows: -t – for shader resource views (SRV) +t - for shader resource views (SRV) TEXTURE1D TEXTURE1DARRAY TEXTURE2D @@ -608,7 +648,7 @@ BUFFER TBUFFER -s – for samplers +s - for samplers SAMPLER SAMPLER1D SAMPLER2D @@ -617,7 +657,7 @@ SAMPLERSTATE SAMPLERCOMPARISONSTATE -u – for unordered access views (UAV) +u - for unordered access views (UAV) RWBYTEADDRESSBUFFER RWSTRUCTUREDBUFFER APPENDSTRUCTUREDBUFFER @@ -629,7 +669,7 @@ RWTEXTURE2DARRAY RWTEXTURE3D -b – for constant buffer views (CBV) +b - for constant buffer views (CBV) CBUFFER CONSTANTBUFFER ********************************************************************************/ diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,7 @@ // // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -76,12 +78,13 @@ // void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) { - if (source == EShSourceNone) - source = unit.source; - - if (source != unit.source) - error(infoSink, "can't link compilation units from different source languages"); + mergeCallGraphs(infoSink, unit); + mergeModes(infoSink, unit); + mergeTrees(infoSink, unit); +} +void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) +{ if (unit.getNumEntryPoints() > 0) { if (getNumEntryPoints() > 0) error(infoSink, "can't handle multiple entry points per stage"); @@ -91,46 +94,88 @@ } } numEntryPoints += unit.getNumEntryPoints(); - numErrors += unit.getNumErrors(); - numPushConstants += unit.numPushConstants; + callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); +} - if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) - error(infoSink, "gl_FragCoord redeclarations must match across shaders"); +#define MERGE_MAX(member) member = std::max(member, unit.member) +#define MERGE_TRUE(member) if (unit.member) member = unit.member; - if (! earlyFragmentTests) - earlyFragmentTests = unit.earlyFragmentTests; +void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) +{ + if (language != unit.language) + error(infoSink, "stages must match when linking into a single stage"); - if (!postDepthCoverage) - postDepthCoverage = unit.postDepthCoverage; + if (source == EShSourceNone) + source = unit.source; + if (source != unit.source) + error(infoSink, "can't link compilation units from different source languages"); - if (depthLayout == EldNone) - depthLayout = unit.depthLayout; - else if (depthLayout != unit.depthLayout) - error(infoSink, "Contradictory depth layouts"); + if (treeRoot == nullptr) { + profile = unit.profile; + version = unit.version; + requestedExtensions = unit.requestedExtensions; + } else { + if ((profile == EEsProfile) != (unit.profile == EEsProfile)) + error(infoSink, "Cannot cross link ES and desktop profiles"); + else if (unit.profile == ECompatibilityProfile) + profile = ECompatibilityProfile; + version = std::max(version, unit.version); + requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end()); + } - blendEquations |= unit.blendEquations; + MERGE_MAX(spvVersion.spv); + MERGE_MAX(spvVersion.vulkanGlsl); + MERGE_MAX(spvVersion.vulkan); + MERGE_MAX(spvVersion.openGl); - if (inputPrimitive == ElgNone) - inputPrimitive = unit.inputPrimitive; - else if (inputPrimitive != unit.inputPrimitive) - error(infoSink, "Contradictory input layout primitives"); + numErrors += unit.getNumErrors(); + numPushConstants += unit.numPushConstants; - if (outputPrimitive == ElgNone) - outputPrimitive = unit.outputPrimitive; - else if (outputPrimitive != unit.outputPrimitive) - error(infoSink, "Contradictory output layout primitives"); + if (unit.invocations != TQualifier::layoutNotSet) { + if (invocations == TQualifier::layoutNotSet) + invocations = unit.invocations; + else if (invocations != unit.invocations) + error(infoSink, "number of invocations must match between compilation units"); + } if (vertices == TQualifier::layoutNotSet) vertices = unit.vertices; else if (vertices != unit.vertices) { - if (language == EShLangGeometry) + if (language == EShLangGeometry +#ifdef NV_EXTENSIONS + || language == EShLangMeshNV +#endif + ) error(infoSink, "Contradictory layout max_vertices values"); else if (language == EShLangTessControl) error(infoSink, "Contradictory layout vertices values"); else assert(0); } +#ifdef NV_EXTENSIONS + if (primitives == TQualifier::layoutNotSet) + primitives = unit.primitives; + else if (primitives != unit.primitives) { + if (language == EShLangMeshNV) + error(infoSink, "Contradictory layout max_primitives values"); + else + assert(0); + } +#endif + + if (inputPrimitive == ElgNone) + inputPrimitive = unit.inputPrimitive; + else if (inputPrimitive != unit.inputPrimitive) + error(infoSink, "Contradictory input layout primitives"); + + if (outputPrimitive == ElgNone) + outputPrimitive = unit.outputPrimitive; + else if (outputPrimitive != unit.outputPrimitive) + error(infoSink, "Contradictory output layout primitives"); + + if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) + error(infoSink, "gl_FragCoord redeclarations must match across shaders"); if (vertexSpacing == EvsNone) vertexSpacing = unit.vertexSpacing; @@ -142,8 +187,7 @@ else if (vertexOrder != unit.vertexOrder) error(infoSink, "Contradictory triangle ordering"); - if (unit.pointMode) - pointMode = true; + MERGE_TRUE(pointMode); for (int i = 0; i < 3; ++i) { if (localSize[i] > 1) @@ -157,48 +201,214 @@ error(infoSink, "Contradictory local size specialization ids"); } - if (unit.xfbMode) - xfbMode = true; + MERGE_TRUE(earlyFragmentTests); + MERGE_TRUE(postDepthCoverage); + + if (depthLayout == EldNone) + depthLayout = unit.depthLayout; + else if (depthLayout != unit.depthLayout) + error(infoSink, "Contradictory depth layouts"); + + MERGE_TRUE(depthReplacing); + MERGE_TRUE(hlslFunctionality1); + + blendEquations |= unit.blendEquations; + + MERGE_TRUE(xfbMode); + for (size_t b = 0; b < xfbBuffers.size(); ++b) { if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd) xfbBuffers[b].stride = unit.xfbBuffers[b].stride; else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride) error(infoSink, "Contradictory xfb_stride"); xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride); - if (unit.xfbBuffers[b].containsDouble) - xfbBuffers[b].containsDouble = true; + if (unit.xfbBuffers[b].contains64BitType) + xfbBuffers[b].contains64BitType = true; +#ifdef AMD_EXTENSIONS + if (unit.xfbBuffers[b].contains32BitType) + xfbBuffers[b].contains32BitType = true; + if (unit.xfbBuffers[b].contains16BitType) + xfbBuffers[b].contains16BitType = true; +#endif // TODO: 4.4 link: enhanced layouts: compare ranges } - if (unit.treeRoot == 0) + MERGE_TRUE(multiStream); + +#ifdef NV_EXTENSIONS + MERGE_TRUE(layoutOverrideCoverage); + MERGE_TRUE(geoPassthroughEXT); +#endif + + for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) { + if (unit.shiftBinding[i] > 0) + setShiftBinding((TResourceType)i, unit.shiftBinding[i]); + } + + for (unsigned int i = 0; i < unit.shiftBindingForSet.size(); ++i) { + for (auto it = unit.shiftBindingForSet[i].begin(); it != unit.shiftBindingForSet[i].end(); ++it) + setShiftBindingForSet((TResourceType)i, it->second, it->first); + } + + resourceSetBinding.insert(resourceSetBinding.end(), unit.resourceSetBinding.begin(), unit.resourceSetBinding.end()); + + MERGE_TRUE(autoMapBindings); + MERGE_TRUE(autoMapLocations); + MERGE_TRUE(invertY); + MERGE_TRUE(flattenUniformArrays); + MERGE_TRUE(useUnknownFormat); + MERGE_TRUE(hlslOffsets); + MERGE_TRUE(useStorageBuffer); + MERGE_TRUE(hlslIoMapping); + + // TODO: sourceFile + // TODO: sourceText + // TODO: processes + + MERGE_TRUE(needToLegalize); + MERGE_TRUE(binaryDoubleOutput); + MERGE_TRUE(usePhysicalStorageBuffer); +} + +// +// Merge the 'unit' AST into 'this' AST. +// That includes rationalizing the unique IDs, which were set up independently, +// and might have overlaps that are not the same symbol, or might have different +// IDs for what should be the same shared symbol. +// +void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) +{ + if (unit.treeRoot == nullptr) return; - if (treeRoot == 0) { + if (treeRoot == nullptr) { treeRoot = unit.treeRoot; - version = unit.version; - requestedExtensions = unit.requestedExtensions; return; } // Getting this far means we have two existing trees to merge... +#ifdef NV_EXTENSIONS + numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks; +#endif - version = std::max(version, unit.version); - requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end()); +#ifdef NV_EXTENSIONS + numTaskNVBlocks += unit.numTaskNVBlocks; +#endif // Get the top-level globals of each unit TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence(); // Get the linker-object lists - TIntermSequence& linkerObjects = findLinkerObjects(); - TIntermSequence& unitLinkerObjects = unit.findLinkerObjects(); + TIntermSequence& linkerObjects = findLinkerObjects()->getSequence(); + const TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence(); + + // Map by global name to unique ID to rationalize the same object having + // differing IDs in different trees. + TMap idMap; + int maxId; + seedIdMap(idMap, maxId); + remapIds(idMap, maxId + 1, unit); mergeBodies(infoSink, globals, unitGlobals); mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); - ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); } +// Traverser that seeds an ID map with all built-ins, and tracks the +// maximum ID used. +// (It would be nice to put this in a function, but that causes warnings +// on having no bodies for the copy-constructor/operator=.) +class TBuiltInIdTraverser : public TIntermTraverser { +public: + TBuiltInIdTraverser(TMap& idMap) : idMap(idMap), maxId(0) { } + // If it's a built in, add it to the map. + // Track the max ID. + virtual void visitSymbol(TIntermSymbol* symbol) + { + const TQualifier& qualifier = symbol->getType().getQualifier(); + if (qualifier.builtIn != EbvNone) + idMap[symbol->getName()] = symbol->getId(); + maxId = std::max(maxId, symbol->getId()); + } + int getMaxId() const { return maxId; } +protected: + TBuiltInIdTraverser(TBuiltInIdTraverser&); + TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&); + TMap& idMap; + int maxId; +}; + +// Traverser that seeds an ID map with non-builtins. +// (It would be nice to put this in a function, but that causes warnings +// on having no bodies for the copy-constructor/operator=.) +class TUserIdTraverser : public TIntermTraverser { +public: + TUserIdTraverser(TMap& idMap) : idMap(idMap) { } + // If its a non-built-in global, add it to the map. + virtual void visitSymbol(TIntermSymbol* symbol) + { + const TQualifier& qualifier = symbol->getType().getQualifier(); + if (qualifier.builtIn == EbvNone) + idMap[symbol->getName()] = symbol->getId(); + } + +protected: + TUserIdTraverser(TUserIdTraverser&); + TUserIdTraverser& operator=(TUserIdTraverser&); + TMap& idMap; // over biggest id +}; + +// Initialize the the ID map with what we know of 'this' AST. +void TIntermediate::seedIdMap(TMap& idMap, int& maxId) +{ + // all built-ins everywhere need to align on IDs and contribute to the max ID + TBuiltInIdTraverser builtInIdTraverser(idMap); + treeRoot->traverse(&builtInIdTraverser); + maxId = builtInIdTraverser.getMaxId(); + + // user variables in the linker object list need to align on ids + TUserIdTraverser userIdTraverser(idMap); + findLinkerObjects()->traverse(&userIdTraverser); +} + +// Traverser to map an AST ID to what was known from the seeding AST. +// (It would be nice to put this in a function, but that causes warnings +// on having no bodies for the copy-constructor/operator=.) +class TRemapIdTraverser : public TIntermTraverser { +public: + TRemapIdTraverser(const TMap& idMap, int idShift) : idMap(idMap), idShift(idShift) { } + // Do the mapping: + // - if the same symbol, adopt the 'this' ID + // - otherwise, ensure a unique ID by shifting to a new space + virtual void visitSymbol(TIntermSymbol* symbol) + { + const TQualifier& qualifier = symbol->getType().getQualifier(); + bool remapped = false; + if (qualifier.isLinkable() || qualifier.builtIn != EbvNone) { + auto it = idMap.find(symbol->getName()); + if (it != idMap.end()) { + symbol->changeId(it->second); + remapped = true; + } + } + if (!remapped) + symbol->changeId(symbol->getId() + idShift); + } +protected: + TRemapIdTraverser(TRemapIdTraverser&); + TRemapIdTraverser& operator=(TRemapIdTraverser&); + const TMap& idMap; + int idShift; +}; + +void TIntermediate::remapIds(const TMap& idMap, int idShift, TIntermediate& unit) +{ + // Remap all IDs to either share or be unique, as dictated by the idMap and idShift. + TRemapIdTraverser idTraverser(idMap, idShift); + unit.getTreeRoot()->traverse(&idTraverser); +} + // // Merge the function bodies and global-level initializers from unitGlobals into globals. // Will error check duplication of function bodies for the same signature. @@ -267,10 +477,13 @@ // Recursively merge the implicit array sizes through the objects' respective type trees. void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) { - if (type.isImplicitlySizedArray() && unitType.isArray()) { - int newImplicitArraySize = unitType.isImplicitlySizedArray() ? unitType.getImplicitArraySize() : unitType.getOuterArraySize(); - if (newImplicitArraySize > type.getImplicitArraySize ()) - type.setImplicitArraySize(newImplicitArraySize); + if (type.isUnsizedArray()) { + if (unitType.isUnsizedArray()) { + type.updateImplicitArraySize(unitType.getImplicitArraySize()); + if (unitType.isArrayVariablyIndexed()) + type.setArrayVariablyIndexed(); + } else if (unitType.isSizedArray()) + type.changeOuterArraySize(unitType.getOuterArraySize()); } // Type mismatches are caught and reported after this, just be careful for now. @@ -293,8 +506,13 @@ // Types have to match if (symbol.getType() != unitSymbol.getType()) { - error(infoSink, "Types must match:"); - writeTypeComparison = true; + // but, we make an exception if one is an implicit array and the other is sized + if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() && + symbol.getType().sameElementType(unitSymbol.getType()) && + (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) { + error(infoSink, "Types must match:"); + writeTypeComparison = true; + } } // Qualifiers have to (almost) match @@ -335,11 +553,16 @@ } // Memory... - if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent || - symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || - symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || - symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly || - symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { + if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent || + symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent || + symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent || + symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent || + symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent || + symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate || + symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || + symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || + symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly || + symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { error(infoSink, "Memory qualifiers must match:"); writeTypeComparison = true; } @@ -417,8 +640,14 @@ error(infoSink, "Cannot use both gl_FragColor and gl_FragData"); for (size_t b = 0; b < xfbBuffers.size(); ++b) { - if (xfbBuffers[b].containsDouble) + if (xfbBuffers[b].contains64BitType) RoundToPow2(xfbBuffers[b].implicitStride, 8); +#ifdef AMD_EXTENSIONS + else if (xfbBuffers[b].contains32BitType) + RoundToPow2(xfbBuffers[b].implicitStride, 4); + else if (xfbBuffers[b].contains16BitType) + RoundToPow2(xfbBuffers[b].implicitStride, 2); +#endif // "It is a compile-time or link-time error to have // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or @@ -433,18 +662,31 @@ xfbBuffers[b].stride = xfbBuffers[b].implicitStride; // "If the buffer is capturing any - // outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a + // outputs with double-precision or 64-bit integer components, the stride must be a multiple of 8, otherwise it must be a // multiple of 4, or a compile-time or link-time error results." - if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) { - error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:"); + if (xfbBuffers[b].contains64BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) { + error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:"); infoSink.info.prefix(EPrefixError); infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; +#ifdef AMD_EXTENSIONS + } else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { +#else } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { +#endif error(infoSink, "xfb_stride must be multiple of 4:"); infoSink.info.prefix(EPrefixError); infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; } +#ifdef AMD_EXTENSIONS + // "If the buffer is capturing any + // outputs with half-precision or 16-bit integer components, the stride must be a multiple of 2" + else if (xfbBuffers[b].contains16BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 2)) { + error(infoSink, "xfb_stride must be multiple of 2 for buffer holding a half float or 16-bit integer:"); + infoSink.info.prefix(EPrefixError); + infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; + } +#endif // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) { @@ -474,17 +716,9 @@ case EShLangGeometry: if (inputPrimitive == ElgNone) error(infoSink, "At least one shader must specify an input layout primitive"); - if (outputPrimitive == ElgNone -#ifdef NV_EXTENSIONS - && !getGeoPassthroughEXT() -#endif - ) + if (outputPrimitive == ElgNone) error(infoSink, "At least one shader must specify an output layout primitive"); - if (vertices == TQualifier::layoutNotSet -#ifdef NV_EXTENSIONS - && !getGeoPassthroughEXT() -#endif - ) + if (vertices == TQualifier::layoutNotSet) error(infoSink, "At least one shader must specify a layout(max_vertices = value)"); break; case EShLangFragment: @@ -496,6 +730,42 @@ break; case EShLangCompute: break; + +#ifdef NV_EXTENSIONS + case EShLangRayGenNV: + case EShLangIntersectNV: + case EShLangAnyHitNV: + case EShLangClosestHitNV: + case EShLangMissNV: + case EShLangCallableNV: + if (numShaderRecordNVBlocks > 1) + error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage"); + break; + case EShLangMeshNV: + // NV_mesh_shader doesn't allow use of both single-view and per-view builtins. + if (inIoAccessed("gl_Position") && inIoAccessed("gl_PositionPerViewNV")) + error(infoSink, "Can only use one of gl_Position or gl_PositionPerViewNV"); + if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipDistancePerViewNV")) + error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipDistancePerViewNV"); + if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_CullDistancePerViewNV")) + error(infoSink, "Can only use one of gl_CullDistance or gl_CullDistancePerViewNV"); + if (inIoAccessed("gl_Layer") && inIoAccessed("gl_LayerPerViewNV")) + error(infoSink, "Can only use one of gl_Layer or gl_LayerPerViewNV"); + if (inIoAccessed("gl_ViewportMask") && inIoAccessed("gl_ViewportMaskPerViewNV")) + error(infoSink, "Can only use one of gl_ViewportMask or gl_ViewportMaskPerViewNV"); + if (outputPrimitive == ElgNone) + error(infoSink, "At least one shader must specify an output layout primitive"); + if (vertices == TQualifier::layoutNotSet) + error(infoSink, "At least one shader must specify a layout(max_vertices = value)"); + if (primitives == TQualifier::layoutNotSet) + error(infoSink, "At least one shader must specify a layout(max_primitives = value)"); + // fall through + case EShLangTaskNV: + if (numTaskNVBlocks > 1) + error(infoSink, "Only one taskNV interface block is allowed per shader"); + break; +#endif + default: error(infoSink, "Unknown Stage."); break; @@ -510,7 +780,9 @@ virtual void visitSymbol(TIntermSymbol* symbol) { // Implicitly size arrays. - symbol->getWritableType().adoptImplicitArraySizes(); + // If an unsized array is left as unsized, it effectively + // becomes run-time sized. + symbol->getWritableType().adoptImplicitArraySizes(false); } } finalLinkTraverser; @@ -688,7 +960,7 @@ // TODO: linker functionality: location collision checking - TIntermSequence& linkObjects = findLinkerObjects(); + TIntermSequence& linkObjects = findLinkerObjects()->getSequence(); for (size_t i = 0; i < linkObjects.size(); ++i) { const TType& type = linkObjects[i]->getAsTyped()->getType(); const TQualifier& qualifier = type.getQualifier(); @@ -707,7 +979,7 @@ } } -TIntermSequence& TIntermediate::findLinkerObjects() const +TIntermAggregate* TIntermediate::findLinkerObjects() const { // Get the top-level globals TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); @@ -715,7 +987,7 @@ // Get the last member of the sequences, expected to be the linker-object lists assert(globals.back()->getAsAggregate()->getOp() == EOpLinkerObjects); - return globals.back()->getAsAggregate()->getSequence(); + return globals.back()->getAsAggregate(); } // See if a variable was both a user-declared output and used. @@ -723,7 +995,7 @@ // is more useful, and perhaps the spec should be changed to reflect that. bool TIntermediate::userOutputUsed() const { - const TIntermSequence& linkerObjects = findLinkerObjects(); + const TIntermSequence& linkerObjects = findLinkerObjects()->getSequence(); bool found = false; for (size_t i = 0; i < linkerObjects.size(); ++i) { @@ -764,8 +1036,8 @@ return -1; int size; - if (qualifier.isUniformOrBuffer()) { - if (type.isExplicitlySizedArray()) + if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) { + if (type.isSizedArray()) size = type.getCumulativeArraySize(); else size = 1; @@ -773,9 +1045,9 @@ // Strip off the outer array dimension for those having an extra one. if (type.isArray() && qualifier.isArrayedIo(language)) { TType elementType(type, 0); - size = computeTypeLocationSize(elementType); + size = computeTypeLocationSize(elementType, language); } else - size = computeTypeLocationSize(type); + size = computeTypeLocationSize(type, language); } // Locations, and components within locations. @@ -836,8 +1108,8 @@ // combine location and component ranges TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0); - // check for collisions, except for vertex inputs on desktop - if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput())) + // check for collisions, except for vertex inputs on desktop targeting OpenGL + if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) collision = checkLocationRange(set, range, type, typeCollision); if (collision < 0) @@ -907,18 +1179,27 @@ // Recursively figure out how many locations are used up by an input or output type. // Return the size of type, as measured by "locations". -int TIntermediate::computeTypeLocationSize(const TType& type) const +int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage) { // "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n // consecutive locations..." if (type.isArray()) { // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness + // TODO: are there valid cases of having an unsized array with a location? If so, running this code too early. TType elementType(type, 0); - if (type.isImplicitlySizedArray()) { - // TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early. - return computeTypeLocationSize(elementType); - } else - return type.getOuterArraySize() * computeTypeLocationSize(elementType); + if (type.isSizedArray() +#ifdef NV_EXTENSIONS + && !type.getQualifier().isPerView() +#endif + ) + return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage); + else { +#ifdef NV_EXTENSIONS + // unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];" + elementType.getQualifier().perViewNV = false; +#endif + return computeTypeLocationSize(elementType, stage); + } } // "The locations consumed by block and structure members are determined by applying the rules above @@ -927,7 +1208,7 @@ int size = 0; for (int member = 0; member < (int)type.getStruct()->size(); ++member) { TType memberType(type, member); - size += computeTypeLocationSize(memberType); + size += computeTypeLocationSize(memberType, stage); } return size; } @@ -941,7 +1222,7 @@ if (type.isScalar()) return 1; if (type.isVector()) { - if (language == EShLangVertex && type.getQualifier().isPipeInput()) + if (stage == EShLangVertex && type.getQualifier().isPipeInput()) return 1; if (type.getBasicType() == EbtDouble && type.getVectorSize() > 2) return 2; @@ -954,13 +1235,44 @@ // for an n-element array of m-component vectors..." if (type.isMatrix()) { TType columnType(type, 0); - return type.getMatrixCols() * computeTypeLocationSize(columnType); + return type.getMatrixCols() * computeTypeLocationSize(columnType, stage); } assert(0); return 1; } +// Same as computeTypeLocationSize but for uniforms +int TIntermediate::computeTypeUniformLocationSize(const TType& type) +{ + // "Individual elements of a uniform array are assigned + // consecutive locations with the first element taking location + // location." + if (type.isArray()) { + // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness + TType elementType(type, 0); + if (type.isSizedArray()) { + return type.getOuterArraySize() * computeTypeUniformLocationSize(elementType); + } else { + // TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early. + return computeTypeUniformLocationSize(elementType); + } + } + + // "Each subsequent inner-most member or element gets incremental + // locations for the entire structure or array." + if (type.isStruct()) { + int size = 0; + for (int member = 0; member < (int)type.getStruct()->size(); ++member) { + TType memberType(type, member); + size += computeTypeUniformLocationSize(memberType); + } + return size; + } + + return 1; +} + // Accumulate xfb buffer ranges and check for collisions as the accumulation is done. // // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. @@ -973,7 +1285,11 @@ TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer]; // compute the range - unsigned int size = computeTypeXfbSize(type, buffer.containsDouble); +#ifdef AMD_EXTENSIONS + unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType); +#else + unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType); +#endif buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size); TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1); @@ -992,11 +1308,18 @@ // Recursively figure out how many bytes of xfb buffer are used by the given type. // Return the size of type, in bytes. -// Sets containsDouble to true if the type contains a double. -// N.B. Caller must set containsDouble to false before calling. -unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const +// Sets contains64BitType to true if the type contains a 64-bit data type. +#ifdef AMD_EXTENSIONS +// Sets contains32BitType to true if the type contains a 32-bit data type. +// Sets contains16BitType to true if the type contains a 16-bit data type. +// N.B. Caller must set contains64BitType, contains32BitType, and contains16BitType to false before calling. +unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const +#else +// N.B. Caller must set contains64BitType to false before calling. +unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType) const +#endif { - // "...if applied to an aggregate containing a double, the offset must also be a multiple of 8, + // "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8. // ...within the qualified entity, subsequent components are each // assigned, in order, to the next available offset aligned to a multiple of @@ -1005,31 +1328,61 @@ if (type.isArray()) { // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness - assert(type.isExplicitlySizedArray()); + assert(type.isSizedArray()); TType elementType(type, 0); - return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble); +#ifdef AMD_EXTENSIONS + return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType); +#else + return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType); +#endif } if (type.isStruct()) { unsigned int size = 0; - bool structContainsDouble = false; + bool structContains64BitType = false; +#ifdef AMD_EXTENSIONS + bool structContains32BitType = false; + bool structContains16BitType = false; +#endif for (int member = 0; member < (int)type.getStruct()->size(); ++member) { TType memberType(type, member); // "... if applied to - // an aggregate containing a double, the offset must also be a multiple of 8, + // an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8." - bool memberContainsDouble = false; - int memberSize = computeTypeXfbSize(memberType, memberContainsDouble); - if (memberContainsDouble) { - structContainsDouble = true; + bool memberContains64BitType = false; +#ifdef AMD_EXTENSIONS + bool memberContains32BitType = false; + bool memberContains16BitType = false; + int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType); +#else + int memberSize = computeTypeXfbSize(memberType, memberContains64BitType); +#endif + if (memberContains64BitType) { + structContains64BitType = true; RoundToPow2(size, 8); +#ifdef AMD_EXTENSIONS + } else if (memberContains32BitType) { + structContains32BitType = true; + RoundToPow2(size, 4); + } else if (memberContains16BitType) { + structContains16BitType = true; + RoundToPow2(size, 2); +#endif } size += memberSize; } - if (structContainsDouble) { - containsDouble = true; + if (structContains64BitType) { + contains64BitType = true; RoundToPow2(size, 8); +#ifdef AMD_EXTENSIONS + } else if (structContains32BitType) { + contains32BitType = true; + RoundToPow2(size, 4); + } else if (structContains16BitType) { + contains16BitType = true; + RoundToPow2(size, 2); +#endif } return size; } @@ -1046,11 +1399,23 @@ numComponents = 1; } - if (type.getBasicType() == EbtDouble) { - containsDouble = true; + if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) { + contains64BitType = true; return 8 * numComponents; +#ifdef AMD_EXTENSIONS + } else if (type.getBasicType() == EbtFloat16 || type.getBasicType() == EbtInt16 || type.getBasicType() == EbtUint16) { + contains16BitType = true; + return 2 * numComponents; + } else if (type.getBasicType() == EbtInt8 || type.getBasicType() == EbtUint8) + return numComponents; + else { + contains32BitType = true; + return 4 * numComponents; + } +#else } else return 4 * numComponents; +#endif } const int baseAlignmentVec4Std140 = 16; @@ -1064,11 +1429,12 @@ case EbtInt64: case EbtUint64: case EbtDouble: size = 8; return 8; -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: case EbtFloat16: size = 2; return 2; -#endif + case EbtInt8: + case EbtUint8: size = 1; return 1; + case EbtInt16: + case EbtUint16: size = 2; return 2; + case EbtReference: size = 8; return 8; default: size = 4; return 4; } } @@ -1087,10 +1453,11 @@ // stride comes from the flattening down to vectors. // // Return value is the alignment of the type. -int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor) +int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor) { int alignment; + bool std140 = layoutPacking == glslang::ElpStd140; // When using the std140 storage layout, structures will be laid out in buffer // storage with its members stored in monotonically increasing order based on their // location in the declaration. A structure and each structure member have a base @@ -1154,7 +1521,7 @@ if (type.isArray()) { // TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness TType derefType(type, 0); - alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor); + alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor); if (std140) alignment = std::max(baseAlignmentVec4Std140, alignment); RoundToPow2(size, alignment); @@ -1174,7 +1541,7 @@ int memberSize; // modify just the children's view of matrix layout, if there is one for this member TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix; - int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140, + int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, layoutPacking, (subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor); maxAlignment = std::max(maxAlignment, memberAlignment); RoundToPow2(size, memberAlignment); @@ -1197,6 +1564,8 @@ if (type.isVector()) { int scalarAlign = getBaseAlignmentScalar(type, size); switch (type.getVectorSize()) { + case 1: // HLSL has this, GLSL does not + return scalarAlign; case 2: size *= 2; return 2 * scalarAlign; @@ -1211,7 +1580,7 @@ // rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows TType derefType(type, 0, rowMajor); - alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor); + alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor); if (std140) alignment = std::max(baseAlignmentVec4Std140, alignment); RoundToPow2(size, alignment); @@ -1239,4 +1608,149 @@ : offset % 16 != 0; } +int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride, bool rowMajor) +{ + int alignment; + + stride = 0; + int dummyStride; + + if (type.isArray()) { + TType derefType(type, 0); + alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor); + + stride = size; + RoundToPow2(stride, alignment); + + size = stride * (type.getOuterArraySize() - 1) + size; + return alignment; + } + + if (type.getBasicType() == EbtStruct) { + const TTypeList& memberList = *type.getStruct(); + + size = 0; + int maxAlignment = 0; + for (size_t m = 0; m < memberList.size(); ++m) { + int memberSize; + // modify just the children's view of matrix layout, if there is one for this member + TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix; + int memberAlignment = getScalarAlignment(*memberList[m].type, memberSize, dummyStride, + (subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor); + maxAlignment = std::max(maxAlignment, memberAlignment); + RoundToPow2(size, memberAlignment); + size += memberSize; + } + + return maxAlignment; + } + + if (type.isScalar()) + return getBaseAlignmentScalar(type, size); + + if (type.isVector()) { + int scalarAlign = getBaseAlignmentScalar(type, size); + + size *= type.getVectorSize(); + return scalarAlign; + } + + if (type.isMatrix()) { + TType derefType(type, 0, rowMajor); + + alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor); + + stride = size; // use intra-matrix stride for stride of a just a matrix + if (rowMajor) + size = stride * type.getMatrixRows(); + else + size = stride * type.getMatrixCols(); + + return alignment; + } + + assert(0); // all cases should be covered above + size = 1; + return 1; +} + +int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor) +{ + if (layoutPacking == glslang::ElpScalar) { + return getScalarAlignment(type, size, stride, rowMajor); + } else { + return getBaseAlignment(type, size, stride, layoutPacking, rowMajor); + } +} + +// shared calculation by getOffset and getOffsets +void TIntermediate::updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize) +{ + int dummyStride; + + // modify just the children's view of matrix layout, if there is one for this member + TLayoutMatrix subMatrixLayout = memberType.getQualifier().layoutMatrix; + int memberAlignment = getMemberAlignment(memberType, memberSize, dummyStride, + parentType.getQualifier().layoutPacking, + subMatrixLayout != ElmNone + ? subMatrixLayout == ElmRowMajor + : parentType.getQualifier().layoutMatrix == ElmRowMajor); + RoundToPow2(offset, memberAlignment); +} + +// Lookup or calculate the offset of a block member, using the recursively +// defined block offset rules. +int TIntermediate::getOffset(const TType& type, int index) +{ + const TTypeList& memberList = *type.getStruct(); + + // Don't calculate offset if one is present, it could be user supplied + // and different than what would be calculated. That is, this is faster, + // but not just an optimization. + if (memberList[index].type->getQualifier().hasOffset()) + return memberList[index].type->getQualifier().layoutOffset; + + int memberSize = 0; + int offset = 0; + for (int m = 0; m <= index; ++m) { + updateOffset(type, *memberList[m].type, offset, memberSize); + + if (m < index) + offset += memberSize; + } + + return offset; +} + +// Calculate the block data size. +// Block arrayness is not taken into account, each element is backed by a separate buffer. +int TIntermediate::getBlockSize(const TType& blockType) +{ + const TTypeList& memberList = *blockType.getStruct(); + int lastIndex = (int)memberList.size() - 1; + int lastOffset = getOffset(blockType, lastIndex); + + int lastMemberSize; + int dummyStride; + getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, + blockType.getQualifier().layoutPacking, + blockType.getQualifier().layoutMatrix == ElmRowMajor); + + return lastOffset + lastMemberSize; +} + +int TIntermediate::computeBufferReferenceTypeSize(const TType& type) +{ + assert(type.getBasicType() == EbtReference); + int size = getBlockSize(*type.getReferentType()); + + int align = type.getBufferReferenceAlignment(); + + if (align) { + size = (size + align - 1) & ~(align-1); + } + + return size; +} + } // end namespace glslang diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,9 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2016 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. +// // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -40,6 +43,8 @@ #include "../Public/ShaderLang.h" #include "Versions.h" +#include +#include #include #include #include @@ -78,7 +83,7 @@ assert(i < MaxSwizzleSelectors); return components[i]; } - + private: int size_; selectorType components[MaxSwizzleSelectors]; @@ -144,11 +149,20 @@ // Things that need to be tracked per xfb buffer. struct TXfbBuffer { - TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), containsDouble(false) { } +#ifdef AMD_EXTENSIONS + TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false), + contains32BitType(false), contains16BitType(false) { } +#else + TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false) { } +#endif std::vector ranges; // byte offsets that have already been assigned unsigned int stride; unsigned int implicitStride; - bool containsDouble; + bool contains64BitType; +#ifdef AMD_EXTENSIONS + bool contains32BitType; + bool contains16BitType; +#endif }; // Track a set of strings describing how the module was processed. @@ -203,13 +217,24 @@ class TSymbol; class TVariable; +#ifdef NV_EXTENSIONS +// +// Texture and Sampler transformation mode. +// +enum ComputeDerivativeMode { + LayoutDerivativeNone, // default layout as SPV_NV_compute_shader_derivatives not enabled + LayoutDerivativeGroupQuads, // derivative_group_quadsNV + LayoutDerivativeGroupLinear, // derivative_group_linearNV +}; +#endif + // // Set of helper functions to help parse and build the tree. // class TIntermediate { public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : - implicitThisName("@this"), + implicitThisName("@this"), implicitCounterName("@count"), language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), @@ -217,10 +242,15 @@ pixelCenterInteger(false), originUpperLeft(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false), + hlslFunctionality1(false), blendEquations(0), xfbMode(false), multiStream(false), #ifdef NV_EXTENSIONS layoutOverrideCoverage(false), geoPassthroughEXT(false), + numShaderRecordNVBlocks(0), + computeDerivativeMode(LayoutDerivativeNone), + primitives(TQualifier::layoutNotSet), + numTaskNVBlocks(0), #endif autoMapBindings(false), autoMapLocations(false), @@ -229,9 +259,14 @@ useUnknownFormat(false), hlslOffsets(false), useStorageBuffer(false), + useVulkanMemoryModel(false), hlslIoMapping(false), + useVariablePointers(false), textureSamplerTransformMode(EShTexSampTransKeep), - needToLegalize(false) + needToLegalize(false), + binaryDoubleOutput(false), + usePhysicalStorageBuffer(false), + uniformLocationBase(0) { localSize[0] = 1; localSize[1] = 1; @@ -346,7 +381,7 @@ if (hlslOffsets) processes.addProcess("hlsl-offsets"); } - bool usingHlslOFfsets() const { return hlslOffsets; } + bool usingHlslOffsets() const { return hlslOffsets; } void setUseStorageBuffer() { useStorageBuffer = true; @@ -360,6 +395,30 @@ processes.addProcess("hlsl-iomap"); } bool usingHlslIoMapping() { return hlslIoMapping; } + void setUseVulkanMemoryModel() + { + useVulkanMemoryModel = true; + processes.addProcess("use-vulkan-memory-model"); + } + bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; } + void setUsePhysicalStorageBuffer() + { + usePhysicalStorageBuffer = true; + } + bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; } + void setUseVariablePointers() + { + useVariablePointers = true; + processes.addProcess("use-variable-pointers"); + } + bool usingVariablePointers() const { return useVariablePointers; } + + template T addCounterBufferName(const T& name) const { return name + implicitCounterName; } + bool hasCounterBufferName(const TString& name) const { + size_t len = strlen(implicitCounterName); + return name.size() > len && + name.compare(name.size() - len, len, implicitCounterName) == 0; + } void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } @@ -377,11 +436,40 @@ if (spvVersion.openGl > 0) processes.addProcess("client opengl100"); + // target SPV + switch (spvVersion.spv) { + case 0: + break; + case EShTargetSpv_1_0: + break; + case EShTargetSpv_1_1: + processes.addProcess("target-env spirv1.1"); + break; + case EShTargetSpv_1_2: + processes.addProcess("target-env spirv1.2"); + break; + case EShTargetSpv_1_3: + processes.addProcess("target-env spirv1.3"); + break; + default: + processes.addProcess("target-env spirvUnknown"); + break; + } + // target-environment processes - if (spvVersion.vulkan == 100) + switch (spvVersion.vulkan) { + case 0: + break; + case EShTargetVulkan_1_0: processes.addProcess("target-env vulkan1.0"); - else if (spvVersion.vulkan > 0) + break; + case EShTargetVulkan_1_1: + processes.addProcess("target-env vulkan1.1"); + break; + default: processes.addProcess("target-env vulkanUnknown"); + break; + } if (spvVersion.openGl > 0) processes.addProcess("target-env opengl"); } @@ -396,14 +484,21 @@ int getNumEntryPoints() const { return numEntryPoints; } int getNumErrors() const { return numErrors; } void addPushConstantCount() { ++numPushConstants; } +#ifdef NV_EXTENSIONS + void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; } + void addTaskNVCount() { ++numTaskNVBlocks; } +#endif + bool isRecursive() const { return recursive; } TIntermSymbol* addSymbol(const TVariable&); TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&); TIntermSymbol* addSymbol(const TType&, const TSourceLoc&); TIntermSymbol* addSymbol(const TIntermSymbol&); - TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const; + TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); + std::tuple addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1); TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*); + TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const; void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode); TIntermTyped* addShapeConversion(const TType&, TIntermTyped*); TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc); @@ -412,6 +507,11 @@ TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc); TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType); bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const; + bool isIntegralPromotion(TBasicType from, TBasicType to) const; + bool isFPPromotion(TBasicType from, TBasicType to) const; + bool isIntegralConversion(TBasicType from, TBasicType to) const; + bool isFPConversion(TBasicType from, TBasicType to) const; + bool isFPIntegralConversion(TBasicType from, TBasicType to) const; TOperator mapTypeToConstructorOp(const TType&) const; TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); @@ -420,27 +520,27 @@ TIntermAggregate* makeAggregate(const TSourceLoc&); TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc); bool areAllChildConst(TIntermAggregate* aggrNode); - TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&, TSelectionControl = ESelectionControlNone); - TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&, TSelectionControl = ESelectionControlNone); + TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&); + TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&); TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&); TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&); TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(signed char, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned char, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(signed short, const TSourceLoc&, bool literal = false) const; + TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const; -#ifdef AMD_EXTENSIONS - TIntermConstantUnion* addConstantUnion(short, const TSourceLoc&, bool literal = false) const; - TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const; - -#endif TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const; TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const; bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false); - TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone); - TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone); + TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&); + TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, + const TSourceLoc&, TIntermLoop*&); TIntermBranch* addBranch(TOperator, const TSourceLoc&); TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&); template TIntermTyped* addSwizzle(TSwizzleSelectors&, const TSourceLoc&); @@ -452,9 +552,6 @@ TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const; TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const; - // Add conversion from node's type to given basic type. - TIntermTyped* convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const; - // Constant folding (in Constant.cpp) TIntermTyped* fold(TIntermAggregate* aggrNode); TIntermTyped* foldConstructor(TIntermAggregate* aggrNode); @@ -560,6 +657,9 @@ void setDepthReplacing() { depthReplacing = true; } bool isDepthReplacing() const { return depthReplacing; } + void setHlslFunctionality1() { hlslFunctionality1 = true; } + bool getHlslFunctionality1() const { return hlslFunctionality1; } + void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); } unsigned int getBlendEquations() const { return blendEquations; } @@ -574,7 +674,8 @@ int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision); int addUsedOffsets(int binding, int offset, int numOffsets); bool addUsedConstantId(int id); - int computeTypeLocationSize(const TType&) const; + static int computeTypeLocationSize(const TType&, EShLanguage); + static int computeTypeUniformLocationSize(const TType&); bool setXfbBufferStride(int buffer, unsigned stride) { @@ -585,10 +686,20 @@ } unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; } int addXfbBufferOffset(const TType&); - unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const; +#ifdef AMD_EXTENSIONS + unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const; +#else + unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const; +#endif static int getBaseAlignmentScalar(const TType&, int& size); - static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor); + static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); + static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor); + static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); static bool improperStraddle(const TType& type, int size, int offset); + static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize); + static int getOffset(const TType& type, int index); + static int getBlockSize(const TType& blockType); + static int computeBufferReferenceTypeSize(const TType&); bool promote(TIntermOperator*); #ifdef NV_EXTENSIONS @@ -596,6 +707,16 @@ bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; } void setGeoPassthroughEXT() { geoPassthroughEXT = true; } bool getGeoPassthroughEXT() const { return geoPassthroughEXT; } + void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; } + ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; } + bool setPrimitives(int m) + { + if (primitives != TQualifier::layoutNotSet) + return primitives == m; + primitives = m; + return true; + } + int getPrimitives() const { return primitives; } #endif const char* addSemanticName(const TString& name) @@ -603,11 +724,14 @@ return semanticNameSet.insert(name).first->c_str(); } - void setSourceFile(const char* file) { sourceFile = file; } + void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; } const std::string& getSourceFile() const { return sourceFile; } - void addSourceText(const char* text) { sourceText = sourceText + text; } + void addSourceText(const char* text, size_t len) { sourceText.append(text, len); } const std::string& getSourceText() const { return sourceText; } - void addProcesses(const std::vector& p) { + const std::map& getIncludeText() const { return includeText; } + void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); } + void addProcesses(const std::vector& p) + { for (int i = 0; i < (int)p.size(); ++i) processes.addProcess(p[i]); } @@ -615,15 +739,43 @@ void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } const std::vector& getProcesses() const { return processes.getProcesses(); } + void addUniformLocationOverride(const char* nameStr, int location) + { + std::string name = nameStr; + uniformLocationOverrides[name] = location; + } + + int getUniformLocationOverride(const char* nameStr) const + { + std::string name = nameStr; + auto pos = uniformLocationOverrides.find(name); + if (pos == uniformLocationOverrides.end()) + return -1; + else + return pos->second; + } + + void setUniformLocationBase(int base) { uniformLocationBase = base; } + int getUniformLocationBase() const { return uniformLocationBase; } + void setNeedsLegalization() { needToLegalize = true; } bool needsLegalization() const { return needToLegalize; } + void setBinaryDoubleOutput() { binaryDoubleOutput = true; } + bool getBinaryDoubleOutput() { return binaryDoubleOutput; } + const char* const implicitThisName; + const char* const implicitCounterName; protected: TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); void error(TInfoSink& infoSink, const char*); void warn(TInfoSink& infoSink, const char*); + void mergeCallGraphs(TInfoSink&, TIntermediate&); + void mergeModes(TInfoSink&, TIntermediate&); + void mergeTrees(TInfoSink&, TIntermediate&); + void seedIdMap(TMap& idMap, int& maxId); + void remapIds(const TMap& idMap, int idShift, TIntermediate&); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); void mergeImplicitArraySizes(TType&, const TType&); @@ -631,9 +783,10 @@ void checkCallGraphCycles(TInfoSink&); void checkCallGraphBodies(TInfoSink&, bool keepUncalled); void inOutLocationCheck(TInfoSink&); - TIntermSequence& findLinkerObjects() const; + TIntermAggregate* findLinkerObjects() const; bool userOutputUsed() const; bool isSpecializationOperation(const TIntermOperator&) const; + bool isNonuniformPropagating(TOperator) const; bool promoteUnary(TIntermUnary&); bool promoteBinary(TIntermBinary&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); @@ -642,15 +795,21 @@ void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&); bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&); void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root); + bool isConversionAllowed(TOperator op, TIntermTyped* node) const; + TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; + std::tuple getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const; + bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();} static const char* getResourceName(TResourceType); const EShLanguage language; // stage, known at construction time EShSource source; // source language, known a bit later std::string entryPointName; std::string entryPointMangledName; + typedef std::list TGraph; + TGraph callGraph; - EProfile profile; - int version; + EProfile profile; // source profile + int version; // source version SpvVersion spvVersion; TIntermNode* treeRoot; std::set requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them @@ -674,20 +833,26 @@ bool postDepthCoverage; TLayoutDepth depthLayout; bool depthReplacing; + bool hlslFunctionality1; int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift bool xfbMode; + std::vector xfbBuffers; // all the data we need to track per xfb buffer bool multiStream; #ifdef NV_EXTENSIONS bool layoutOverrideCoverage; bool geoPassthroughEXT; + int numShaderRecordNVBlocks; + ComputeDerivativeMode computeDerivativeMode; + int primitives; + int numTaskNVBlocks; #endif // Base shift values std::array shiftBinding; // Per-descriptor-set shift values - std::array, EResCount> shiftBindingForSet; + std::array, EResCount> shiftBindingForSet; std::vector resourceSetBinding; bool autoMapBindings; @@ -697,15 +862,13 @@ bool useUnknownFormat; bool hlslOffsets; bool useStorageBuffer; + bool useVulkanMemoryModel; bool hlslIoMapping; - - typedef std::list TGraph; - TGraph callGraph; + bool useVariablePointers; std::set ioAccessed; // set of names of statically read/written I/O that might need extra checking std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers std::vector usedAtomics; // sets of bindings used by atomic counters - std::vector xfbBuffers; // all the data we need to track per xfb buffer std::unordered_set usedConstantId; // specialization constant ids used std::set semanticNameSet; @@ -715,10 +878,18 @@ std::string sourceFile; std::string sourceText; + // Included text. First string is a name, second is the included text + std::map includeText; + // for OpModuleProcessed, or equivalent TProcesses processes; bool needToLegalize; + bool binaryDoubleOutput; + bool usePhysicalStorageBuffer; + + std::unordered_map uniformLocationOverrides; + int uniformLocationBase; private: void operator=(TIntermediate&); // prevent assignments diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -152,7 +152,17 @@ case EvqBuffer: if (node->getQualifier().readonly) message = "can't modify a readonly buffer"; +#ifdef NV_EXTENSIONS + if (node->getQualifier().layoutShaderRecordNV) + message = "can't modify a shaderrecordnv qualified buffer"; +#endif break; +#ifdef NV_EXTENSIONS + case EvqHitAttrNV: + if (language != EShLangIntersectNV) + message = "cannot modify hitAttributeNV in this stage"; + break; +#endif default: // @@ -168,6 +178,11 @@ case EbtVoid: message = "can't modify void"; break; +#ifdef NV_EXTENSIONS + case EbtAccStructNV: + message = "can't modify accelerationStructureNV"; + break; +#endif default: break; } @@ -228,6 +243,7 @@ // must still be valid. // It is okay if the symbol's type will be subsequently edited; // the modifications will be tracked. +// Order is preserved, to avoid creating novel forward references. void TParseContextBase::trackLinkage(TSymbol& symbol) { if (!parsingBuiltins) @@ -242,7 +258,7 @@ error(loc, "", "[", "index out of range '%d'", index); index = 0; } else if (type.isArray()) { - if (type.isExplicitlySizedArray() && index >= type.getOuterArraySize()) { + if (type.isSizedArray() && index >= type.getOuterArraySize()) { error(loc, "", "[", "array index out of range '%d'", index); index = type.getOuterArraySize() - 1; } @@ -602,7 +618,7 @@ if (parsingBuiltins) return; - // Transfer the linkage symbols to AST nodes + // Transfer the linkage symbols to AST nodes, preserving order. TIntermAggregate* linkage = new TIntermAggregate; for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i) intermediate.addSymbolLinkageNode(linkage, **i); diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2015 LunarG, Inc. -// Copyright (C) 2015-2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -75,6 +76,10 @@ globalBufferDefaults.layoutMatrix = ElmColumnMajor; globalBufferDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd430 : ElpShared; + // use storage buffer on SPIR-V 1.3 and up + if (spvVersion.spv >= EShTargetSpv_1_3) + intermediate.setUseStorageBuffer(); + globalInputDefaults.clear(); globalOutputDefaults.clear(); @@ -266,7 +271,20 @@ if (tokens.size() != 1) error(loc, "extra tokens", "#pragma", ""); intermediate.setUseStorageBuffer(); - } + } else if (spvVersion.spv > 0 && tokens[0].compare("use_vulkan_memory_model") == 0) { + if (tokens.size() != 1) + error(loc, "extra tokens", "#pragma", ""); + intermediate.setUseVulkanMemoryModel(); + } else if (spvVersion.spv > 0 && tokens[0].compare("use_variable_pointers") == 0) { + if (tokens.size() != 1) + error(loc, "extra tokens", "#pragma", ""); + if (spvVersion.spv < glslang::EShTargetSpv_1_3) + error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", ""); + intermediate.setUseVariablePointers(); + } else if (tokens[0].compare("once") == 0) { + warn(loc, "not implemented", "#pragma once", ""); + } else if (tokens[0].compare("glslang_binary_double_output") == 0) + intermediate.setBinaryDoubleOutput(); } // @@ -281,17 +299,17 @@ requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str()); if (symbol && symbol->isReadOnly()) { - // All shared things containing an implicitly sized array must be copied up + // All shared things containing an unsized array must be copied up // on first use, so that all future references will share its array structure, // so that editing the implicit size will effect all nodes consuming it, // and so that editing the implicit size won't change the shared one. // // If this is a variable or a block, check it and all it contains, but if this // is a member of an anonymous block, check the whole block, as the whole block - // will need to be copied up if it contains an implicitly-sized array. - if (symbol->getType().containsImplicitlySizedArray() || + // will need to be copied up if it contains an unsized array. + if (symbol->getType().containsUnsizedArray() || (symbol->getAsAnonMember() && - symbol->getAsAnonMember()->getAnonContainer().getType().containsImplicitlySizedArray())) + symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) makeEditable(symbol); } @@ -300,9 +318,6 @@ if (anon) { // It was a member of an anonymous container. - // The "getNumExtensions()" mechanism above doesn't yet work for block members - blockMemberExtensionCheck(loc, nullptr, *string); - // Create a subtree for its dereference. variable = anon->getAnonContainer().getAsVariable(); TIntermTyped* container = intermediate.addSymbol(*variable, loc); @@ -342,6 +357,11 @@ if (variable->getType().getQualifier().isIo()) intermediate.addIoAccessed(*string); + if (variable->getType().getBasicType() == EbtReference && + variable->getType().getQualifier().bufferReferenceNeedsVulkanMemoryModel()) { + intermediate.setUseVulkanMemoryModel(); + } + return node; } @@ -350,83 +370,126 @@ // TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index) { - TIntermTyped* result = nullptr; - int indexValue = 0; if (index->getQualifier().isFrontEndConstant()) indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst(); + // basic type checks... variableCheck(base); - if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) { + + if (! base->isArray() && ! base->isMatrix() && ! base->isVector() && ! base->getType().isCoopMat() && + base->getBasicType() != EbtReference) { if (base->getAsSymbolNode()) error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), ""); else error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", ""); - } else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) { + + // Insert dummy error-recovery result + return intermediate.addConstantUnion(0.0, EbtFloat, loc); + } + + if (!base->isArray() && base->isVector()) { + if (base->getType().containsBasicType(EbtFloat16)) + requireFloat16Arithmetic(loc, "[", "does not operate on types containing float16"); + if (base->getType().contains16BitInt()) + requireInt16Arithmetic(loc, "[", "does not operate on types containing (u)int16"); + if (base->getType().contains8BitInt()) + requireInt8Arithmetic(loc, "[", "does not operate on types containing (u)int8"); + } + + // check for constant folding + if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) { // both base and index are front-end constants checkIndex(loc, base->getType(), indexValue); return intermediate.foldDereference(base, indexValue, loc); - } else { - // at least one of base and index is not a front-end constant variable... - - if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) - handleIoResizeArrayAccess(loc, base); + } - if (index->getQualifier().isFrontEndConstant()) { - if (base->getType().isImplicitlySizedArray()) - updateImplicitArraySize(loc, base, indexValue); - else - checkIndex(loc, base->getType(), indexValue); - result = intermediate.addIndex(EOpIndexDirect, base, index, loc); - } else { - if (base->getType().isImplicitlySizedArray()) { - if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) - error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable"); - else - error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); - } - if (base->getBasicType() == EbtBlock) { - if (base->getQualifier().storage == EvqBuffer) - requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array"); - else if (base->getQualifier().storage == EvqUniform) - profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, - "variable indexing uniform block array"); - else { - // input/output blocks either don't exist or can be variable indexed - } - } else if (language == EShLangFragment && base->getQualifier().isPipeOutput()) - requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array"); - else if (base->getBasicType() == EbtSampler && version >= 130) { - const char* explanation = "variable indexing sampler array"; - requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation); - profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation); - profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation); - } + // at least one of base and index is not a front-end constant variable... + TIntermTyped* result = nullptr; - result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); - } + if (base->getBasicType() == EbtReference && ! base->isArray()) { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing"); + result = intermediate.addBinaryMath(EOpAdd, base, index, loc); + result->setType(base->getType()); + return result; } - if (result == nullptr) { - // Insert dummy error-recovery result - result = intermediate.addConstantUnion(0.0, EbtFloat, loc); + if (index->getQualifier().isFrontEndConstant()) + checkIndex(loc, base->getType(), indexValue); + + if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) + handleIoResizeArrayAccess(loc, base); + + if (index->getQualifier().isFrontEndConstant()) { + if (base->getType().isUnsizedArray()) { + base->getWritableType().updateImplicitArraySize(indexValue + 1); +#ifdef NV_EXTENSIONS + // For 2D per-view builtin arrays, update the inner dimension size in parent type + if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) { + TIntermBinary* binaryNode = base->getAsBinaryNode(); + if (binaryNode) { + TType& leftType = binaryNode->getLeft()->getWritableType(); + TArraySizes& arraySizes = *leftType.getArraySizes(); + assert(arraySizes.getNumDims() == 2); + arraySizes.setDimSize(1, std::max(arraySizes.getDimSize(1), indexValue + 1)); + } + } +#endif + } else + checkIndex(loc, base->getType(), indexValue); + result = intermediate.addIndex(EOpIndexDirect, base, index, loc); } else { - // Insert valid dereferenced result - TType newType(base->getType(), 0); // dereferenced type - if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) { - newType.getQualifier().storage = EvqConst; - // If base or index is a specialization constant, the result should also be a specialization constant. - if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) { - newType.getQualifier().makeSpecConstant(); + if (base->getType().isUnsizedArray()) { + // we have a variable index into an unsized array, which is okay, + // depending on the situation + if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) + error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable"); + else { + // it is okay for a run-time sized array + checkRuntimeSizable(loc, *base); } - } else { - newType.getQualifier().makePartialTemporary(); + base->getWritableType().setArrayVariablyIndexed(); } - result->setType(newType); - - if (anyIndexLimits) - handleIndexLimits(loc, base, index); + if (base->getBasicType() == EbtBlock) { + if (base->getQualifier().storage == EvqBuffer) + requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array"); + else if (base->getQualifier().storage == EvqUniform) + profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, + "variable indexing uniform block array"); + else { + // input/output blocks either don't exist or can be variable indexed + } + } else if (language == EShLangFragment && base->getQualifier().isPipeOutput()) + requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array"); + else if (base->getBasicType() == EbtSampler && version >= 130) { + const char* explanation = "variable indexing sampler array"; + requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation); + profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation); + profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation); + } + + result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); + } + + // Insert valid dereferenced result + TType newType(base->getType(), 0); // dereferenced type + if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) { + newType.getQualifier().storage = EvqConst; + // If base or index is a specialization constant, the result should also be a specialization constant. + if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) { + newType.getQualifier().makeSpecConstant(); + } + } else { + newType.getQualifier().makePartialTemporary(); } + result->setType(newType); + + // Propagate nonuniform + if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform()) + result->getWritableType().getQualifier().nonUniform = true; + + if (anyIndexLimits) + handleIndexLimits(loc, base, index); return result; } @@ -461,12 +524,20 @@ ioArraySymbolResizeList.push_back(symbol); } -// Return true if this is a geometry shader input array or tessellation control output array. +// Return true if this is a geometry shader input array or tessellation control output array +// or mesh shader output array. bool TParseContext::isIoResizeArray(const TType& type) const { return type.isArray() && ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || - (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch)); + (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch) +#ifdef NV_EXTENSIONS + || + (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && type.getQualifier().pervertexNV) || + (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && !type.getQualifier().perTaskNV) + +#endif + ); } // If an array is not isIoResizeArray() but is an io array, make sure it has the right size @@ -482,7 +553,7 @@ if (language == EShLangTessControl || language == EShLangTessEvaluation) { if (type.getOuterArraySize() != resources.maxPatchVertices) { - if (type.isExplicitlySizedArray()) + if (type.isSizedArray()) error(loc, "tessellation input array size must be gl_MaxPatchVertices or implicitly sized", "[]", ""); type.changeOuterArraySize(resources.maxPatchVertices); } @@ -515,8 +586,8 @@ return; // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing) - if (symbolNode->getType().isImplicitlySizedArray()) { - int newSize = getIoArrayImplicitSize(); + if (symbolNode->getType().isUnsizedArray()) { + int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier()); if (newSize > 0) symbolNode->getWritableType().changeOuterArraySize(newSize); } @@ -530,48 +601,99 @@ // Types without an array size will be given one. // Types already having a size that is wrong will get an error. // -void TParseContext::checkIoArraysConsistency(const TSourceLoc& loc, bool tailOnly) +void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, bool tailOnly) { - int requiredSize = getIoArrayImplicitSize(); - if (requiredSize == 0) - return; - - const char* feature; - if (language == EShLangGeometry) - feature = TQualifier::getGeometryString(intermediate.getInputPrimitive()); - else if (language == EShLangTessControl) - feature = "vertices"; - else - feature = "unknown"; + int requiredSize = 0; + TString featureString; + size_t listSize = ioArraySymbolResizeList.size(); + size_t i = 0; + // If tailOnly = true, only check the last array symbol in the list. if (tailOnly) { - checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList.back()->getWritableType(), ioArraySymbolResizeList.back()->getName()); - return; + i = listSize - 1; } + for (bool firstIteration = true; i < listSize; ++i) { + TType &type = ioArraySymbolResizeList[i]->getWritableType(); + + // As I/O array sizes don't change, fetch requiredSize only once, + // except for mesh shaders which could have different I/O array sizes based on type qualifiers. + if (firstIteration +#ifdef NV_EXTENSIONS + || (language == EShLangMeshNV) +#endif + ) + { + requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString); + if (requiredSize == 0) + break; + firstIteration = false; + } - for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i) - checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName()); + checkIoArrayConsistency(loc, requiredSize, featureString.c_str(), type, + ioArraySymbolResizeList[i]->getName()); + } } -int TParseContext::getIoArrayImplicitSize() const +int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString *featureString) const { - if (language == EShLangGeometry) - return TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); - else if (language == EShLangTessControl) - return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; - else - return 0; + int expectedSize = 0; + TString str = "unknown"; + unsigned int maxVertices = intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0; + + if (language == EShLangGeometry) { + expectedSize = TQualifier::mapGeometryToSize(intermediate.getInputPrimitive()); + str = TQualifier::getGeometryString(intermediate.getInputPrimitive()); + } + else if (language == EShLangTessControl) { + expectedSize = maxVertices; + str = "vertices"; + } +#ifdef NV_EXTENSIONS + else if (language == EShLangFragment) { + // Number of vertices for Fragment shader is always three. + expectedSize = 3; + str = "vertices"; + } + else if (language == EShLangMeshNV) { + unsigned int maxPrimitives = + intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0; + if (qualifier.builtIn == EbvPrimitiveIndicesNV) { + expectedSize = maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive()); + str = "max_primitives*"; + str += TQualifier::getGeometryString(intermediate.getOutputPrimitive()); + } + else if (qualifier.isPerPrimitive()) { + expectedSize = maxPrimitives; + str = "max_primitives"; + } + else { + expectedSize = maxVertices; + str = "max_vertices"; + } + } +#endif + if (featureString) + *featureString = str; + return expectedSize; } void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name) { - if (type.isImplicitlySizedArray()) + if (type.isUnsizedArray()) type.changeOuterArraySize(requiredSize); else if (type.getOuterArraySize() != requiredSize) { if (language == EShLangGeometry) error(loc, "inconsistent input primitive for array size of", feature, name.c_str()); else if (language == EShLangTessControl) error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str()); +#ifdef NV_EXTENSIONS + else if (language == EShLangFragment) { + if (type.getOuterArraySize() > requiredSize) + error(loc, " cannot be greater than 3 for pervertexNV", feature, name.c_str()); + } + else if (language == EShLangMeshNV) + error(loc, "inconsistent output array size of", feature, name.c_str()); +#endif else assert(0); } @@ -599,6 +721,12 @@ break; } + if (((left->getType().containsBasicType(EbtFloat16) || right->getType().containsBasicType(EbtFloat16)) && !float16Arithmetic()) || + ((left->getType().contains16BitInt() || right->getType().contains16BitInt()) && !int16Arithmetic()) || + ((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic())) { + allowed = false; + } + TIntermTyped* result = nullptr; if (allowed) result = intermediate.addBinaryMath(op, left, right, loc); @@ -614,7 +742,17 @@ { rValueErrorCheck(loc, str, childNode); - TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc); + bool allowed = true; + if ((childNode->getType().containsBasicType(EbtFloat16) && !float16Arithmetic()) || + (childNode->getType().contains16BitInt() && !int16Arithmetic()) || + (childNode->getType().contains8BitInt() && !int8Arithmetic())) { + allowed = false; + } + + TIntermTyped* result = nullptr; + + if (allowed) + result = intermediate.addUnaryMath(op, childNode, loc); if (result) return result; @@ -644,7 +782,7 @@ const char* feature = ".length() on vectors and matrices"; requireProfile(loc, ~EEsProfile, feature); profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature); - } else { + } else if (!base->getType().isCoopMat()) { error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str()); return base; @@ -661,6 +799,11 @@ return base; } + if (base->getType().isCoopMat()) { + error(loc, "cannot apply to a cooperative matrix type:", ".", field.c_str()); + return base; + } + // It's neither an array nor .length() if we get here, // leaving swizzles and struct/block dereferences. @@ -676,6 +819,13 @@ TSwizzleSelectors selectors; parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); + if (base->isVector() && selectors.size() != 1 && base->getType().containsBasicType(EbtFloat16)) + requireFloat16Arithmetic(loc, ".", "can't swizzle types containing float16"); + if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt()) + requireInt16Arithmetic(loc, ".", "can't swizzle types containing (u)int16"); + if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt()) + requireInt8Arithmetic(loc, ".", "can't swizzle types containing (u)int8"); + if (base->isScalar()) { if (selectors.size() == 1) return result; @@ -704,8 +854,12 @@ if (base->getType().getQualifier().isSpecConstant()) result->getWritableType().getQualifier().makeSpecConstant(); } - } else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) { - const TTypeList* fields = base->getType().getStruct(); + } else if (base->getBasicType() == EbtStruct || + base->getBasicType() == EbtBlock || + base->getBasicType() == EbtReference) { + const TTypeList* fields = base->getBasicType() == EbtReference ? + base->getType().getReferentType()->getStruct() : + base->getType().getStruct(); bool fieldFound = false; int member; for (member = 0; member < (int)fields->size(); ++member) { @@ -718,10 +872,12 @@ if (base->getType().getQualifier().isFrontEndConstant()) result = intermediate.foldDereference(base, member, loc); else { - blockMemberExtensionCheck(loc, base, field); + blockMemberExtensionCheck(loc, base, member, field); TIntermTyped* index = intermediate.addConstantUnion(member, loc); result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc); result->setType(*(*fields)[member].type); + if ((*fields)[member].type->getQualifier().isIo()) + intermediate.addIoAccessed(field); } } else error(loc, "no such field in structure", field.c_str(), ""); @@ -732,17 +888,37 @@ if (base->getQualifier().noContraction) result->getWritableType().getQualifier().noContraction = true; + // Propagate nonuniform + if (base->getQualifier().isNonUniform()) + result->getWritableType().getQualifier().nonUniform = true; + return result; } -void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* /*base*/, const TString& field) +void TParseContext::blockMemberExtensionCheck(const TSourceLoc& loc, const TIntermTyped* base, int member, const TString& memberName) { - if (profile == EEsProfile && field == "gl_PointSize") { - if (language == EShLangGeometry) - requireExtensions(loc, Num_AEP_geometry_point_size, AEP_geometry_point_size, "gl_PointSize"); - else if (language == EShLangTessControl || language == EShLangTessEvaluation) - requireExtensions(loc, Num_AEP_tessellation_point_size, AEP_tessellation_point_size, "gl_PointSize"); - } + // a block that needs extension checking is either 'base', or if arrayed, + // one level removed to the left + const TIntermSymbol* baseSymbol = nullptr; + if (base->getAsBinaryNode() == nullptr) + baseSymbol = base->getAsSymbolNode(); + else + baseSymbol = base->getAsBinaryNode()->getLeft()->getAsSymbolNode(); + if (baseSymbol == nullptr) + return; + const TSymbol* symbol = symbolTable.find(baseSymbol->getName()); + if (symbol == nullptr) + return; + const TVariable* variable = symbol->getAsVariable(); + if (variable == nullptr) + return; + if (!variable->hasMemberExtensions()) + return; + + // We now have a variable that is the base of a dot reference + // with members that need extension checking. + if (variable->getNumMemberExtensions(member) > 0) + requireExtensions(loc, variable->getNumMemberExtensions(member), variable->getMemberExtensions(member), memberName.c_str()); } // @@ -776,7 +952,7 @@ if (prevDec->isPrototyped() && prototype) profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function"); if (prevDec->getType() != function.getType()) - error(loc, "overloaded functions must have the same return type", function.getType().getBasicTypeString().c_str(), ""); + error(loc, "overloaded functions must have the same return type", function.getName().c_str(), ""); for (int i = 0; i < prevDec->getParamCount(); ++i) { if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage) error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1); @@ -950,7 +1126,14 @@ if (builtIn && fnCandidate->getNumExtensions()) requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str()); - if (arguments) { + if (builtIn && fnCandidate->getType().containsBasicType(EbtFloat16)) + requireFloat16Arithmetic(loc, "built-in function", "float16 types can only be in uniform block or buffer storage"); + if (builtIn && fnCandidate->getType().contains16BitInt()) + requireInt16Arithmetic(loc, "built-in function", "(u)int16 types can only be in uniform block or buffer storage"); + if (builtIn && fnCandidate->getType().contains8BitInt()) + requireInt8Arithmetic(loc, "built-in function", "(u)int8 types can only be in uniform block or buffer storage"); + + if (arguments != nullptr) { // Make sure qualifications work for these arguments. TIntermAggregate* aggregate = arguments->getAsAggregate(); for (int i = 0; i < fnCandidate->getParamCount(); ++i) { @@ -968,13 +1151,38 @@ const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; if (argQualifier.volatil && ! formalQualifier.volatil) error(arguments->getLoc(), message, "volatile", ""); - if (argQualifier.coherent && ! formalQualifier.coherent) + if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent)) error(arguments->getLoc(), message, "coherent", ""); + if (argQualifier.devicecoherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent)) + error(arguments->getLoc(), message, "devicecoherent", ""); + if (argQualifier.queuefamilycoherent && ! (formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent)) + error(arguments->getLoc(), message, "queuefamilycoherent", ""); + if (argQualifier.workgroupcoherent && ! (formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent)) + error(arguments->getLoc(), message, "workgroupcoherent", ""); + if (argQualifier.subgroupcoherent && ! (formalQualifier.subgroupcoherent || formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent)) + error(arguments->getLoc(), message, "subgroupcoherent", ""); if (argQualifier.readonly && ! formalQualifier.readonly) error(arguments->getLoc(), message, "readonly", ""); if (argQualifier.writeonly && ! formalQualifier.writeonly) error(arguments->getLoc(), message, "writeonly", ""); + if (!builtIn && argQualifier.restrict && ! formalQualifier.restrict) + error(arguments->getLoc(), message, "restrict", ""); } + if (!builtIn && argQualifier.layoutFormat != formalQualifier.layoutFormat) { + // we have mismatched formats, which should only be allowed if writeonly + // and at least one format is unknown + if (!formalQualifier.writeonly || (formalQualifier.layoutFormat != ElfNone && + argQualifier.layoutFormat != ElfNone)) + error(arguments->getLoc(), "image formats must match", "format", ""); + } + + if (builtIn && arg->getAsTyped()->getType().containsBasicType(EbtFloat16)) + requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage"); + if (builtIn && arg->getAsTyped()->getType().contains16BitInt()) + requireInt16Arithmetic(arguments->getLoc(), "built-in function", "(u)int16 types can only be in uniform block or buffer storage"); + if (builtIn && arg->getAsTyped()->getType().contains8BitInt()) + requireInt8Arithmetic(arguments->getLoc(), "built-in function", "(u)int8 types can only be in uniform block or buffer storage"); + // TODO 4.5 functionality: A shader will fail to compile // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the @@ -988,7 +1196,7 @@ if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) { // A function call mapped to a built-in operation. - result = handleBuiltInFunctionCall(loc, *arguments, *fnCandidate); + result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate); } else { // This is a function call not mapped to built-in operator. // It could still be a built-in function, but only if PureOperatorBuiltins == false. @@ -1025,6 +1233,13 @@ } result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate()); } + + if (result->getAsTyped()->getType().isCoopMat() && + !result->getAsTyped()->getType().isParameterized()) { + assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd); + + result->setType(result->getAsAggregate()->getSequence()[2]->getAsTyped()->getType()); + } } } @@ -1036,20 +1251,24 @@ return result; } -TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode& arguments, +TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode* arguments, const TFunction& function) { checkLocation(loc, function.getBuiltInOp()); TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(), function.getParamCount() == 1, - &arguments, function.getType()); + arguments, function.getType()); if (obeyPrecisionQualifiers()) computeBuiltinPrecisions(*result, function); - if (result == nullptr) { - error(arguments.getLoc(), " wrong operand type", "Internal Error", - "built in unary operator function. Type: %s", - static_cast(&arguments)->getCompleteString().c_str()); + if (result == nullptr) { + if (arguments == nullptr) + error(loc, " wrong operand type", "Internal Error", + "built in unary operator function. Type: %s", ""); + else + error(arguments->getLoc(), " wrong operand type", "Internal Error", + "built in unary operator function. Type: %s", + static_cast(arguments)->getCompleteString().c_str()); } else if (result->getAsOperator()) builtInOpCheck(loc, function, *result->getAsOperator()); @@ -1155,6 +1374,8 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value) { + storage16BitAssignmentCheck(loc, value->getType(), "return"); + functionReturnsValue = true; if (currentFunctionType->getBasicType() == EbtVoid) { error(loc, "void function cannot return a value", "return", ""); @@ -1208,23 +1429,30 @@ else { const TType& type = intermNode->getAsTyped()->getType(); if (type.isArray()) { - if (type.isRuntimeSizedArray()) { - // Create a unary op and let the back end handle it - return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); - } else if (type.isImplicitlySizedArray()) { + if (type.isUnsizedArray()) { if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) { // We could be between a layout declaration that gives a built-in io array implicit size and // a user redeclaration of that array, meaning we have to substitute its implicit size here // without actually redeclaring the array. (It is an error to use a member before the // redeclaration, but not an error to use the array name itself.) const TString& name = intermNode->getAsSymbolNode()->getName(); - if (name == "gl_in" || name == "gl_out") - length = getIoArrayImplicitSize(); + if (name == "gl_in" || name == "gl_out" +#ifdef NV_EXTENSIONS + || name == "gl_MeshVerticesNV" + || name == "gl_MeshPrimitivesNV" +#endif + ) + { + length = getIoArrayImplicitSize(type.getQualifier()); + } } if (length == 0) { if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier"); - else + else if (isRuntimeLength(*intermNode->getAsTyped())) { + // Create a unary op and let the back end handle it + return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); + } else error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); } } else if (type.getOuterArrayNode()) { @@ -1238,6 +1466,8 @@ length = type.getMatrixCols(); else if (type.isVector()) length = type.getVectorSize(); + else if (type.isCoopMat()) + return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); else { // we should not get here, because earlier semantic checking should have prevented this path error(loc, ".length()", "unexpected use of .length()", ""); @@ -1264,7 +1494,8 @@ // means take 'arguments' itself as the one argument. TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped()); if (*function[i].type != arg->getType()) { - if (function[i].type->getQualifier().isParamInput()) { + if (function[i].type->getQualifier().isParamInput() && + !function[i].type->isCoopMat()) { // In-qualified arguments just need an extra node added above the argument to // convert to the correct type. arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg); @@ -1332,7 +1563,14 @@ if (function[i].type->getQualifier().isParamOutput()) { // Out-qualified arguments need to use the topology set up above. // do the " ...(tempArg, ...), arg = tempArg" bit from above - TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type); + TType paramType; + paramType.shallowCopy(*function[i].type); + if (arguments[i]->getAsTyped()->getType().isParameterized() && + !paramType.isParameterized()) { + paramType.shallowCopy(arguments[i]->getAsTyped()->getType()); + paramType.copyTypeParameters(*arguments[i]->getAsTyped()->getType().getTypeParameters()); + } + TVariable* tempArg = makeInternalVariable("tempArg", paramType); tempArg->getWritableType().getQualifier().makeTemporary(); TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc()); TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc()); @@ -1354,6 +1592,161 @@ return conversionTree; } +void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode) +{ + const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence(); + + //const int gl_SemanticsRelaxed = 0x0; + const int gl_SemanticsAcquire = 0x2; + const int gl_SemanticsRelease = 0x4; + const int gl_SemanticsAcquireRelease = 0x8; + const int gl_SemanticsMakeAvailable = 0x2000; + const int gl_SemanticsMakeVisible = 0x4000; + + //const int gl_StorageSemanticsNone = 0x0; + const int gl_StorageSemanticsBuffer = 0x40; + const int gl_StorageSemanticsShared = 0x100; + const int gl_StorageSemanticsImage = 0x800; + const int gl_StorageSemanticsOutput = 0x1000; + + + unsigned int semantics = 0, storageClassSemantics = 0; + unsigned int semantics2 = 0, storageClassSemantics2 = 0; + + // Grab the semantics and storage class semantics from the operands, based on opcode + switch (callNode.getOp()) { + case EOpAtomicAdd: + case EOpAtomicMin: + case EOpAtomicMax: + case EOpAtomicAnd: + case EOpAtomicOr: + case EOpAtomicXor: + case EOpAtomicExchange: + case EOpAtomicStore: + storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + case EOpAtomicLoad: + storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + case EOpAtomicCompSwap: + storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics2 = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + + case EOpImageAtomicAdd: + case EOpImageAtomicMin: + case EOpImageAtomicMax: + case EOpImageAtomicAnd: + case EOpImageAtomicOr: + case EOpImageAtomicXor: + case EOpImageAtomicExchange: + case EOpImageAtomicStore: + storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + case EOpImageAtomicLoad: + storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + case EOpImageAtomicCompSwap: + storageClassSemantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst(); + storageClassSemantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics2 = (*argp)[8]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + + case EOpBarrier: + storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + case EOpMemoryBarrier: + storageClassSemantics = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst(); + semantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst(); + break; + default: + break; + } + + if ((semantics & gl_SemanticsAcquire) && + (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) { + error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store", + fnCandidate.getName().c_str(), ""); + } + if ((semantics & gl_SemanticsRelease) && + (callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) { + error(loc, "gl_SemanticsRelease must not be used with (image) atomic load", + fnCandidate.getName().c_str(), ""); + } + if ((semantics & gl_SemanticsAcquireRelease) && + (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore || + callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) { + error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store", + fnCandidate.getName().c_str(), ""); + } + if (((semantics | semantics2) & ~(gl_SemanticsAcquire | + gl_SemanticsRelease | + gl_SemanticsAcquireRelease | + gl_SemanticsMakeAvailable | + gl_SemanticsMakeVisible))) { + error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), ""); + } + if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer | + gl_StorageSemanticsShared | + gl_StorageSemanticsImage | + gl_StorageSemanticsOutput))) { + error(loc, "Invalid storage class semantics value", fnCandidate.getName().c_str(), ""); + } + + if (callNode.getOp() == EOpMemoryBarrier) { + if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) { + error(loc, "Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or " + "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), ""); + } + } else { + if (semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) { + if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) { + error(loc, "Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or " + "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), ""); + } + } + if (semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) { + if (!IsPow2(semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) { + error(loc, "semUnequal must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or " + "gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), ""); + } + } + } + if (callNode.getOp() == EOpMemoryBarrier) { + if (storageClassSemantics == 0) { + error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), ""); + } + } + if (callNode.getOp() == EOpBarrier && semantics != 0 && storageClassSemantics == 0) { + error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), ""); + } + if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) && + (semantics2 & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) { + error(loc, "semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease", + fnCandidate.getName().c_str(), ""); + } + if ((semantics & gl_SemanticsMakeAvailable) && + !(semantics & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) { + error(loc, "gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease", + fnCandidate.getName().c_str(), ""); + } + if ((semantics & gl_SemanticsMakeVisible) && + !(semantics & (gl_SemanticsAcquire | gl_SemanticsAcquireRelease))) { + error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease", + fnCandidate.getName().c_str(), ""); + } + +} + + // // Do additional checking of built-in function calls that is not caught // by normal semantic checks on argument type, extension tagging, etc. @@ -1388,7 +1781,8 @@ // Figure out which variants are allowed by what extensions, // and what arguments must be constant for which situations. - featureString = fnCandidate.getName() + "(...)"; + featureString = fnCandidate.getName(); + featureString += "(...)"; feature = featureString.c_str(); profileRequires(loc, EEsProfile, 310, nullptr, feature); int compArg = -1; // track which argument, if any, is the constant component argument @@ -1445,7 +1839,8 @@ bias = fnCandidate.getParamCount() > 4; if (bias) { - featureString = fnCandidate.getName() + "with bias argument"; + featureString = fnCandidate.getName(); + featureString += "with bias argument"; feature = featureString.c_str(); profileRequires(loc, ~EEsProfile, 450, nullptr, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); @@ -1468,7 +1863,8 @@ bias = fnCandidate.getParamCount() > 5; if (bias) { - featureString = fnCandidate.getName() + "with bias argument"; + featureString = fnCandidate.getName(); + featureString += "with bias argument"; feature = featureString.c_str(); profileRequires(loc, ~EEsProfile, 450, nullptr, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); @@ -1484,6 +1880,39 @@ requireExtensions(loc, 1, &E_GL_ARB_sparse_texture2, fnCandidate.getName().c_str()); break; } + + case EOpSwizzleInvocations: + { + if (! (*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "offset", ""); + else { + unsigned offset[4] = {}; + offset[0] = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst(); + offset[1] = (*argp)[1]->getAsConstantUnion()->getConstArray()[1].getUConst(); + offset[2] = (*argp)[1]->getAsConstantUnion()->getConstArray()[2].getUConst(); + offset[3] = (*argp)[1]->getAsConstantUnion()->getConstArray()[3].getUConst(); + if (offset[0] > 3 || offset[1] > 3 || offset[2] > 3 || offset[3] > 3) + error(loc, "components must be in the range [0, 3]", "offset", ""); + } + + break; + } + + case EOpSwizzleInvocationsMasked: + { + if (! (*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "mask", ""); + else { + unsigned mask[3] = {}; + mask[0] = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst(); + mask[1] = (*argp)[1]->getAsConstantUnion()->getConstArray()[1].getUConst(); + mask[2] = (*argp)[1]->getAsConstantUnion()->getConstArray()[2].getUConst(); + if (mask[0] > 31 || mask[1] > 31 || mask[2] > 31) + error(loc, "components must be in the range [0, 31]", "mask", ""); + } + + break; + } #endif case EOpTextureOffset: @@ -1511,6 +1940,12 @@ } if (arg > 0) { + +#ifdef AMD_EXTENSIONS + bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow; + if (f16ShadowCompare) + ++arg; +#endif if (! (*argp)[arg]->getAsConstantUnion()) error(loc, "argument must be compile-time constant", "texel offset", ""); else { @@ -1526,6 +1961,17 @@ break; } +#ifdef NV_EXTENSIONS + case EOpTraceNV: + if (!(*argp)[10]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "payload number", ""); + break; + case EOpExecuteCallableNV: + if (!(*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "callable data number", ""); + break; +#endif + case EOpTextureQuerySamples: case EOpImageQuerySamples: // GL_ARB_shader_texture_image_samples @@ -1540,6 +1986,8 @@ case EOpImageAtomicXor: case EOpImageAtomicExchange: case EOpImageAtomicCompSwap: + case EOpImageAtomicLoad: + case EOpImageAtomicStore: { // Make sure the image types have the correct layout() format and correct argument types const TType& imageType = arg0->getType(); @@ -1553,10 +2001,15 @@ error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); } + const size_t maxArgs = imageType.getSampler().isMultiSample() ? 5 : 4; + if (argp->size() > maxArgs) { + requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str()); + memorySemanticsCheck(loc, fnCandidate, callNode); + } + break; } -#ifdef NV_EXTENSIONS case EOpAtomicAdd: case EOpAtomicMin: case EOpAtomicMax: @@ -1565,17 +2018,30 @@ case EOpAtomicXor: case EOpAtomicExchange: case EOpAtomicCompSwap: + case EOpAtomicLoad: + case EOpAtomicStore: { - if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) - requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str()); - + if (argp->size() > 3) { + requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str()); + memorySemanticsCheck(loc, fnCandidate, callNode); + } else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) { +#ifdef NV_EXTENSIONS + const char* const extensions[2] = { E_GL_NV_shader_atomic_int64, + E_GL_EXT_shader_atomic_int64 }; + requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str()); +#else + requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_int64, fnCandidate.getName().c_str()); +#endif + } break; } -#endif case EOpInterpolateAtCentroid: case EOpInterpolateAtSample: case EOpInterpolateAtOffset: +#ifdef AMD_EXTENSIONS + case EOpInterpolateAtVertex: +#endif // Make sure the first argument is an interpolant, or an array element of an interpolant if (arg0->getType().getQualifier().storage != EvqVaryingIn) { // It might still be an array element. @@ -1590,6 +2056,23 @@ if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn) error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), ""); } + +#ifdef AMD_EXTENSIONS + if (callNode.getOp() == EOpInterpolateAtVertex) { + if (!arg0->getType().getQualifier().isExplicitInterpolation()) + error(loc, "argument must be qualified as __explicitInterpAMD in", "interpolant", ""); + else { + if (! (*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "vertex index", ""); + else { + unsigned vertexIdx = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (vertexIdx > 2) + error(loc, "must be in the range [0, 2]", "vertex index", ""); + } + } + } +#endif + break; case EOpEmitStreamVertex: @@ -1597,9 +2080,76 @@ intermediate.setMultiStream(); break; + case EOpSubgroupClusteredAdd: + case EOpSubgroupClusteredMul: + case EOpSubgroupClusteredMin: + case EOpSubgroupClusteredMax: + case EOpSubgroupClusteredAnd: + case EOpSubgroupClusteredOr: + case EOpSubgroupClusteredXor: + // The as used in the subgroupClustered() operations must be: + // - An integral constant expression. + // - At least 1. + // - A power of 2. + if ((*argp)[1]->getAsConstantUnion() == nullptr) + error(loc, "argument must be compile-time constant", "cluster size", ""); + else { + int size = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst(); + if (size < 1) + error(loc, "argument must be at least 1", "cluster size", ""); + else if (!IsPow2(size)) + error(loc, "argument must be a power of 2", "cluster size", ""); + } + break; + + case EOpSubgroupBroadcast: + // must be an integral constant expression. + if ((*argp)[1]->getAsConstantUnion() == nullptr) + error(loc, "argument must be compile-time constant", "id", ""); + break; + + case EOpBarrier: + case EOpMemoryBarrier: + if (argp->size() > 0) { + requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str()); + memorySemanticsCheck(loc, fnCandidate, callNode); + } + break; + default: break; } + + // Texture operations on texture objects (aside from texelFetch on a + // textureBuffer) require EXT_samplerless_texture_functions. + switch (callNode.getOp()) { + case EOpTextureQuerySize: + case EOpTextureQueryLevels: + case EOpTextureQuerySamples: + case EOpTextureFetch: + case EOpTextureFetchOffset: + { + const TSampler& sampler = fnCandidate[0].type->getSampler(); + + const bool isTexture = sampler.isTexture() && !sampler.isCombined(); + const bool isBuffer = sampler.dim == EsdBuffer; + const bool isFetch = callNode.getOp() == EOpTextureFetch || callNode.getOp() == EOpTextureFetchOffset; + + if (isTexture && (!isBuffer || !isFetch)) + requireExtensions(loc, 1, &E_GL_EXT_samplerless_texture_functions, fnCandidate.getName().c_str()); + + break; + } + + default: + break; + } + + if (callNode.getOp() > EOpSubgroupGuardStart && callNode.getOp() < EOpSubgroupGuardStop) { + // these require SPIR-V 1.3 + if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3) + error(loc, "requires SPIR-V 1.3", "subgroup op", ""); + } } extern bool PureOperatorBuiltins; @@ -1925,6 +2475,10 @@ } } + if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct && + binaryNode->getLeft()->getBasicType() == EbtReference) + return false; + // Let the base class check errors if (TParseContextBase::lValueErrorCheck(loc, op, node)) return true; @@ -2161,7 +2715,6 @@ case EOpConstructDMat4x2: case EOpConstructDMat4x3: case EOpConstructDMat4x4: -#ifdef AMD_EXTENSIONS case EOpConstructF16Mat2x2: case EOpConstructF16Mat2x3: case EOpConstructF16Mat2x4: @@ -2171,7 +2724,6 @@ case EOpConstructF16Mat4x2: case EOpConstructF16Mat4x3: case EOpConstructF16Mat4x4: -#endif constructingMatrix = true; break; default: @@ -2192,7 +2744,7 @@ bool floatArgument = false; for (int arg = 0; arg < function.getParamCount(); ++arg) { if (function[arg].type->isArray()) { - if (! function[arg].type->isExplicitlySizedArray()) { + if (function[arg].type->isUnsizedArray()) { // Can't construct from an unsized array. error(loc, "array argument must be sized", "constructor", ""); return true; @@ -2220,26 +2772,91 @@ specConstType = true; if (function[arg].type->isFloatingDomain()) floatArgument = true; + if (type.isStruct()) { + if (function[arg].type->containsBasicType(EbtFloat16)) { + requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + } + if (function[arg].type->containsBasicType(EbtUint16) || + function[arg].type->containsBasicType(EbtInt16)) { + requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + } + if (function[arg].type->containsBasicType(EbtUint8) || + function[arg].type->containsBasicType(EbtInt8)) { + requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type"); + } + } } - // inherit constness from children - if (constType) { - bool makeSpecConst; - // Finish pinning down spec-const semantics - if (specConstType) { - switch (op) { - case EOpConstructInt: - case EOpConstructUint: - case EOpConstructInt64: - case EOpConstructUint64: -#ifdef AMD_EXTENSIONS + switch (op) { + case EOpConstructFloat16: + case EOpConstructF16Vec2: + case EOpConstructF16Vec3: + case EOpConstructF16Vec4: + if (type.isArray()) + requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported"); + if (type.isVector() && function.getParamCount() != 1) + requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types"); + break; + case EOpConstructUint16: + case EOpConstructU16Vec2: + case EOpConstructU16Vec3: + case EOpConstructU16Vec4: + case EOpConstructInt16: + case EOpConstructI16Vec2: + case EOpConstructI16Vec3: + case EOpConstructI16Vec4: + if (type.isArray()) + requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported"); + if (type.isVector() && function.getParamCount() != 1) + requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types"); + break; + case EOpConstructUint8: + case EOpConstructU8Vec2: + case EOpConstructU8Vec3: + case EOpConstructU8Vec4: + case EOpConstructInt8: + case EOpConstructI8Vec2: + case EOpConstructI8Vec3: + case EOpConstructI8Vec4: + if (type.isArray()) + requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported"); + if (type.isVector() && function.getParamCount() != 1) + requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types"); + break; + default: + break; + } + + // inherit constness from children + if (constType) { + bool makeSpecConst; + // Finish pinning down spec-const semantics + if (specConstType) { + switch (op) { + case EOpConstructInt8: + case EOpConstructUint8: case EOpConstructInt16: case EOpConstructUint16: -#endif + case EOpConstructInt: + case EOpConstructUint: + case EOpConstructInt64: + case EOpConstructUint64: case EOpConstructBool: case EOpConstructBVec2: case EOpConstructBVec3: case EOpConstructBVec4: + case EOpConstructI8Vec2: + case EOpConstructI8Vec3: + case EOpConstructI8Vec4: + case EOpConstructU8Vec2: + case EOpConstructU8Vec3: + case EOpConstructU8Vec4: + case EOpConstructI16Vec2: + case EOpConstructI16Vec3: + case EOpConstructI16Vec4: + case EOpConstructU16Vec2: + case EOpConstructU16Vec3: + case EOpConstructU16Vec4: case EOpConstructIVec2: case EOpConstructIVec3: case EOpConstructIVec4: @@ -2252,14 +2869,6 @@ case EOpConstructU64Vec2: case EOpConstructU64Vec3: case EOpConstructU64Vec4: -#ifdef AMD_EXTENSIONS - case EOpConstructI16Vec2: - case EOpConstructI16Vec3: - case EOpConstructI16Vec4: - case EOpConstructU16Vec2: - case EOpConstructU16Vec3: - case EOpConstructU16Vec4: -#endif // This was the list of valid ones, if they aren't converting from float // and aren't making an array. makeSpecConst = ! floatArgument && ! type.isArray(); @@ -2286,7 +2895,7 @@ return true; } - if (type.isImplicitlySizedArray()) { + if (type.isUnsizedArray()) { // auto adapt the constructor type to the number of arguments type.changeOuterArraySize(function.getParamCount()); } else if (type.getOuterArraySize() != function.getParamCount()) { @@ -2298,20 +2907,21 @@ // Types have to match, but we're still making the type. // Finish making the type, and the comparison is done later // when checking for conversion. - TArraySizes& arraySizes = type.getArraySizes(); + TArraySizes& arraySizes = *type.getArraySizes(); // At least the dimensionalities have to match. - if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes().getNumDims() + 1) { + if (! function[0].type->isArray() || + arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) { error(loc, "array constructor argument not correct type to construct array element", "constructor", ""); return true; } - if (arraySizes.isInnerImplicit()) { + if (arraySizes.isInnerUnsized()) { // "Arrays of arrays ..., and the size for any dimension is optional" // That means we need to adopt (from the first argument) the other array sizes into the type. for (int d = 1; d < arraySizes.getNumDims(); ++d) { if (arraySizes.getDimSize(d) == UnsizedArraySize) { - arraySizes.setDimSize(d, function[0].type->getArraySizes().getDimSize(d - 1)); + arraySizes.setDimSize(d, function[0].type->getArraySizes()->getDimSize(d - 1)); } } } @@ -2349,6 +2959,16 @@ return true; } + if (type.isCoopMat() && function.getParamCount() != 1) { + error(loc, "wrong number of arguments", "constructor", ""); + return true; + } + if (type.isCoopMat() && + !(function[0].type->isScalar() || function[0].type->isCoopMat())) { + error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", ""); + return true; + } + TIntermTyped* typed = node->getAsTyped(); if (typed == nullptr) { error(loc, "constructor argument does not have a type", "constructor", ""); @@ -2414,18 +3034,12 @@ // second argument // * the constructor's second argument must be a scalar of type // *sampler* or *samplerShadow* - // * the presence or absence of depth comparison (Shadow) must match - // between the constructed sampler type and the type of the second argument if ( function[1].type->getBasicType() != EbtSampler || ! function[1].type->getSampler().isPureSampler() || function[1].type->isArray()) { error(loc, "sampler-constructor second argument must be a scalar type 'sampler'", token, ""); return true; } - if (function.getType().getSampler().shadow != function[1].type->getSampler().shadow) { - error(loc, "sampler-constructor second argument presence of shadow must match constructor presence of shadow", token, ""); - return true; - } return false; } @@ -2469,6 +3083,9 @@ requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES"); } } + if (type.getSampler().yuv) { + requireExtensions(loc, 1, &E_GL_EXT_YUV_target, "__samplerExternal2DY2YEXT"); + } if (type.getQualifier().storage == EvqUniform) return; @@ -2493,6 +3110,20 @@ else if (type.getBasicType() == EbtAtomicUint && type.getQualifier().storage != EvqUniform) error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); } +#ifdef NV_EXTENSIONS +void TParseContext::accStructNVCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) +{ + if (type.getQualifier().storage == EvqUniform) + return; + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStructNV)) + error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str()); + else if (type.getBasicType() == EbtAccStructNV && type.getQualifier().storage != EvqUniform) + error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:", + type.getBasicTypeString().c_str(), identifier.c_str()); + +} +#endif void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { @@ -2513,16 +3144,32 @@ } // +// Qualifier checks knowing the qualifier and that it is a member of a struct/block. +// +void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType) +{ + globalQualifierFixCheck(publicType.loc, publicType.qualifier); + checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers); + if (publicType.qualifier.isNonUniform()) { + error(publicType.loc, "not allowed on block or structure members", "nonuniformEXT", ""); + publicType.qualifier.nonUniform = false; + } +} + +// // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level. // void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier) { + bool nonuniformOkay = false; + // move from parameter/unknown qualifiers to pipeline in/out qualifiers switch (qualifier.storage) { case EvqIn: profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs"); profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs"); qualifier.storage = EvqVaryingIn; + nonuniformOkay = true; break; case EvqOut: profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs"); @@ -2533,10 +3180,17 @@ qualifier.storage = EvqVaryingIn; error(loc, "cannot use 'inout' at global scope", "", ""); break; + case EvqGlobal: + case EvqTemporary: + nonuniformOkay = true; + break; default: break; } + if (!nonuniformOkay && qualifier.nonUniform) + error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", ""); + invariantCheck(loc, qualifier); } @@ -2548,10 +3202,17 @@ if (! symbolTable.atGlobalLevel()) return; - if (qualifier.isMemory() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) - error(loc, "memory qualifiers cannot be used on this type", "", ""); + if (!(publicType.userDef && publicType.userDef->getBasicType() == EbtReference)) { + if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) { + error(loc, "memory qualifiers cannot be used on this type", "", ""); + } else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) { + error(loc, "memory qualifiers cannot be used on this type", "", ""); + } + } - if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock) + if (qualifier.storage == EvqBuffer && + publicType.basicType != EbtBlock && + !qualifier.layoutBufferReference) error(loc, "buffers can be declared only as blocks", "buffer", ""); if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) @@ -2567,26 +3228,24 @@ return; } - if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || -#ifdef AMD_EXTENSIONS - publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 || -#endif - publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 || - publicType.basicType == EbtDouble) + if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble) profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output"); + if (!qualifier.flat #ifdef AMD_EXTENSIONS - if (! qualifier.flat && ! qualifier.explicitInterp) { -#else - if (!qualifier.flat) { + && !qualifier.explicitInterp #endif - if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || -#ifdef AMD_EXTENSIONS - publicType.basicType == EbtInt16 || publicType.basicType == EbtUint16 || +#ifdef NV_EXTENSIONS + && !qualifier.pervertexNV #endif - publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 || + ) { + if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble || - (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) || + (publicType.userDef && (publicType.userDef->containsBasicType(EbtInt8) || + publicType.userDef->containsBasicType(EbtUint8) || + publicType.userDef->containsBasicType(EbtInt16) || + publicType.userDef->containsBasicType(EbtUint16) || + publicType.userDef->containsBasicType(EbtInt) || publicType.userDef->containsBasicType(EbtUint) || publicType.userDef->containsBasicType(EbtInt64) || publicType.userDef->containsBasicType(EbtUint64) || @@ -2601,6 +3260,11 @@ if (qualifier.patch && qualifier.isInterpolation()) error(loc, "cannot use interpolation qualifiers with patch", "patch", ""); +#ifdef NV_EXTENSIONS + if (qualifier.perTaskNV && publicType.basicType != EbtBlock) + error(loc, "taskNV variables can be declared only as blocks", "taskNV", ""); +#endif + if (qualifier.storage == EvqVaryingIn) { switch (language) { case EShLangVertex: @@ -2688,8 +3352,8 @@ error(loc, "can't use auxiliary qualifier on a fragment output", "centroid/sample/patch", ""); if (qualifier.isInterpolation()) error(loc, "can't use interpolation qualifier on a fragment output", "flat/smooth/noperspective", ""); - if (publicType.basicType == EbtDouble) - error(loc, "cannot contain a double", GetStorageQualifierString(qualifier.storage), ""); + if (publicType.basicType == EbtDouble || publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64) + error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), ""); break; case EShLangCompute: @@ -2767,6 +3431,13 @@ if (dst.precision == EpqNone || (force && src.precision != EpqNone)) dst.precision = src.precision; + if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || + (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || + (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) || + (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) || + (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) { + error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), ""); + } // Layout qualifiers mergeObjectLayoutQualifiers(dst, src, false); @@ -2782,14 +3453,25 @@ #ifdef AMD_EXTENSIONS MERGE_SINGLETON(explicitInterp); #endif +#ifdef NV_EXTENSIONS + MERGE_SINGLETON(perPrimitiveNV); + MERGE_SINGLETON(perViewNV); + MERGE_SINGLETON(perTaskNV); +#endif MERGE_SINGLETON(patch); MERGE_SINGLETON(sample); MERGE_SINGLETON(coherent); + MERGE_SINGLETON(devicecoherent); + MERGE_SINGLETON(queuefamilycoherent); + MERGE_SINGLETON(workgroupcoherent); + MERGE_SINGLETON(subgroupcoherent); + MERGE_SINGLETON(nonprivate); MERGE_SINGLETON(volatil); MERGE_SINGLETON(restrict); MERGE_SINGLETON(readonly); MERGE_SINGLETON(writeonly); MERGE_SINGLETON(specConstant); + MERGE_SINGLETON(nonUniform); if (repeated) error(loc, "replicated qualifiers", "", ""); @@ -2880,6 +3562,13 @@ { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque()) error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), ""); + + if (!parsingBuiltins && type.containsBasicType(EbtFloat16)) + requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage"); + if (!parsingBuiltins && type.contains16BitInt()) + requireInt16Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int16 types can only be in uniform block or buffer storage"); + if (!parsingBuiltins && type.contains8BitInt()) + requireInt8Arithmetic(loc, type.getBasicTypeString().c_str(), "(u)int8 types can only be in uniform block or buffer storage"); } bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType) @@ -2901,7 +3590,7 @@ // // Do size checking for an array type's size. // -void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair) +void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, const char *sizeType) { bool isConst = false; sizePair.node = nullptr; @@ -2921,18 +3610,24 @@ TIntermSymbol* symbol = expr->getAsSymbolNode(); if (symbol && symbol->getConstArray().size() > 0) size = symbol->getConstArray()[0].getIConst(); + } else if (expr->getAsUnaryNode() && + expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength && + expr->getAsUnaryNode()->getOperand()->getType().isCoopMat()) { + isConst = true; + size = 1; + sizePair.node = expr->getAsUnaryNode(); } } sizePair.size = size; if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) { - error(loc, "array size must be a constant integer expression", "", ""); + error(loc, sizeType, "", "must be a constant integer expression"); return; } if (size <= 0) { - error(loc, "array size must be a positive integer", "", ""); + error(loc, sizeType, "", "must be a positive integer"); return; } } @@ -2990,7 +3685,7 @@ // void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes) { - if (arraySizes.isImplicit()) + if (!parsingBuiltins && arraySizes.hasUnsized()) error(loc, "array size required", "", ""); } @@ -3004,7 +3699,8 @@ } } -void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, TArraySizes* arraySizes, bool initializer, bool lastMember) +void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, TArraySizes* arraySizes, + const TIntermTyped* initializer, bool lastMember) { assert(arraySizes); @@ -3012,17 +3708,22 @@ if (parsingBuiltins) return; - // always allow an initializer to set any unknown array sizes - if (initializer) + // initializer must be a sized array, in which case + // allow the initializer to set any unknown array sizes + if (initializer != nullptr) { + if (initializer->getType().isUnsizedArray()) + error(loc, "array initializer must be sized", "[]", ""); return; + } // No environment allows any non-outer-dimension to be implicitly sized - if (arraySizes->isInnerImplicit()) { + if (arraySizes->isInnerUnsized()) { error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", ""); - arraySizes->clearInnerImplicit(); + arraySizes->clearInnerUnsized(); } - if (arraySizes->isInnerSpecialization()) + if (arraySizes->isInnerSpecialization() && + (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst)) error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", ""); // desktop always allows outer-dimension-unsized variable arrays, @@ -3058,6 +3759,14 @@ extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; +#ifdef NV_EXTENSIONS + case EShLangMeshNV: + if (qualifier.storage == EvqVaryingOut) + if ((profile == EEsProfile && version >= 320) || + extensionTurnedOn(E_GL_NV_mesh_shader)) + return; + break; +#endif default: break; } @@ -3065,8 +3774,11 @@ arraySizeRequiredCheck(loc, *arraySizes); } -void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc) +void TParseContext::arrayOfArrayVersionCheck(const TSourceLoc& loc, const TArraySizes* sizes) { + if (sizes == nullptr || sizes->getNumDims() == 1) + return; + const char* feature = "arrays of arrays"; requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); @@ -3074,36 +3786,6 @@ profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature); } -void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TArraySizes* sizes1, const TArraySizes* sizes2) -{ - if ((sizes1 && sizes2) || - (sizes1 && sizes1->getNumDims() > 1) || - (sizes2 && sizes2->getNumDims() > 1)) - arrayOfArrayVersionCheck(loc); -} - -void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, const TArraySizes* sizes2) -{ - // skip checking for multiple dimensions on the type; it was caught earlier - if ((type && type->isArray() && sizes2) || - (sizes2 && sizes2->getNumDims() > 1)) - arrayOfArrayVersionCheck(loc); -} - -// Merge array dimensions listed in 'sizes' onto the type's array dimensions. -// -// From the spec: "vec4[2] a[3]; // size-3 array of size-2 array of vec4" -// -// That means, the 'sizes' go in front of the 'type' as outermost sizes. -// 'type' is the type part of the declaration (to the left) -// 'sizes' is the arrayness tagged on the identifier (to the right) -// -void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes) -{ - if (sizes) - type.addArrayOuterSizes(*sizes); -} - // // Do all the semantic checking for declaring or redeclaring an array, with and // without a size, and make the right changes to the symbol table. @@ -3173,7 +3855,7 @@ return; } - if (existingType.isExplicitlySizedArray()) { + if (existingType.isSizedArray()) { // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize())) error(loc, "redeclaration of array with size", identifier.c_str(), ""); @@ -3188,65 +3870,79 @@ checkIoArraysConsistency(loc); } -void TParseContext::updateImplicitArraySize(const TSourceLoc& loc, TIntermNode *node, int index) +// Policy and error check for needing a runtime sized array. +void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base) { - // maybe there is nothing to do... - TIntermTyped* typedNode = node->getAsTyped(); - if (typedNode->getType().getImplicitArraySize() > index) - return; - - // something to do... - - // Figure out what symbol to lookup, as we will use its type to edit for the size change, - // as that type will be shared through shallow copies for future references. - TSymbol* symbol = nullptr; - int blockIndex = -1; - const TString* lookupName = nullptr; - if (node->getAsSymbolNode()) - lookupName = &node->getAsSymbolNode()->getName(); - else if (node->getAsBinaryNode()) { - const TIntermBinary* deref = node->getAsBinaryNode(); - // This has to be the result of a block dereference, unless it's bad shader code - // If it's a uniform block, then an error will be issued elsewhere, but - // return early now to avoid crashing later in this function. - if (deref->getLeft()->getBasicType() != EbtBlock || - deref->getLeft()->getType().getQualifier().storage == EvqUniform || - deref->getRight()->getAsConstantUnion() == nullptr) - return; - - const TIntermTyped* left = deref->getLeft(); - const TIntermTyped* right = deref->getRight(); + // runtime length implies runtime sizeable, so no problem + if (isRuntimeLength(base)) + return; - if (left->getAsBinaryNode()) { - left = left->getAsBinaryNode()->getLeft(); // Block array access - assert(left->isArray()); + // Check for last member of a bufferreference type, which is runtime sizeable + // but doesn't support runtime length + if (base.getType().getQualifier().storage == EvqBuffer) { + const TIntermBinary* binary = base.getAsBinaryNode(); + if (binary != nullptr && + binary->getOp() == EOpIndexDirectStruct && + binary->getLeft()->getBasicType() == EbtReference) { + + const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + const int memberCount = (int)binary->getLeft()->getType().getReferentType()->getStruct()->size(); + if (index == memberCount - 1) + return; } + } - if (! left->getAsSymbolNode()) - return; + // check for additional things allowed by GL_EXT_nonuniform_qualifier + if (base.getBasicType() == EbtSampler || + (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) + requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index"); + else + error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); +} - blockIndex = right->getAsConstantUnion()->getConstArray()[0].getIConst(); +// Policy decision for whether a run-time .length() is allowed. +bool TParseContext::isRuntimeLength(const TIntermTyped& base) const +{ + if (base.getType().getQualifier().storage == EvqBuffer) { + // in a buffer block + const TIntermBinary* binary = base.getAsBinaryNode(); + if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) { + // is it the last member? + const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + + if (binary->getLeft()->getBasicType() == EbtReference) + return false; - lookupName = &left->getAsSymbolNode()->getName(); - if (IsAnonymous(*lookupName)) - lookupName = &(*left->getType().getStruct())[blockIndex].type->getFieldName(); + const int memberCount = (int)binary->getLeft()->getType().getStruct()->size(); + if (index == memberCount - 1) + return true; + } } - // Lookup the symbol, should only fail if shader code is incorrect - symbol = symbolTable.find(*lookupName); - if (symbol == nullptr) - return; + return false; +} - if (symbol->getAsFunction()) { - error(loc, "array variable name expected", symbol->getName().c_str(), ""); - return; - } +#ifdef NV_EXTENSIONS +// Fix mesh view output array dimension +void TParseContext::resizeMeshViewDimension(const TSourceLoc& loc, TType& type) +{ + // see if member is a per-view attribute + if (type.getQualifier().isPerView()) { + // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value + int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV; - if (symbol->getType().isStruct() && blockIndex != -1) - (*symbol->getWritableType().getStruct())[blockIndex].type->setImplicitArraySize(index + 1); - else - symbol->getWritableType().setImplicitArraySize(index + 1); + if (! type.isArray()) { + error(loc, "requires an view array dimension", "perviewNV", ""); + } + else if (!type.isUnsizedArray() && type.getOuterArraySize() != maxViewCount) { + error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", ""); + } + else if (type.isUnsizedArray()) { + type.changeOuterArraySize(maxViewCount); + } + } } +#endif // Returns true if the first argument to the #line directive is the line number for the next line. // @@ -3322,9 +4018,12 @@ identifier == "gl_BackSecondaryColor" || identifier == "gl_SecondaryColor" || (identifier == "gl_Color" && language == EShLangFragment) || + (identifier == "gl_FragStencilRefARB" && (nonEsRedecls && version >= 140) + && language == EShLangFragment) || #ifdef NV_EXTENSIONS identifier == "gl_SampleMask" || identifier == "gl_Layer" || + identifier == "gl_PrimitiveIndicesNV" || #endif identifier == "gl_TexCoord") { @@ -3404,6 +4103,16 @@ error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str()); } } + else if ( +#ifdef NV_EXTENSIONS + identifier == "gl_PrimitiveIndicesNV" || +#endif + identifier == "gl_FragStencilRefARB") { + if (qualifier.hasLayout()) + error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str()); + if (qualifier.storage != EvqVaryingOut) + error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str()); + } #ifdef NV_EXTENSIONS else if (identifier == "gl_SampleMask") { if (!publicType.layoutOverrideCoverage) { @@ -3431,13 +4140,19 @@ // Either redeclare the requested block, or give an error message why it can't be done. // // TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size -void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes) +void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, + const TString* instanceName, TArraySizes* arraySizes) { const char* feature = "built-in block redeclaration"; profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature); - if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment") { + if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" +#ifdef NV_EXTENSIONS + && blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV" +#endif + ) + { error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str()); return; } @@ -3483,8 +4198,11 @@ // Fix XFB stuff up, it applies to the order of the redeclaration, not // the order of the original members. if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) { - currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; - fixBlockXfbOffsets(currentBlockQualifier, newTypeList); + if (!currentBlockQualifier.hasXfbBuffer()) + currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + if (!currentBlockQualifier.hasStream()) + currentBlockQualifier.layoutStream = globalOutputDefaults.layoutStream; + fixXfbOffsets(currentBlockQualifier, newTypeList); } // Edit and error check the container against the redeclaration @@ -3532,18 +4250,43 @@ error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), ""); if (oldType.isArray() != newType.isArray()) error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), ""); - else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray()) + else if (! oldType.getQualifier().isPerView() && ! oldType.sameArrayness(newType) && oldType.isSizedArray()) error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), ""); - else if (newType.isArray()) + else if (! oldType.getQualifier().isPerView() && newType.isArray()) arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize()); +#ifdef NV_EXTENSIONS + if (oldType.getQualifier().isPerView() && ! newType.getQualifier().isPerView()) + error(memberLoc, "missing perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); + else if (! oldType.getQualifier().isPerView() && newType.getQualifier().isPerView()) + error(memberLoc, "cannot add perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); + else if (newType.getQualifier().isPerView()) { + if (oldType.getArraySizes()->getNumDims() != newType.getArraySizes()->getNumDims()) + error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), ""); + else if (! newType.isUnsizedArray() && newType.getOuterArraySize() != resources.maxMeshViewCountNV) + error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", ""); + else if (newType.getArraySizes()->getNumDims() == 2) { + int innerDimSize = newType.getArraySizes()->getDimSize(1); + arrayLimitCheck(memberLoc, member->type->getFieldName(), innerDimSize); + oldType.getArraySizes()->setDimSize(1, innerDimSize); + } + } + if (oldType.getQualifier().isPerPrimitive() && ! newType.getQualifier().isPerPrimitive()) + error(memberLoc, "missing perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); + else if (! oldType.getQualifier().isPerPrimitive() && newType.getQualifier().isPerPrimitive()) + error(memberLoc, "cannot add perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); +#endif if (newType.getQualifier().isMemory()) error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); if (newType.getQualifier().hasNonXfbLayout()) error(memberLoc, "cannot add non-XFB layout to redeclared block member", member->type->getFieldName().c_str(), ""); if (newType.getQualifier().patch) error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), ""); - if (newType.getQualifier().hasXfbBuffer() && newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer) + if (newType.getQualifier().hasXfbBuffer() && + newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer) error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); + if (newType.getQualifier().hasStream() && + newType.getQualifier().layoutStream != currentBlockQualifier.layoutStream) + error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_stream", ""); oldType.getQualifier().centroid = newType.getQualifier().centroid; oldType.getQualifier().sample = newType.getQualifier().sample; oldType.getQualifier().invariant = newType.getQualifier().invariant; @@ -3552,11 +4295,20 @@ oldType.getQualifier().flat = newType.getQualifier().flat; oldType.getQualifier().nopersp = newType.getQualifier().nopersp; oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset; - if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) + oldType.getQualifier().layoutXfbBuffer = newType.getQualifier().layoutXfbBuffer; + oldType.getQualifier().layoutXfbStride = newType.getQualifier().layoutXfbStride; + if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) { + // If any member has an xfb_offset, then the block's xfb_buffer inherents current xfb_buffer, + // and for xfb processing, the member needs it as well, along with xfb_stride. type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; - if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray()) + oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; + } + if (oldType.isUnsizedArray() && newType.isSizedArray()) oldType.changeOuterArraySize(newType.getOuterArraySize()); + // check and process the member's type, which will include managing xfb information + layoutTypeCheck(loc, oldType); + // go to next member ++member; } else { @@ -3572,17 +4324,31 @@ } } + if (spvVersion.vulkan > 0) { + // ...then streams apply to built-in blocks, instead of them being only on stream 0 + type.getQualifier().layoutStream = currentBlockQualifier.layoutStream; + } + if (numOriginalMembersFound < newTypeList.size()) error(loc, "block redeclaration has extra members", blockName.c_str(), ""); - if (type.isArray() != (arraySizes != nullptr)) + if (type.isArray() != (arraySizes != nullptr) || + (type.isArray() && arraySizes != nullptr && type.getArraySizes()->getNumDims() != arraySizes->getNumDims())) error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), ""); else if (type.isArray()) { - if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize) - error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), ""); - else if (type.isExplicitlySizedArray() && type.getArraySizes() != *arraySizes) - error(loc, "cannot change array size of redeclared block", blockName.c_str(), ""); - else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize) + // At this point, we know both are arrays and both have the same number of dimensions. + + // It is okay for a built-in block redeclaration to be unsized, and keep the size of the + // original block declaration. + if (!arraySizes->isSized() && type.isSizedArray()) + arraySizes->changeOuterSize(type.getOuterArraySize()); + + // And, okay to be giving a size to the array, by the redeclaration + if (!type.isSizedArray() && arraySizes->isSized()) type.changeOuterArraySize(arraySizes->getOuterSize()); + + // Now, they must match in all dimensions. + if (type.isSizedArray() && *type.getArraySizes() != *arraySizes) + error(loc, "cannot change array size of redeclared block", blockName.c_str(), ""); } symbolTable.insert(*block); @@ -3601,7 +4367,7 @@ trackLinkage(*block); } -void TParseContext::paramCheckFix(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type) +void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type) { switch (qualifier) { case EvqConst: @@ -3629,6 +4395,11 @@ if (qualifier.isMemory()) { type.getQualifier().volatil = qualifier.volatil; type.getQualifier().coherent = qualifier.coherent; + type.getQualifier().devicecoherent = qualifier.devicecoherent ; + type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent; + type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent; + type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent; + type.getQualifier().nonprivate = qualifier.nonprivate; type.getQualifier().readonly = qualifier.readonly; type.getQualifier().writeonly = qualifier.writeonly; type.getQualifier().restrict = qualifier.restrict; @@ -3647,8 +4418,10 @@ else warn(loc, "qualifier has no effect on non-output parameters", "precise", ""); } + if (qualifier.isNonUniform()) + type.getQualifier().nonUniform = qualifier.nonUniform; - paramCheckFix(loc, qualifier.storage, type); + paramCheckFixStorage(loc, qualifier.storage, type); } void TParseContext::nestedBlockCheck(const TSourceLoc& loc) @@ -3680,6 +4453,45 @@ error(loc, "can't use with samplers or structs containing samplers", op, ""); } +void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ + if (containsFieldWithBasicType(type, EbtReference)) + error(loc, "can't use with reference types", op, ""); +} + +void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16)) + requireFloat16Arithmetic(loc, op, "can't use with structs containing float16"); + + if (type.isArray() && type.getBasicType() == EbtFloat16) + requireFloat16Arithmetic(loc, op, "can't use with arrays containing float16"); + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt16)) + requireInt16Arithmetic(loc, op, "can't use with structs containing int16"); + + if (type.isArray() && type.getBasicType() == EbtInt16) + requireInt16Arithmetic(loc, op, "can't use with arrays containing int16"); + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint16)) + requireInt16Arithmetic(loc, op, "can't use with structs containing uint16"); + + if (type.isArray() && type.getBasicType() == EbtUint16) + requireInt16Arithmetic(loc, op, "can't use with arrays containing uint16"); + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt8)) + requireInt8Arithmetic(loc, op, "can't use with structs containing int8"); + + if (type.isArray() && type.getBasicType() == EbtInt8) + requireInt8Arithmetic(loc, op, "can't use with arrays containing int8"); + + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint8)) + requireInt8Arithmetic(loc, op, "can't use with structs containing uint8"); + + if (type.isArray() && type.getBasicType() == EbtUint8) + requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8"); +} + void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op) { if (type.containsSpecializationSize()) @@ -3835,6 +4647,12 @@ limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size"); else if (identifier.compare("gl_CullDistance") == 0) limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size"); +#ifdef NV_EXTENSIONS + else if (identifier.compare("gl_ClipDistancePerViewNV") == 0) + limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistancePerViewNV array size"); + else if (identifier.compare("gl_CullDistancePerViewNV") == 0) + limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size"); +#endif } // See if the provided value is less than or equal to the symbol indicated by limit, @@ -3884,9 +4702,39 @@ if (profile != EEsProfile && version < 430) requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders"); break; +#ifdef NV_EXTENSIONS + case EShLangTaskNV: + requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders"); + break; + case EShLangMeshNV: + requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders"); + break; +#endif default: break; } + +#ifdef NV_EXTENSIONS + // Set default outputs for GL_NV_geometry_shader_passthrough + if (language == EShLangGeometry && extensionTurnedOn(E_SPV_NV_geometry_shader_passthrough)) { + if (intermediate.getOutputPrimitive() == ElgNone) { + switch (intermediate.getInputPrimitive()) { + case ElgPoints: intermediate.setOutputPrimitive(ElgPoints); break; + case ElgLines: intermediate.setOutputPrimitive(ElgLineStrip); break; + case ElgTriangles: intermediate.setOutputPrimitive(ElgTriangleStrip); break; + default: break; + } + } + if (intermediate.getVertices() == TQualifier::layoutNotSet) { + switch (intermediate.getInputPrimitive()) { + case ElgPoints: intermediate.setVertices(1); break; + case ElgLines: intermediate.setVertices(2); break; + case ElgTriangles: intermediate.setVertices(3); break; + default: break; + } + } + } +#endif } // @@ -3930,6 +4778,12 @@ publicType.qualifier.layoutPacking = ElpStd430; return; } + if (id == TQualifier::getLayoutPackingString(ElpScalar)) { + requireVulkan(loc, "scalar"); + requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "scalar block layout"); + publicType.qualifier.layoutPacking = ElpScalar; + return; + } // TODO: compile-time performance: may need to stop doing linear searches for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) { if (id == TQualifier::getLayoutFormatString(format)) { @@ -3948,44 +4802,65 @@ publicType.qualifier.layoutPushConstant = true; return; } - if (language == EShLangGeometry || language == EShLangTessEvaluation) { + if (id == "buffer_reference") { + requireVulkan(loc, "buffer_reference"); + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference"); + publicType.qualifier.layoutBufferReference = true; + intermediate.setUseStorageBuffer(); + intermediate.setUsePhysicalStorageBuffer(); + return; + } + if (language == EShLangGeometry || language == EShLangTessEvaluation +#ifdef NV_EXTENSIONS + || language == EShLangMeshNV +#endif + ) { if (id == TQualifier::getGeometryString(ElgTriangles)) { publicType.shaderQualifiers.geometry = ElgTriangles; return; } - if (language == EShLangGeometry) { + if (language == EShLangGeometry +#ifdef NV_EXTENSIONS + || language == EShLangMeshNV +#endif + ) { if (id == TQualifier::getGeometryString(ElgPoints)) { publicType.shaderQualifiers.geometry = ElgPoints; return; } - if (id == TQualifier::getGeometryString(ElgLineStrip)) { - publicType.shaderQualifiers.geometry = ElgLineStrip; - return; - } if (id == TQualifier::getGeometryString(ElgLines)) { publicType.shaderQualifiers.geometry = ElgLines; return; } - if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) { - publicType.shaderQualifiers.geometry = ElgLinesAdjacency; - return; - } - if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) { - publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency; - return; - } - if (id == TQualifier::getGeometryString(ElgTriangleStrip)) { - publicType.shaderQualifiers.geometry = ElgTriangleStrip; - return; - } #ifdef NV_EXTENSIONS - if (id == "passthrough") { - requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough"); - publicType.qualifier.layoutPassthrough = true; - intermediate.setGeoPassthroughEXT(); - return; - } + if (language == EShLangGeometry) #endif + { + if (id == TQualifier::getGeometryString(ElgLineStrip)) { + publicType.shaderQualifiers.geometry = ElgLineStrip; + return; + } + if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) { + publicType.shaderQualifiers.geometry = ElgLinesAdjacency; + return; + } + if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) { + publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency; + return; + } + if (id == TQualifier::getGeometryString(ElgTriangleStrip)) { + publicType.shaderQualifiers.geometry = ElgTriangleStrip; + return; + } +#ifdef NV_EXTENSIONS + if (id == "passthrough") { + requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough"); + publicType.qualifier.layoutPassthrough = true; + intermediate.setGeoPassthroughEXT(); + return; + } +#endif + } } else { assert(language == EShLangTessEvaluation); @@ -4099,6 +4974,27 @@ publicType.qualifier.layoutViewportRelative = true; return; } + } else { + if (language == EShLangRayGenNV || language == EShLangIntersectNV || + language == EShLangAnyHitNV || language == EShLangClosestHitNV || + language == EShLangMissNV || language == EShLangCallableNV) { + if (id == "shaderrecordnv") { + publicType.qualifier.layoutShaderRecordNV = true; + return; + } + } + } + if (language == EShLangCompute) { + if (id.compare(0, 17, "derivative_group_") == 0) { + requireExtensions(loc, 1, &E_GL_NV_compute_shader_derivatives, "compute shader derivatives"); + if (id == "derivative_group_quadsnv") { + publicType.shaderQualifiers.layoutDerivativeGroupQuads = true; + return; + } else if (id == "derivative_group_linearnv") { + publicType.shaderQualifiers.layoutDerivativeGroupLinear = true; + return; + } + } } #else } @@ -4116,6 +5012,7 @@ integerCheck(node, feature); const TIntermConstantUnion* constUnion = node->getAsConstantUnion(); int value; + bool nonLiteral = false; if (constUnion) { value = constUnion->getConstArray()[0].getIConst(); if (! constUnion->isLiteral()) { @@ -4125,6 +5022,7 @@ } else { // grammar should have give out the error message value = 0; + nonLiteral = true; } if (value < 0) { @@ -4146,6 +5044,8 @@ profileRequires(loc, EEsProfile, 310, nullptr, feature); } publicType.qualifier.layoutOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "offset", ""); return; } else if (id == "align") { const char* feature = "uniform buffer-member align"; @@ -4158,6 +5058,8 @@ error(loc, "must be a power of 2", "align", ""); else publicType.qualifier.layoutAlign = value; + if (nonLiteral) + error(loc, "needs a literal integer", "align", ""); return; } else if (id == "location") { profileRequires(loc, EEsProfile, 300, nullptr, "location"); @@ -4167,6 +5069,8 @@ error(loc, "location is too large", id.c_str(), ""); else publicType.qualifier.layoutLocation = value; + if (nonLiteral) + error(loc, "needs a literal integer", "location", ""); return; } else if (id == "set") { if ((unsigned int)value >= TQualifier::layoutSetEnd) @@ -4175,6 +5079,8 @@ publicType.qualifier.layoutSet = value; if (value != 0) requireVulkan(loc, "descriptor set"); + if (nonLiteral) + error(loc, "needs a literal integer", "set", ""); return; } else if (id == "binding") { profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); @@ -4183,6 +5089,8 @@ error(loc, "binding is too large", id.c_str(), ""); else publicType.qualifier.layoutBinding = value; + if (nonLiteral) + error(loc, "needs a literal integer", "binding", ""); return; } else if (id == "component") { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component"); @@ -4191,6 +5099,8 @@ error(loc, "component is too large", id.c_str(), ""); else publicType.qualifier.layoutComponent = value; + if (nonLiteral) + error(loc, "needs a literal integer", "component", ""); return; } else if (id.compare(0, 4, "xfb_") == 0) { // "Any shader making any static use (after preprocessing) of any of these @@ -4211,22 +5121,30 @@ error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd-1); else publicType.qualifier.layoutXfbBuffer = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_buffer", ""); return; } else if (id == "xfb_offset") { if (value >= (int)TQualifier::layoutXfbOffsetEnd) error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd-1); else publicType.qualifier.layoutXfbOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_offset", ""); return; } else if (id == "xfb_stride") { // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." - if (value > 4 * resources.maxTransformFeedbackInterleavedComponents) - error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", resources.maxTransformFeedbackInterleavedComponents); - else if (value >= (int)TQualifier::layoutXfbStrideEnd) + if (value > 4 * resources.maxTransformFeedbackInterleavedComponents) { + error(loc, "1/4 stride is too large:", id.c_str(), "gl_MaxTransformFeedbackInterleavedComponents is %d", + resources.maxTransformFeedbackInterleavedComponents); + } + if (value >= (int)TQualifier::layoutXfbStrideEnd) error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd-1); - if (value < (int)TQualifier::layoutXfbStrideEnd) + else publicType.qualifier.layoutXfbStride = value; + if (nonLiteral) + error(loc, "needs a literal integer", "xfb_stride", ""); return; } } @@ -4237,6 +5155,8 @@ error(loc, "attachment index is too large", id.c_str(), ""); else publicType.qualifier.layoutAttachment = value; + if (nonLiteral) + error(loc, "needs a literal integer", "input_attachment_index", ""); return; } if (id == "constant_id") { @@ -4249,11 +5169,15 @@ if (! intermediate.addUsedConstantId(value)) error(loc, "specialization-constant id already used", id.c_str(), ""); } + if (nonLiteral) + error(loc, "needs a literal integer", "constant_id", ""); return; } if (id == "num_views") { requireExtensions(loc, Num_OVR_multiview_EXTs, OVR_multiview_EXTs, "num_views"); publicType.shaderQualifiers.numViews = value; + if (nonLiteral) + error(loc, "needs a literal integer", "num_views", ""); return; } @@ -4265,11 +5189,24 @@ if (id == "secondary_view_offset") { requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering"); publicType.qualifier.layoutSecondaryViewportRelativeOffset = value; + if (nonLiteral) + error(loc, "needs a literal integer", "secondary_view_offset", ""); return; } } #endif + if (id == "buffer_reference_align") { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference, "buffer_reference_align"); + if (! IsPow2(value)) + error(loc, "must be a power of 2", "buffer_reference_align", ""); + else + publicType.qualifier.layoutBufferReferenceAlign = (unsigned int)std::log2(value); + if (nonLiteral) + error(loc, "needs a literal integer", "buffer_reference_align", ""); + return; + } + switch (language) { case EShLangVertex: break; @@ -4280,6 +5217,8 @@ error(loc, "must be greater than 0", "vertices", ""); else publicType.shaderQualifiers.vertices = value; + if (nonLiteral) + error(loc, "needs a literal integer", "vertices", ""); return; } break; @@ -4294,12 +5233,16 @@ error(loc, "must be at least 1", "invocations", ""); else publicType.shaderQualifiers.invocations = value; + if (nonLiteral) + error(loc, "needs a literal integer", "invocations", ""); return; } if (id == "max_vertices") { publicType.shaderQualifiers.vertices = value; if (value > resources.maxGeometryOutputVertices) error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_vertices", ""); return; } if (id == "stream") { @@ -4307,6 +5250,8 @@ publicType.qualifier.layoutStream = value; if (value > 0) intermediate.setMultiStream(); + if (nonLiteral) + error(loc, "needs a literal integer", "stream", ""); return; } break; @@ -4324,14 +5269,51 @@ } publicType.qualifier.layoutIndex = value; + if (nonLiteral) + error(loc, "needs a literal integer", "index", ""); return; } break; +#ifdef NV_EXTENSIONS + case EShLangMeshNV: + if (id == "max_vertices") { + requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices"); + publicType.shaderQualifiers.vertices = value; + if (value > resources.maxMeshOutputVerticesNV) + error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_vertices", ""); + return; + } + if (id == "max_primitives") { + requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_primitives"); + publicType.shaderQualifiers.primitives = value; + if (value > resources.maxMeshOutputPrimitivesNV) + error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", ""); + if (nonLiteral) + error(loc, "needs a literal integer", "max_primitives", ""); + return; + } + // Fall through + + case EShLangTaskNV: + // Fall through +#endif case EShLangCompute: if (id.compare(0, 11, "local_size_") == 0) { - profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); - profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); +#ifdef NV_EXTENSIONS + if (language == EShLangMeshNV || language == EShLangTaskNV) { + requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize"); + } + else +#endif + { + profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); + profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); + } + if (nonLiteral) + error(loc, "needs a literal integer", "local_size", ""); if (id.size() == 12 && value == 0) { error(loc, "must be at least 1", id.c_str(), ""); return; @@ -4405,6 +5387,9 @@ if (src.hasAlign()) dst.layoutAlign = src.layoutAlign; + if (src.hasBufferReferenceAlign()) + dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign; + if (! inheritOnly) { if (src.hasLocation()) dst.layoutLocation = src.layoutLocation; @@ -4433,6 +5418,9 @@ if (src.layoutPushConstant) dst.layoutPushConstant = true; + if (src.layoutBufferReference) + dst.layoutBufferReference = true; + #ifdef NV_EXTENSIONS if (src.layoutPassthrough) dst.layoutPassthrough = true; @@ -4440,6 +5428,10 @@ dst.layoutViewportRelative = true; if (src.layoutSecondaryViewportRelativeOffset != -2048) dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset; + if (src.layoutShaderRecordNV) + dst.layoutShaderRecordNV = true; + if (src.pervertexNV) + dst.pervertexNV = true; #endif } } @@ -4476,9 +5468,10 @@ switch (qualifier.storage) { case EvqVaryingIn: case EvqVaryingOut: - if (type.getBasicType() != EbtBlock || - (!(*type.getStruct())[0].type->getQualifier().hasLocation() && - (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)) + if (!type.getQualifier().isTaskMemory() && + (type.getBasicType() != EbtBlock || + (!(*type.getStruct())[0].type->getQualifier().hasLocation() && + (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))) error(loc, "SPIR-V requires location for user input/output", "location", ""); break; default: @@ -4504,6 +5497,10 @@ error(loc, "cannot specify on a variable declaration", "align", ""); if (qualifier.layoutPushConstant) error(loc, "can only specify on a uniform block", "push_constant", ""); +#ifdef NV_EXTENSIONS + if (qualifier.layoutShaderRecordNV) + error(loc, "can only specify on a buffer block", "shaderRecordNV", ""); +#endif } break; default: @@ -4520,7 +5517,8 @@ // they are not allowed on block members. For arrayed interfaces (those generally having an // extra level of arrayness due to interface expansion), the outer array is stripped before // applying this rule." -void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation, TArraySizes* arraySizes) +void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool memberWithLocation, + TArraySizes* arraySizes) { if (memberWithLocation && arraySizes != nullptr) { if (arraySizes->getNumDims() > (currentBlockQualifier.isArrayedIo(language) ? 1 : 0)) @@ -4566,12 +5564,24 @@ case EvqVaryingOut: if (type.getBasicType() == EbtBlock) profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block"); - break; +#ifdef NV_EXTENSIONS + if (type.getQualifier().isTaskMemory()) + error(loc, "cannot apply to taskNV in/out blocks", "location", ""); +#endif + break; case EvqUniform: case EvqBuffer: if (type.getBasicType() == EbtBlock) error(loc, "cannot apply to uniform or buffer block", "location", ""); break; +#ifdef NV_EXTENSIONS + case EvqPayloadNV: + case EvqPayloadInNV: + case EvqHitAttrNV: + case EvqCallableDataNV: + case EvqCallableDataInNV: + break; +#endif default: error(loc, "can only apply to uniform, buffer, in, or out storage qualifiers", "location", ""); break; @@ -4594,16 +5604,23 @@ // "The offset must be a multiple of the size of the first component of the first // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate - // containing a double, the offset must also be a multiple of 8..." - if (type.containsBasicType(EbtDouble) && ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8)) - error(loc, "type contains double; xfb_offset must be a multiple of 8", "xfb_offset", ""); + // containing a double or 64-bit integer, the offset must also be a multiple of 8..." + if ((type.containsBasicType(EbtDouble) || type.containsBasicType(EbtInt64) || type.containsBasicType(EbtUint64)) && + ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 8)) + error(loc, "type contains double or 64-bit integer; xfb_offset must be a multiple of 8", "xfb_offset", ""); #ifdef AMD_EXTENSIONS - // ..., if applied to an aggregate containing a float16_t, the offset must also be a multiple of 2..." - else if (type.containsBasicType(EbtFloat16) && !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2)) - error(loc, "type contains half float; xfb_offset must be a multiple of 2", "xfb_offset", ""); -#endif + else if ((type.containsBasicType(EbtBool) || type.containsBasicType(EbtFloat) || + type.containsBasicType(EbtInt) || type.containsBasicType(EbtUint)) && + ! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4)) + error(loc, "must be a multiple of size of first component", "xfb_offset", ""); + // ..., if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2..." + else if ((type.containsBasicType(EbtFloat16) || type.containsBasicType(EbtInt16) || type.containsBasicType(EbtUint16)) && + !IsMultipleOfPow2(qualifier.layoutXfbOffset, 2)) + error(loc, "type contains half float or 16-bit integer; xfb_offset must be a multiple of 2", "xfb_offset", ""); +#else else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4)) error(loc, "must be a multiple of size of first component", "xfb_offset", ""); +#endif } if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) { @@ -4625,11 +5642,17 @@ if (type.getBasicType() == EbtSampler) { int lastBinding = qualifier.layoutBinding; if (type.isArray()) { - if (type.isImplicitlySizedArray()) { + if (spvVersion.vulkan > 0) lastBinding += 1; - warn(loc, "assuming array size of one for compile-time checking of binding numbers for implicitly-sized array", "[]", ""); - } else - lastBinding += type.getCumulativeArraySize(); + else { + if (type.isSizedArray()) + lastBinding += type.getCumulativeArraySize(); + else { + lastBinding += 1; + if (spvVersion.vulkan == 0) + warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", ""); + } + } } if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); @@ -4640,12 +5663,35 @@ return; } } - } + } else if (!intermediate.getAutoMapBindings()) { + // some types require bindings - // atomic_uint - if (type.getBasicType() == EbtAtomicUint) { - if (! type.getQualifier().hasBinding()) + // atomic_uint + if (type.getBasicType() == EbtAtomicUint) error(loc, "layout(binding=X) is required", "atomic_uint", ""); + + // SPIR-V + if (spvVersion.spv > 0) { + if (qualifier.isUniformOrBuffer()) { + if (type.getBasicType() == EbtBlock && !qualifier.layoutPushConstant && +#ifdef NV_EXTENSIONS + !qualifier.layoutShaderRecordNV && +#endif + !qualifier.layoutAttachment && + !qualifier.layoutBufferReference) + error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", ""); + else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler) + error(loc, "sampler/texture/image requires layout(binding=X)", "binding", ""); + } + } + } + + // some things can't have arrays of arrays + if (type.isArrayOfArrays()) { + if (spvVersion.vulkan > 0) { + if (type.isOpaque() || (type.getQualifier().isUniformOrBuffer() && type.getBasicType() == EbtBlock)) + warn(loc, "Generating SPIR-V array-of-arrays, but Vulkan only supports single array level for this resource", "[][]", ""); + } } // "The offset qualifier can only be used on block members of blocks..." @@ -4684,6 +5730,14 @@ if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "push_constant", ""); + if (qualifier.layoutBufferReference && type.getBasicType() != EbtBlock) + error(loc, "can only be used with a block", "buffer_reference", ""); + +#ifdef NV_EXTENSIONS + if (qualifier.layoutShaderRecordNV && type.getBasicType() != EbtBlock) + error(loc, "can only be used with a block", "shaderRecordNV", ""); +#endif + // input attachment if (type.isSubpass()) { if (! qualifier.hasAttachment()) @@ -4701,20 +5755,18 @@ error(loc, "can only be applied to a scalar", "constant_id", ""); switch (type.getBasicType()) { + case EbtInt8: + case EbtUint8: + case EbtInt16: + case EbtUint16: case EbtInt: case EbtUint: case EbtInt64: case EbtUint64: -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: -#endif case EbtBool: case EbtFloat: case EbtDouble: -#ifdef AMD_EXTENSIONS case EbtFloat16: -#endif break; default: error(loc, "cannot be applied to this type", "constant_id", ""); @@ -4796,19 +5848,19 @@ } if (qualifier.hasBinding()) { - if (! qualifier.isUniformOrBuffer()) + if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) error(loc, "requires uniform or buffer storage qualifier", "binding", ""); } if (qualifier.hasStream()) { - if (qualifier.storage != EvqVaryingOut) + if (!qualifier.isPipeOutput()) error(loc, "can only be used on an output", "stream", ""); } if (qualifier.hasXfb()) { - if (qualifier.storage != EvqVaryingOut) + if (!qualifier.isPipeOutput()) error(loc, "can only be used on an output", "xfb layout qualifier", ""); } if (qualifier.hasUniformLayout()) { - if (! qualifier.isUniformOrBuffer()) { + if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) { if (qualifier.hasMatrix() || qualifier.hasPacking()) error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", ""); if (qualifier.hasOffset() || qualifier.hasAlign()) @@ -4821,6 +5873,24 @@ if (qualifier.hasSet()) error(loc, "cannot be used with push_constant", "set", ""); } + if (qualifier.layoutBufferReference) { + if (qualifier.storage != EvqBuffer) + error(loc, "can only be used with buffer", "buffer_reference", ""); + } +#ifdef NV_EXTENSIONS + if (qualifier.layoutShaderRecordNV) { + if (qualifier.storage != EvqBuffer) + error(loc, "can only be used with a buffer", "shaderRecordNV", ""); + if (qualifier.hasBinding()) + error(loc, "cannot be used with shaderRecordNV", "binding", ""); + if (qualifier.hasSet()) + error(loc, "cannot be used with shaderRecordNV", "set", ""); + + } + if (qualifier.storage == EvqHitAttrNV && qualifier.hasLayout()) { + error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", ""); + } +#endif } // For places that can't have shader-level layout qualifiers @@ -4849,13 +5919,25 @@ error(loc, message, "local_size id", ""); } if (shaderQualifiers.vertices != TQualifier::layoutNotSet) { - if (language == EShLangGeometry) + if (language == EShLangGeometry +#ifdef NV_EXTENSIONS + || language == EShLangMeshNV +#endif + ) error(loc, message, "max_vertices", ""); else if (language == EShLangTessControl) error(loc, message, "vertices", ""); else assert(0); } +#ifdef NV_EXTENSIONS + if (shaderQualifiers.primitives != TQualifier::layoutNotSet) { + if (language == EShLangMeshNV) + error(loc, message, "max_primitives", ""); + else + assert(0); + } +#endif if (shaderQualifiers.blendEquation) error(loc, message, "blend equation", ""); if (shaderQualifiers.numViews != TQualifier::layoutNotSet) @@ -4880,7 +5962,7 @@ // Check for overlap int numOffsets = 4; if (symbol.getType().isArray()) { - if (symbol.getType().isExplicitlySizedArray() && ! symbol.getType().getArraySizes()->isInnerImplicit()) + if (symbol.getType().isSizedArray() && !symbol.getType().getArraySizes()->isInnerUnsized()) numOffsets *= symbol.getType().getCumulativeArraySize(); else { // "It is a compile-time error to declare an unsized array of atomic_uint." @@ -4911,10 +5993,21 @@ return nullptr; } + bool explicitTypesEnabled = extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) || + extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64); + if (profile == EEsProfile || version < 120) function = findFunctionExact(loc, call, builtIn); else if (version < 400) function = findFunction120(loc, call, builtIn); + else if (explicitTypesEnabled) + function = findFunctionExplicitTypes(loc, call, builtIn); else function = findFunction400(loc, call, builtIn); @@ -5057,9 +6150,18 @@ symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); // can 'from' convert to 'to'? - const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool { + const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool { if (from == to) return true; + if (from.coopMatParameterOK(to)) + return true; + // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions + if (builtIn && from.isArray() && to.isUnsizedArray()) { + TType fromElementType(from, 0); + TType toElementType(to, 0); + if (fromElementType == toElementType) + return true; + } if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) return false; return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); @@ -5099,6 +6201,94 @@ return bestMatch; } +// "To determine whether the conversion for a single argument in one match +// is better than that for another match, the conversion is assigned of the +// three ranks ordered from best to worst: +// 1. Exact match: no conversion. +// 2. Promotion: integral or floating-point promotion. +// 3. Conversion: integral conversion, floating-point conversion, +// floating-integral conversion. +// A conversion C1 is better than a conversion C2 if the rank of C1 is +// better than the rank of C2." +const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn) +{ + // first, look for an exact match + TSymbol* symbol = symbolTable.find(call.getMangledName(), &builtIn); + if (symbol) + return symbol->getAsFunction(); + + // no exact match, use the generic selector, parameterized by the GLSL rules + + // create list of candidates to send + TVector candidateList; + symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn); + + // can 'from' convert to 'to'? + const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool { + if (from == to) + return true; + if (from.coopMatParameterOK(to)) + return true; + // Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions + if (builtIn && from.isArray() && to.isUnsizedArray()) { + TType fromElementType(from, 0); + TType toElementType(to, 0); + if (fromElementType == toElementType) + return true; + } + if (from.isArray() || to.isArray() || ! from.sameElementShape(to)) + return false; + return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); + }; + + // Is 'to2' a better conversion than 'to1'? + // Ties should not be considered as better. + // Assumes 'convertible' already said true. + const auto better = [this](const TType& from, const TType& to1, const TType& to2) -> bool { + // 1. exact match + if (from == to2) + return from != to1; + if (from == to1) + return false; + + // 2. Promotion (integral, floating-point) is better + TBasicType from_type = from.getBasicType(); + TBasicType to1_type = to1.getBasicType(); + TBasicType to2_type = to2.getBasicType(); + bool isPromotion1 = (intermediate.isIntegralPromotion(from_type, to1_type) || + intermediate.isFPPromotion(from_type, to1_type)); + bool isPromotion2 = (intermediate.isIntegralPromotion(from_type, to2_type) || + intermediate.isFPPromotion(from_type, to2_type)); + if (isPromotion2) + return !isPromotion1; + if(isPromotion1) + return false; + + // 3. Conversion (integral, floating-point , floating-integral) + bool isConversion1 = (intermediate.isIntegralConversion(from_type, to1_type) || + intermediate.isFPConversion(from_type, to1_type) || + intermediate.isFPIntegralConversion(from_type, to1_type)); + bool isConversion2 = (intermediate.isIntegralConversion(from_type, to2_type) || + intermediate.isFPConversion(from_type, to2_type) || + intermediate.isFPIntegralConversion(from_type, to2_type)); + + return isConversion2 && !isConversion1; + }; + + // for ambiguity reporting + bool tie = false; + + // send to the generic selector + const TFunction* bestMatch = selectFunction(candidateList, call, convertible, better, tie); + + if (bestMatch == nullptr) + error(loc, "no matching overloaded function found", call.getName().c_str(), ""); + else if (tie) + error(loc, "ambiguous best function under implicit type conversion", call.getName().c_str(), ""); + + return bestMatch; +} + // When a declaration includes a type, but not a variable name, it can be // to establish defaults. void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType) @@ -5112,7 +6302,7 @@ return; } - if (publicType.qualifier.hasLayout()) + if (publicType.qualifier.hasLayout() && !publicType.qualifier.layoutBufferReference) warn(loc, "useless application of layout qualifier", "layout", ""); } @@ -5127,14 +6317,33 @@ // 'publicType' is the type part of the declaration (to the left) // 'arraySizes' is the arrayness tagged on the identifier (to the right) // -TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer) +TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, + TArraySizes* arraySizes, TIntermTyped* initializer) { - TType type(publicType); // shallow copy; 'type' shares the arrayness and structure definition with 'publicType' - if (type.isImplicitlySizedArray()) { - // Because "int[] a = int[2](...), b = int[3](...)" makes two arrays a and b - // of different sizes, for this case sharing the shallow copy of arrayness - // with the publicType oversubscribes it, so get a deep copy of the arrayness. - type.newArraySizes(*publicType.arraySizes); + // Make a fresh type that combines the characteristics from the individual + // identifier syntax and the declaration-type syntax. + TType type(publicType); + type.transferArraySizes(arraySizes); + type.copyArrayInnerSizes(publicType.arraySizes); + arrayOfArrayVersionCheck(loc, type.getArraySizes()); + + if (type.isCoopMat()) { + intermediate.setUseVulkanMemoryModel(); + intermediate.setUseStorageBuffer(); + + if (!publicType.typeParameters || publicType.typeParameters->getNumDims() != 4) { + error(loc, "expected four type parameters", identifier.c_str(), ""); + } + if (publicType.typeParameters && + publicType.typeParameters->getDimSize(0) != 16 && + publicType.typeParameters->getDimSize(0) != 32 && + publicType.typeParameters->getDimSize(0) != 64) { + error(loc, "expected 16, 32, or 64 bits for first type parameter", identifier.c_str(), ""); + } + } else { + if (publicType.typeParameters && publicType.typeParameters->getNumDims() != 0) { + error(loc, "unexpected type parameters", identifier.c_str(), ""); + } } if (voidErrorCheck(loc, identifier, type.getBasicType())) @@ -5148,6 +6357,25 @@ samplerCheck(loc, type, identifier, initializer); atomicUintCheck(loc, type, identifier); transparentOpaqueCheck(loc, type, identifier); +#ifdef NV_EXTENSIONS + accStructNVCheck(loc, type, identifier); +#endif + if (type.getQualifier().storage == EvqConst && type.containsBasicType(EbtReference)) { + error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", ""); + } + + if (type.getQualifier().storage != EvqUniform && type.getQualifier().storage != EvqBuffer) { + if (type.containsBasicType(EbtFloat16)) + requireFloat16Arithmetic(loc, "qualifier", "float16 types can only be in uniform block or buffer storage"); + if (type.contains16BitInt()) + requireInt16Arithmetic(loc, "qualifier", "(u)int16 types can only be in uniform block or buffer storage"); + if (type.contains8BitInt()) + requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage"); + } + + if (type.getQualifier().storage == EvqShared && + type.containsCoopMat()) + error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", ""); if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger)) error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", ""); @@ -5162,15 +6390,9 @@ inheritGlobalDefaults(type.getQualifier()); // Declare the variable - if (arraySizes || type.isArray()) { - // Arrayness is potentially coming both from the type and from the - // variable: "int[] a[];" or just one or the other. - // Merge it all to the type, so all arrayness is part of the type. - arrayDimCheck(loc, &type, arraySizes); - arrayDimMerge(type, arraySizes); - + if (type.isArray()) { // Check that implicit sizing is only where allowed. - arraySizesCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false); + arraySizesCheck(loc, type.getQualifier(), type.getArraySizes(), initializer, false); if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type)) declareArray(loc, identifier, type, symbol); @@ -5301,8 +6523,7 @@ } // Fix outer arrayness if variable is unsized, getting size from the initializer - if (initializer->getType().isExplicitlySizedArray() && - variable->getType().isImplicitlySizedArray()) + if (initializer->getType().isSizedArray() && variable->getType().isUnsizedArray()) variable->getWritableType().changeOuterArraySize(initializer->getType().getOuterArraySize()); // Inner arrayness can also get set by an initializer @@ -5311,8 +6532,10 @@ variable->getType().getArraySizes()->getNumDims()) { // adopt unsized sizes from the initializer's sizes for (int d = 1; d < variable->getType().getArraySizes()->getNumDims(); ++d) { - if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) - variable->getWritableType().getArraySizes().setDimSize(d, initializer->getType().getArraySizes()->getDimSize(d)); + if (variable->getType().getArraySizes()->getDimSize(d) == UnsizedArraySize) { + variable->getWritableType().getArraySizes()->setDimSize(d, + initializer->getType().getArraySizes()->getDimSize(d)); + } } } @@ -5423,16 +6646,16 @@ // Later on, initializer execution code will deal with array size logic. TType arrayType; arrayType.shallowCopy(type); // sharing struct stuff is fine - arrayType.newArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below + arrayType.copyArraySizes(*type.getArraySizes()); // but get a fresh copy of the array information, to edit below // edit array sizes to fill in unsized dimensions arrayType.changeOuterArraySize((int)initList->getSequence().size()); TIntermTyped* firstInit = initList->getSequence()[0]->getAsTyped(); if (arrayType.isArrayOfArrays() && firstInit->getType().isArray() && - arrayType.getArraySizes().getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) { - for (int d = 1; d < arrayType.getArraySizes().getNumDims(); ++d) { - if (arrayType.getArraySizes().getDimSize(d) == UnsizedArraySize) - arrayType.getArraySizes().setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1)); + arrayType.getArraySizes()->getNumDims() == firstInit->getType().getArraySizes()->getNumDims() + 1) { + for (int d = 1; d < arrayType.getArraySizes()->getNumDims(); ++d) { + if (arrayType.getArraySizes()->getDimSize(d) == UnsizedArraySize) + arrayType.getArraySizes()->setDimSize(d, firstInit->getType().getArraySizes()->getDimSize(d - 1)); } } @@ -5505,8 +6728,14 @@ // Combined texture-sampler constructors are completely semantic checked // in constructorTextureSamplerError() - if (op == EOpConstructTextureSampler) + if (op == EOpConstructTextureSampler) { + if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) { + // Transfer depth into the texture (SPIR-V image) type, as a hint + // for tools to know this texture/image is a depth image. + aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true; + } return intermediate.setAggregateOperator(aggrNode, op, type, loc); + } TTypeList::const_iterator memberTypes; if (op == EOpConstructStruct) @@ -5582,8 +6811,22 @@ // // Returns nullptr for an error or the constructed node. // -TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, bool subset) +TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, + bool subset) { + // If we are changing a matrix in both domain of basic type and to a non matrix, + // do the shape change first (by default, below, basic type is changed before shape). + // This avoids requesting a matrix of a new type that is going to be discarded anyway. + // TODO: This could be generalized to more type combinations, but that would require + // more extensive testing and full algorithm rework. For now, the need to do two changes makes + // the recursive call work, and avoids the most aggregious case of creating integer matrices. + if (node->getType().isMatrix() && (type.isScalar() || type.isVector()) && + type.isFloatingDomain() != node->getType().isFloatingDomain()) { + TType transitionType(node->getBasicType(), glslang::EvqTemporary, type.getVectorSize(), 0, 0, node->isVector()); + TOperator transitionOp = intermediate.mapTypeToConstructorOp(transitionType); + node = constructBuiltIn(transitionType, transitionOp, node, loc, false); + } + TIntermTyped* newNode; TOperator basicOp; @@ -5623,7 +6866,6 @@ basicOp = EOpConstructDouble; break; -#ifdef AMD_EXTENSIONS case EOpConstructF16Vec2: case EOpConstructF16Vec3: case EOpConstructF16Vec4: @@ -5639,7 +6881,34 @@ case EOpConstructFloat16: basicOp = EOpConstructFloat16; break; -#endif + + case EOpConstructI8Vec2: + case EOpConstructI8Vec3: + case EOpConstructI8Vec4: + case EOpConstructInt8: + basicOp = EOpConstructInt8; + break; + + case EOpConstructU8Vec2: + case EOpConstructU8Vec3: + case EOpConstructU8Vec4: + case EOpConstructUint8: + basicOp = EOpConstructUint8; + break; + + case EOpConstructI16Vec2: + case EOpConstructI16Vec3: + case EOpConstructI16Vec4: + case EOpConstructInt16: + basicOp = EOpConstructInt16; + break; + + case EOpConstructU16Vec2: + case EOpConstructU16Vec3: + case EOpConstructU16Vec4: + case EOpConstructUint16: + basicOp = EOpConstructUint16; + break; case EOpConstructIVec2: case EOpConstructIVec3: @@ -5662,29 +6931,18 @@ basicOp = EOpConstructInt64; break; + case EOpConstructUint64: + if (type.isScalar() && node->getType().getBasicType() == EbtReference) { + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUint64, true, node, type); + return newNode; + } + // fall through case EOpConstructU64Vec2: case EOpConstructU64Vec3: case EOpConstructU64Vec4: - case EOpConstructUint64: basicOp = EOpConstructUint64; break; -#ifdef AMD_EXTENSIONS - case EOpConstructI16Vec2: - case EOpConstructI16Vec3: - case EOpConstructI16Vec4: - case EOpConstructInt16: - basicOp = EOpConstructInt16; - break; - - case EOpConstructU16Vec2: - case EOpConstructU16Vec3: - case EOpConstructU16Vec4: - case EOpConstructUint16: - basicOp = EOpConstructUint16; - break; -#endif - case EOpConstructBVec2: case EOpConstructBVec3: case EOpConstructBVec4: @@ -5692,6 +6950,52 @@ basicOp = EOpConstructBool; break; + case EOpConstructNonuniform: + // Make a nonuniform copy of node + newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, node->getType()); + newNode->getWritableType().getQualifier().nonUniform = true; + return newNode; + + case EOpConstructReference: + // construct reference from reference + if (node->getType().getBasicType() == EbtReference) { + newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructReference, true, node, type); + return newNode; + // construct reference from uint64 + } else if (node->getType().isScalar() && node->getType().getBasicType() == EbtUint64) { + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToPtr, true, node, type); + return newNode; + } else { + return nullptr; + } + + case EOpConstructCooperativeMatrix: + if (!node->getType().isCoopMat()) { + if (type.getBasicType() != node->getType().getBasicType()) { + node = intermediate.addConversion(type.getBasicType(), node); + } + node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc()); + } else { + switch (type.getBasicType()) { + default: + assert(0); + break; + case EbtFloat: + assert(node->getType().getBasicType() == EbtFloat16); + node = intermediate.addUnaryNode(EOpConvFloat16ToFloat, node, node->getLoc(), type); + break; + case EbtFloat16: + assert(node->getType().getBasicType() == EbtFloat); + node = intermediate.addUnaryNode(EOpConvFloatToFloat16, node, node->getLoc(), type); + break; + } + // If it's a (non-specialization) constant, it must be folded. + if (node->getAsUnaryNode()->getOperand()->getAsConstantUnion()) + return node->getAsUnaryNode()->getOperand()->getAsConstantUnion()->fold(op, node->getType()); + } + + return node; + default: error(loc, "unsupported construction", "", ""); @@ -5736,13 +7040,14 @@ // // Do everything needed to add an interface block. // -void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes) +void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, + TArraySizes* arraySizes) { blockStageIoCheck(loc, currentBlockQualifier); blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr); - if (arraySizes) { - arraySizesCheck(loc, currentBlockQualifier, arraySizes, false, false); - arrayDimCheck(loc, arraySizes, 0); + if (arraySizes != nullptr) { + arraySizesCheck(loc, currentBlockQualifier, arraySizes, nullptr, false); + arrayOfArrayVersionCheck(loc, arraySizes); if (arraySizes->getNumDims() > 1) requireProfile(loc, ~EEsProfile, "array-of-array of block"); } @@ -5756,10 +7061,18 @@ if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal && memberQualifier.storage != currentBlockQualifier.storage) error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), ""); memberQualifier.storage = currentBlockQualifier.storage; +#ifdef NV_EXTENSIONS + if (currentBlockQualifier.perPrimitiveNV) + memberQualifier.perPrimitiveNV = currentBlockQualifier.perPrimitiveNV; + if (currentBlockQualifier.perViewNV) + memberQualifier.perViewNV = currentBlockQualifier.perViewNV; + if (currentBlockQualifier.perTaskNV) + memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV; +#endif if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary())) error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), ""); if (memberType.isArray()) - arraySizesCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1); + arraySizesCheck(memberLoc, currentBlockQualifier, memberType.getArraySizes(), nullptr, member == typeList.size() - 1); if (memberQualifier.hasOffset()) { if (spvVersion.spv == 0) { requireProfile(memberLoc, ~EEsProfile, "offset on block member"); @@ -5769,6 +7082,9 @@ if (memberType.containsOpaque()) error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), ""); + + if (memberType.containsCoopMat()) + error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), ""); } // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will @@ -5798,23 +7114,38 @@ // Special case for "push_constant uniform", which has a default of std430, // contrary to normal uniform defaults, and can't have a default tracked for it. - if (currentBlockQualifier.layoutPushConstant && !currentBlockQualifier.hasPacking()) + if ((currentBlockQualifier.layoutPushConstant && !currentBlockQualifier.hasPacking()) +#ifdef NV_EXTENSIONS + || (currentBlockQualifier.layoutShaderRecordNV && !currentBlockQualifier.hasPacking()) +#endif + ) currentBlockQualifier.layoutPacking = ElpStd430; +#ifdef NV_EXTENSIONS + // Special case for "taskNV in/out", which has a default of std430, + if (currentBlockQualifier.perTaskNV && !currentBlockQualifier.hasPacking()) + currentBlockQualifier.layoutPacking = ElpStd430; +#endif + // fix and check for member layout qualifiers mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true); // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts." if (currentBlockQualifier.hasAlign()) { - if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) { - error(loc, "can only be used with std140 or std430 layout packing", "align", ""); + if (defaultQualification.layoutPacking != ElpStd140 && + defaultQualification.layoutPacking != ElpStd430 && + defaultQualification.layoutPacking != ElpScalar) { + error(loc, "can only be used with std140, std430, or scalar layout packing", "align", ""); defaultQualification.layoutAlign = -1; } } bool memberWithLocation = false; bool memberWithoutLocation = false; +#ifdef NV_EXTENSIONS + bool memberWithPerViewQualifier = false; +#endif for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier& memberQualifier = typeList[member].type->getQualifier(); const TSourceLoc& memberLoc = typeList[member].loc; @@ -5854,9 +7185,17 @@ // "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts." // "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts." if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) { - if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) - error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", ""); + if (defaultQualification.layoutPacking != ElpStd140 && + defaultQualification.layoutPacking != ElpStd430 && + defaultQualification.layoutPacking != ElpScalar) + error(memberLoc, "can only be used with std140, std430, or scalar layout packing", "offset/align", ""); + } + +#ifdef NV_EXTENSIONS + if (memberQualifier.isPerView()) { + memberWithPerViewQualifier = true; } +#endif TQualifier newMemberQualification = defaultQualification; mergeQualifiers(memberLoc, newMemberQualification, memberQualifier, false); @@ -5865,13 +7204,31 @@ layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes); + // Ensure that the block has an XfbBuffer assigned. This is needed + // because if the block has a XfbOffset assigned, then it is + // assumed that it has implicitly assigned the current global + // XfbBuffer, and because it's members need to be assigned a + // XfbOffset if they lack it. + if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) { + if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset()) + currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + } + // Process the members fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); - fixBlockXfbOffsets(currentBlockQualifier, typeList); + fixXfbOffsets(currentBlockQualifier, typeList); fixBlockUniformOffsets(currentBlockQualifier, typeList); for (unsigned int member = 0; member < typeList.size(); ++member) layoutTypeCheck(typeList[member].loc, *typeList[member].type); +#ifdef NV_EXTENSIONS + if (memberWithPerViewQualifier) { + for (unsigned int member = 0; member < typeList.size(); ++member) { + resizeMeshViewDimension(typeList[member].loc, *typeList[member].type); + } + } +#endif + // reverse merge, so that currentBlockQualifier now has all layout information // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers) mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true); @@ -5881,37 +7238,63 @@ // TType blockType(&typeList, *blockName, currentBlockQualifier); - if (arraySizes) - blockType.newArraySizes(*arraySizes); + if (arraySizes != nullptr) + blockType.transferArraySizes(arraySizes); else ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); - // - // Don't make a user-defined type out of block name; that will cause an error - // if the same block name gets reused in a different interface. - // - // "Block names have no other use within a shader - // beyond interface matching; it is a compile-time error to use a block name at global scope for anything - // other than as a block name (e.g., use of a block name for a global variable name or function name is - // currently reserved)." - // - // Use the symbol table to prevent normal reuse of the block's name, as a variable entry, - // whose type is EbtBlock, but without all the structure; that will come from the type - // the instances point to. - // - TType blockNameType(EbtBlock, blockType.getQualifier().storage); - TVariable* blockNameVar = new TVariable(blockName, blockNameType); - if (! symbolTable.insert(*blockNameVar)) { - TSymbol* existingName = symbolTable.find(*blockName); - if (existingName->getType().getBasicType() == EbtBlock) { - if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) { - error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString()); - return; + if (currentBlockQualifier.layoutBufferReference) { + + if (currentBlockQualifier.storage != EvqBuffer) + error(loc, "can only be used with buffer", "buffer_reference", ""); + + // Create the block reference type. If it was forward-declared, detect that + // as a referent struct type with no members. Replace the referent type with + // blockType. + TType blockNameType(EbtReference, blockType, *blockName); + TVariable* blockNameVar = new TVariable(blockName, blockNameType, true); + if (! symbolTable.insert(*blockNameVar)) { + TSymbol* existingName = symbolTable.find(*blockName); + if (existingName->getType().getBasicType() == EbtReference && + existingName->getType().getReferentType()->getStruct() && + existingName->getType().getReferentType()->getStruct()->size() == 0 && + existingName->getType().getQualifier().storage == blockType.getQualifier().storage) { + existingName->getType().getReferentType()->deepCopy(blockType); + } else { + error(loc, "block name cannot be redefined", blockName->c_str(), ""); } - } else { - error(loc, "block name cannot redefine a non-block name", blockName->c_str(), ""); + } + if (!instanceName) { return; } + } else { + // + // Don't make a user-defined type out of block name; that will cause an error + // if the same block name gets reused in a different interface. + // + // "Block names have no other use within a shader + // beyond interface matching; it is a compile-time error to use a block name at global scope for anything + // other than as a block name (e.g., use of a block name for a global variable name or function name is + // currently reserved)." + // + // Use the symbol table to prevent normal reuse of the block's name, as a variable entry, + // whose type is EbtBlock, but without all the structure; that will come from the type + // the instances point to. + // + TType blockNameType(EbtBlock, blockType.getQualifier().storage); + TVariable* blockNameVar = new TVariable(blockName, blockNameType); + if (! symbolTable.insert(*blockNameVar)) { + TSymbol* existingName = symbolTable.find(*blockName); + if (existingName->getType().getBasicType() == EbtBlock) { + if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) { + error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString()); + return; + } + } else { + error(loc, "block name cannot redefine a non-block name", blockName->c_str(), ""); + return; + } + } } // Add the variable, as anonymous or named instanceName. @@ -5952,7 +7335,7 @@ profileRequires(loc, EEsProfile, 300, nullptr, "uniform block"); profileRequires(loc, ENoProfile, 140, nullptr, "uniform block"); if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant) - error(loc, "requires the 'buffer' storage qualifier", "std430", ""); + requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier"); break; case EvqBuffer: requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block"); @@ -5963,17 +7346,65 @@ profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "input block"); // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader // "Compute shaders do not permit user-defined input variables..." - requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|EShLangFragmentMask), "input block"); - if (language == EShLangFragment) + requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|EShLangFragmentMask +#ifdef NV_EXTENSIONS + |EShLangMeshNVMask +#endif + ), "input block"); + if (language == EShLangFragment) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); + } +#ifdef NV_EXTENSIONS + else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { + error(loc, "input blocks cannot be used in a mesh shader", "out", ""); + } +#endif break; case EvqVaryingOut: profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block"); - requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask), "output block"); + requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask +#ifdef NV_EXTENSIONS + |EShLangMeshNVMask|EShLangTaskNVMask +#endif + ), "output block"); // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins - if (language == EShLangVertex && ! parsingBuiltins) + if (language == EShLangVertex && ! parsingBuiltins) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block"); + } +#ifdef NV_EXTENSIONS + else if (language == EShLangMeshNV && qualifier.isTaskMemory()) { + error(loc, "can only use on input blocks in mesh shader", "taskNV", ""); + } + else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) { + error(loc, "output blocks cannot be used in a task shader", "out", ""); + } +#endif + break; +#ifdef NV_EXTENSIONS + case EvqPayloadNV: + profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), + "rayPayloadNV block"); + break; + case EvqPayloadInNV: + profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV block"); + requireStage(loc, (EShLanguageMask)(EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), + "rayPayloadInNV block"); + break; + case EvqHitAttrNV: + profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV block"); + requireStage(loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask), "hitAttributeNV block"); + break; + case EvqCallableDataNV: + profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), + "callableDataNV block"); + break; + case EvqCallableDataInNV: + profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV block"); + requireStage(loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV block"); break; +#endif default: error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), ""); break; @@ -6010,6 +7441,12 @@ error(loc, "cannot use invariant qualifier on an interface block", "invariant", ""); if (qualifier.layoutPushConstant) intermediate.addPushConstantCount(); +#ifdef NV_EXTENSIONS + if (qualifier.layoutShaderRecordNV) + intermediate.addShaderRecordNVCount(); + if (qualifier.perTaskNV) + intermediate.addTaskNVCount(); +#endif } // @@ -6049,13 +7486,14 @@ memberQualifier.layoutLocation = nextLocation; memberQualifier.layoutComponent = TQualifier::layoutComponentEnd; } - nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize(*typeList[member].type); + nextLocation = memberQualifier.layoutLocation + intermediate.computeTypeLocationSize( + *typeList[member].type, language); } } } } -void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList) +void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) { // "If a block is qualified with xfb_offset, all its // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any @@ -6068,13 +7506,25 @@ int nextOffset = qualifier.layoutXfbOffset; for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier& memberQualifier = typeList[member].type->getQualifier(); - bool containsDouble = false; - int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, containsDouble); + bool contains64BitType = false; +#ifdef AMD_EXTENSIONS + bool contains32BitType = false; + bool contains16BitType = false; + int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType); +#else + int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType); +#endif // see if we need to auto-assign an offset to this member if (! memberQualifier.hasXfbOffset()) { - // "if applied to an aggregate containing a double, the offset must also be a multiple of 8" - if (containsDouble) + // "if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8" + if (contains64BitType) RoundToPow2(nextOffset, 8); +#ifdef AMD_EXTENSIONS + else if (contains32BitType) + RoundToPow2(nextOffset, 4); + else if (contains16BitType) + RoundToPow2(nextOffset, 2); +#endif memberQualifier.layoutXfbOffset = nextOffset; } else nextOffset = memberQualifier.layoutXfbOffset; @@ -6094,9 +7544,9 @@ // void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList) { - if (! qualifier.isUniformOrBuffer()) + if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) return; - if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430) + if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar) return; int offset = 0; @@ -6110,8 +7560,8 @@ // modify just the children's view of matrix layout, if there is one for this member TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix; int dummyStride; - int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140, - subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor); + int memberAlignment = intermediate.getMemberAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking, + subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor); if (memberQualifier.hasOffset()) { // "The specified offset must be a multiple // of the base alignment of the type of the block member it qualifies, or a compile-time error results." @@ -6155,6 +7605,22 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qualifier, const TString& identifier) { TSymbol* symbol = symbolTable.find(identifier); + + // A forward declaration of a block reference looks to the grammar like adding + // a qualifier to an existing symbol. Detect this and create the block reference + // type with an empty type list, which will be filled in later in + // TParseContext::declareBlock. + if (!symbol && qualifier.layoutBufferReference) { + TTypeList typeList; + TType blockType(&typeList, identifier, qualifier);; + TType blockNameType(EbtReference, blockType, identifier); + TVariable* blockNameVar = new TVariable(&identifier, blockNameType, true); + if (! symbolTable.insert(*blockNameVar)) { + error(loc, "block name cannot redefine a non-block name", blockName->c_str(), ""); + } + return; + } + if (! symbol) { error(loc, "identifier not previously declared", identifier.c_str(), ""); return; @@ -6226,7 +7692,11 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType) { if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) { +#ifdef NV_EXTENSIONS + assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV); +#else assert(language == EShLangTessControl || language == EShLangGeometry); +#endif const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; if (publicType.qualifier.storage != EvqVaryingOut) @@ -6237,6 +7707,17 @@ if (language == EShLangTessControl) checkIoArraysConsistency(loc); } +#ifdef NV_EXTENSIONS + if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) { + assert(language == EShLangMeshNV); + const char* id = "max_primitives"; + + if (publicType.qualifier.storage != EvqVaryingOut) + error(loc, "can only apply to 'out'", id, ""); + if (! intermediate.setPrimitives(publicType.shaderQualifiers.primitives)) + error(loc, "cannot change previously set layout value", id, ""); + } +#endif if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) { if (publicType.qualifier.storage != EvqVaryingIn) error(loc, "can only apply to 'in'", "invocations", ""); @@ -6253,6 +7734,12 @@ case ElgTrianglesAdjacency: case ElgQuads: case ElgIsolines: +#ifdef NV_EXTENSIONS + if (language == EShLangMeshNV) { + error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + break; + } +#endif if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) { if (language == EShLangGeometry) checkIoArraysConsistency(loc); @@ -6264,6 +7751,15 @@ } } else if (publicType.qualifier.storage == EvqVaryingOut) { switch (publicType.shaderQualifiers.geometry) { +#ifdef NV_EXTENSIONS + case ElgLines: + case ElgTriangles: + if (language != EShLangMeshNV) { + error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + break; + } +#endif + // Fall through case ElgPoints: case ElgLineStrip: case ElgTriangleStrip: @@ -6303,14 +7799,41 @@ error(loc, "cannot change previously set size", "local_size", ""); else { int max = 0; - switch (i) { - case 0: max = resources.maxComputeWorkGroupSizeX; break; - case 1: max = resources.maxComputeWorkGroupSizeY; break; - case 2: max = resources.maxComputeWorkGroupSizeZ; break; - default: break; + if (language == EShLangCompute) { + switch (i) { + case 0: max = resources.maxComputeWorkGroupSizeX; break; + case 1: max = resources.maxComputeWorkGroupSizeY; break; + case 2: max = resources.maxComputeWorkGroupSizeZ; break; + default: break; + } + if (intermediate.getLocalSize(i) > (unsigned int)max) + error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", ""); + } +#ifdef NV_EXTENSIONS + else if (language == EShLangMeshNV) { + switch (i) { + case 0: max = resources.maxMeshWorkGroupSizeX_NV; break; + case 1: max = resources.maxMeshWorkGroupSizeY_NV; break; + case 2: max = resources.maxMeshWorkGroupSizeZ_NV; break; + default: break; + } + if (intermediate.getLocalSize(i) > (unsigned int)max) + error(loc, "too large; see gl_MaxMeshWorkGroupSizeNV", "local_size", ""); + } + else if (language == EShLangTaskNV) { + switch (i) { + case 0: max = resources.maxTaskWorkGroupSizeX_NV; break; + case 1: max = resources.maxTaskWorkGroupSizeY_NV; break; + case 2: max = resources.maxTaskWorkGroupSizeZ_NV; break; + default: break; + } + if (intermediate.getLocalSize(i) > (unsigned int)max) + error(loc, "too large; see gl_MaxTaskWorkGroupSizeNV", "local_size", ""); + } +#endif + else { + assert(0); } - if (intermediate.getLocalSize(i) > (unsigned int)max) - error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", ""); // Fix the existing constant gl_WorkGroupSize with this new information. TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize"); @@ -6349,6 +7872,44 @@ error(loc, "can only apply to 'out'", "blend equation", ""); } +#ifdef NV_EXTENSIONS + if (publicType.shaderQualifiers.layoutDerivativeGroupQuads && + publicType.shaderQualifiers.layoutDerivativeGroupLinear) { + error(loc, "cannot be both specified", "derivative_group_quadsNV and derivative_group_linearNV", ""); + } + + if (publicType.shaderQualifiers.layoutDerivativeGroupQuads) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if ((intermediate.getLocalSize(0) & 1) || + (intermediate.getLocalSize(1) & 1)) + error(loc, "requires local_size_x and local_size_y to be multiple of two", "derivative_group_quadsNV", ""); + else + intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupQuads); + } + else + error(loc, "can only apply to 'in'", "derivative_group_quadsNV", ""); + } + if (publicType.shaderQualifiers.layoutDerivativeGroupLinear) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if((intermediate.getLocalSize(0) * + intermediate.getLocalSize(1) * + intermediate.getLocalSize(2)) % 4 != 0) + error(loc, "requires total group size to be multiple of four", "derivative_group_linearNV", ""); + else + intermediate.setLayoutDerivativeMode(LayoutDerivativeGroupLinear); + } + else + error(loc, "can only apply to 'in'", "derivative_group_linearNV", ""); + } + // Check mesh out array sizes, once all the necessary out qualifiers are defined. + if ((language == EShLangMeshNV) && + (intermediate.getVertices() != TQualifier::layoutNotSet) && + (intermediate.getPrimitives() != TQualifier::layoutNotSet) && + (intermediate.getOutputPrimitive() != ElgNone)) + { + checkIoArraysConsistency(loc); + } +#endif const TQualifier& qualifier = publicType.qualifier; if (qualifier.isAuxiliary() || @@ -6402,8 +7963,14 @@ error(loc, "cannot declare a default, use a full declaration", "xfb_offset", ""); if (qualifier.layoutPushConstant) error(loc, "cannot declare a default, can only be used on a block", "push_constant", ""); + if (qualifier.layoutBufferReference) + error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", ""); if (qualifier.hasSpecConstantId()) error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", ""); +#ifdef NV_EXTENSIONS + if (qualifier.layoutShaderRecordNV) + error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", ""); +#endif } // @@ -6492,3 +8059,4 @@ } } // end namespace glslang + diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -44,13 +45,15 @@ #ifndef _PARSER_HELPER_INCLUDED_ #define _PARSER_HELPER_INCLUDED_ +#include +#include + #include "parseVersions.h" #include "../Include/ShHandle.h" #include "SymbolTable.h" #include "localintermediate.h" #include "Scan.h" -#include -#include +#include "attribute.h" namespace glslang { @@ -185,7 +188,7 @@ TParseContextBase& operator=(TParseContextBase&); const bool parsingBuiltins; // true if parsing built-in symbols/functions - TVector linkageSymbols; // these need to be transferred to 'linkage', after all editing is done + TVector linkageSymbols; // will be transferred to 'linkage', after all editing is done, order preserving TScanContext* scanContext; TPpContext* ppContext; TBuiltInResource resources; @@ -297,17 +300,17 @@ void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base); void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false); - int getIoArrayImplicitSize() const; + int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const; void checkIoArrayConsistency(const TSourceLoc&, int requiredSize, const char* feature, TType&, const TString&); TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode); TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field); - void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, const TString& field); + void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName); TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype); TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&); TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); - TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode& arguments, const TFunction& function); + TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode* arguments, const TFunction& function); void computeBuiltinPrecisions(TIntermTyped&, const TFunction&); TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*); void checkLocation(const TSourceLoc&, TOperator); @@ -321,6 +324,7 @@ TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&); void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier); void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier); + void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode); void assignError(const TSourceLoc&, const char* op, TString left, TString right); void unaryOpError(const TSourceLoc&, const char* op, TString operand); @@ -333,22 +337,21 @@ void globalCheck(const TSourceLoc&, const char* token); bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&); bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&); - void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&); + void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType); bool arrayQualifierError(const TSourceLoc&, const TQualifier&); bool arrayError(const TSourceLoc&, const TType&); void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); void structArrayCheck(const TSourceLoc&, const TType& structure); - void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, bool initializer, bool lastMember); - void arrayOfArrayVersionCheck(const TSourceLoc&); - void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2); - void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*); - void arrayDimMerge(TType& type, const TArraySizes* sizes); + void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, const TIntermTyped* initializer, bool lastMember); + void arrayOfArrayVersionCheck(const TSourceLoc&, const TArraySizes*); bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType); void boolCheck(const TSourceLoc&, const TIntermTyped*); void boolCheck(const TSourceLoc&, const TPublicType&); void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer); void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier); + void accStructNVCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); + void memberQualifierCheck(glslang::TPublicType&); void globalQualifierFixCheck(const TSourceLoc&, TQualifier&); void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&); bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType); @@ -361,12 +364,14 @@ bool containsFieldWithBasicType(const TType& type ,TBasicType basicType); TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&); void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes); - void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type); + void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type); void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type); void nestedBlockCheck(const TSourceLoc&); void nestedStructCheck(const TSourceLoc&); void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op); void opaqueCheck(const TSourceLoc&, const TType&, const char* op); + void referenceCheck(const TSourceLoc&, const TType&, const char* op); + void storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op); void specializationCheck(const TSourceLoc&, const TType&, const char* op); void structTypeCheck(const TSourceLoc&, TPublicType&); void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop); @@ -390,6 +395,7 @@ const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn); const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn); const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn); + const TFunction* findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn); void declareTypeDefaults(const TSourceLoc&, const TPublicType&); TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&); @@ -399,7 +405,7 @@ void blockStageIoCheck(const TSourceLoc&, const TQualifier&); void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); - void fixBlockXfbOffsets(TQualifier&, TTypeList&); + void fixXfbOffsets(TQualifier&, TTypeList&); void fixBlockUniformOffsets(TQualifier&, TTypeList&); void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier); void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); @@ -408,7 +414,19 @@ void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); - void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index); + TAttributeType attributeFromName(const TString& name) const; + TAttributes* makeAttributes(const TString& identifier) const; + TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const; + TAttributes* mergeAttributes(TAttributes*, TAttributes*) const; + + // Determine selection control from attributes + void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*); + void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*); + + // Determine loop control from attributes + void handleLoopAttributes(const TAttributes& attributes, TIntermNode*); + + void resizeMeshViewDimension(const TSourceLoc&, TType&); protected: void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); @@ -416,6 +434,8 @@ TVariable* makeInternalVariable(const char* name, const TType&) const; TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&); void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&); + void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&); + bool isRuntimeLength(const TIntermTyped&) const; TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); void finish() override; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,6 @@ // -// Copyright (C) 2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -77,17 +78,33 @@ virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); virtual void fullIntegerCheck(const TSourceLoc&, const char* op); virtual void doubleCheck(const TSourceLoc&, const char* op); -#ifdef AMD_EXTENSIONS - virtual void int16Check(const TSourceLoc& loc, const char* op, bool builtIn = false); virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); + virtual bool float16Arithmetic(); + virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); + virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); + virtual bool int16Arithmetic(); + virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); + virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false); + virtual bool int8Arithmetic(); + virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc); +#ifdef AMD_EXTENSIONS + virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false); #endif virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void spvRemoved(const TSourceLoc&, const char* op); virtual void vulkanRemoved(const TSourceLoc&, const char* op); virtual void requireVulkan(const TSourceLoc&, const char* op); virtual void requireSpv(const TSourceLoc&, const char* op); virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); + virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); + virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) = 0; @@ -113,6 +130,8 @@ bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } + bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } + bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } TInfoSink& infoSink; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/pch.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/pch.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/pch.cpp 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/pch.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,35 @@ +// +// Copyright (C) 2018 The Khronos Group Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "pch.h" diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/pch.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/pch.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/pch.h 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/pch.h 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,49 @@ +#ifndef _PCH_H +#define _PCH_H +// +// Copyright (C) 2018 The Khronos Group Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#include +#include +#include +#include +#include +#include +#include +#include +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "Scan.h" +#include "ScanContext.h" + +#endif /* _PCH_H */ diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -77,6 +78,7 @@ \****************************************************************************/ #include +#include #include "PpContext.h" @@ -91,6 +93,8 @@ for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++) elseSeen[elsetracker] = false; elsetracker = 0; + + strtodStream.imbue(std::locale::classic()); } TPpContext::~TPpContext() diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,6 @@ // // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -80,8 +81,10 @@ #include #include +#include #include "../ParseHelper.h" +#include "PpTokens.h" /* windows only pragma */ #ifdef _MSC_VER @@ -92,13 +95,16 @@ class TPpToken { public: - TPpToken() : space(false), i64val(0) + TPpToken() { clear(); } + void clear() { + space = false; + i64val = 0; loc.init(); name[0] = 0; } - // This is used for comparing macro definitions, so checks what is relevant for that. + // Used for comparing macro definitions, so checks what is relevant for that. bool operator==(const TPpToken& right) { return space == right.space && @@ -108,15 +114,17 @@ bool operator!=(const TPpToken& right) { return ! operator==(right); } TSourceLoc loc; - bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned - + // True if a space (for white space or a removed comment) should also be + // recognized, in front of the token returned: + bool space; + // Numeric value of the token: union { int ival; double dval; long long i64val; }; - - char name[MaxTokenLength + 1]; + // Text string of the token: + char name[MaxTokenLength + 1]; }; class TStringAtomMap { @@ -177,6 +185,13 @@ class TInputScanner; +enum MacroExpandResult { + MacroExpandNotStarted, // macro not expanded, which might not be an error + MacroExpandError, // a clear error occurred while expanding, no expansion + MacroExpandStarted, // macro expansion process has started + MacroExpandUndef // macro is undefined and will be expanded +}; + // This class is the result of turning a huge pile of C code communicating through globals // into a class. This was done to allowing instancing to attain thread safety. // Don't expect too much in terms of OO design. @@ -198,7 +213,8 @@ virtual int scan(TPpToken*) = 0; virtual int getch() = 0; virtual void ungetch() = 0; - virtual bool peekPasting() { return false; } // true when about to see ## + virtual bool peekPasting() { return false; } // true when about to see ## + virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define) virtual bool isMacroInput() { return false; } @@ -229,24 +245,79 @@ // From PpTokens.cpp // + // Capture the needed parts of a token stream for macro recording/playback. class TokenStream { public: - TokenStream() : current(0) { } + // Manage a stream of these 'Token', which capture the relevant parts + // of a TPpToken, plus its atom. + class Token { + public: + Token(int atom, const TPpToken& ppToken) : + atom(atom), + space(ppToken.space), + i64val(ppToken.i64val), + name(ppToken.name) { } + int get(TPpToken& ppToken) + { + ppToken.clear(); + ppToken.space = space; + ppToken.i64val = i64val; + snprintf(ppToken.name, sizeof(ppToken.name), "%s", name.c_str()); + return atom; + } + bool isAtom(int a) const { return atom == a; } + int getAtom() const { return atom; } + bool nonSpaced() const { return !space; } + protected: + Token() {} + int atom; + bool space; // did a space precede the token? + long long i64val; + TString name; + }; + + TokenStream() : currentPos(0) { } void putToken(int token, TPpToken* ppToken); + bool peekToken(int atom) { return !atEnd() && stream[currentPos].isAtom(atom); } + bool peekContinuedPasting(int atom) + { + // This is basically necessary because, for example, the PP + // tokenizer only accepts valid numeric-literals plus suffixes, so + // separates numeric-literals plus bad suffix into two tokens, which + // should get both pasted together as one token when token pasting. + // + // The following code is a bit more generalized than the above example. + if (!atEnd() && atom == PpAtomIdentifier && stream[currentPos].nonSpaced()) { + switch(stream[currentPos].getAtom()) { + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: + case PpAtomConstInt16: + case PpAtomConstUint16: + case PpAtomConstFloat: + case PpAtomConstDouble: + case PpAtomConstFloat16: + case PpAtomConstString: + case PpAtomIdentifier: + return true; + default: + break; + } + } + + return false; + } int getToken(TParseContextBase&, TPpToken*); - bool atEnd() { return current >= data.size(); } + bool atEnd() { return currentPos >= stream.size(); } bool peekTokenizedPasting(bool lastTokenPastes); bool peekUntokenizedPasting(); - void reset() { current = 0; } + void reset() { currentPos = 0; } protected: - void putSubtoken(char); - int getSubtoken(); - void ungetSubtoken(); - - TVector data; - size_t current; + TVector stream; + size_t currentPos; }; // @@ -254,12 +325,12 @@ // struct MacroSymbol { - MacroSymbol() : emptyArgs(0), busy(0), undef(0) { } + MacroSymbol() : functionLike(0), busy(0), undef(0) { } TVector args; TokenStream body; - unsigned emptyArgs : 1; - unsigned busy : 1; - unsigned undef : 1; + unsigned functionLike : 1; // 0 means object-like, 1 means function-like + unsigned busy : 1; + unsigned undef : 1; }; typedef TMap TSymbolMap; @@ -306,6 +377,10 @@ int getChar() { return inputStack.back()->getch(); } void ungetChar() { inputStack.back()->ungetch(); } bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); } + bool peekContinuedPasting(int a) + { + return !inputStack.empty() && inputStack.back()->peekContinuedPasting(a); + } bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); } bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); } @@ -330,6 +405,7 @@ virtual int getch() override { assert(0); return EndOfInput; } virtual void ungetch() override { assert(0); } bool peekPasting() override { return prepaste; } + bool peekContinuedPasting(int a) override { return mac->body.peekContinuedPasting(a); } bool endOfReplacementList() override { return mac->body.atEnd(); } bool isMacroInput() override { return true; } @@ -394,7 +470,7 @@ int readCPPline(TPpToken * ppToken); int scanHeaderName(TPpToken* ppToken, char delimit); TokenStream* PrescanMacroArg(TokenStream&, TPpToken*, bool newLineOkay); - int MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay); + MacroExpandResult MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay); // // From PpTokens.cpp @@ -404,14 +480,18 @@ class tTokenInput : public tInput { public: - tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { } + tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : + tInput(pp), + tokens(t), + lastTokenPastes(prepasting) { } virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); } virtual int getch() override { assert(0); return EndOfInput; } virtual void ungetch() override { assert(0); } virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); } + bool peekContinuedPasting(int a) override { return tokens->peekContinuedPasting(a); } protected: TokenStream* tokens; - bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token + bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token }; class tUngotTokenInput : public tInput { @@ -520,7 +600,7 @@ prologue_(prologue), epilogue_(epilogue), includedFile_(includedFile), - scanner(3, strings, lengths, names, 0, 0, true), + scanner(3, strings, lengths, nullptr, 0, 0, true), prevScanner(nullptr), stringInput(pp, scanner) { @@ -535,9 +615,9 @@ scanner.setLine(startLoc.line); scanner.setString(startLoc.string); - scanner.setFile(startLoc.name, 0); - scanner.setFile(startLoc.name, 1); - scanner.setFile(startLoc.name, 2); + scanner.setFile(startLoc.getFilenameStr(), 0); + scanner.setFile(startLoc.getFilenameStr(), 1); + scanner.setFile(startLoc.getFilenameStr(), 2); } // tInput methods: @@ -577,8 +657,6 @@ const char* strings[3]; // Length of str_, passed to scanner constructor. size_t lengths[3]; - // String names - const char* names[3]; // Scans over str_. TInputScanner scanner; // The previous effective scanner before the scanner in this instance @@ -615,6 +693,8 @@ std::string rootFileName; std::stack includeStack; std::string currentSourceFile; + + std::istringstream strtodStream; }; } // end namespace glslang diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -109,11 +110,12 @@ // save the macro name const int defAtom = atomStrings.getAddAtom(ppToken->name); + TSourceLoc defineLoc = ppToken->loc; // because ppToken might go to the next line before we report errors // gather parameters to the macro, between (...) token = scanToken(ppToken); - if (token == '(' && ! ppToken->space) { - mac.emptyArgs = 1; + if (token == '(' && !ppToken->space) { + mac.functionLike = 1; do { token = scanToken(ppToken); if (mac.args.size() == 0 && token == ')') @@ -123,7 +125,6 @@ return token; } - mac.emptyArgs = 0; const int argAtom = atomStrings.getAddAtom(ppToken->name); // check for duplication of parameter name @@ -146,10 +147,13 @@ } token = scanToken(ppToken); + } else if (token != '\n' && token != EndOfInput && !ppToken->space) { + parseContext.ppWarn(ppToken->loc, "missing space after macro name", "#define", ""); + + return token; } // record the definition of the macro - TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors while (token != '\n' && token != EndOfInput) { mac.body.putToken(token, ppToken); token = scanToken(ppToken); @@ -162,27 +166,43 @@ if (existing != nullptr) { if (! existing->undef) { // Already defined -- need to make sure they are identical: - // "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number, - // ordering, spelling, and white-space separation, where all white-space separations are considered identical." - if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs) - parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom)); - else { - if (existing->args != mac.args) - parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom)); + // "Two replacement lists are identical if and only if the + // preprocessing tokens in both have the same number, + // ordering, spelling, and white-space separation, where all + // white-space separations are considered identical." + if (existing->functionLike != mac.functionLike) { + parseContext.ppError(defineLoc, "Macro redefined; function-like versus object-like:", "#define", + atomStrings.getString(defAtom)); + } else if (existing->args.size() != mac.args.size()) { + parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", + atomStrings.getString(defAtom)); + } else { + if (existing->args != mac.args) { + parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", + atomStrings.getString(defAtom)); + } + // set up to compare the two existing->body.reset(); mac.body.reset(); int newToken; + bool firstToken = true; do { int oldToken; TPpToken oldPpToken; TPpToken newPpToken; oldToken = existing->body.getToken(parseContext, &oldPpToken); newToken = mac.body.getToken(parseContext, &newPpToken); + // for the first token, preceding spaces don't matter + if (firstToken) { + newPpToken.space = oldPpToken.space; + firstToken = false; + } if (oldToken != newToken || oldPpToken != newPpToken) { - parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom)); + parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", + atomStrings.getString(defAtom)); break; } - } while (newToken > 0); + } while (newToken != EndOfInput); } } *existing = mac; @@ -515,15 +535,16 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken) { while (token == PpAtomIdentifier && strcmp("defined", ppToken->name) != 0) { - int macroReturn = MacroExpand(ppToken, true, false); - if (macroReturn == 0) { + switch (MacroExpand(ppToken, true, false)) { + case MacroExpandNotStarted: + case MacroExpandError: parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", ""); err = true; res = 0; - token = scanToken(ppToken); break; - } - if (macroReturn == -1) { + case MacroExpandStarted: + break; + case MacroExpandUndef: if (! shortCircuit && parseContext.profile == EEsProfile) { const char* message = "undefined macro in expression not allowed in es profile"; if (parseContext.relaxedErrors()) @@ -531,8 +552,11 @@ else parseContext.ppError(ppToken->loc, message, "preprocessor evaluation", ppToken->name); } + break; } token = scanToken(ppToken); + if (err) + break; } return token; @@ -647,6 +671,7 @@ epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n"; pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this)); + parseContext.intermediate.addIncludeText(res->headerName.c_str(), res->headerData, res->headerLength); // There's no "current" location anymore. parseContext.setCurrentColumn(0); } else { @@ -731,12 +756,10 @@ TSourceLoc loc = ppToken->loc; while (token != '\n' && token != EndOfInput) { - if (token == PpAtomConstInt || token == PpAtomConstUint || + if (token == PpAtomConstInt16 || token == PpAtomConstUint16 || + token == PpAtomConstInt || token == PpAtomConstUint || token == PpAtomConstInt64 || token == PpAtomConstUint64 || -#ifdef AMD_EXTENSIONS - token == PpAtomConstInt16 || token == PpAtomConstUint16 || token == PpAtomConstFloat16 || -#endif token == PpAtomConstFloat || token == PpAtomConstDouble) { message.append(ppToken->name); } else if (token == PpAtomIdentifier || token == PpAtomConstString) { @@ -775,9 +798,7 @@ #endif case PpAtomConstFloat: case PpAtomConstDouble: -#ifdef AMD_EXTENSIONS case PpAtomConstFloat16: -#endif tokens.push_back(ppToken->name); break; default: @@ -859,8 +880,7 @@ if (token != PpAtomIdentifier) parseContext.ppError(ppToken->loc, "extension name expected", "#extension", ""); - assert(strlen(ppToken->name) <= MaxTokenLength); - strcpy(extensionName, ppToken->name); + snprintf(extensionName, sizeof(extensionName), "%s", ppToken->name); token = scanToken(ppToken); if (token != ':') { @@ -1015,20 +1035,29 @@ int token; while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) { token = tokenPaste(token, *ppToken); + if (token == PpAtomIdentifier) { + switch (MacroExpand(ppToken, false, newLineOkay)) { + case MacroExpandNotStarted: + break; + case MacroExpandError: + // toss the rest of the pushed-input argument by scanning until tMarkerInput + while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) + ; + break; + case MacroExpandStarted: + case MacroExpandUndef: + continue; + } + } if (token == tMarkerInput::marker || token == EndOfInput) break; - if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0) - continue; expandedArg->putToken(token, ppToken); } - if (token == EndOfInput) { - // MacroExpand ate the marker, so had bad input, recover + if (token != tMarkerInput::marker) { + // Error, or MacroExpand ate the marker, so had bad input, recover delete expandedArg; expandedArg = nullptr; - } else { - // remove the marker - popInput(); } return expandedArg; @@ -1110,7 +1139,8 @@ if (done) return EndOfInput; - strcpy(ppToken->name, "0"); + ppToken->name[0] = '0'; + ppToken->name[1] = 0; ppToken->ival = 0; ppToken->space = false; done = true; @@ -1119,14 +1149,18 @@ } // -// Check a token to see if it is a macro that should be expanded. -// If it is, and defined, push a tInput that will produce the appropriate expansion -// and return 1. -// If it is, but undefined, and expandUndef is requested, push a tInput that will -// expand to 0 and return -1. -// Otherwise, return 0 to indicate no expansion, which is not necessarily an error. +// Check a token to see if it is a macro that should be expanded: +// - If it is, and defined, push a tInput that will produce the appropriate +// expansion and return MacroExpandStarted. +// - If it is, but undefined, and expandUndef is requested, push a tInput +// that will expand to 0 and return MacroExpandUndef. +// - Otherwise, there is no expansion, and there are two cases: +// * It might be okay there is no expansion, and no specific error was +// detected. Returns MacroExpandNotStarted. +// * The expansion was started, but could not be completed, due to an error +// that cannot be recovered from. Returns MacroExpandError. // -int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay) +MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay) { ppToken->space = false; int macroAtom = atomStrings.getAtom(ppToken->name); @@ -1135,7 +1169,7 @@ ppToken->ival = parseContext.getCurrentLoc().line; snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival); UngetToken(PpAtomConstInt, ppToken); - return 1; + return MacroExpandStarted; case PpAtomFileMacro: { if (parseContext.getCurrentLoc().name) @@ -1143,50 +1177,55 @@ ppToken->ival = parseContext.getCurrentLoc().string; snprintf(ppToken->name, sizeof(ppToken->name), "%s", ppToken->loc.getStringNameOrNum().c_str()); UngetToken(PpAtomConstInt, ppToken); - return 1; + return MacroExpandStarted; } case PpAtomVersionMacro: ppToken->ival = parseContext.version; snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival); UngetToken(PpAtomConstInt, ppToken); - return 1; + return MacroExpandStarted; default: break; } MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom); - int depth = 0; // no recursive expansions if (macro != nullptr && macro->busy) - return 0; + return MacroExpandNotStarted; // not expanding undefined macros if ((macro == nullptr || macro->undef) && ! expandUndef) - return 0; + return MacroExpandNotStarted; // 0 is the value of an undefined macro if ((macro == nullptr || macro->undef) && expandUndef) { pushInput(new tZeroInput(this)); - return -1; + return MacroExpandUndef; } tMacroInput *in = new tMacroInput(this); TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error in->mac = macro; - if (macro->args.size() > 0 || macro->emptyArgs) { - int token = scanToken(ppToken); + if (macro->functionLike) { + // We don't know yet if this will be a successful call of a + // function-like macro; need to look for a '(', but without trashing + // the passed in ppToken, until we know we are no longer speculative. + TPpToken parenToken; + int token = scanToken(&parenToken); if (newLineOkay) { while (token == '\n') - token = scanToken(ppToken); + token = scanToken(&parenToken); } if (token != '(') { - UngetToken(token, ppToken); + // Function-like macro called with object-like syntax: okay, don't expand. + // (We ate exactly one token that might not be white space; put it back. + UngetToken(token, &parenToken); delete in; - return 0; + return MacroExpandNotStarted; } in->args.resize(in->mac->args.size()); for (size_t i = 0; i < in->mac->args.size(); i++) @@ -1197,63 +1236,70 @@ size_t arg = 0; bool tokenRecorded = false; do { - depth = 0; - while (1) { + TVector nestStack; + while (true) { token = scanToken(ppToken); if (token == EndOfInput || token == tMarkerInput::marker) { parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom)); delete in; - return 0; + return MacroExpandError; } if (token == '\n') { if (! newLineOkay) { parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom)); delete in; - return 0; + return MacroExpandError; } continue; } if (token == '#') { parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom)); delete in; - return 0; + return MacroExpandError; } if (in->mac->args.size() == 0 && token != ')') break; - if (depth == 0 && (token == ',' || token == ')')) + if (nestStack.size() == 0 && (token == ',' || token == ')')) break; if (token == '(') - depth++; - if (token == ')') - depth--; + nestStack.push_back(')'); + else if (token == '{' && parseContext.isReadingHLSL()) + nestStack.push_back('}'); + else if (nestStack.size() > 0 && token == nestStack.back()) + nestStack.pop_back(); in->args[arg]->putToken(token, ppToken); tokenRecorded = true; } + // end of single argument scan + if (token == ')') { - if (in->mac->args.size() == 1 && tokenRecorded == 0) + // closing paren of call + if (in->mac->args.size() == 1 && !tokenRecorded) break; arg++; break; } arg++; } while (arg < in->mac->args.size()); + // end of all arguments scan if (arg < in->mac->args.size()) parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom)); else if (token != ')') { - depth=0; + // Error recover code; find end of call, if possible + int depth = 0; while (token != EndOfInput && (depth > 0 || token != ')')) { - if (token == ')') + if (token == ')' || token == '}') depth--; token = scanToken(ppToken); - if (token == '(') + if (token == '(' || token == '{') depth++; } if (token == EndOfInput) { parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom)); delete in; - return 0; + return MacroExpandError; } parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom)); } @@ -1268,7 +1314,7 @@ macro->busy = 1; macro->body.reset(); - return 1; + return MacroExpandStarted; } } // end namespace glslang diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,9 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. +// // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -93,42 +96,54 @@ /////////////////////////////////// Floating point constants: ///////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// -/* -* lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner -* has seen at least one digit, followed by either a decimal '.' or the -* letter 'e', or a precision ending (e.g., F or LF). -*/ - +// +// Scan a single- or double-precision floating point constant. +// Assumes that the scanner has seen at least one digit, +// followed by either a decimal '.' or the letter 'e', or a +// precision ending (e.g., F or LF). +// +// This is technically not correct, as the preprocessor should just +// accept the numeric literal along with whatever suffix it has, but +// currently, it stops on seeing a bad suffix, treating that as the +// next token. This effects things like token pasting, where it is +// relevant how many tokens something was broken into. +// +// See peekContinuedPasting(). int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) { - bool HasDecimalOrExponent = false; - int isDouble = 0; - bool generateFloat16 = false; - bool acceptFloat16 = parseContext.intermediate.getSource() == EShSourceHlsl; - bool isFloat16 = false; - bool requireHF = false; -#ifdef AMD_EXTENSIONS - if (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float)) { - acceptFloat16 = true; - generateFloat16 = true; - requireHF = true; - } -#endif - const auto saveName = [&](int ch) { if (len <= MaxTokenLength) ppToken->name[len++] = static_cast(ch); }; - // Decimal: + // find the range of non-zero digits before the decimal point + int startNonZero = 0; + while (startNonZero < len && ppToken->name[startNonZero] == '0') + ++startNonZero; + int endNonZero = len; + while (endNonZero > startNonZero && ppToken->name[endNonZero-1] == '0') + --endNonZero; + int numWholeNumberDigits = endNonZero - startNonZero; + + // accumulate the range's value + bool fastPath = numWholeNumberDigits <= 15; // when the number gets too complex, set to false + unsigned long long wholeNumber = 0; + if (fastPath) { + for (int i = startNonZero; i < endNonZero; ++i) + wholeNumber = wholeNumber * 10 + (ppToken->name[i] - '0'); + } + int decimalShift = len - endNonZero; + // Decimal point: + bool hasDecimalOrExponent = false; if (ch == '.') { - HasDecimalOrExponent = true; + hasDecimalOrExponent = true; saveName(ch); ch = getChar(); + int firstDecimal = len; // 1.#INF or -1.#INF - if (parseContext.intermediate.getSource() == EShSourceHlsl && ch == '#') { + if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) { if ((len < 2) || (len == 2 && ppToken->name[0] != '1') || (len == 3 && ppToken->name[1] != '1' && !(ppToken->name[0] == '-' || ppToken->name[0] == '+')) || @@ -155,55 +170,118 @@ } } + // Consume leading-zero digits after the decimal point + while (ch == '0') { + saveName(ch); + ch = getChar(); + } + int startNonZeroDecimal = len; + int endNonZeroDecimal = len; + + // Consume remaining digits, up to the exponent while (ch >= '0' && ch <= '9') { saveName(ch); + if (ch != '0') + endNonZeroDecimal = len; ch = getChar(); } + + // Compute accumulation up to the last non-zero digit + if (endNonZeroDecimal > startNonZeroDecimal) { + numWholeNumberDigits += endNonZeroDecimal - endNonZero - 1; // don't include the "." + if (numWholeNumberDigits > 15) + fastPath = false; + if (fastPath) { + for (int i = endNonZero; i < endNonZeroDecimal; ++i) { + if (ppToken->name[i] != '.') + wholeNumber = wholeNumber * 10 + (ppToken->name[i] - '0'); + } + } + decimalShift = firstDecimal - endNonZeroDecimal; + } } // Exponent: - - if (ch == 'e' || ch == 'E') { - HasDecimalOrExponent = true; - saveName(ch); - ch = getChar(); - if (ch == '+' || ch == '-') { + bool negativeExponent = false; + double exponentValue = 0.0; + int exponent = 0; + { + if (ch == 'e' || ch == 'E') { + hasDecimalOrExponent = true; saveName(ch); ch = getChar(); - } - if (ch >= '0' && ch <= '9') { - while (ch >= '0' && ch <= '9') { + if (ch == '+' || ch == '-') { + negativeExponent = ch == '-'; saveName(ch); ch = getChar(); } - } else { - parseContext.ppError(ppToken->loc, "bad character in float exponent", "", ""); + if (ch >= '0' && ch <= '9') { + while (ch >= '0' && ch <= '9') { + exponent = exponent * 10 + (ch - '0'); + saveName(ch); + ch = getChar(); + } + } else { + parseContext.ppError(ppToken->loc, "bad character in float exponent", "", ""); + } + } + + // Compensate for location of decimal + if (negativeExponent) + exponent -= decimalShift; + else { + exponent += decimalShift; + if (exponent < 0) { + negativeExponent = true; + exponent = -exponent; + } + } + if (exponent > 22) + fastPath = false; + + if (fastPath) { + // Compute the floating-point value of the exponent + exponentValue = 1.0; + if (exponent > 0) { + double expFactor = 10; + while (exponent > 0) { + if (exponent & 0x1) + exponentValue *= expFactor; + expFactor *= expFactor; + exponent >>= 1; + } + } } } // Suffix: - + bool isDouble = false; + bool isFloat16 = false; if (ch == 'l' || ch == 'L') { - parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); - if (! HasDecimalOrExponent) + if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) + parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); + if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); - int ch2 = getChar(); - if (ch2 != 'f' && ch2 != 'F') { - ungetChar(); - ungetChar(); - } else { + if (parseContext.intermediate.getSource() == EShSourceGlsl) { + int ch2 = getChar(); + if (ch2 != 'f' && ch2 != 'F') { + ungetChar(); + ungetChar(); + } else { + saveName(ch); + saveName(ch2); + isDouble = true; + } + } else if (parseContext.intermediate.getSource() == EShSourceHlsl) { saveName(ch); - saveName(ch2); - isDouble = 1; + isDouble = true; } - } else if (acceptFloat16 && (ch == 'h' || ch == 'H')) { -#ifdef AMD_EXTENSIONS - if (generateFloat16) + } else if (ch == 'h' || ch == 'H') { + if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) parseContext.float16Check(ppToken->loc, "half floating-point suffix"); -#endif - if (!HasDecimalOrExponent) + if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); - if (requireHF) { + if (parseContext.intermediate.getSource() == EShSourceGlsl) { int ch2 = getChar(); if (ch2 != 'f' && ch2 != 'F') { ungetChar(); @@ -211,23 +289,24 @@ } else { saveName(ch); saveName(ch2); - isFloat16 = generateFloat16; + isFloat16 = true; } - } else { + } else if (parseContext.intermediate.getSource() == EShSourceHlsl) { saveName(ch); - isFloat16 = generateFloat16; + isFloat16 = true; } } else if (ch == 'f' || ch == 'F') { - parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); - if (! parseContext.relaxedErrors()) + if (ifdepth == 0) + parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); + if (ifdepth == 0 && !parseContext.relaxedErrors()) parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix"); - if (! HasDecimalOrExponent) + if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); saveName(ch); } else ungetChar(); - // Patch up the name, length, etc. + // Patch up the name and length for overflow if (len > MaxTokenLength) { len = MaxTokenLength; @@ -235,8 +314,45 @@ } ppToken->name[len] = '\0'; - // Get the numerical value - ppToken->dval = strtod(ppToken->name, nullptr); + // Compute the numerical value + if (fastPath) { + // compute the floating-point value of the exponent + if (exponentValue == 0.0) + ppToken->dval = (double)wholeNumber; + else if (negativeExponent) + ppToken->dval = (double)wholeNumber / exponentValue; + else + ppToken->dval = (double)wholeNumber * exponentValue; + } else { + // slow path + ppToken->dval = 0.0; + + // remove suffix + TString numstr(ppToken->name); + if (numstr.back() == 'f' || numstr.back() == 'F') + numstr.pop_back(); + if (numstr.back() == 'h' || numstr.back() == 'H') + numstr.pop_back(); + if (numstr.back() == 'l' || numstr.back() == 'L') + numstr.pop_back(); + + // use platform library + strtodStream.clear(); + strtodStream.str(numstr.c_str()); + strtodStream >> ppToken->dval; + if (strtodStream.fail()) { + // Assume failure combined with a large exponent was overflow, in + // an attempt to set INF. + if (!negativeExponent && exponent + numWholeNumberDigits > 300) + ppToken->i64val = 0x7ff0000000000000; // +Infinity + // Assume failure combined with a small exponent was overflow. + if (negativeExponent && exponent + numWholeNumberDigits > 300) + ppToken->dval = 0.0; + // Unknown reason for failure. Theory is that either + // - the 0.0 is still there, or + // - something reasonable was written that is better than 0.0 + } + } // Return the right token type if (isDouble) @@ -326,6 +442,14 @@ // // Scanner used to tokenize source stream. // +// N.B. Invalid numeric suffixes are not consumed.// +// This is technically not correct, as the preprocessor should just +// accept the numeric literal along with whatever suffix it has, but +// currently, it stops on seeing a bad suffix, treating that as the +// next token. This effects things like token pasting, where it is +// relevant how many tokens something was broken into. +// See peekContinuedPasting(). +// int TPpContext::tStringInput::scan(TPpToken* ppToken) { int AlreadyComplained = 0; @@ -333,19 +457,23 @@ int ch = 0; int ii = 0; unsigned long long ival = 0; - bool enableInt64 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64); -#ifdef AMD_EXTENSIONS - bool enableInt16 = pp->parseContext.version >= 450 && pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16); -#endif - bool acceptHalf = pp->parseContext.intermediate.getSource() == EShSourceHlsl; -#ifdef AMD_EXTENSIONS - if (pp->parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float)) - acceptHalf = true; -#endif - const auto floatingPointChar = [&](int ch) { return ch == '.' || ch == 'e' || ch == 'E' || ch == 'f' || ch == 'F' || - (acceptHalf && (ch == 'h' || ch == 'H')); }; + ch == 'h' || ch == 'H'; }; + + static const char* const Int64_Extensions[] = { + E_GL_ARB_gpu_shader_int64, + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int64 }; + static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]); + + static const char* const Int16_Extensions[] = { +#ifdef AMD_EXTENSIONS + E_GL_AMD_gpu_shader_int16, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int16 }; + static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]); ppToken->ival = 0; ppToken->i64val = 0; @@ -409,9 +537,7 @@ bool isUnsigned = false; bool isInt64 = false; -#ifdef AMD_EXTENSIONS bool isInt16 = false; -#endif ppToken->name[len++] = (char)ch; ch = getch(); if ((ch >= '0' && ch <= '9') || @@ -420,7 +546,7 @@ ival = 0; do { - if (len < MaxTokenLength && (ival <= 0x0fffffffu || (enableInt64 && ival <= 0x0fffffffffffffffull))) { + if (len < MaxTokenLength && ival <= 0x0fffffffffffffffull) { ppToken->name[len++] = (char)ch; if (ch >= '0' && ch <= '9') { ii = ch - '0'; @@ -453,33 +579,31 @@ ppToken->name[len++] = (char)ch; isUnsigned = true; - if (enableInt64) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt64 = true; - } else - ungetch(); - } + int nextCh = getch(); + if (nextCh == 'l' || nextCh == 'L') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); #ifdef AMD_EXTENSIONS - if (enableInt16) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt16 = true; - } else - ungetch(); - } + nextCh = getch(); + if ((nextCh == 's' || nextCh == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); #endif - } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; #ifdef AMD_EXTENSIONS - } else if (enableInt16 && (ch == 's' || ch == 'S')) { + } else if ((ch == 's' || ch == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt16 = true; @@ -488,15 +612,29 @@ ungetch(); ppToken->name[len] = '\0'; - if (isInt64) { + if (isInt64 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (pp->ifdepth == 0) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit hexadecimal literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int64_Extensions, Int64_Extensions, "64-bit hexadecimal literal"); + } ppToken->i64val = ival; return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; -#ifdef AMD_EXTENSIONS } else if (isInt16) { + if (pp->ifdepth == 0) { + if (pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "16-bit hexadecimal literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int16_Extensions, Int16_Extensions, "16-bit hexadecimal literal"); + } + } ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; -#endif } else { + if (ival > 0xffffffffu && !AlreadyComplained) + pp->parseContext.ppError(ppToken->loc, "hexadecimal literal too big", "", ""); ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint : PpAtomConstInt; } @@ -505,9 +643,7 @@ bool isUnsigned = false; bool isInt64 = false; -#ifdef AMD_EXTENSIONS bool isInt16 = false; -#endif bool octalOverflow = false; bool nonOctal = false; ival = 0; @@ -520,7 +656,7 @@ pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", ""); AlreadyComplained = 1; } - if (ival <= 0x1fffffffu || (enableInt64 && ival <= 0x1fffffffffffffffull)) { + if (ival <= 0x1fffffffffffffffull) { ii = ch - '0'; ival = (ival << 3) | ii; } else @@ -553,33 +689,31 @@ ppToken->name[len++] = (char)ch; isUnsigned = true; - if (enableInt64) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt64 = true; - } else - ungetch(); - } + int nextCh = getch(); + if (nextCh == 'l' || nextCh == 'L') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); #ifdef AMD_EXTENSIONS - if (enableInt16) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt16 = true; - } else - ungetch(); - } + nextCh = getch(); + if ((nextCh == 's' || nextCh == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); #endif - } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; #ifdef AMD_EXTENSIONS - } else if (enableInt16 && (ch == 's' || ch == 'S')) { + } else if ((ch == 's' || ch == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt16 = true; @@ -588,17 +722,32 @@ ungetch(); ppToken->name[len] = '\0'; + if (!isInt64 && ival > 0xffffffffu) + octalOverflow = true; + if (octalOverflow) pp->parseContext.ppError(ppToken->loc, "octal literal too big", "", ""); - if (isInt64) { + if (isInt64 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (pp->ifdepth == 0) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit octal literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int64_Extensions, Int64_Extensions, "64-bit octal literal"); + } ppToken->i64val = ival; return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; -#ifdef AMD_EXTENSIONS } else if (isInt16) { + if (pp->ifdepth == 0) { + if (pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "16-bit octal literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int16_Extensions, Int16_Extensions, "16-bit octal literal"); + } + } ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; -#endif } else { ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint : PpAtomConstInt; @@ -625,41 +774,37 @@ int numericLen = len; bool isUnsigned = false; bool isInt64 = false; -#ifdef AMD_EXTENSIONS bool isInt16 = false; -#endif if (ch == 'u' || ch == 'U') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isUnsigned = true; - if (enableInt64) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 'l') || (ch == 'U' && nextCh == 'L')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt64 = true; - } else - ungetch(); - } + int nextCh = getch(); + if (nextCh == 'l' || nextCh == 'L') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); #ifdef AMD_EXTENSIONS - if (enableInt16) { - int nextCh = getch(); - if ((ch == 'u' && nextCh == 's') || (ch == 'U' && nextCh == 'S')) { - if (len < MaxTokenLength) - ppToken->name[len++] = (char)nextCh; - isInt16 = true; - } else - ungetch(); - } + nextCh = getch(); + if ((nextCh == 's' || nextCh == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); #endif - } else if (enableInt64 && (ch == 'l' || ch == 'L')) { + } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; #ifdef AMD_EXTENSIONS - } else if (enableInt16 && (ch == 's' || ch == 'S')) { + } else if ((ch == 's' || ch == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt16 = true; @@ -673,19 +818,15 @@ const unsigned remainderMaxInt = 0xFFFFFFFFu - 10 * oneTenthMaxInt; const unsigned long long oneTenthMaxInt64 = 0xFFFFFFFFFFFFFFFFull / 10; const unsigned long long remainderMaxInt64 = 0xFFFFFFFFFFFFFFFFull - 10 * oneTenthMaxInt64; -#ifdef AMD_EXTENSIONS const unsigned short oneTenthMaxInt16 = 0xFFFFu / 10; const unsigned short remainderMaxInt16 = 0xFFFFu - 10 * oneTenthMaxInt16; -#endif for (int i = 0; i < numericLen; i++) { ch = ppToken->name[i] - '0'; bool overflow = false; if (isInt64) overflow = (ival > oneTenthMaxInt64 || (ival == oneTenthMaxInt64 && (unsigned long long)ch > remainderMaxInt64)); -#ifdef AMD_EXTENSIONS else if (isInt16) overflow = (ival > oneTenthMaxInt16 || (ival == oneTenthMaxInt16 && (unsigned short)ch > remainderMaxInt16)); -#endif else overflow = (ival > oneTenthMaxInt || (ival == oneTenthMaxInt && (unsigned)ch > remainderMaxInt)); if (overflow) { @@ -696,14 +837,24 @@ ival = ival * 10 + ch; } - if (isInt64) { + if (isInt64 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (pp->ifdepth == 0) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int64_Extensions, Int64_Extensions, "64-bit literal"); + } ppToken->i64val = ival; return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; -#ifdef AMD_EXTENSIONS } else if (isInt16) { + if (pp->ifdepth == 0 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "16-bit literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int16_Extensions, Int16_Extensions, "16-bit literal"); + } ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; -#endif } else { ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint : PpAtomConstInt; @@ -943,8 +1094,17 @@ continue; // expand macros - if (token == PpAtomIdentifier && MacroExpand(&ppToken, false, true) != 0) - continue; + if (token == PpAtomIdentifier) { + switch (MacroExpand(&ppToken, false, true)) { + case MacroExpandNotStarted: + break; + case MacroExpandError: + return EndOfInput; + case MacroExpandStarted: + case MacroExpandUndef: + continue; + } + } switch (token) { case PpAtomIdentifier: @@ -953,19 +1113,15 @@ case PpAtomConstFloat: case PpAtomConstInt64: case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS case PpAtomConstInt16: case PpAtomConstUint16: -#endif case PpAtomConstDouble: -#ifdef AMD_EXTENSIONS case PpAtomConstFloat16: -#endif if (ppToken.name[0] == '\0') continue; break; case PpAtomConstString: - if (parseContext.intermediate.getSource() != EShSourceHlsl) { + if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) { // HLSL allows string literals. parseContext.ppError(ppToken.loc, "string literals not supported", "\"\"", ""); continue; @@ -975,7 +1131,7 @@ parseContext.ppError(ppToken.loc, "character literals not supported", "\'", ""); continue; default: - strcpy(ppToken.name, atomStrings.getString(token)); + snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(token)); break; } @@ -1012,61 +1168,69 @@ break; } - // get the token after the ## - token = scanToken(&pastedPpToken); - - // This covers end of argument expansion - if (token == tMarkerInput::marker) { - parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); - break; - } - - // get the token text - switch (resultToken) { - case PpAtomIdentifier: - // already have the correct text in token.names - break; - case '=': - case '!': - case '-': - case '~': - case '+': - case '*': - case '/': - case '%': - case '<': - case '>': - case '|': - case '^': - case '&': - case PpAtomRight: - case PpAtomLeft: - case PpAtomAnd: - case PpAtomOr: - case PpAtomXor: - strcpy(ppToken.name, atomStrings.getString(resultToken)); - strcpy(pastedPpToken.name, atomStrings.getString(token)); - break; - default: - parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", ""); - return resultToken; - } + // Get the token(s) after the ##. + // Because of "space" semantics, and prior tokenization, what + // appeared a single token, e.g. "3A", might have been tokenized + // into two tokens "3" and "A", but the "A" will have 'space' set to + // false. Accumulate all of these to recreate the original lexical + // appearing token. + do { + token = scanToken(&pastedPpToken); - // combine the tokens - if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) { - parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", ""); - return resultToken; - } - strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name)); + // This covers end of argument expansion + if (token == tMarkerInput::marker) { + parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); + return resultToken; + } - // correct the kind of token we are making, if needed (identifiers stay identifiers) - if (resultToken != PpAtomIdentifier) { - int newToken = atomStrings.getAtom(ppToken.name); - if (newToken > 0) - resultToken = newToken; - else - parseContext.ppError(ppToken.loc, "combined token is invalid", "##", ""); - } + // get the token text + switch (resultToken) { + case PpAtomIdentifier: + // already have the correct text in token.names + break; + case '=': + case '!': + case '-': + case '~': + case '+': + case '*': + case '/': + case '%': + case '<': + case '>': + case '|': + case '^': + case '&': + case PpAtomRight: + case PpAtomLeft: + case PpAtomAnd: + case PpAtomOr: + case PpAtomXor: + snprintf(ppToken.name, sizeof(ppToken.name), "%s", atomStrings.getString(resultToken)); + snprintf(pastedPpToken.name, sizeof(pastedPpToken.name), "%s", atomStrings.getString(token)); + break; + default: + parseContext.ppError(ppToken.loc, "not supported for these tokens", "##", ""); + return resultToken; + } + + // combine the tokens + if (strlen(ppToken.name) + strlen(pastedPpToken.name) > MaxTokenLength) { + parseContext.ppError(ppToken.loc, "combined tokens are too long", "##", ""); + return resultToken; + } + snprintf(&ppToken.name[0] + strlen(ppToken.name), sizeof(ppToken.name) - strlen(ppToken.name), + "%s", pastedPpToken.name); + + // correct the kind of token we are making, if needed (identifiers stay identifiers) + if (resultToken != PpAtomIdentifier) { + int newToken = atomStrings.getAtom(ppToken.name); + if (newToken > 0) + resultToken = newToken; + else + parseContext.ppError(ppToken.loc, "combined token is invalid", "##", ""); + } + } while (peekContinuedPasting(resultToken)); } return resultToken; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -97,179 +99,34 @@ namespace glslang { -// push onto back of stream -void TPpContext::TokenStream::putSubtoken(char subtoken) -{ - data.push_back(static_cast(subtoken)); -} - -// get the next token in stream -int TPpContext::TokenStream::getSubtoken() -{ - if (current < data.size()) - return data[current++]; - else - return EndOfInput; -} - -// back up one position in the stream -void TPpContext::TokenStream::ungetSubtoken() -{ - if (current > 0) - --current; -} - -// Add a complete token (including backing string) to the end of a list -// for later playback. -void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken) +// Add a token (including backing string) to the end of a macro +// token stream, for later playback. +void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken) { - const char* s; - char* str = NULL; - - assert((token & ~0xff) == 0); - putSubtoken(static_cast(token)); - - switch (token) { - case PpAtomIdentifier: - case PpAtomConstString: - s = ppToken->name; - while (*s) - putSubtoken(*s++); - putSubtoken(0); - break; - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: -#endif - case PpAtomConstFloat: - case PpAtomConstDouble: -#ifdef AMD_EXTENSIONS - case PpAtomConstFloat16: -#endif - str = ppToken->name; - while (*str) { - putSubtoken(*str); - str++; - } - putSubtoken(0); - break; - default: - break; - } + TokenStream::Token streamToken(atom, *ppToken); + stream.push_back(streamToken); } -// Read the next token from a token stream. -// (Not the source stream, but a stream used to hold a tokenized macro). +// Read the next token from a macro token stream. int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken) { - int len; - int ch; + if (atEnd()) + return EndOfInput; - int subtoken = getSubtoken(); + int atom = stream[currentPos++].get(*ppToken); ppToken->loc = parseContext.getCurrentLoc(); - switch (subtoken) { - case '#': - // Check for ##, unless the current # is the last character - if (current < data.size()) { - if (getSubtoken() == '#') { - parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); - parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); - subtoken = PpAtomPaste; - } else - ungetSubtoken(); - } - break; - case PpAtomConstString: - case PpAtomIdentifier: - case PpAtomConstFloat: - case PpAtomConstDouble: -#ifdef AMD_EXTENSIONS - case PpAtomConstFloat16: -#endif - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: -#endif - len = 0; - ch = getSubtoken(); - while (ch != 0 && ch != EndOfInput) { - if (len < MaxTokenLength) { - ppToken->name[len] = (char)ch; - len++; - ch = getSubtoken(); - } else { - parseContext.error(ppToken->loc, "token too long", "", ""); - break; - } - } - ppToken->name[len] = 0; - switch (subtoken) { - case PpAtomIdentifier: - break; - case PpAtomConstString: - break; - case PpAtomConstFloat: - case PpAtomConstDouble: -#ifdef AMD_EXTENSIONS - case PpAtomConstFloat16: -#endif - ppToken->dval = atof(ppToken->name); - break; - case PpAtomConstInt: -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: -#endif - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->ival = (int)strtol(ppToken->name, 0, 16); - else - ppToken->ival = (int)strtol(ppToken->name, 0, 8); - } else - ppToken->ival = atoi(ppToken->name); - break; - case PpAtomConstUint: -#ifdef AMD_EXTENSIONS - case PpAtomConstUint16: -#endif - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->ival = (int)strtoul(ppToken->name, 0, 16); - else - ppToken->ival = (int)strtoul(ppToken->name, 0, 8); - } else - ppToken->ival = (int)strtoul(ppToken->name, 0, 10); - break; - case PpAtomConstInt64: - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->i64val = strtoll(ppToken->name, nullptr, 16); - else - ppToken->i64val = strtoll(ppToken->name, nullptr, 8); - } else - ppToken->i64val = atoll(ppToken->name); - break; - case PpAtomConstUint64: - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16); - else - ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8); - } else - ppToken->i64val = (long long)strtoull(ppToken->name, 0, 10); - break; + // Check for ##, unless the current # is the last character + if (atom == '#') { + if (peekToken('#')) { + parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); + currentPos++; + atom = PpAtomPaste; } } - return subtoken; + return atom; } // We are pasting if @@ -281,15 +138,14 @@ { // 1. preceding ##? - size_t savePos = current; - int subtoken; + size_t savePos = currentPos; // skip white space - do { - subtoken = getSubtoken(); - } while (subtoken == ' '); - current = savePos; - if (subtoken == PpAtomPaste) + while (peekToken(' ')) + ++currentPos; + if (peekToken(PpAtomPaste)) { + currentPos = savePos; return true; + } // 2. last token and we've been told after this there will be a ## @@ -298,18 +154,18 @@ // Getting here means the last token will be pasted, after this // Are we at the last non-whitespace token? - savePos = current; + savePos = currentPos; bool moreTokens = false; do { - subtoken = getSubtoken(); - if (subtoken == EndOfInput) + if (atEnd()) break; - if (subtoken != ' ') { + if (!peekToken(' ')) { moreTokens = true; break; } + ++currentPos; } while (true); - current = savePos; + currentPos = savePos; return !moreTokens; } @@ -318,23 +174,21 @@ bool TPpContext::TokenStream::peekUntokenizedPasting() { // don't return early, have to restore this - size_t savePos = current; + size_t savePos = currentPos; // skip white-space - int subtoken; - do { - subtoken = getSubtoken(); - } while (subtoken == ' '); + while (peekToken(' ')) + ++currentPos; // check for ## bool pasting = false; - if (subtoken == '#') { - subtoken = getSubtoken(); - if (subtoken == '#') + if (peekToken('#')) { + ++currentPos; + if (peekToken('#')) pasting = true; } - current = savePos; + currentPos = savePos; return pasting; } diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h 2019-10-27 13:44:49.000000000 +0000 @@ -127,10 +127,8 @@ PpAtomConstUint, PpAtomConstInt64, PpAtomConstUint64, -#ifdef AMD_EXTENSIONS PpAtomConstInt16, PpAtomConstUint16, -#endif PpAtomConstFloat, PpAtomConstDouble, PpAtomConstFloat16, diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -93,72 +93,128 @@ // Use a degenerate (empty) set of dereferences to immediately put as at the end of // the dereference change expected by blowUpActiveAggregate. TList derefs; - blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0); + blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0, + base.getQualifier().storage, true); } } - void addAttribute(const TIntermSymbol& base) + void addPipeIOVariable(const TIntermSymbol& base) { if (processedDerefs.find(&base) == processedDerefs.end()) { processedDerefs.insert(&base); const TString &name = base.getName(); const TType &type = base.getType(); + const bool input = base.getQualifier().isPipeInput(); - TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name); - if (it == reflection.nameToIndex.end()) { - reflection.nameToIndex[name] = (int)reflection.indexToAttribute.size(); - reflection.indexToAttribute.push_back(TObjectReflection(name, type, 0, mapToGlType(type), 0, 0)); + TReflection::TMapIndexToReflection &ioItems = + input ? reflection.indexToPipeInput : reflection.indexToPipeOutput; + + if (reflection.options & EShReflectionUnwrapIOBlocks) { + bool anonymous = IsAnonymous(name); + + TString baseName; + if (type.getBasicType() == EbtBlock) { + baseName = anonymous ? TString() : type.getTypeName(); + } else { + baseName = anonymous ? TString() : name; + } + + // by convention if this is an arrayed block we ignore the array in the reflection + if (type.isArray() && type.getBasicType() == EbtBlock) { + blowUpIOAggregate(input, baseName, TType(type, 0)); + } else { + blowUpIOAggregate(input, baseName, type); + } + } else { + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); + if (it == reflection.nameToIndex.end()) { + reflection.nameToIndex[name.c_str()] = (int)ioItems.size(); + ioItems.push_back( + TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0)); + + EShLanguageMask& stages = ioItems.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { + EShLanguageMask& stages = ioItems[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } } } } - // Lookup or calculate the offset of a block member, using the recursively + // Lookup or calculate the offset of all block members at once, using the recursively // defined block offset rules. - int getOffset(const TType& type, int index) + void getOffsets(const TType& type, TVector& offsets) { const TTypeList& memberList = *type.getStruct(); - // Don't calculate offset if one is present, it could be user supplied - // and different than what would be calculated. That is, this is faster, - // but not just an optimization. - if (memberList[index].type->getQualifier().hasOffset()) - return memberList[index].type->getQualifier().layoutOffset; - - int memberSize; - int dummyStride; + int memberSize = 0; int offset = 0; - for (int m = 0; m <= index; ++m) { - // modify just the children's view of matrix layout, if there is one for this member - TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix; - int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, dummyStride, - type.getQualifier().layoutPacking == ElpStd140, - subMatrixLayout != ElmNone - ? subMatrixLayout == ElmRowMajor - : type.getQualifier().layoutMatrix == ElmRowMajor); - RoundToPow2(offset, memberAlignment); - if (m < index) - offset += memberSize; - } - - return offset; - } - - // Calculate the block data size. - // Block arrayness is not taken into account, each element is backed by a separate buffer. - int getBlockSize(const TType& blockType) - { - const TTypeList& memberList = *blockType.getStruct(); - int lastIndex = (int)memberList.size() - 1; - int lastOffset = getOffset(blockType, lastIndex); - - int lastMemberSize; - int dummyStride; - intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, - blockType.getQualifier().layoutPacking == ElpStd140, - blockType.getQualifier().layoutMatrix == ElmRowMajor); + for (size_t m = 0; m < offsets.size(); ++m) { + // if the user supplied an offset, snap to it now + if (memberList[m].type->getQualifier().hasOffset()) + offset = memberList[m].type->getQualifier().layoutOffset; + + // calculate the offset of the next member and align the current offset to this member + intermediate.updateOffset(type, *memberList[m].type, offset, memberSize); + + // save the offset of this member + offsets[m] = offset; + + // update for the next member + offset += memberSize; + } + } + + // Calculate the stride of an array type + int getArrayStride(const TType& baseType, const TType& type) + { + int dummySize; + int stride; + + // consider blocks to have 0 stride, so that all offsets are relative to the start of their block + if (type.getBasicType() == EbtBlock) + return 0; + + TLayoutMatrix subMatrixLayout = type.getQualifier().layoutMatrix; + intermediate.getMemberAlignment(type, dummySize, stride, + baseType.getQualifier().layoutPacking, + subMatrixLayout != ElmNone + ? subMatrixLayout == ElmRowMajor + : baseType.getQualifier().layoutMatrix == ElmRowMajor); + + return stride; + } + + // count the total number of leaf members from iterating out of a block type + int countAggregateMembers(const TType& parentType) + { + if (! parentType.isStruct()) + return 1; - return lastOffset + lastMemberSize; + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + + bool blockParent = (parentType.getBasicType() == EbtBlock && parentType.getQualifier().storage == EvqBuffer); + + const TTypeList &memberList = *parentType.getStruct(); + + int ret = 0; + + for (size_t i = 0; i < memberList.size(); i++) + { + const TType &memberType = *memberList[i].type; + int numMembers = countAggregateMembers(memberType); + // for sized arrays of structs, apply logic to expand out the same as we would below in + // blowUpActiveAggregate + if (memberType.isArray() && ! memberType.getArraySizes()->hasUnsized() && memberType.isStruct()) { + if (! strictArraySuffix || ! blockParent) + numMembers *= memberType.getArraySizes()->getCumulativeSize(); + } + ret += numMembers; + } + + return ret; } // Traverse the provided deref chain, including the base, and @@ -169,8 +225,19 @@ // arraySize tracks, just for the final dereference in the chain, if there was a specific known size. // A value of 0 for arraySize will mean to use the full array's size. void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList& derefs, - TList::const_iterator deref, int offset, int blockIndex, int arraySize) + TList::const_iterator deref, int offset, int blockIndex, int arraySize, + int topLevelArrayStride, TStorageQualifier baseStorage, bool active) { + // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. + // Broadly: + // * arrays-of-structs always have a [x] suffix. + // * with array-of-struct variables in the root of a buffer block, only ever return [0]. + // * otherwise, array suffixes are added whenever we iterate, even if that means expanding out an array. + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + + // is this variable inside a buffer block. This flag is set back to false after we iterate inside the first array element. + bool blockParent = (baseType.getBasicType() == EbtBlock && baseType.getQualifier().storage == EvqBuffer); + // process the part of the dereference chain that was explicit in the shader TString name = baseName; const TType* terminalType = &baseType; @@ -179,29 +246,54 @@ terminalType = &visitNode->getType(); int index; switch (visitNode->getOp()) { - case EOpIndexIndirect: + case EOpIndexIndirect: { + int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + // Visit all the indices of this array, and for each one add on the remaining dereferencing for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) { TString newBaseName = name; - if (baseType.getBasicType() != EbtBlock) + if (strictArraySuffix && blockParent) + newBaseName.append(TString("[0]")); + else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) newBaseName.append(TString("[") + String(i) + "]"); TList::const_iterator nextDeref = deref; ++nextDeref; - TType derefType(*terminalType, 0); - blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize); + blowUpActiveAggregate(*terminalType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize, + topLevelArrayStride, baseStorage, active); + + if (offset >= 0) + offset += stride; } // it was all completed in the recursive calls above return; - case EOpIndexDirect: + } + case EOpIndexDirect: { + int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); + index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); - if (baseType.getBasicType() != EbtBlock) + if (strictArraySuffix && blockParent) { + name.append(TString("[0]")); + } else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) { name.append(TString("[") + String(index) + "]"); + + if (offset >= 0) + offset += stride * index; + } + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + + blockParent = false; break; + } case EOpIndexDirectStruct: index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); if (offset >= 0) - offset += getOffset(visitNode->getLeft()->getType(), index); + offset += intermediate.getOffset(visitNode->getLeft()->getType(), index); if (name.size() > 0) name.append("."); name.append((*visitNode->getLeft()->getType().getStruct())[index].type->getFieldName()); @@ -213,24 +305,65 @@ // if the terminalType is still too coarse a granularity, this is still an aggregate to expand, expand it... if (! isReflectionGranularity(*terminalType)) { + // the base offset of this node, that children are relative to + int baseOffset = offset; + if (terminalType->isArray()) { // Visit all the indices of this array, and for each one, // fully explode the remaining aggregate to dereference - for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) { + + int stride = 0; + if (offset >= 0) + stride = getArrayStride(baseType, *terminalType); + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + + int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1); + + // for top-level arrays in blocks, only expand [0] to avoid explosion of items + if (strictArraySuffix && blockParent) + arrayIterateSize = 1; + + for (int i = 0; i < arrayIterateSize; ++i) { TString newBaseName = name; newBaseName.append(TString("[") + String(i) + "]"); TType derefType(*terminalType, 0); - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + if (offset >= 0) + offset = baseOffset + stride * i; + + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + topLevelArrayStride, baseStorage, active); } } else { // Visit all members of this aggregate, and for each one, // fully explode the remaining aggregate to dereference const TTypeList& typeList = *terminalType->getStruct(); + + TVector memberOffsets; + + if (baseOffset >= 0) { + memberOffsets.resize(typeList.size()); + getOffsets(*terminalType, memberOffsets); + } + for (int i = 0; i < (int)typeList.size(); ++i) { TString newBaseName = name; - newBaseName.append(TString(".") + typeList[i].type->getFieldName()); + if (newBaseName.size() > 0) + newBaseName.append("."); + newBaseName.append(typeList[i].type->getFieldName()); TType derefType(*terminalType, i); - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + if (offset >= 0) + offset = baseOffset + memberOffsets[i]; + + int arrayStride = topLevelArrayStride; + if (terminalType->getBasicType() == EbtBlock && terminalType->getQualifier().storage == EvqBuffer && + derefType.isArray()) { + arrayStride = getArrayStride(baseType, derefType); + } + + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + arrayStride, baseStorage, active); } } @@ -238,6 +371,10 @@ return; } + if ((reflection.options & EShReflectionBasicArraySuffix) && terminalType->isArray()) { + name.append(TString("[0]")); + } + // Finally, add a full string to the reflection database, and update the array size if necessary. // If the dereferenced entity to record is an array, compute the size and update the maximum size. @@ -245,15 +382,100 @@ if (arraySize == 0) arraySize = mapToGlArraySize(*terminalType); - TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name); + TReflection::TMapIndexToReflection& variables = reflection.GetVariableMapForStorage(baseStorage); + + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); if (it == reflection.nameToIndex.end()) { - reflection.nameToIndex[name] = (int)reflection.indexToUniform.size(); - reflection.indexToUniform.push_back(TObjectReflection(name, *terminalType, offset, - mapToGlType(*terminalType), - arraySize, blockIndex)); - } else if (arraySize > 1) { - int& reflectedArraySize = reflection.indexToUniform[it->second].size; - reflectedArraySize = std::max(arraySize, reflectedArraySize); + int uniformIndex = (int)variables.size(); + reflection.nameToIndex[name.c_str()] = uniformIndex; + variables.push_back(TObjectReflection(name.c_str(), *terminalType, offset, mapToGlType(*terminalType), + arraySize, blockIndex)); + if (terminalType->isArray()) { + variables.back().arrayStride = getArrayStride(baseType, *terminalType); + if (topLevelArrayStride == 0) + topLevelArrayStride = variables.back().arrayStride; + } + + if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->getBasicType() == EbtAtomicUint) + reflection.atomicCounterUniformIndices.push_back(uniformIndex); + + variables.back().topLevelArrayStride = topLevelArrayStride; + + if ((reflection.options & EShReflectionAllBlockVariables) && active) { + EShLanguageMask& stages = variables.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } else { + if (arraySize > 1) { + int& reflectedArraySize = variables[it->second].size; + reflectedArraySize = std::max(arraySize, reflectedArraySize); + } + + if ((reflection.options & EShReflectionAllBlockVariables) && active) { + EShLanguageMask& stages = variables[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } + } + + // similar to blowUpActiveAggregate, but with simpler rules and no dereferences to follow. + void blowUpIOAggregate(bool input, const TString &baseName, const TType &type) + { + TString name = baseName; + + // if the type is still too coarse a granularity, this is still an aggregate to expand, expand it... + if (! isReflectionGranularity(type)) { + if (type.isArray()) { + // Visit all the indices of this array, and for each one, + // fully explode the remaining aggregate to dereference + for (int i = 0; i < std::max(type.getOuterArraySize(), 1); ++i) { + TString newBaseName = name; + newBaseName.append(TString("[") + String(i) + "]"); + TType derefType(type, 0); + + blowUpIOAggregate(input, newBaseName, derefType); + } + } else { + // Visit all members of this aggregate, and for each one, + // fully explode the remaining aggregate to dereference + const TTypeList& typeList = *type.getStruct(); + + for (int i = 0; i < (int)typeList.size(); ++i) { + TString newBaseName = name; + if (newBaseName.size() > 0) + newBaseName.append("."); + newBaseName.append(typeList[i].type->getFieldName()); + TType derefType(type, i); + + blowUpIOAggregate(input, newBaseName, derefType); + } + } + + // it was all completed in the recursive calls above + return; + } + + if ((reflection.options & EShReflectionBasicArraySuffix) && type.isArray()) { + name.append(TString("[0]")); + } + + TReflection::TMapIndexToReflection &ioItems = + input ? reflection.indexToPipeInput : reflection.indexToPipeOutput; + + std::string namespacedName = input ? "in " : "out "; + namespacedName += name.c_str(); + + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(namespacedName); + if (it == reflection.nameToIndex.end()) { + reflection.nameToIndex[namespacedName] = (int)ioItems.size(); + ioItems.push_back( + TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0)); + + EShLanguageMask& stages = ioItems.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { + EShLanguageMask& stages = ioItems[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); } } @@ -303,6 +525,10 @@ anonymous = IsAnonymous(base->getName()); const TString& blockName = base->getType().getTypeName(); + TString baseName; + + if (! anonymous) + baseName = blockName; if (base->getType().isArray()) { TType derefType(base->getType(), 0); @@ -310,9 +536,57 @@ assert(! anonymous); for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e) blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType, - getBlockSize(base->getType())); + intermediate.getBlockSize(base->getType())); + baseName.append(TString("[0]")); } else - blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType())); + blockIndex = addBlockName(blockName, base->getType(), intermediate.getBlockSize(base->getType())); + + if (reflection.options & EShReflectionAllBlockVariables) { + // Use a degenerate (empty) set of dereferences to immediately put as at the end of + // the dereference change expected by blowUpActiveAggregate. + TList derefs; + + // because we don't have any derefs, the first thing blowUpActiveAggregate will do is iterate over each + // member in the struct definition. This will lose any information about whether the parent was a buffer + // block. So if we're using strict array rules which don't expand the first child of a buffer block we + // instead iterate over the children here. + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer); + + if (strictArraySuffix && blockParent) { + const TTypeList& typeList = *base->getType().getStruct(); + + TVector memberOffsets; + + memberOffsets.resize(typeList.size()); + getOffsets(base->getType(), memberOffsets); + + for (int i = 0; i < (int)typeList.size(); ++i) { + TType derefType(base->getType(), i); + TString name = baseName; + if (name.size() > 0) + name.append("."); + name.append(typeList[i].type->getFieldName()); + + // if this member is an array, store the top-level array stride but start the explosion from + // the inner struct type. + if (derefType.isArray() && derefType.isStruct()) { + name.append("[0]"); + blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i], + blockIndex, 0, getArrayStride(base->getType(), derefType), + base->getQualifier().storage, false); + } else { + blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex, + 0, 0, base->getQualifier().storage, false); + } + } + } else { + // otherwise - if we're not using strict array suffix rules, or this isn't a block so we are + // expanding root arrays anyway, just start the iteration from the base block type. + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, 0, + base->getQualifier().storage, false); + } + } } // Process the dereference chain, backward, accumulating the pieces for later forward traversal. @@ -342,27 +616,39 @@ else baseName = base->getName(); } - blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize); + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0, + base->getQualifier().storage, true); } int addBlockName(const TString& name, const TType& type, int size) { + TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage); + int blockIndex; - TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name); - if (reflection.nameToIndex.find(name) == reflection.nameToIndex.end()) { - blockIndex = (int)reflection.indexToUniformBlock.size(); - reflection.nameToIndex[name] = blockIndex; - reflection.indexToUniformBlock.push_back(TObjectReflection(name, type, -1, -1, size, -1)); - } else + TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); + if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) { + blockIndex = (int)blocks.size(); + reflection.nameToIndex[name.c_str()] = blockIndex; + blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1)); + + blocks.back().numMembers = countAggregateMembers(type); + + EShLanguageMask& stages = blocks.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { blockIndex = it->second; + EShLanguageMask& stages = blocks[blockIndex].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + return blockIndex; } // Are we at a level in a dereference chain at which individual active uniform queries are made? bool isReflectionGranularity(const TType& type) { - return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct; + return type.getBasicType() != EbtBlock && type.getBasicType() != EbtStruct && !type.isArrayOfArrays(); } // For a binary operation indexing into an aggregate, chase down the base of the aggregate. @@ -415,6 +701,36 @@ case EsdBuffer: return GL_SAMPLER_BUFFER; } +#ifdef AMD_EXTENSIONS + case EbtFloat16: + switch ((int)sampler.dim) { + case Esd1D: + switch ((int)sampler.shadow) { + case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_AMD : GL_FLOAT16_SAMPLER_1D_AMD; + case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_1D_SHADOW_AMD; + } + case Esd2D: + switch ((int)sampler.ms) { + case false: + switch ((int)sampler.shadow) { + case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_AMD; + case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_SHADOW_AMD; + } + case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD; + } + case Esd3D: + return GL_FLOAT16_SAMPLER_3D_AMD; + case EsdCube: + switch ((int)sampler.shadow) { + case false: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_SAMPLER_CUBE_AMD; + case true: return sampler.arrayed ? GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD : GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD; + } + case EsdRect: + return sampler.shadow ? GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD : GL_FLOAT16_SAMPLER_2D_RECT_AMD; + case EsdBuffer: + return GL_FLOAT16_SAMPLER_BUFFER_AMD; + } +#endif case EbtInt: switch ((int)sampler.dim) { case Esd1D: @@ -477,6 +793,26 @@ case EsdBuffer: return GL_IMAGE_BUFFER; } +#ifdef AMD_EXTENSIONS + case EbtFloat16: + switch ((int)sampler.dim) { + case Esd1D: + return sampler.arrayed ? GL_FLOAT16_IMAGE_1D_ARRAY_AMD : GL_FLOAT16_IMAGE_1D_AMD; + case Esd2D: + switch ((int)sampler.ms) { + case false: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_AMD; + case true: return sampler.arrayed ? GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD : GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD; + } + case Esd3D: + return GL_FLOAT16_IMAGE_3D_AMD; + case EsdCube: + return sampler.arrayed ? GL_FLOAT16_IMAGE_CUBE_MAP_ARRAY_AMD : GL_FLOAT16_IMAGE_CUBE_AMD; + case EsdRect: + return GL_FLOAT16_IMAGE_2D_RECT_AMD; + case EsdBuffer: + return GL_FLOAT16_IMAGE_BUFFER_AMD; + } +#endif case EbtInt: switch ((int)sampler.dim) { case Esd1D: @@ -696,8 +1032,47 @@ if (base->getQualifier().storage == EvqUniform) addUniform(*base); - if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput()) - addAttribute(*base); + if ((intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) || + (intermediate.getStage() == reflection.lastStage && base->getQualifier().isPipeOutput())) + addPipeIOVariable(*base); +} + +// +// Implement TObjectReflection methods. +// + +TObjectReflection::TObjectReflection(const std::string &pName, const TType &pType, int pOffset, int pGLDefineType, + int pSize, int pIndex) + : name(pName), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), + numMembers(-1), arrayStride(0), topLevelArrayStride(0), stages(EShLanguageMask(0)), type(pType.clone()) +{ +} + +int TObjectReflection::getBinding() const +{ + if (type == nullptr || !type->getQualifier().hasBinding()) + return -1; + return type->getQualifier().layoutBinding; +} + +void TObjectReflection::dump() const +{ + printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d", name.c_str(), offset, glDefineType, size, + index, getBinding(), stages); + + if (counterIndex != -1) + printf(", counter %d", counterIndex); + + if (numMembers != -1) + printf(", numMembers %d", numMembers); + + if (arrayStride != 0) + printf(", arrayStride %d", arrayStride); + + if (topLevelArrayStride != 0) + printf(", topLevelArrayStride %d", topLevelArrayStride); + + printf("\n"); } // @@ -716,11 +1091,11 @@ } // build counter block index associations for buffers -void TReflection::buildCounterIndices() +void TReflection::buildCounterIndices(const TIntermediate& intermediate) { // search for ones that have counters for (int i = 0; i < int(indexToUniformBlock.size()); ++i) { - const TString counterName(indexToUniformBlock[i].name + "@count"); + const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str()); const int index = getIndex(counterName); if (index >= 0) @@ -728,6 +1103,22 @@ } } +// build Shader Stages mask for all uniforms +void TReflection::buildUniformStageMask(const TIntermediate& intermediate) +{ + if (options & EShReflectionAllBlockVariables) + return; + + for (int i = 0; i < int(indexToUniform.size()); ++i) { + indexToUniform[i].stages = static_cast(indexToUniform[i].stages | 1 << intermediate.getStage()); + } + + for (int i = 0; i < int(indexToBufferVariable.size()); ++i) { + indexToBufferVariable[i].stages = + static_cast(indexToBufferVariable[i].stages | 1 << intermediate.getStage()); + } +} + // Merge live symbols from 'intermediate' into the existing reflection database. // // Returns false if the input is too malformed to do this. @@ -752,7 +1143,8 @@ function->traverse(&it); } - buildCounterIndices(); + buildCounterIndices(intermediate); + buildUniformStageMask(intermediate); return true; } @@ -769,9 +1161,24 @@ indexToUniformBlock[i].dump(); printf("\n"); - printf("Vertex attribute reflection:\n"); - for (size_t i = 0; i < indexToAttribute.size(); ++i) - indexToAttribute[i].dump(); + printf("Buffer variable reflection:\n"); + for (size_t i = 0; i < indexToBufferVariable.size(); ++i) + indexToBufferVariable[i].dump(); + printf("\n"); + + printf("Buffer block reflection:\n"); + for (size_t i = 0; i < indexToBufferBlock.size(); ++i) + indexToBufferBlock[i].dump(); + printf("\n"); + + printf("Pipeline input reflection:\n"); + for (size_t i = 0; i < indexToPipeInput.size(); ++i) + indexToPipeInput[i].dump(); + printf("\n"); + + printf("Pipeline output reflection:\n"); + for (size_t i = 0; i < indexToPipeOutput.size(); ++i) + indexToPipeOutput[i].dump(); printf("\n"); if (getLocalSize(0) > 1) { diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/reflection.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/reflection.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/reflection.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/reflection.h 2019-10-27 13:44:49.000000000 +0000 @@ -52,49 +52,11 @@ class TIntermAggregate; class TReflectionTraverser; -// Data needed for just a single object at the granularity exchanged by the reflection API -class TObjectReflection { -public: - TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : - name(pName), offset(pOffset), - glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), type(pType.clone()) { } - - const TType* const getType() const { return type; } - int getBinding() const - { - if (type == nullptr || !type->getQualifier().hasBinding()) - return -1; - return type->getQualifier().layoutBinding; - } - void dump() const - { - printf("%s: offset %d, type %x, size %d, index %d, binding %d", - name.c_str(), offset, glDefineType, size, index, getBinding() ); - - if (counterIndex != -1) - printf(", counter %d", counterIndex); - - printf("\n"); - } - static TObjectReflection badReflection() { return TObjectReflection(); } - - TString name; - int offset; - int glDefineType; - int size; // data size in bytes for a block, array size for a (non-block) object that's an array - int index; - int counterIndex; - -protected: - TObjectReflection() : offset(-1), glDefineType(-1), size(-1), index(-1), type(nullptr) { } - - const TType* type; -}; - // The full reflection database class TReflection { public: - TReflection() : badReflection(TObjectReflection::badReflection()) + TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last) + : options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection()) { for (int dim=0; dim<3; ++dim) localSize[dim] = 0; @@ -125,17 +87,57 @@ return badReflection; } - // for mapping an attribute index to the attribute's description - int getNumAttributes() { return (int)indexToAttribute.size(); } - const TObjectReflection& getAttribute(int i) const + // for mapping an pipeline input index to the input's description + int getNumPipeInputs() { return (int)indexToPipeInput.size(); } + const TObjectReflection& getPipeInput(int i) const + { + if (i >= 0 && i < (int)indexToPipeInput.size()) + return indexToPipeInput[i]; + else + return badReflection; + } + + // for mapping an pipeline output index to the output's description + int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); } + const TObjectReflection& getPipeOutput(int i) const { - if (i >= 0 && i < (int)indexToAttribute.size()) - return indexToAttribute[i]; + if (i >= 0 && i < (int)indexToPipeOutput.size()) + return indexToPipeOutput[i]; else return badReflection; } - // for mapping any name to its index (block names, uniform names and attribute names) + // for mapping from an atomic counter to the uniform index + int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); } + const TObjectReflection& getAtomicCounter(int i) const + { + if (i >= 0 && i < (int)atomicCounterUniformIndices.size()) + return getUniform(atomicCounterUniformIndices[i]); + else + return badReflection; + } + + // for mapping a buffer variable index to a buffer variable object's description + int getNumBufferVariables() { return (int)indexToBufferVariable.size(); } + const TObjectReflection& getBufferVariable(int i) const + { + if (i >= 0 && i < (int)indexToBufferVariable.size()) + return indexToBufferVariable[i]; + else + return badReflection; + } + + // for mapping a storage block index to the storage block's description + int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); } + const TObjectReflection& getStorageBufferBlock(int i) const + { + if (i >= 0 && i < (int)indexToBufferBlock.size()) + return indexToBufferBlock[i]; + else + return badReflection; + } + + // for mapping any name to its index (block names, uniform names and input/output names) int getIndex(const char* name) const { TNameToIndex::const_iterator it = nameToIndex.find(name); @@ -156,18 +158,42 @@ protected: friend class glslang::TReflectionTraverser; - void buildCounterIndices(); + void buildCounterIndices(const TIntermediate&); + void buildUniformStageMask(const TIntermediate& intermediate); void buildAttributeReflection(EShLanguage, const TIntermediate&); // Need a TString hash: typedef std::unordered_map TNameToIndex; - typedef std::map TNameToIndex; + typedef std::map TNameToIndex; typedef std::vector TMapIndexToReflection; + typedef std::vector TIndices; + + TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage) + { + if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer) + return indexToBufferBlock; + return indexToUniformBlock; + } + TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage) + { + if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer) + return indexToBufferVariable; + return indexToUniform; + } + + EShReflectionOptions options; + + EShLanguage firstStage; + EShLanguage lastStage; TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed TMapIndexToReflection indexToUniform; TMapIndexToReflection indexToUniformBlock; - TMapIndexToReflection indexToAttribute; + TMapIndexToReflection indexToBufferVariable; + TMapIndexToReflection indexToBufferBlock; + TMapIndexToReflection indexToPipeInput; + TMapIndexToReflection indexToPipeOutput; + TIndices atomicCounterUniformIndices; unsigned int localSize[3]; }; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/ScanContext.h 2019-10-27 13:44:49.000000000 +0000 @@ -50,7 +50,10 @@ class TScanContext { public: - explicit TScanContext(TParseContextBase& pc) : parseContext(pc), afterType(false), field(false) { } + explicit TScanContext(TParseContextBase& pc) : + parseContext(pc), + afterType(false), afterStruct(false), + field(false), afterBuffer(false) { } virtual ~TScanContext() { } static void fillInKeywordMap(); @@ -76,7 +79,9 @@ TParseContextBase& parseContext; bool afterType; // true if we've recognized a type, so can only be looking for an identifier + bool afterStruct; // true if we've recognized the STRUCT keyword, so can only be looking for an identifier bool field; // true if we're on a field, right after a '.' + bool afterBuffer; // true if we've recognized the BUFFER keyword TSourceLoc loc; TParserToken* parserToken; TPpToken* ppToken; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. // // All rights reserved. // @@ -45,6 +46,7 @@ #include "../Include/Types.h" #include "SymbolTable.h" #include "ParseHelper.h" +#include "attribute.h" #include "glslang_tab.cpp.h" #include "ScanContext.h" #include "Scan.h" @@ -339,6 +341,7 @@ (*KeywordMap)["const"] = CONST; (*KeywordMap)["uniform"] = UNIFORM; + (*KeywordMap)["nonuniformEXT"] = NONUNIFORM; (*KeywordMap)["in"] = IN; (*KeywordMap)["out"] = OUT; (*KeywordMap)["inout"] = INOUT; @@ -377,6 +380,11 @@ (*KeywordMap)["varying"] = VARYING; (*KeywordMap)["buffer"] = BUFFER; (*KeywordMap)["coherent"] = COHERENT; + (*KeywordMap)["devicecoherent"] = DEVICECOHERENT; + (*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT; + (*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT; + (*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT; + (*KeywordMap)["nonprivate"] = NONPRIVATE; (*KeywordMap)["restrict"] = RESTRICT; (*KeywordMap)["readonly"] = READONLY; (*KeywordMap)["writeonly"] = WRITEONLY; @@ -463,16 +471,34 @@ (*KeywordMap)["u64vec3"] = U64VEC3; (*KeywordMap)["u64vec4"] = U64VEC4; -#ifdef AMD_EXTENSIONS + // GL_EXT_shader_explicit_arithmetic_types + (*KeywordMap)["int8_t"] = INT8_T; + (*KeywordMap)["i8vec2"] = I8VEC2; + (*KeywordMap)["i8vec3"] = I8VEC3; + (*KeywordMap)["i8vec4"] = I8VEC4; + (*KeywordMap)["uint8_t"] = UINT8_T; + (*KeywordMap)["u8vec2"] = U8VEC2; + (*KeywordMap)["u8vec3"] = U8VEC3; + (*KeywordMap)["u8vec4"] = U8VEC4; + (*KeywordMap)["int16_t"] = INT16_T; - (*KeywordMap)["uint16_t"] = UINT16_T; (*KeywordMap)["i16vec2"] = I16VEC2; (*KeywordMap)["i16vec3"] = I16VEC3; (*KeywordMap)["i16vec4"] = I16VEC4; + (*KeywordMap)["uint16_t"] = UINT16_T; (*KeywordMap)["u16vec2"] = U16VEC2; (*KeywordMap)["u16vec3"] = U16VEC3; (*KeywordMap)["u16vec4"] = U16VEC4; + (*KeywordMap)["int32_t"] = INT32_T; + (*KeywordMap)["i32vec2"] = I32VEC2; + (*KeywordMap)["i32vec3"] = I32VEC3; + (*KeywordMap)["i32vec4"] = I32VEC4; + (*KeywordMap)["uint32_t"] = UINT32_T; + (*KeywordMap)["u32vec2"] = U32VEC2; + (*KeywordMap)["u32vec3"] = U32VEC3; + (*KeywordMap)["u32vec4"] = U32VEC4; + (*KeywordMap)["float16_t"] = FLOAT16_T; (*KeywordMap)["f16vec2"] = F16VEC2; (*KeywordMap)["f16vec3"] = F16VEC3; @@ -489,7 +515,39 @@ (*KeywordMap)["f16mat4x2"] = F16MAT4X2; (*KeywordMap)["f16mat4x3"] = F16MAT4X3; (*KeywordMap)["f16mat4x4"] = F16MAT4X4; -#endif + + (*KeywordMap)["float32_t"] = FLOAT32_T; + (*KeywordMap)["f32vec2"] = F32VEC2; + (*KeywordMap)["f32vec3"] = F32VEC3; + (*KeywordMap)["f32vec4"] = F32VEC4; + (*KeywordMap)["f32mat2"] = F32MAT2; + (*KeywordMap)["f32mat3"] = F32MAT3; + (*KeywordMap)["f32mat4"] = F32MAT4; + (*KeywordMap)["f32mat2x2"] = F32MAT2X2; + (*KeywordMap)["f32mat2x3"] = F32MAT2X3; + (*KeywordMap)["f32mat2x4"] = F32MAT2X4; + (*KeywordMap)["f32mat3x2"] = F32MAT3X2; + (*KeywordMap)["f32mat3x3"] = F32MAT3X3; + (*KeywordMap)["f32mat3x4"] = F32MAT3X4; + (*KeywordMap)["f32mat4x2"] = F32MAT4X2; + (*KeywordMap)["f32mat4x3"] = F32MAT4X3; + (*KeywordMap)["f32mat4x4"] = F32MAT4X4; + (*KeywordMap)["float64_t"] = FLOAT64_T; + (*KeywordMap)["f64vec2"] = F64VEC2; + (*KeywordMap)["f64vec3"] = F64VEC3; + (*KeywordMap)["f64vec4"] = F64VEC4; + (*KeywordMap)["f64mat2"] = F64MAT2; + (*KeywordMap)["f64mat3"] = F64MAT3; + (*KeywordMap)["f64mat4"] = F64MAT4; + (*KeywordMap)["f64mat2x2"] = F64MAT2X2; + (*KeywordMap)["f64mat2x3"] = F64MAT2X3; + (*KeywordMap)["f64mat2x4"] = F64MAT2X4; + (*KeywordMap)["f64mat3x2"] = F64MAT3X2; + (*KeywordMap)["f64mat3x3"] = F64MAT3X3; + (*KeywordMap)["f64mat3x4"] = F64MAT3X4; + (*KeywordMap)["f64mat4x2"] = F64MAT4X2; + (*KeywordMap)["f64mat4x3"] = F64MAT4X3; + (*KeywordMap)["f64mat4x4"] = F64MAT4X4; (*KeywordMap)["sampler2D"] = SAMPLER2D; (*KeywordMap)["samplerCube"] = SAMPLERCUBE; @@ -534,6 +592,8 @@ (*KeywordMap)["samplerExternalOES"] = SAMPLEREXTERNALOES; // GL_OES_EGL_image_external + (*KeywordMap)["__samplerExternal2DY2YEXT"] = SAMPLEREXTERNAL2DY2YEXT; // GL_EXT_YUV_target + (*KeywordMap)["sampler"] = SAMPLER; (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; @@ -578,19 +638,84 @@ (*KeywordMap)["usubpassInput"] = USUBPASSINPUT; (*KeywordMap)["usubpassInputMS"] = USUBPASSINPUTMS; +#ifdef AMD_EXTENSIONS + (*KeywordMap)["f16sampler1D"] = F16SAMPLER1D; + (*KeywordMap)["f16sampler2D"] = F16SAMPLER2D; + (*KeywordMap)["f16sampler3D"] = F16SAMPLER3D; + (*KeywordMap)["f16sampler2DRect"] = F16SAMPLER2DRECT; + (*KeywordMap)["f16samplerCube"] = F16SAMPLERCUBE; + (*KeywordMap)["f16sampler1DArray"] = F16SAMPLER1DARRAY; + (*KeywordMap)["f16sampler2DArray"] = F16SAMPLER2DARRAY; + (*KeywordMap)["f16samplerCubeArray"] = F16SAMPLERCUBEARRAY; + (*KeywordMap)["f16samplerBuffer"] = F16SAMPLERBUFFER; + (*KeywordMap)["f16sampler2DMS"] = F16SAMPLER2DMS; + (*KeywordMap)["f16sampler2DMSArray"] = F16SAMPLER2DMSARRAY; + (*KeywordMap)["f16sampler1DShadow"] = F16SAMPLER1DSHADOW; + (*KeywordMap)["f16sampler2DShadow"] = F16SAMPLER2DSHADOW; + (*KeywordMap)["f16sampler2DRectShadow"] = F16SAMPLER2DRECTSHADOW; + (*KeywordMap)["f16samplerCubeShadow"] = F16SAMPLERCUBESHADOW; + (*KeywordMap)["f16sampler1DArrayShadow"] = F16SAMPLER1DARRAYSHADOW; + (*KeywordMap)["f16sampler2DArrayShadow"] = F16SAMPLER2DARRAYSHADOW; + (*KeywordMap)["f16samplerCubeArrayShadow"] = F16SAMPLERCUBEARRAYSHADOW; + + (*KeywordMap)["f16image1D"] = F16IMAGE1D; + (*KeywordMap)["f16image2D"] = F16IMAGE2D; + (*KeywordMap)["f16image3D"] = F16IMAGE3D; + (*KeywordMap)["f16image2DRect"] = F16IMAGE2DRECT; + (*KeywordMap)["f16imageCube"] = F16IMAGECUBE; + (*KeywordMap)["f16image1DArray"] = F16IMAGE1DARRAY; + (*KeywordMap)["f16image2DArray"] = F16IMAGE2DARRAY; + (*KeywordMap)["f16imageCubeArray"] = F16IMAGECUBEARRAY; + (*KeywordMap)["f16imageBuffer"] = F16IMAGEBUFFER; + (*KeywordMap)["f16image2DMS"] = F16IMAGE2DMS; + (*KeywordMap)["f16image2DMSArray"] = F16IMAGE2DMSARRAY; + + (*KeywordMap)["f16texture1D"] = F16TEXTURE1D; + (*KeywordMap)["f16texture2D"] = F16TEXTURE2D; + (*KeywordMap)["f16texture3D"] = F16TEXTURE3D; + (*KeywordMap)["f16texture2DRect"] = F16TEXTURE2DRECT; + (*KeywordMap)["f16textureCube"] = F16TEXTURECUBE; + (*KeywordMap)["f16texture1DArray"] = F16TEXTURE1DARRAY; + (*KeywordMap)["f16texture2DArray"] = F16TEXTURE2DARRAY; + (*KeywordMap)["f16textureCubeArray"] = F16TEXTURECUBEARRAY; + (*KeywordMap)["f16textureBuffer"] = F16TEXTUREBUFFER; + (*KeywordMap)["f16texture2DMS"] = F16TEXTURE2DMS; + (*KeywordMap)["f16texture2DMSArray"] = F16TEXTURE2DMSARRAY; + + (*KeywordMap)["f16subpassInput"] = F16SUBPASSINPUT; + (*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS; +#endif + (*KeywordMap)["noperspective"] = NOPERSPECTIVE; (*KeywordMap)["smooth"] = SMOOTH; (*KeywordMap)["flat"] = FLAT; #ifdef AMD_EXTENSIONS - (*KeywordMap)["__explicitInterpAMD"] = __EXPLICITINTERPAMD; + (*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD; #endif (*KeywordMap)["centroid"] = CENTROID; +#ifdef NV_EXTENSIONS + (*KeywordMap)["pervertexNV"] = PERVERTEXNV; +#endif (*KeywordMap)["precise"] = PRECISE; (*KeywordMap)["invariant"] = INVARIANT; (*KeywordMap)["packed"] = PACKED; (*KeywordMap)["resource"] = RESOURCE; (*KeywordMap)["superp"] = SUPERP; +#ifdef NV_EXTENSIONS + (*KeywordMap)["rayPayloadNV"] = PAYLOADNV; + (*KeywordMap)["rayPayloadInNV"] = PAYLOADINNV; + (*KeywordMap)["hitAttributeNV"] = HITATTRNV; + (*KeywordMap)["callableDataNV"] = CALLDATANV; + (*KeywordMap)["callableDataInNV"] = CALLDATAINNV; + (*KeywordMap)["accelerationStructureNV"] = ACCSTRUCTNV; + (*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV; + (*KeywordMap)["perviewNV"] = PERVIEWNV; + (*KeywordMap)["taskNV"] = PERTASKNV; +#endif + + (*KeywordMap)["fcoopmatNV"] = FCOOPMATNV; + ReservedSet = new std::unordered_set; ReservedSet->insert("common"); @@ -655,7 +780,7 @@ loc = ppToken.loc; parserToken->sType.lex.loc = loc; switch (token) { - case ';': afterType = false; return SEMICOLON; + case ';': afterType = false; afterBuffer = false; return SEMICOLON; case ',': afterType = false; return COMMA; case ':': return COLON; case '=': afterType = false; return EQUAL; @@ -677,7 +802,7 @@ case '?': return QUESTION; case '[': return LEFT_BRACKET; case ']': return RIGHT_BRACKET; - case '{': return LEFT_BRACE; + case '{': afterStruct = false; afterBuffer = false; return LEFT_BRACE; case '}': return RIGHT_BRACE; case '\\': parseContext.error(loc, "illegal use of escape character", "\\", ""); @@ -714,19 +839,15 @@ parseContext.error(loc, "not supported", "::", ""); break; - case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; - case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; - case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT; - case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT; -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT; - case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT; -#endif - case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; - case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; -#ifdef AMD_EXTENSIONS - case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT; -#endif + case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; + case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; + case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT; + case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT; + case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT; + case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT; + case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; + case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; + case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT; case PpAtomIdentifier: { int token = tokenizeIdentifier(); @@ -764,7 +885,6 @@ case IN: case OUT: case INOUT: - case STRUCT: case BREAK: case CONTINUE: case DO: @@ -777,6 +897,16 @@ case CASE: return keyword; + case STRUCT: + afterStruct = true; + return keyword; + + case NONUNIFORM: + if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) + return keyword; + else + return identifierOrType(); + case SWITCH: case DEFAULT: if ((parseContext.profile == EEsProfile && parseContext.version < 300) || @@ -819,11 +949,26 @@ return keyword; case BUFFER: + afterBuffer = true; if ((parseContext.profile == EEsProfile && parseContext.version < 310) || (parseContext.profile != EEsProfile && parseContext.version < 430)) return identifierOrType(); return keyword; +#ifdef NV_EXTENSIONS + case PAYLOADNV: + case PAYLOADINNV: + case HITATTRNV: + case CALLDATANV: + case CALLDATAINNV: + case ACCSTRUCTNV: + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.profile != EEsProfile && parseContext.version >= 460 + && parseContext.extensionTurnedOn(E_GL_NV_ray_tracing))) + return keyword; + return identifierOrType(); +#endif + case ATOMIC_UINT: if ((parseContext.profile == EEsProfile && parseContext.version >= 310) || parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters)) @@ -831,6 +976,11 @@ return es30ReservedFromGLSL(420); case COHERENT: + case DEVICECOHERENT: + case QUEUEFAMILYCOHERENT: + case WORKGROUPCOHERENT: + case SUBGROUPCOHERENT: + case NONPRIVATE: case RESTRICT: case READONLY: case WRITEONLY: @@ -841,7 +991,8 @@ case VOLATILE: if (parseContext.profile == EEsProfile && parseContext.version >= 310) return keyword; - if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) + if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || + (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) reservedWord(); return keyword; @@ -865,7 +1016,7 @@ case PATCH: if (parseContext.symbolTable.atBuiltInLevel() || (parseContext.profile == EEsProfile && - (parseContext.version >= 320 || + (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) || (parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader))) return keyword; @@ -985,12 +1136,30 @@ case U64VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + (parseContext.profile != EEsProfile && parseContext.version >= 450 && + (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64)))) + return keyword; + return identifierOrType(); + + case INT8_T: + case UINT8_T: + case I8VEC2: + case I8VEC3: + case I8VEC4: + case U8VEC2: + case U8VEC3: + case U8VEC4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8)) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) return keyword; return identifierOrType(); -#ifdef AMD_EXTENSIONS case INT16_T: case UINT16_T: case I16VEC2: @@ -1001,15 +1170,97 @@ case U16VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) && + (parseContext.profile != EEsProfile && parseContext.version >= 450 && + ( +#ifdef AMD_EXTENSIONS + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) || +#endif + parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16)))) + return keyword; + return identifierOrType(); + case INT32_T: + case UINT32_T: + case I32VEC2: + case I32VEC3: + case I32VEC4: + case U32VEC2: + case U32VEC3: + case U32VEC4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) && parseContext.profile != EEsProfile && parseContext.version >= 450)) return keyword; return identifierOrType(); + case FLOAT32_T: + case F32VEC2: + case F32VEC3: + case F32VEC4: + case F32MAT2: + case F32MAT3: + case F32MAT4: + case F32MAT2X2: + case F32MAT2X3: + case F32MAT2X4: + case F32MAT3X2: + case F32MAT3X3: + case F32MAT3X4: + case F32MAT4X2: + case F32MAT4X3: + case F32MAT4X4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) + return keyword; + return identifierOrType(); + + case FLOAT64_T: + case F64VEC2: + case F64VEC3: + case F64VEC4: + case F64MAT2: + case F64MAT3: + case F64MAT4: + case F64MAT2X2: + case F64MAT2X3: + case F64MAT2X4: + case F64MAT3X2: + case F64MAT3X3: + case F64MAT3X4: + case F64MAT4X2: + case F64MAT4X3: + case F64MAT4X4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + ((parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) + return keyword; + return identifierOrType(); case FLOAT16_T: case F16VEC2: case F16VEC3: case F16VEC4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.profile != EEsProfile && parseContext.version >= 450 && + ( +#ifdef AMD_EXTENSIONS + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || +#endif + parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)))) + return keyword; + + return identifierOrType(); + case F16MAT2: case F16MAT3: case F16MAT4: @@ -1024,11 +1275,16 @@ case F16MAT4X4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + (parseContext.profile != EEsProfile && parseContext.version >= 450 && + ( +#ifdef AMD_EXTENSIONS + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || +#endif + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)))) return keyword; + return identifierOrType(); -#endif case SAMPLERCUBEARRAY: case SAMPLERCUBEARRAYSHADOW: @@ -1112,7 +1368,7 @@ case SAMPLER3D: afterType = true; if (parseContext.profile == EEsProfile && parseContext.version < 300) { - if (! parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) + if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) reservedWord(); } return keyword; @@ -1177,6 +1433,13 @@ return keyword; return identifierOrType(); + case SAMPLEREXTERNAL2DY2YEXT: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_YUV_target)) + return keyword; + return identifierOrType(); + case TEXTURE2D: case TEXTURECUBE: case TEXTURECUBEARRAY: @@ -1212,7 +1475,7 @@ case TEXTURE1DARRAY: case SAMPLER: case SAMPLERSHADOW: - if (parseContext.spvVersion.vulkan >= 100) + if (parseContext.spvVersion.vulkan > 0) return keyword; else return identifierOrType(); @@ -1223,12 +1486,71 @@ case ISUBPASSINPUTMS: case USUBPASSINPUT: case USUBPASSINPUTMS: - if (parseContext.spvVersion.vulkan >= 100) + if (parseContext.spvVersion.vulkan > 0) return keyword; else return identifierOrType(); +#ifdef AMD_EXTENSIONS + case F16SAMPLER1D: + case F16SAMPLER2D: + case F16SAMPLER3D: + case F16SAMPLER2DRECT: + case F16SAMPLERCUBE: + case F16SAMPLER1DARRAY: + case F16SAMPLER2DARRAY: + case F16SAMPLERCUBEARRAY: + case F16SAMPLERBUFFER: + case F16SAMPLER2DMS: + case F16SAMPLER2DMSARRAY: + case F16SAMPLER1DSHADOW: + case F16SAMPLER2DSHADOW: + case F16SAMPLER1DARRAYSHADOW: + case F16SAMPLER2DARRAYSHADOW: + case F16SAMPLER2DRECTSHADOW: + case F16SAMPLERCUBESHADOW: + case F16SAMPLERCUBEARRAYSHADOW: + + case F16IMAGE1D: + case F16IMAGE2D: + case F16IMAGE3D: + case F16IMAGE2DRECT: + case F16IMAGECUBE: + case F16IMAGE1DARRAY: + case F16IMAGE2DARRAY: + case F16IMAGECUBEARRAY: + case F16IMAGEBUFFER: + case F16IMAGE2DMS: + case F16IMAGE2DMSARRAY: + + case F16TEXTURE1D: + case F16TEXTURE2D: + case F16TEXTURE3D: + case F16TEXTURE2DRECT: + case F16TEXTURECUBE: + case F16TEXTURE1DARRAY: + case F16TEXTURE2DARRAY: + case F16TEXTURECUBEARRAY: + case F16TEXTUREBUFFER: + case F16TEXTURE2DMS: + case F16TEXTURE2DMSARRAY: + + case F16SUBPASSINPUT: + case F16SUBPASSINPUTMS: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) && + parseContext.profile != EEsProfile && parseContext.version >= 450)) + return keyword; + return identifierOrType(); +#endif + case NOPERSPECTIVE: +#ifdef NV_EXTENSIONS + if (parseContext.profile == EEsProfile && parseContext.version >= 300 && + parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation)) + return keyword; +#endif return es30ReservedFromGLSL(130); case SMOOTH: @@ -1238,13 +1560,22 @@ return keyword; #ifdef AMD_EXTENSIONS - case __EXPLICITINTERPAMD: + case EXPLICITINTERPAMD: if (parseContext.profile != EEsProfile && parseContext.version >= 450 && parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) return keyword; return identifierOrType(); #endif +#ifdef NV_EXTENSIONS + case PERVERTEXNV: + if (((parseContext.profile != EEsProfile && parseContext.version >= 450) || + (parseContext.profile == EEsProfile && parseContext.version >= 320)) && + parseContext.extensionTurnedOn(E_GL_NV_fragment_shader_barycentric)) + return keyword; + return identifierOrType(); +#endif + case FLAT: if (parseContext.profile == EEsProfile && parseContext.version < 300) reservedWord(); @@ -1291,6 +1622,24 @@ return identifierOrReserved(reserved); } +#ifdef NV_EXTENSIONS + case PERPRIMITIVENV: + case PERVIEWNV: + case PERTASKNV: + if ((parseContext.profile != EEsProfile && parseContext.version >= 450) || + (parseContext.profile == EEsProfile && parseContext.version >= 320) || + parseContext.extensionTurnedOn(E_GL_NV_mesh_shader)) + return keyword; + return identifierOrType(); +#endif + + case FCOOPMATNV: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix)) + return keyword; + return identifierOrType(); + default: parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); return 0; @@ -1304,9 +1653,11 @@ return IDENTIFIER; parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string); - if (afterType == false && parserToken->sType.lex.symbol) { + if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) { if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) { - if (variable->isUserType()) { + if (variable->isUserType() && + // treat redeclaration of forward-declared buffer/uniform reference as an identifier + !(variable->getType().getBasicType() == EbtReference && afterBuffer)) { afterType = true; return TYPE_NAME; @@ -1422,7 +1773,8 @@ int TScanContext::firstGenerationImage(bool inEs310) { if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) || + (parseContext.profile != EEsProfile && (parseContext.version >= 420 || + parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) || (inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310)) return keyword; diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Scan.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/Scan.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Scan.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Scan.h 2019-10-27 13:44:49.000000000 +0000 @@ -65,7 +65,7 @@ } if (names != nullptr) { for (int i = 0; i < numSources; ++i) - loc[i].name = names[i]; + loc[i].name = names[i] != nullptr ? NewPoolTString(names[i]) : nullptr; } loc[currentSource].line = 1; logicalSourceLoc.init(1); @@ -170,16 +170,18 @@ // for #line override in filename based parsing void setFile(const char* filename) { - logicalSourceLoc.name = filename; - loc[getLastValidSourceIndex()].name = filename; + TString* fn_tstr = NewPoolTString(filename); + logicalSourceLoc.name = fn_tstr; + loc[getLastValidSourceIndex()].name = fn_tstr; } void setFile(const char* filename, int i) { + TString* fn_tstr = NewPoolTString(filename); if (i == getLastValidSourceIndex()) { - logicalSourceLoc.name = filename; + logicalSourceLoc.name = fn_tstr; } - loc[i].name = filename; + loc[i].name = fn_tstr; } void setString(int newString) diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,7 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013-2016 LunarG, Inc. -// Copyright (C) 2015-2017 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -67,6 +67,11 @@ #include "iomapper.h" #include "Initialize.h" +// TODO: this really shouldn't be here, it is only because of the trial addition +// of printing pre-processed tokens, which requires knowing the string literal +// token to print ", but none of that seems appropriate for this file. +#include "preprocessor/PpTokens.h" + namespace { // anonymous namespace for file-local functions and symbols // Total number of successful initializers of glslang: a refcount @@ -342,6 +347,38 @@ InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, infoSink, commonTable, symbolTables); +#ifdef NV_EXTENSIONS + // check for ray tracing stages + if (profile != EEsProfile && version >= 450) { + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source, + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source, + infoSink, commonTable, symbolTables); + } + + // check for mesh + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 320)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source, + infoSink, commonTable, symbolTables); + + // check for task + if ((profile != EEsProfile && version >= 450) || + (profile == EEsProfile && version >= 320)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source, + infoSink, commonTable, symbolTables); +#endif + + + return true; } @@ -439,6 +476,16 @@ glslang::ReleaseGlobalLock(); } +// Function to Print all builtins +void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) +{ + infoSink.debug << "BuiltinSymbolTable {\n"; + + symbolTable.dump(infoSink, true); + + infoSink.debug << "}\n"; +} + // Return true if the shader was correctly specified for version/profile/stage. bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion, EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion) @@ -565,6 +612,28 @@ version = profile == EEsProfile ? 310 : 420; } break; +#ifdef NV_EXTENSIONS + case EShLangRayGenNV: + case EShLangIntersectNV: + case EShLangAnyHitNV: + case EShLangClosestHitNV: + case EShLangMissNV: + case EShLangCallableNV: + if (profile == EEsProfile || version < 460) { + correct = false; + infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above"); + version = 460; + } + break; + case EShLangMeshNV: + case EShLangTaskNV: + if ((profile == EEsProfile && version < 320) || + (profile != EEsProfile && version < 450)) { + correct = false; + infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above"); + version = profile == EEsProfile ? 320 : 450; + } +#endif default: break; } @@ -578,7 +647,7 @@ if (spvVersion.spv != 0) { switch (profile) { case EEsProfile: - if (spvVersion.vulkan >= 100 && version < 310) { + if (spvVersion.vulkan > 0 && version < 310) { correct = false; infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher"); version = 310; @@ -593,7 +662,7 @@ infoSink.info.message(EPrefixError, "#version: compilation for SPIR-V does not support the compatibility profile"); break; default: - if (spvVersion.vulkan >= 100 && version < 140) { + if (spvVersion.vulkan > 0 && version < 140) { correct = false; infoSink.info.message(EPrefixError, "#version: Desktop shaders for Vulkan SPIR-V require version 140 or higher"); version = 140; @@ -619,9 +688,9 @@ { // Set up environmental defaults, first ignoring 'environment'. if (messages & EShMsgSpvRules) - spvVersion.spv = 0x00010000; + spvVersion.spv = EShTargetSpv_1_0; if (messages & EShMsgVulkanRules) { - spvVersion.vulkan = 100; + spvVersion.vulkan = EShTargetVulkan_1_0; spvVersion.vulkanGlsl = 100; } else if (spvVersion.spv != 0) spvVersion.openGl = 100; @@ -744,9 +813,9 @@ const int numPre = 2; const int numPost = requireNonempty? 1 : 0; const int numTotal = numPre + numStrings + numPost; - size_t* lengths = new size_t[numTotal]; - const char** strings = new const char*[numTotal]; - const char** names = new const char*[numTotal]; + std::unique_ptr lengths(new size_t[numTotal]); + std::unique_ptr strings(new const char*[numTotal]); + std::unique_ptr names(new const char*[numTotal]); for (int s = 0; s < numStrings; ++s) { strings[s + numPre] = shaderStrings[s]; if (inputLengths == nullptr || inputLengths[s] < 0) @@ -768,6 +837,8 @@ SpvVersion spvVersion; EShLanguage stage = compiler->getLanguage(); TranslateEnvironment(environment, messages, source, stage, spvVersion); + if (environment != nullptr && environment->target.hlslFunctionality1) + intermediate.setHlslFunctionality1(); // First, without using the preprocessor or parser, find the #version, so we know what // symbol tables, processing rules, etc. to set up. This does not need the extra strings @@ -814,14 +885,17 @@ intermediate.setProfile(profile); intermediate.setSpv(spvVersion); RecordProcesses(intermediate, messages, sourceEntryPointName); - if (spvVersion.vulkan >= 100) + if (spvVersion.vulkan > 0) intermediate.setOriginUpperLeft(); if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl) intermediate.setHlslOffsets(); if (messages & EShMsgDebugInfo) { intermediate.setSourceFile(names[numPre]); - for (int s = 0; s < numStrings; ++s) - intermediate.addSourceText(strings[numPre + s]); + for (int s = 0; s < numStrings; ++s) { + // The string may not be null-terminated, so make sure we provide + // the length along with the string. + intermediate.addSourceText(strings[numPre + s], lengths[numPre + s]); + } } SetupBuiltinSymbolTable(version, profile, spvVersion, source); @@ -832,25 +906,27 @@ [stage]; // Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool. - TSymbolTable* symbolTableMemory = new TSymbolTable; - TSymbolTable& symbolTable = *symbolTableMemory; + std::unique_ptr symbolTable(new TSymbolTable); if (cachedTable) - symbolTable.adoptLevels(*cachedTable); + symbolTable->adoptLevels(*cachedTable); // Add built-in symbols that are potentially context dependent; // they get popped again further down. - if (! AddContextSpecificSymbols(resources, compiler->infoSink, symbolTable, version, profile, spvVersion, - stage, source)) + if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, + stage, source)) { return false; + } + + if (messages & EShMsgBuiltinSymbolTable) + DumpBuiltinSymbolTable(compiler->infoSink, *symbolTable); // // Now we can process the full shader under proper symbols and rules. // - TParseContextBase* parseContext = CreateParseContext(symbolTable, intermediate, version, profile, source, - stage, compiler->infoSink, - spvVersion, forwardCompatible, messages, false, sourceEntryPointName); - + std::unique_ptr parseContext(CreateParseContext(*symbolTable, intermediate, version, profile, source, + stage, compiler->infoSink, + spvVersion, forwardCompatible, messages, false, sourceEntryPointName)); TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer); // only GLSL (bison triggered, really) needs an externally set scan context @@ -886,23 +962,14 @@ lengths[postIndex] = strlen(strings[numStrings + numPre]); names[postIndex] = nullptr; } - TInputScanner fullInput(numStrings + numPre + numPost, strings, lengths, names, numPre, numPost); + TInputScanner fullInput(numStrings + numPre + numPost, strings.get(), lengths.get(), names.get(), numPre, numPost); // Push a new symbol allocation scope that will get used for the shader's globals. - symbolTable.push(); + symbolTable->push(); bool success = processingContext(*parseContext, ppContext, fullInput, - versionWillBeError, symbolTable, + versionWillBeError, *symbolTable, intermediate, optLevel, messages); - - // Clean up the symbol table. The AST is self-sufficient now. - delete symbolTableMemory; - - delete parseContext; - delete [] lengths; - delete [] strings; - delete [] names; - return success; } @@ -912,7 +979,7 @@ class SourceLineSynchronizer { public: SourceLineSynchronizer(const std::function& lastSourceIndex, - std::stringstream* output) + std::string* output) : getLastSourceIndex(lastSourceIndex), output(output), lastSource(-1), lastLine(0) {} // SourceLineSynchronizer(const SourceLineSynchronizer&) = delete; // SourceLineSynchronizer& operator=(const SourceLineSynchronizer&) = delete; @@ -927,7 +994,7 @@ // used. We also need to output a newline to separate the output // from the previous source string (if there is one). if (lastSource != -1 || lastLine != 0) - *output << std::endl; + *output += '\n'; lastSource = getLastSourceIndex(); lastLine = -1; return true; @@ -942,7 +1009,7 @@ syncToMostRecentString(); const bool newLineStarted = lastLine < tokenLine; for (; lastLine < tokenLine; ++lastLine) { - if (lastLine > 0) *output << std::endl; + if (lastLine > 0) *output += '\n'; } return newLineStarted; } @@ -956,8 +1023,8 @@ // A function for getting the index of the last valid source string we've // read tokens from. const std::function getLastSourceIndex; - // output stream for newlines. - std::stringstream* output; + // output string for newlines. + std::string* output; // lastSource is the source string index (starting from 0) of the last token // processed. It is tracked in order for newlines to be inserted when a new // source string starts. -1 means we haven't started processing any source @@ -973,6 +1040,8 @@ // DoPreprocessing is a valid ProcessingContext template argument, // which only performs the preprocessing step of compilation. // It places the result in the "string" argument to its constructor. +// +// This is not an officially supported or fully working path. struct DoPreprocessing { explicit DoPreprocessing(std::string* string): outputString(string) {} bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, @@ -988,27 +1057,33 @@ parseContext.setScanner(&input); ppContext.setInput(input, versionWillBeError); - std::stringstream outputStream; + std::string outputBuffer; SourceLineSynchronizer lineSync( - std::bind(&TInputScanner::getLastValidSourceIndex, &input), &outputStream); + std::bind(&TInputScanner::getLastValidSourceIndex, &input), &outputBuffer); - parseContext.setExtensionCallback([&lineSync, &outputStream]( + parseContext.setExtensionCallback([&lineSync, &outputBuffer]( int line, const char* extension, const char* behavior) { lineSync.syncToLine(line); - outputStream << "#extension " << extension << " : " << behavior; + outputBuffer += "#extension "; + outputBuffer += extension; + outputBuffer += " : "; + outputBuffer += behavior; }); - parseContext.setLineCallback([&lineSync, &outputStream, &parseContext]( + parseContext.setLineCallback([&lineSync, &outputBuffer, &parseContext]( int curLineNum, int newLineNum, bool hasSource, int sourceNum, const char* sourceName) { // SourceNum is the number of the source-string that is being parsed. lineSync.syncToLine(curLineNum); - outputStream << "#line " << newLineNum; + outputBuffer += "#line "; + outputBuffer += std::to_string(newLineNum); if (hasSource) { - outputStream << " "; + outputBuffer += ' '; if (sourceName != nullptr) { - outputStream << "\"" << sourceName << "\""; + outputBuffer += '\"'; + outputBuffer += sourceName; + outputBuffer += '\"'; } else { - outputStream << sourceNum; + outputBuffer += std::to_string(sourceNum); } } if (parseContext.lineDirectiveShouldSetNextLine()) { @@ -1016,33 +1091,36 @@ // directive. So the new line number for the current line is newLineNum -= 1; } - outputStream << std::endl; + outputBuffer += '\n'; // And we are at the next line of the #line directive now. lineSync.setLineNum(newLineNum + 1); }); parseContext.setVersionCallback( - [&lineSync, &outputStream](int line, int version, const char* str) { + [&lineSync, &outputBuffer](int line, int version, const char* str) { lineSync.syncToLine(line); - outputStream << "#version " << version; + outputBuffer += "#version "; + outputBuffer += std::to_string(version); if (str) { - outputStream << " " << str; + outputBuffer += ' '; + outputBuffer += str; } }); - parseContext.setPragmaCallback([&lineSync, &outputStream]( + parseContext.setPragmaCallback([&lineSync, &outputBuffer]( int line, const glslang::TVector& ops) { lineSync.syncToLine(line); - outputStream << "#pragma "; + outputBuffer += "#pragma "; for(size_t i = 0; i < ops.size(); ++i) { - outputStream << ops[i]; + outputBuffer += ops[i].c_str(); } }); - parseContext.setErrorCallback([&lineSync, &outputStream]( + parseContext.setErrorCallback([&lineSync, &outputBuffer]( int line, const char* errorMessage) { lineSync.syncToLine(line); - outputStream << "#error " << errorMessage; + outputBuffer += "#error "; + outputBuffer += errorMessage; }); int lastToken = EndOfInput; // lastToken records the last token processed. @@ -1058,7 +1136,7 @@ // Don't emit whitespace onto empty lines. // Copy any whitespace characters at the start of a line // from the input to the output. - outputStream << std::string(ppToken.loc.column - 1, ' '); + outputBuffer += std::string(ppToken.loc.column - 1, ' '); } // Output a space in between tokens, but not at the start of a line, @@ -1068,13 +1146,17 @@ (unNeededSpaceTokens.find((char)token) == std::string::npos) && (unNeededSpaceTokens.find((char)lastToken) == std::string::npos) && (noSpaceBeforeTokens.find((char)token) == std::string::npos)) { - outputStream << " "; + outputBuffer += ' '; } lastToken = token; - outputStream << ppToken.name; + if (token == PpAtomConstString) + outputBuffer += "\""; + outputBuffer += ppToken.name; + if (token == PpAtomConstString) + outputBuffer += "\""; } while (true); - outputStream << std::endl; - *outputString = outputStream.str(); + outputBuffer += '\n'; + *outputString = std::move(outputBuffer); bool success = true; if (parseContext.getNumErrors() > 0) { @@ -1121,6 +1203,9 @@ // Return: True if there were no issues found in preprocessing, // False if during preprocessing any unknown version, pragmas or // extensions were found. +// +// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string +// is not an officially supported or fully working path. bool PreprocessDeferred( TCompiler* compiler, const char* const shaderStrings[], @@ -1265,7 +1350,7 @@ // // Cleanup symbol tables // -int __fastcall ShFinalize() +int ShFinalize() { glslang::GetGlobalLock(); --NumberOfClients; @@ -1568,14 +1653,17 @@ #include "../Include/revision.h" +#define QUOTE(s) #s +#define STR(n) QUOTE(n) + const char* GetEsslVersionString() { - return "OpenGL ES GLSL 3.20 glslang Khronos." GLSLANG_REVISION " " GLSLANG_DATE; + return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); } const char* GetGlslVersionString() { - return "4.60 glslang Khronos." GLSLANG_REVISION " " GLSLANG_DATE; + return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); } int GetKhronosToolId() @@ -1612,6 +1700,7 @@ environment.input.dialect = EShClientNone; environment.client.client = EShClientNone; environment.target.language = EShTargetNone; + environment.target.hlslFunctionality1 = false; } TShader::~TShader() @@ -1690,6 +1779,14 @@ void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } // Fragile: currently within one stage: simple auto-assignment of location void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } +void TShader::addUniformLocationOverride(const char* name, int loc) +{ + intermediate->addUniformLocationOverride(name, loc); +} +void TShader::setUniformLocationBase(int base) +{ + intermediate->setUniformLocationBase(base); +} // See comment above TDefaultHlslIoMapper in iomapper.cpp: void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } @@ -1721,6 +1818,9 @@ // Fill in a string with the result of preprocessing ShaderStrings // Returns true if all extensions, pragmas and version strings were valid. +// +// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string +// is not an officially supported or fully working path. bool TShader::preprocess(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, @@ -1881,12 +1981,27 @@ // Reflection implementation. // -bool TProgram::buildReflection() +bool TProgram::buildReflection(int opts) { if (! linked || reflection) return false; - reflection = new TReflection; + int firstStage = EShLangVertex, lastStage = EShLangFragment; + + if (opts & EShReflectionIntermediateIO) { + // if we're reflecting intermediate I/O, determine the first and last stage linked and use those as the + // boundaries for which stages generate pipeline inputs/outputs + firstStage = EShLangCount; + lastStage = 0; + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) { + firstStage = std::min(firstStage, s); + lastStage = std::max(lastStage, s); + } + } + } + + reflection = new TReflection((EShReflectionOptions)opts, (EShLanguage)firstStage, (EShLanguage)lastStage); for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { @@ -1898,25 +2013,23 @@ return true; } -int TProgram::getNumLiveUniformVariables() const { return reflection->getNumUniforms(); } -int TProgram::getNumLiveUniformBlocks() const { return reflection->getNumUniformBlocks(); } -const char* TProgram::getUniformName(int index) const { return reflection->getUniform(index).name.c_str(); } -const char* TProgram::getUniformBlockName(int index) const { return reflection->getUniformBlock(index).name.c_str(); } -int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; } -int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); } -int TProgram::getUniformBinding(int index) const { return reflection->getUniform(index).getBinding(); } -int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; } -int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; } -int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; } -int TProgram::getUniformBufferOffset(int index) const { return reflection->getUniform(index).offset; } -int TProgram::getUniformArraySize(int index) const { return reflection->getUniform(index).size; } -int TProgram::getNumLiveAttributes() const { return reflection->getNumAttributes(); } -const char* TProgram::getAttributeName(int index) const { return reflection->getAttribute(index).name.c_str(); } -int TProgram::getAttributeType(int index) const { return reflection->getAttribute(index).glDefineType; } -const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); } -const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); } -const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); } -unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } +unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } +int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); } + +int TProgram::getNumUniformVariables() const { return reflection->getNumUniforms(); } +const TObjectReflection& TProgram::getUniform(int index) const { return reflection->getUniform(index); } +int TProgram::getNumUniformBlocks() const { return reflection->getNumUniformBlocks(); } +const TObjectReflection& TProgram::getUniformBlock(int index) const { return reflection->getUniformBlock(index); } +int TProgram::getNumPipeInputs() const { return reflection->getNumPipeInputs(); } +const TObjectReflection& TProgram::getPipeInput(int index) const { return reflection->getPipeInput(index); } +int TProgram::getNumPipeOutputs() const { return reflection->getNumPipeOutputs(); } +const TObjectReflection& TProgram::getPipeOutput(int index) const { return reflection->getPipeOutput(index); } +int TProgram::getNumBufferVariables() const { return reflection->getNumBufferVariables(); } +const TObjectReflection& TProgram::getBufferVariable(int index) const { return reflection->getBufferVariable(index); } +int TProgram::getNumBufferBlocks() const { return reflection->getNumStorageBuffers(); } +const TObjectReflection& TProgram::getBufferBlock(int index) const { return reflection->getStorageBufferBlock(index); } +int TProgram::getNumAtomicCounters() const { return reflection->getNumAtomicCounters(); } +const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); } void TProgram::dumpReflection() { reflection->dump(); } diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -60,21 +62,25 @@ switch (basicType) { case EbtFloat: mangledName += 'f'; break; case EbtDouble: mangledName += 'd'; break; -#ifdef AMD_EXTENSIONS case EbtFloat16: mangledName += "f16"; break; -#endif case EbtInt: mangledName += 'i'; break; case EbtUint: mangledName += 'u'; break; - case EbtInt64: mangledName += "i64"; break; - case EbtUint64: mangledName += "u64"; break; -#ifdef AMD_EXTENSIONS + case EbtInt8: mangledName += "i8"; break; + case EbtUint8: mangledName += "u8"; break; case EbtInt16: mangledName += "i16"; break; case EbtUint16: mangledName += "u16"; break; -#endif + case EbtInt64: mangledName += "i64"; break; + case EbtUint64: mangledName += "u64"; break; case EbtBool: mangledName += 'b'; break; case EbtAtomicUint: mangledName += "au"; break; +#ifdef NV_EXTENSIONS + case EbtAccStructNV: mangledName += "asnv"; break; +#endif case EbtSampler: switch (sampler.type) { +#ifdef AMD_EXTENSIONS + case EbtFloat16: mangledName += "f16"; break; +#endif case EbtInt: mangledName += "i"; break; case EbtUint: mangledName += "u"; break; default: break; // some compilers want this @@ -93,6 +99,8 @@ mangledName += "S"; if (sampler.external) mangledName += "E"; + if (sampler.yuv) + mangledName += "Y"; switch (sampler.dim) { case Esd1D: mangledName += "1"; break; case Esd2D: mangledName += "2"; break; @@ -168,37 +176,77 @@ // Dump functions. // -void TVariable::dump(TInfoSink& infoSink) const +void TSymbol::dumpExtensions(TInfoSink& infoSink) const +{ + int numExtensions = getNumExtensions(); + if (numExtensions) { + infoSink.debug << " <"; + + for (int i = 0; i < numExtensions; i++) + infoSink.debug << getExtensions()[i] << ","; + + infoSink.debug << ">"; + } +} + +void TVariable::dump(TInfoSink& infoSink, bool complete) const { - infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString(); - if (type.isArray()) { - infoSink.debug << "[0]"; + if (complete) { + infoSink.debug << getName().c_str() << ": " << type.getCompleteString(); + dumpExtensions(infoSink); + } else { + infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " + << type.getBasicTypeString(); + + if (type.isArray()) + infoSink.debug << "[0]"; } + infoSink.debug << "\n"; } -void TFunction::dump(TInfoSink& infoSink) const +void TFunction::dump(TInfoSink& infoSink, bool complete) const { - infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " " << getMangledName().c_str() << "\n"; + if (complete) { + infoSink.debug << getName().c_str() << ": " << returnType.getCompleteString() << " " << getName().c_str() + << "("; + + int numParams = getParamCount(); + for (int i = 0; i < numParams; i++) { + const TParameter ¶m = parameters[i]; + infoSink.debug << param.type->getCompleteString() << " " + << (param.type->isStruct() ? "of " + param.type->getTypeName() + " " : "") + << (param.name ? *param.name : "") << (i < numParams - 1 ? "," : ""); + } + + infoSink.debug << ")"; + dumpExtensions(infoSink); + } else { + infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " " + << getMangledName().c_str() << "n"; + } + + infoSink.debug << "\n"; } -void TAnonMember::dump(TInfoSink& TInfoSink) const +void TAnonMember::dump(TInfoSink& TInfoSink, bool complete) const { - TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() << "\n"; + TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() + << "\n"; } -void TSymbolTableLevel::dump(TInfoSink &infoSink) const +void TSymbolTableLevel::dump(TInfoSink& infoSink, bool complete) const { tLevel::const_iterator it; for (it = level.begin(); it != level.end(); ++it) - (*it).second->dump(infoSink); + (*it).second->dump(infoSink, complete); } -void TSymbolTable::dump(TInfoSink &infoSink) const +void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const { for (int level = currentLevel(); level >= 0; --level) { infoSink.debug << "LEVEL " << level << "\n"; - table[level]->dump(infoSink); + table[level]->dump(infoSink, complete); } } @@ -281,19 +329,25 @@ { type.deepCopy(copyOf.type); userType = copyOf.userType; - numExtensions = 0; - extensions = 0; - if (copyOf.numExtensions != 0) - setExtensions(copyOf.numExtensions, copyOf.extensions); + + // we don't support specialization-constant subtrees in cloned tables, only extensions + constSubtree = nullptr; + extensions = nullptr; + memberExtensions = nullptr; + if (copyOf.getNumExtensions() > 0) + setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions()); + if (copyOf.hasMemberExtensions()) { + for (int m = 0; m < (int)copyOf.type.getStruct()->size(); ++m) { + if (copyOf.getNumMemberExtensions(m) > 0) + setMemberExtensions(m, copyOf.getNumMemberExtensions(m), copyOf.getMemberExtensions(m)); + } + } if (! copyOf.constArray.empty()) { assert(! copyOf.type.isStruct()); TConstUnionArray newArray(copyOf.constArray, 0, copyOf.constArray.size()); constArray = newArray; } - - // don't support specialization-constant subtrees in cloned tables - constSubtree = nullptr; } TVariable* TVariable::clone() const @@ -311,10 +365,9 @@ parameters.back().copyParam(copyOf.parameters[i]); } - numExtensions = 0; - extensions = 0; - if (copyOf.extensions != 0) - setExtensions(copyOf.numExtensions, copyOf.extensions); + extensions = nullptr; + if (copyOf.getNumExtensions() > 0) + setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions()); returnType.deepCopy(copyOf.returnType); mangledName = copyOf.mangledName; op = copyOf.op; @@ -353,12 +406,12 @@ const TAnonMember* anon = iter->second->getAsAnonMember(); if (anon) { // Insert all the anonymous members of this same container at once, - // avoid inserting the other members in the future, once this has been done, + // avoid inserting the remaining members in the future, once this has been done, // allowing them to all be part of the same new container. if (! containerCopied[anon->getAnonId()]) { TVariable* container = anon->getAnonContainer().clone(); container->changeName(NewPoolTString("")); - // insert the whole container + // insert the container and all its members symTableLevel->insert(*container, false); containerCopied[anon->getAnonId()] = true; } diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -78,10 +79,12 @@ class TFunction; class TAnonMember; +typedef TVector TExtensionList; + class TSymbol { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - explicit TSymbol(const TString *n) : name(n), numExtensions(0), extensions(0), writable(true) { } + explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { } virtual TSymbol* clone() const = 0; virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool @@ -103,18 +106,18 @@ virtual TType& getWritableType() = 0; virtual void setUniqueId(int id) { uniqueId = id; } virtual int getUniqueId() const { return uniqueId; } - virtual void setExtensions(int num, const char* const exts[]) + virtual void setExtensions(int numExts, const char* const exts[]) { assert(extensions == 0); - assert(num > 0); - numExtensions = num; - extensions = NewPoolObject(exts[0], num); - for (int e = 0; e < num; ++e) - extensions[e] = exts[e]; - } - virtual int getNumExtensions() const { return numExtensions; } - virtual const char** getExtensions() const { return extensions; } - virtual void dump(TInfoSink &infoSink) const = 0; + assert(numExts > 0); + extensions = NewPoolObject(extensions); + for (int e = 0; e < numExts; ++e) + extensions->push_back(exts[e]); + } + virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } + virtual const char** getExtensions() const { return extensions->data(); } + virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; + void dumpExtensions(TInfoSink& infoSink) const; virtual bool isReadOnly() const { return ! writable; } virtual void makeReadOnly() { writable = false; } @@ -128,8 +131,7 @@ // For tracking what extensions must be present // (don't use if correct version/profile is present). - int numExtensions; - const char** extensions; // an array of pointers to existing constant char strings + TExtensionList* extensions; // an array of pointers to existing constant char strings // // N.B.: Non-const functions that will be generally used should assert on this, @@ -154,7 +156,9 @@ : TSymbol(name), userType(uT), constSubtree(nullptr), - anonId(-1) { type.shallowCopy(t); } + memberExtensions(nullptr), + anonId(-1) + { type.shallowCopy(t); } virtual TVariable* clone() const; virtual ~TVariable() { } @@ -171,7 +175,25 @@ virtual void setAnonId(int i) { anonId = i; } virtual int getAnonId() const { return anonId; } - virtual void dump(TInfoSink &infoSink) const; + virtual void setMemberExtensions(int member, int numExts, const char* const exts[]) + { + assert(type.isStruct()); + assert(numExts > 0); + if (memberExtensions == nullptr) { + memberExtensions = NewPoolObject(memberExtensions); + memberExtensions->resize(type.getStruct()->size()); + } + for (int e = 0; e < numExts; ++e) + (*memberExtensions)[member].push_back(exts[e]); + } + virtual bool hasMemberExtensions() const { return memberExtensions != nullptr; } + virtual int getNumMemberExtensions(int member) const + { + return memberExtensions == nullptr ? 0 : (int)(*memberExtensions)[member].size(); + } + virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); } + + virtual void dump(TInfoSink& infoSink, bool complete = false) const; protected: explicit TVariable(const TVariable&); @@ -179,15 +201,14 @@ TType type; bool userType; + // we are assuming that Pool Allocator will free the memory allocated to unionArray // when this object is destroyed - // TODO: these two should be a union - // A variable could be a compile-time constant, or a specialization - // constant, or neither, but never both. - TConstUnionArray constArray; // for compile-time constant value - TIntermTyped* constSubtree; // for specialization constant computation - int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose + TConstUnionArray constArray; // for compile-time constant value + TIntermTyped* constSubtree; // for specialization constant computation + TVector* memberExtensions; // per-member extension list, allocated only when needed + int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose }; // @@ -293,7 +314,7 @@ virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } virtual const TParameter& operator[](int i) const { return parameters[i]; } - virtual void dump(TInfoSink &infoSink) const override; + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; protected: explicit TFunction(const TFunction&); @@ -324,35 +345,42 @@ // class TAnonMember : public TSymbol { public: - TAnonMember(const TString* n, unsigned int m, const TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { } - virtual TAnonMember* clone() const; + TAnonMember(const TString* n, unsigned int m, TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { } + virtual TAnonMember* clone() const override; virtual ~TAnonMember() { } - virtual const TAnonMember* getAsAnonMember() const { return this; } + virtual const TAnonMember* getAsAnonMember() const override { return this; } virtual const TVariable& getAnonContainer() const { return anonContainer; } virtual unsigned int getMemberNumber() const { return memberNumber; } - virtual const TType& getType() const + virtual const TType& getType() const override { const TTypeList& types = *anonContainer.getType().getStruct(); return *types[memberNumber].type; } - virtual TType& getWritableType() + virtual TType& getWritableType() override { assert(writable); const TTypeList& types = *anonContainer.getType().getStruct(); return *types[memberNumber].type; } + virtual void setExtensions(int numExts, const char* const exts[]) override + { + anonContainer.setMemberExtensions(memberNumber, numExts, exts); + } + virtual int getNumExtensions() const override { return anonContainer.getNumMemberExtensions(memberNumber); } + virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); } + virtual int getAnonId() const { return anonId; } - virtual void dump(TInfoSink &infoSink) const; + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; protected: explicit TAnonMember(const TAnonMember&); TAnonMember& operator=(const TAnonMember&); - const TVariable& anonContainer; + TVariable& anonContainer; unsigned int memberNumber; int anonId; }; @@ -514,7 +542,7 @@ void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); - void dump(TInfoSink &infoSink) const; + void dump(TInfoSink& infoSink, bool complete = false) const; TSymbolTableLevel* clone() const; void readOnly(); @@ -788,15 +816,34 @@ table[level]->setFunctionExtensions(name, num, extensions); } - void setVariableExtensions(const char* name, int num, const char* const extensions[]) + void setVariableExtensions(const char* name, int numExts, const char* const extensions[]) { TSymbol* symbol = find(TString(name)); - if (symbol) - symbol->setExtensions(num, extensions); + if (symbol == nullptr) + return; + + symbol->setExtensions(numExts, extensions); + } + + void setVariableExtensions(const char* blockName, const char* name, int numExts, const char* const extensions[]) + { + TSymbol* symbol = find(TString(blockName)); + if (symbol == nullptr) + return; + TVariable* variable = symbol->getAsVariable(); + assert(variable != nullptr); + + const TTypeList& structure = *variable->getAsVariable()->getType().getStruct(); + for (int member = 0; member < (int)structure.size(); ++member) { + if (structure[member].type->getFieldName().compare(name) == 0) { + variable->setMemberExtensions(member, numExts, extensions); + return; + } + } } int getMaxSymbolId() { return uniqueId; } - void dump(TInfoSink &infoSink) const; + void dump(TInfoSink& infoSink, bool complete = false) const; void copyTable(const TSymbolTable& copyOf); void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp love-11.3/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -155,6 +157,7 @@ extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable; extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable; extensionBehavior[E_GL_OES_EGL_image_external_essl3] = EBhDisable; + extensionBehavior[E_GL_EXT_YUV_target] = EBhDisable; extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable; extensionBehavior[E_GL_EXT_texture_array] = EBhDisable; extensionBehavior[E_GL_EXT_shadow_samplers] = EBhDisable; @@ -186,9 +189,31 @@ extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable; extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_arithmetic] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_ballot] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_shuffle] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable; + extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable; + extensionBehavior[E_GL_KHR_memory_scope_semantics] = EBhDisable; + + extensionBehavior[E_GL_EXT_shader_atomic_int64] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable; extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable; extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable; + extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable; + extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable; + extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable; + extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable; + extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable; + extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable; + extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable; + + extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable; // #line and #include extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; @@ -204,6 +229,7 @@ extensionBehavior[E_GL_AMD_gpu_shader_int16] = EBhDisable; extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable; extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable; + extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable; #endif #ifdef NV_EXTENSIONS @@ -214,8 +240,18 @@ extensionBehavior[E_GL_NVX_multiview_per_view_attributes] = EBhDisable; extensionBehavior[E_GL_NV_shader_atomic_int64] = EBhDisable; extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable; + extensionBehavior[E_GL_NV_shader_noperspective_interpolation] = EBhDisable; + extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable; + extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable; + extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable; + extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable; + extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable; + extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable; + extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable; #endif + extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable; + // AEP extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable; extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable; @@ -251,6 +287,16 @@ // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; extensionBehavior[E_GL_OVR_multiview2] = EBhDisable; + + // explicit types + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int8] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int16] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int32] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_int64] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float16] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = EBhDisable; } // Get code that is not part of a shared symbol table, is specific to this shader, @@ -267,6 +313,7 @@ "#define GL_EXT_frag_depth 1\n" "#define GL_OES_EGL_image_external 1\n" "#define GL_OES_EGL_image_external_essl3 1\n" + "#define GL_EXT_YUV_target 1\n" "#define GL_EXT_shader_texture_lod 1\n" "#define GL_EXT_shadow_samplers 1\n" @@ -299,6 +346,13 @@ "#define GL_OES_texture_cube_map_array 1\n" "#define GL_EXT_shader_non_constant_global_initializers 1\n" ; + +#ifdef NV_EXTENSIONS + if (profile == EEsProfile && version >= 300) { + preamble += "#define GL_NV_shader_noperspective_interpolation 1\n"; + } +#endif + } else { preamble = "#define GL_FRAGMENT_PRECISION_HIGH 1\n" @@ -331,6 +385,27 @@ "#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_EXT_shader_image_load_formatted 1\n" "#define GL_EXT_post_depth_coverage 1\n" + "#define GL_EXT_control_flow_attributes 1\n" + "#define GL_EXT_nonuniform_qualifier 1\n" + "#define GL_EXT_shader_16bit_storage 1\n" + "#define GL_EXT_shader_8bit_storage 1\n" + "#define GL_EXT_samplerless_texture_functions 1\n" + "#define GL_EXT_scalar_block_layout 1\n" + "#define GL_EXT_fragment_invocation_density 1\n" + "#define GL_EXT_buffer_reference 1\n" + "#define GL_EXT_buffer_reference2 1\n" + + // GL_KHR_shader_subgroup + "#define GL_KHR_shader_subgroup_basic 1\n" + "#define GL_KHR_shader_subgroup_vote 1\n" + "#define GL_KHR_shader_subgroup_arithmetic 1\n" + "#define GL_KHR_shader_subgroup_ballot 1\n" + "#define GL_KHR_shader_subgroup_shuffle 1\n" + "#define GL_KHR_shader_subgroup_shuffle_relative 1\n" + "#define GL_KHR_shader_subgroup_clustered 1\n" + "#define GL_KHR_shader_subgroup_quad 1\n" + + "#define E_GL_EXT_shader_atomic_int64 1\n" #ifdef AMD_EXTENSIONS "#define GL_AMD_shader_ballot 1\n" @@ -342,6 +417,7 @@ "#define GL_AMD_gpu_shader_int16 1\n" "#define GL_AMD_shader_image_load_store_lod 1\n" "#define GL_AMD_shader_fragment_mask 1\n" + "#define GL_AMD_gpu_shader_half_float_fetch 1\n" #endif #ifdef NV_EXTENSIONS @@ -350,7 +426,24 @@ "#define GL_NV_viewport_array2 1\n" "#define GL_NV_shader_atomic_int64 1\n" "#define GL_NV_conservative_raster_underestimation 1\n" + "#define GL_NV_shader_subgroup_partitioned 1\n" + "#define GL_NV_shading_rate_image 1\n" + "#define GL_NV_ray_tracing 1\n" + "#define GL_NV_fragment_shader_barycentric 1\n" + "#define GL_NV_compute_shader_derivatives 1\n" + "#define GL_NV_shader_texture_footprint 1\n" + "#define GL_NV_mesh_shader 1\n" #endif + "#define GL_NV_cooperative_matrix 1\n" + + "#define GL_EXT_shader_explicit_arithmetic_types 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_int16 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_int32 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_int64 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_float16 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_float32 1\n" + "#define GL_EXT_shader_explicit_arithmetic_types_float64 1\n" ; if (version >= 150) { @@ -429,6 +522,16 @@ case EShLangGeometry: return "geometry"; case EShLangFragment: return "fragment"; case EShLangCompute: return "compute"; +#ifdef NV_EXTENSIONS + case EShLangRayGenNV: return "ray-generation"; + case EShLangIntersectNV: return "intersection"; + case EShLangAnyHitNV: return "any-hit"; + case EShLangClosestHitNV: return "closest-hit"; + case EShLangMissNV: return "miss"; + case EShLangCallableNV: return "callable"; + case EShLangMeshNV: return "mesh"; + case EShLangTaskNV: return "task"; +#endif default: return "unknown stage"; } } @@ -573,7 +676,8 @@ // void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) { - if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; + if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) + return; // If we get this far, give errors explaining what extensions are needed if (numExtensions == 1) @@ -591,7 +695,8 @@ // void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) { - if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return; + if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) + return; // If we get this far, give errors explaining what extensions are needed if (numExtensions == 1) @@ -629,7 +734,8 @@ bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[]) { for (int i = 0; i < numExtensions; ++i) { - if (extensionTurnedOn(extensions[i])) return true; + if (extensionTurnedOn(extensions[i])) + return true; } return false; } @@ -654,6 +760,9 @@ return; } + // check if extension is used with correct shader stage + checkExtensionStage(getCurrentLoc(), extension); + // update the requested extension updateExtensionBehavior(extension, behavior); @@ -685,6 +794,27 @@ updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString); else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString); + // subgroup_* to subgroup_basic + else if (strcmp(extension, "GL_KHR_shader_subgroup_vote") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); + else if (strcmp(extension, "GL_KHR_shader_subgroup_arithmetic") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); + else if (strcmp(extension, "GL_KHR_shader_subgroup_ballot") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); + else if (strcmp(extension, "GL_KHR_shader_subgroup_shuffle") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); + else if (strcmp(extension, "GL_KHR_shader_subgroup_shuffle_relative") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); + else if (strcmp(extension, "GL_KHR_shader_subgroup_clustered") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); + else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); +#ifdef NV_EXTENSIONS + else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0) + updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); +#endif + else if (strcmp(extension, "GL_EXT_buffer_reference2") == 0) + updateExtensionBehavior(line, "GL_EXT_buffer_reference", behaviorString); } void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior) @@ -727,6 +857,20 @@ } } +// Check if extension is used with correct shader stage. +void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension) +{ +#ifdef NV_EXTENSIONS + // GL_NV_mesh_shader extension is only allowed in task/mesh shaders + if (strcmp(extension, "GL_NV_mesh_shader") == 0) { + requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask), + "#extension GL_NV_mesh_shader"); + profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader"); + profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader"); + } +#endif +} + // Call for any operation needing full GLSL integer data-type support. void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) { @@ -738,42 +882,223 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op) { requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 400, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 400, nullptr, op); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); +} + +// Call for any operation needing GLSL float16 data-type support. +void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_half_float, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} + +bool TParseVersions::float16Arithmetic() +{ + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_half_float, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float16}; + return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions); +} + +bool TParseVersions::int16Arithmetic() +{ + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_int16, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int16}; + return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions); +} + +bool TParseVersions::int8Arithmetic() +{ + const char* const extensions[] = { + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int8}; + return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions); +} + +void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) +{ + TString combined; + combined = op; + combined += ": "; + combined += featureDesc; + + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_half_float, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str()); +} + +void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) +{ + TString combined; + combined = op; + combined += ": "; + combined += featureDesc; + + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_int16, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str()); +} + +void TParseVersions::requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) +{ + TString combined; + combined = op; + combined += ": "; + combined += featureDesc; + + const char* const extensions[] = { + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int8}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str()); +} + +void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_half_float, +#endif + E_GL_EXT_shader_16bit_storage, + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} + +// Call for any operation needing GLSL float32 data-type support. +void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float32}; + requireExtensions(loc, 2, extensions, op); + } +} + +// Call for any operation needing GLSL float64 data-type support. +void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float64}; + requireExtensions(loc, 2, extensions, op); + requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); + } +} + +// Call for any operation needing GLSL explicit int8 data-type support. +void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int8}; + requireExtensions(loc, 2, extensions, op); + } } #ifdef AMD_EXTENSIONS -// Call for any operation needing GLSL 16-bit integer data-type support. -void TParseVersions::int16Check(const TSourceLoc& loc, const char* op, bool builtIn) +// Call for any operation needing GLSL float16 opaque-type support +void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { - requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_int16, "shader int16"); + requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float_fetch, op); requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); } } +#endif -// Call for any operation needing GLSL float16 data-type support. -void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn) +// Call for any operation needing GLSL explicit int16 data-type support. +void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { - requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float, "shader half float"); - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_int16, +#endif + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); } } + +void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + const char* const extensions[] = { +#if AMD_EXTENSIONS + E_GL_AMD_gpu_shader_int16, #endif + E_GL_EXT_shader_16bit_storage, + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} + +void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + const char* const extensions[] = { + E_GL_EXT_shader_8bit_storage, + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int8}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} + +// Call for any operation needing GLSL explicit int32 data-type support. +void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (! builtIn) { + const char* const extensions[2] = {E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int32}; + requireExtensions(loc, 2, extensions, op); + } +} // Call for any operation needing GLSL 64-bit integer data-type support. void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { - requireExtensions(loc, 1, &E_GL_ARB_gpu_shader_int64, "shader int64"); + const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64, + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_int64}; + requireExtensions(loc, 3, extensions, op); requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); + } +} + +void TParseVersions::fcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = {E_GL_NV_cooperative_matrix}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); } } @@ -787,7 +1112,7 @@ // Call for any operation removed because Vulkan SPIR-V is being generated. void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) { - if (spvVersion.vulkan >= 100) + if (spvVersion.vulkan > 0) error(loc, "not allowed when using GLSL for Vulkan", op, ""); } diff -Nru love-11.1/src/libraries/glslang/glslang/MachineIndependent/Versions.h love-11.3/src/libraries/glslang/glslang/MachineIndependent/Versions.h --- love-11.1/src/libraries/glslang/glslang/MachineIndependent/Versions.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/MachineIndependent/Versions.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -72,7 +74,7 @@ } // -// What source rules, validation rules, target language, etc. are needed +// What source rules, validation rules, target language, etc. are needed or // desired for SPIR-V? // // 0 means a target or rule set is not enabled (ignore rules from that entity). @@ -83,7 +85,7 @@ SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {} unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX" - int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use (100 means 1.0) + int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX" }; @@ -108,6 +110,7 @@ const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth"; const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external"; const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3"; +const char* const E_GL_EXT_YUV_target = "GL_EXT_YUV_target"; const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod"; const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers"; @@ -140,13 +143,36 @@ const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage"; const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array"; +const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic"; +const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote"; +const char* const E_GL_KHR_shader_subgroup_arithmetic = "GL_KHR_shader_subgroup_arithmetic"; +const char* const E_GL_KHR_shader_subgroup_ballot = "GL_KHR_shader_subgroup_ballot"; +const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_subgroup_shuffle"; +const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative"; +const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered"; +const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad"; +const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics"; + +const char* const E_GL_EXT_shader_atomic_int64 = "GL_EXT_shader_atomic_int64"; + const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers"; const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted"; +const char* const E_GL_EXT_shader_16bit_storage = "GL_EXT_shader_16bit_storage"; +const char* const E_GL_EXT_shader_8bit_storage = "GL_EXT_shader_8bit_storage"; + + // EXT extensions -const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; -const char* const E_GL_EXT_multiview = "GL_EXT_multiview"; -const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage"; +const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; +const char* const E_GL_EXT_multiview = "GL_EXT_multiview"; +const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage"; +const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes"; +const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier"; +const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions"; +const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout"; +const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density"; +const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference"; +const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2"; // Arrays of extensions for the above viewportEXTs duplications @@ -174,6 +200,7 @@ const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16"; const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod"; const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask"; +const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch"; #endif #ifdef NV_EXTENSIONS @@ -185,6 +212,14 @@ const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes"; const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64"; const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation"; +const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation"; +const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned"; +const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image"; +const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing"; +const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric"; +const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives"; +const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint"; +const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader"; // Arrays of extensions for the above viewportEXTs duplications @@ -192,6 +227,8 @@ const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]); #endif +const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix"; + // AEP const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced"; @@ -220,6 +257,16 @@ const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer"; const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array"; +// KHX +const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int32 = "GL_EXT_shader_explicit_arithmetic_types_int32"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int64 = "GL_EXT_shader_explicit_arithmetic_types_int64"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_shader_explicit_arithmetic_types_float16"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64"; + // Arrays of extensions for the above AEP duplications const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; diff -Nru love-11.1/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp love-11.3/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp --- love-11.1/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -45,7 +45,10 @@ #include #include #include + +#if !defined(__Fuchsia__) #include +#endif namespace glslang { @@ -70,7 +73,7 @@ // void OS_CleanupThreadData(void) { -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__Fuchsia__) DetachThreadLinux(NULL); #else int old_cancel_state, old_cancel_type; diff -Nru love-11.1/src/libraries/glslang/glslang/Public/ShaderLang.h love-11.3/src/libraries/glslang/glslang/Public/ShaderLang.h --- love-11.1/src/libraries/glslang/glslang/Public/ShaderLang.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/glslang/glslang/Public/ShaderLang.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,6 +1,7 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2013-2016 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -52,9 +53,6 @@ #define SH_IMPORT_EXPORT #else #define SH_IMPORT_EXPORT -#ifndef __fastcall -#define __fastcall -#endif #define C_DECL #endif @@ -67,6 +65,11 @@ extern "C" { #endif +// This should always increase, as some paths to do not consume +// a more major number. +// It should increment by one when new functionality is added. +#define GLSLANG_MINOR_VERSION 12 + // // Call before doing any other compiler/linker operations. // @@ -77,7 +80,7 @@ // // Call this at process shutdown to clean up memory. // -SH_IMPORT_EXPORT int __fastcall ShFinalize(); +SH_IMPORT_EXPORT int ShFinalize(); // // Types of languages the compiler can consume. @@ -89,6 +92,14 @@ EShLangGeometry, EShLangFragment, EShLangCompute, + EShLangRayGenNV, + EShLangIntersectNV, + EShLangAnyHitNV, + EShLangClosestHitNV, + EShLangMissNV, + EShLangCallableNV, + EShLangTaskNV, + EShLangMeshNV, EShLangCount, } EShLanguage; // would be better as stage, but this is ancient now @@ -99,6 +110,14 @@ EShLangGeometryMask = (1 << EShLangGeometry), EShLangFragmentMask = (1 << EShLangFragment), EShLangComputeMask = (1 << EShLangCompute), + EShLangRayGenNVMask = (1 << EShLangRayGenNV), + EShLangIntersectNVMask = (1 << EShLangIntersectNV), + EShLangAnyHitNVMask = (1 << EShLangAnyHitNV), + EShLangClosestHitNVMask = (1 << EShLangClosestHitNV), + EShLangMissNVMask = (1 << EShLangMissNV), + EShLangCallableNVMask = (1 << EShLangCallableNV), + EShLangTaskNVMask = (1 << EShLangTaskNV), + EShLangMeshNVMask = (1 << EShLangMeshNV), } EShLanguageMask; namespace glslang { @@ -119,9 +138,26 @@ typedef enum { EShTargetNone, - EshTargetSpv, + EShTargetSpv, // preferred spelling + EshTargetSpv = EShTargetSpv, // legacy spelling } EShTargetLanguage; +typedef enum { + EShTargetVulkan_1_0 = (1 << 22), + EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), + EShTargetOpenGL_450 = 450, +} EShTargetClientVersion; + +typedef EShTargetClientVersion EshTargetClientVersion; + +typedef enum { + EShTargetSpv_1_0 = (1 << 16), + EShTargetSpv_1_1 = (1 << 16) | (1 << 8), + EShTargetSpv_1_2 = (1 << 16) | (2 << 8), + EShTargetSpv_1_3 = (1 << 16) | (3 << 8), + EShTargetSpv_1_4 = (1 << 16) | (4 << 8), +} EShTargetLanguageVersion; + struct TInputLanguage { EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone @@ -131,12 +167,13 @@ struct TClient { EShClient client; - int version; // version of client itself (not the client's input dialect) + EShTargetClientVersion version; // version of client itself (not the client's input dialect) }; struct TTarget { EShTargetLanguage language; - unsigned int version; // the version to target, if SPIR-V, defined by "word 1" of the SPIR-V binary header + EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header + bool hlslFunctionality1; // can target hlsl_functionality1 extension(s) }; // All source/client/target versions and settings. @@ -194,9 +231,26 @@ EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules EShMsgDebugInfo = (1 << 10), // save debug information + EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL + EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages + EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers) + EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table }; // +// Options for building reflection +// +typedef enum { + EShReflectionDefault = 0, // default is original behaviour before options were added + EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes + EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection + EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader + EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately + EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive + EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks +} EShReflectionOptions; + +// // Build a table for bindings. This can be used for locating // attributes, uniforms, globals, etc., as needed. // @@ -334,11 +388,15 @@ EResCount }; -// Make one TShader per shader that you will link into a program. Then provide -// the shader through setStrings() or setStringsWithLengths(), then call parse(), -// then query the info logs. -// Optionally use setPreamble() to set a special shader string that will be -// processed before all others but won't affect the validity of #version. +// Make one TShader per shader that you will link into a program. Then +// - provide the shader through setStrings() or setStringsWithLengths() +// - optionally call setEnv*(), see below for more detail +// - optionally use setPreamble() to set a special shader string that will be +// processed before all others but won't affect the validity of #version +// - call parse(): source language and target environment must be selected +// either by correct setting of EShMessages sent to parse(), or by +// explicitly calling setEnv*() +// - query the info logs // // N.B.: Does not yet support having the same TShader instance being linked into // multiple programs. @@ -371,13 +429,18 @@ void setResourceSetBinding(const std::vector& base); void setAutoMapBindings(bool map); void setAutoMapLocations(bool map); + void addUniformLocationOverride(const char* name, int loc); + void setUniformLocationBase(int base); void setInvertY(bool invert); void setHlslIoMapping(bool hlslIoMap); void setFlattenUniformArrays(bool flatten); void setNoStorageFormat(bool useUnknownFormat); void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); - // For setting up the environment (initialized in the constructor): + // For setting up the environment (cleared to nothingness in the constructor). + // These must be called so that parsing is done for the right source language and + // target environment, either indirectly through TranslateEnvironment() based on + // EShMessages et. al., or directly by the user. void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version) { environment.input.languageFamily = lang; @@ -385,16 +448,18 @@ environment.input.dialect = client; environment.input.dialectVersion = version; } - void setEnvClient(EShClient client, int version) + void setEnvClient(EShClient client, EShTargetClientVersion version) { environment.client.client = client; environment.client.version = version; } - void setEnvTarget(EShTargetLanguage lang, unsigned int version) + void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version) { environment.target.language = lang; environment.target.version = version; } + void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; } + bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; } // Interface to #include handlers. // @@ -501,6 +566,8 @@ return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer); } + // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string + // is not an officially supported or fully working path. bool preprocess(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool forwardCompatible, EShMessages message, std::string* outputString, @@ -543,6 +610,41 @@ TShader& operator=(TShader&); }; +// +// A reflection database and its interface, consistent with the OpenGL API reflection queries. +// + +// Data needed for just a single object at the granularity exchanged by the reflection API +class TObjectReflection { +public: + TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex); + + const TType* getType() const { return type; } + int getBinding() const; + void dump() const; + static TObjectReflection badReflection() { return TObjectReflection(); } + + std::string name; + int offset; + int glDefineType; + int size; // data size in bytes for a block, array size for a (non-block) object that's an array + int index; + int counterIndex; + int numMembers; + int arrayStride; // stride of an array variable + int topLevelArrayStride; // stride of the top-level variable in a storage buffer member + EShLanguageMask stages; + +protected: + TObjectReflection() + : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0), + topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr) + { + } + + const TType* type; +}; + class TReflection; class TIoMapper; @@ -632,26 +734,89 @@ TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } // Reflection Interface - bool buildReflection(); // call first, to do liveness analysis, index mapping, etc.; returns false on failure - int getNumLiveUniformVariables() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) - int getNumLiveUniformBlocks() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) - const char* getUniformName(int index) const; // can be used for "name" part of glGetActiveUniform() - const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName() - int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) - int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices() - int getUniformBinding(int index) const; // returns the binding number - int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) - int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter. - int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) - int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) - int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) - int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + + // call first, to do liveness analysis, index mapping, etc.; returns false on failure + bool buildReflection(int opts = EShReflectionDefault); + unsigned getLocalSize(int dim) const; // return dim'th local size - const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib() - int getAttributeType(int index) const; // can be used for glGetActiveAttrib() - const TType* getUniformTType(int index) const; // returns a TType* - const TType* getUniformBlockTType(int index) const; // returns a TType* - const TType* getAttributeTType(int index) const; // returns a TType* + int getReflectionIndex(const char *name) const; + + int getNumUniformVariables() const; + const TObjectReflection& getUniform(int index) const; + int getNumUniformBlocks() const; + const TObjectReflection& getUniformBlock(int index) const; + int getNumPipeInputs() const; + const TObjectReflection& getPipeInput(int index) const; + int getNumPipeOutputs() const; + const TObjectReflection& getPipeOutput(int index) const; + int getNumBufferVariables() const; + const TObjectReflection& getBufferVariable(int index) const; + int getNumBufferBlocks() const; + const TObjectReflection& getBufferBlock(int index) const; + int getNumAtomicCounters() const; + const TObjectReflection& getAtomicCounter(int index) const; + + // Legacy Reflection Interface - expressed in terms of above interface + + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) + int getNumLiveUniformVariables() const { return getNumUniformVariables(); } + + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) + int getNumLiveUniformBlocks() const { return getNumUniformBlocks(); } + + // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + int getNumLiveAttributes() const { return getNumPipeInputs(); } + + // can be used for glGetUniformIndices() + int getUniformIndex(const char *name) const { return getReflectionIndex(name); } + + // can be used for "name" part of glGetActiveUniform() + const char *getUniformName(int index) const { return getUniform(index).name.c_str(); } + + // returns the binding number + int getUniformBinding(int index) const { return getUniform(index).getBinding(); } + + // returns Shaders Stages where a Uniform is present + EShLanguageMask getUniformStages(int index) const { return getUniform(index).stages; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) + int getUniformBlockIndex(int index) const { return getUniform(index).index; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) + int getUniformType(int index) const { return getUniform(index).glDefineType; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) + int getUniformBufferOffset(int index) const { return getUniform(index).offset; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) + int getUniformArraySize(int index) const { return getUniform(index).size; } + + // returns a TType* + const TType *getUniformTType(int index) const { return getUniform(index).getType(); } + + // can be used for glGetActiveUniformBlockName() + const char *getUniformBlockName(int index) const { return getUniformBlock(index).name.c_str(); } + + // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) + int getUniformBlockSize(int index) const { return getUniformBlock(index).size; } + + // returns the block binding number + int getUniformBlockBinding(int index) const { return getUniformBlock(index).getBinding(); } + + // returns block index of associated counter. + int getUniformBlockCounterIndex(int index) const { return getUniformBlock(index).counterIndex; } + + // returns a TType* + const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); } + + // can be used for glGetActiveAttrib() + const char *getAttributeName(int index) const { return getPipeInput(index).name.c_str(); } + + // can be used for glGetActiveAttrib() + int getAttributeType(int index) const { return getPipeInput(index).glDefineType; } + + // returns a TType* + const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); } void dumpReflection(); diff -Nru love-11.1/src/libraries/luasocket/luasocket.cpp love-11.3/src/libraries/luasocket/luasocket.cpp --- love-11.1/src/libraries/luasocket/luasocket.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/luasocket/luasocket.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/libraries/luasocket/luasocket.h love-11.3/src/libraries/luasocket/luasocket.h --- love-11.1/src/libraries/luasocket/luasocket.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/luasocket/luasocket.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/libraries/physfs/physfs_archiver_7z.c love-11.3/src/libraries/physfs/physfs_archiver_7z.c --- love-11.1/src/libraries/physfs/physfs_archiver_7z.c 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/physfs/physfs_archiver_7z.c 2019-10-27 13:44:49.000000000 +0000 @@ -203,6 +203,8 @@ SZIPinfo *info = (SZIPinfo *) opaque; if (info) { + if (info->io) + info->io->destroy(info->io); SzArEx_Free(&info->db, &SZIP_SzAlloc); __PHYSFS_DirTreeDeinit(&info->tree); allocator.Free(info); diff -Nru love-11.1/src/libraries/physfs/physfs.c love-11.3/src/libraries/physfs/physfs.c --- love-11.1/src/libraries/physfs/physfs.c 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/physfs/physfs.c 2019-10-27 13:44:49.000000000 +0000 @@ -46,6 +46,8 @@ void *opaque; /* Instance data unique to the archiver. */ char *dirName; /* Path to archive in platform-dependent notation. */ char *mountPoint; /* Mountpoint in virtual file tree. */ + char *root; /* subdirectory of archiver to use as root of archive (NULL for actual root) */ + size_t rootlen; /* subdirectory of archiver to use as root of archive (NULL for actual root) */ const PHYSFS_Archiver *funcs; /* Ptr to archiver info for this handle. */ struct __PHYSFS_DIRHANDLE__ *next; /* linked list stuff. */ } DirHandle; @@ -86,6 +88,7 @@ static PHYSFS_Archiver **archivers = NULL; static PHYSFS_ArchiveInfo **archiveInfo = NULL; static volatile size_t numArchivers = 0; +static size_t longest_root = 0; /* mutexes ... */ static void *errorLock = NULL; /* protects error message list. */ @@ -879,13 +882,20 @@ if (io == NULL) { + /* file doesn't exist, etc? Just fail out. */ + PHYSFS_Stat statbuf; + BAIL_IF_ERRPASS(!__PHYSFS_platformStat(d, &statbuf, 1), NULL); + /* DIR gets first shot (unlike the rest, it doesn't deal with files). */ - retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed); - if (retval || claimed) - return retval; + if (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY) + { + retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed); + if (retval || claimed) + return retval; + } /* if */ io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r'); - BAIL_IF_ERRPASS(!io, 0); + BAIL_IF_ERRPASS(!io, NULL); created_io = 1; } /* if */ @@ -973,6 +983,18 @@ } /* sanitizePlatformIndependentPath */ +static inline size_t dirHandleRootLen(const DirHandle *h) +{ + return h ? h->rootlen : 0; +} /* dirHandleRootLen */ + +static inline int sanitizePlatformIndependentPathWithRoot(const DirHandle *h, const char *src, char *dst) +{ + return sanitizePlatformIndependentPath(src, dst + dirHandleRootLen(h)); +} /* sanitizePlatformIndependentPathWithRoot */ + + + /* * Figure out if (fname) is part of (h)'s mountpoint. (fname) must be an * output from sanitizePlatformIndependentPath(), so that it is in a known @@ -1371,6 +1393,7 @@ archivers = NULL; } /* if */ + longest_root = 0; allowSymLinks = 0; initialized = 0; @@ -1677,6 +1700,54 @@ } /* PHYSFS_setWriteDir */ +int PHYSFS_setRoot(const char *archive, const char *subdir) +{ + DirHandle *i; + + BAIL_IF(!archive, PHYSFS_ERR_INVALID_ARGUMENT, 0); + + __PHYSFS_platformGrabMutex(stateLock); + + for (i = searchPath; i != NULL; i = i->next) + { + if ((i->dirName != NULL) && (strcmp(archive, i->dirName) == 0)) + { + if (!subdir || (strcmp(subdir, "/") == 0)) + { + if (i->root) + allocator.Free(i->root); + i->root = NULL; + i->rootlen = 0; + } /* if */ + else + { + const size_t len = strlen(subdir) + 1; + char *ptr = (char *) allocator.Malloc(len); + BAIL_IF_MUTEX(!ptr, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); + if (!sanitizePlatformIndependentPath(subdir, ptr)) + { + allocator.Free(ptr); + BAIL_MUTEX_ERRPASS(stateLock, 0); + } /* if */ + + if (i->root) + allocator.Free(i->root); + i->root = ptr; + i->rootlen = len; + + if (longest_root < len) + longest_root = len; + } /* else */ + + break; + } /* if */ + } /* for */ + + __PHYSFS_platformReleaseMutex(stateLock); + return 1; +} /* PHYSFS_setRoot */ + + static int doMount(PHYSFS_Io *io, const char *fname, const char *mountPoint, int appendToPath) { @@ -1994,6 +2065,9 @@ * like ".." which should be done once instead of once per archive. This also * gives us license to treat (fname) as scratch space in this function. * + * (fname)'s buffer must have enough space available before it for this + * function to prepend any root directory for this DirHandle. + * * Returns non-zero if string is safe, zero if there's a security issue. * PHYSFS_getLastError() will specify what was wrong. (*fname) will be * updated to point past any mount point elements so it is prepared to @@ -2006,7 +2080,7 @@ char *start; char *end; - if (*fname == '\0') /* quick rejection. */ + if ((*fname == '\0') && (!h->root)) /* quick rejection. */ return 1; /* !!! FIXME: This codeblock sucks. */ @@ -2029,6 +2103,17 @@ retval = 1; /* may be reset, below. */ } /* if */ + /* prepend the root directory, if any. */ + if (h->root) + { + const int isempty = (*fname == '\0'); + fname -= h->rootlen - 1; + strcpy(fname, h->root); + if (!isempty) + fname[h->rootlen - 2] = '/'; + *_fname = fname; + } /* if */ + start = fname; if (!allowSymLinks) { @@ -2074,20 +2159,19 @@ } /* verifyPath */ +/* This must hold the stateLock before calling. */ static int doMkdir(const char *_dname, char *dname) { - DirHandle *h; + DirHandle *h = writeDir; char *start; char *end; int retval = 0; int exists = 1; /* force existance check on first path element. */ - BAIL_IF_ERRPASS(!sanitizePlatformIndependentPath(_dname, dname), 0); + assert(h != NULL); - __PHYSFS_platformGrabMutex(stateLock); - BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0); - h = writeDir; - BAIL_IF_MUTEX_ERRPASS(!verifyPath(h, &dname, 1), stateLock, 0); + BAIL_IF_ERRPASS(!sanitizePlatformIndependentPathWithRoot(h, _dname, dname), 0); + BAIL_IF_ERRPASS(!verifyPath(h, &dname, 1), 0); start = dname; while (1) @@ -2119,7 +2203,6 @@ start = end + 1; } /* while */ - __PHYSFS_platformReleaseMutex(stateLock); return retval; } /* doMkdir */ @@ -2131,30 +2214,26 @@ size_t len; BAIL_IF(!_dname, PHYSFS_ERR_INVALID_ARGUMENT, 0); - len = strlen(_dname) + 1; + + __PHYSFS_platformGrabMutex(stateLock); + BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0); + len = strlen(_dname) + dirHandleRootLen(writeDir) + 1; dname = (char *) __PHYSFS_smallAlloc(len); - BAIL_IF(!dname, PHYSFS_ERR_OUT_OF_MEMORY, 0); + BAIL_IF_MUTEX(!dname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); retval = doMkdir(_dname, dname); + __PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_smallFree(dname); return retval; } /* PHYSFS_mkdir */ +/* This must hold the stateLock before calling. */ static int doDelete(const char *_fname, char *fname) { - int retval; - DirHandle *h; - BAIL_IF_ERRPASS(!sanitizePlatformIndependentPath(_fname, fname), 0); - - __PHYSFS_platformGrabMutex(stateLock); - - BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0); - h = writeDir; - BAIL_IF_MUTEX_ERRPASS(!verifyPath(h, &fname, 0), stateLock, 0); - retval = h->funcs->remove(h->opaque, fname); - - __PHYSFS_platformReleaseMutex(stateLock); - return retval; + DirHandle *h = writeDir; + BAIL_IF_ERRPASS(!sanitizePlatformIndependentPathWithRoot(h, _fname, fname), 0); + BAIL_IF_ERRPASS(!verifyPath(h, &fname, 0), 0); + return h->funcs->remove(h->opaque, fname); } /* doDelete */ @@ -2164,11 +2243,13 @@ char *fname; size_t len; - BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0); - len = strlen(_fname) + 1; + __PHYSFS_platformGrabMutex(stateLock); + BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0); + len = strlen(_fname) + dirHandleRootLen(writeDir) + 1; fname = (char *) __PHYSFS_smallAlloc(len); - BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0); + BAIL_IF_MUTEX(!fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); retval = doDelete(_fname, fname); + __PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_smallFree(fname); return retval; } /* PHYSFS_delete */ @@ -2177,17 +2258,20 @@ static DirHandle *getRealDirHandle(const char *_fname) { DirHandle *retval = NULL; + char *allocated_fname = NULL; char *fname = NULL; size_t len; BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, NULL); - len = strlen(_fname) + 1; - fname = __PHYSFS_smallAlloc(len); - BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, NULL); + + __PHYSFS_platformGrabMutex(stateLock); + len = strlen(_fname) + longest_root + 1; + allocated_fname = __PHYSFS_smallAlloc(len); + BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, NULL); + fname = allocated_fname + longest_root; if (sanitizePlatformIndependentPath(_fname, fname)) { DirHandle *i; - __PHYSFS_platformGrabMutex(stateLock); for (i = searchPath; i != NULL; i = i->next) { char *arcfname = fname; @@ -2206,10 +2290,10 @@ } /* if */ } /* if */ } /* for */ - __PHYSFS_platformReleaseMutex(stateLock); } /* if */ - __PHYSFS_smallFree(fname); + __PHYSFS_platformReleaseMutex(stateLock); + __PHYSFS_smallFree(allocated_fname); return retval; } /* getRealDirHandle */ @@ -2404,15 +2488,18 @@ { PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; size_t len; + char *allocated_fname; char *fname; BAIL_IF(!_fn, PHYSFS_ERR_INVALID_ARGUMENT, 0); BAIL_IF(!cb, PHYSFS_ERR_INVALID_ARGUMENT, 0); - len = strlen(_fn) + 1; - fname = (char *) __PHYSFS_smallAlloc(len); - BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0); + __PHYSFS_platformGrabMutex(stateLock); + len = strlen(_fn) + longest_root + 1; + allocated_fname = (char *) __PHYSFS_smallAlloc(len); + BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); + fname = allocated_fname + longest_root; if (!sanitizePlatformIndependentPath(_fn, fname)) retval = PHYSFS_ENUM_STOP; else @@ -2420,8 +2507,6 @@ DirHandle *i; SymlinkFilterData filterdata; - __PHYSFS_platformGrabMutex(stateLock); - if (!allowSymLinks) { memset(&filterdata, '\0', sizeof (filterdata)); @@ -2470,10 +2555,11 @@ } /* else if */ } /* for */ - __PHYSFS_platformReleaseMutex(stateLock); } /* if */ - __PHYSFS_smallFree(fname); + __PHYSFS_platformReleaseMutex(stateLock); + + __PHYSFS_smallFree(allocated_fname); return (retval == PHYSFS_ENUM_ERROR) ? 0 : 1; } /* PHYSFS_enumerate */ @@ -2534,57 +2620,58 @@ } /* PHYSFS_isSymbolicLink */ -static PHYSFS_File *doOpenWrite(const char *_fname, int appending) +static PHYSFS_File *doOpenWrite(const char *_fname, const int appending) { FileHandle *fh = NULL; + DirHandle *h; size_t len; char *fname; BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0); - len = strlen(_fname) + 1; - fname = (char *) __PHYSFS_smallAlloc(len); - BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0); - if (sanitizePlatformIndependentPath(_fname, fname)) - { - PHYSFS_Io *io = NULL; - DirHandle *h = NULL; - const PHYSFS_Archiver *f; - - __PHYSFS_platformGrabMutex(stateLock); - - GOTO_IF(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, doOpenWriteEnd); - - h = writeDir; - GOTO_IF_ERRPASS(!verifyPath(h, &fname, 0), doOpenWriteEnd); + __PHYSFS_platformGrabMutex(stateLock); - f = h->funcs; - if (appending) - io = f->openAppend(h->opaque, fname); - else - io = f->openWrite(h->opaque, fname); + h = writeDir; + BAIL_IF_MUTEX(!h, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0); - GOTO_IF_ERRPASS(!io, doOpenWriteEnd); + len = strlen(_fname) + dirHandleRootLen(h) + 1; + fname = (char *) __PHYSFS_smallAlloc(len); + BAIL_IF_MUTEX(!fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); - fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle)); - if (fh == NULL) - { - io->destroy(io); - GOTO(PHYSFS_ERR_OUT_OF_MEMORY, doOpenWriteEnd); - } /* if */ - else + if (sanitizePlatformIndependentPathWithRoot(h, _fname, fname)) + { + PHYSFS_Io *io = NULL; + char *arcfname = fname; + if (verifyPath(h, &arcfname, 0)) { - memset(fh, '\0', sizeof (FileHandle)); - fh->io = io; - fh->dirHandle = h; - fh->next = openWriteList; - openWriteList = fh; - } /* else */ + const PHYSFS_Archiver *f = h->funcs; + if (appending) + io = f->openAppend(h->opaque, arcfname); + else + io = f->openWrite(h->opaque, arcfname); - doOpenWriteEnd: - __PHYSFS_platformReleaseMutex(stateLock); + if (io) + { + fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle)); + if (fh == NULL) + { + io->destroy(io); + PHYSFS_setErrorCode(PHYSFS_ERR_OUT_OF_MEMORY); + } /* if */ + else + { + memset(fh, '\0', sizeof (FileHandle)); + fh->io = io; + fh->dirHandle = h; + fh->next = openWriteList; + openWriteList = fh; + } /* else */ + } /* if */ + } /* if */ } /* if */ + __PHYSFS_platformReleaseMutex(stateLock); + __PHYSFS_smallFree(fname); return ((PHYSFS_File *) fh); } /* doOpenWrite */ @@ -2605,22 +2692,25 @@ PHYSFS_File *PHYSFS_openRead(const char *_fname) { FileHandle *fh = NULL; + char *allocated_fname; char *fname; size_t len; BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0); - len = strlen(_fname) + 1; - fname = (char *) __PHYSFS_smallAlloc(len); - BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0); + + __PHYSFS_platformGrabMutex(stateLock); + + BAIL_IF_MUTEX(!searchPath, PHYSFS_ERR_NOT_FOUND, stateLock, 0); + + len = strlen(_fname) + longest_root + 1; + allocated_fname = (char *) __PHYSFS_smallAlloc(len); + BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); + fname = allocated_fname + longest_root; if (sanitizePlatformIndependentPath(_fname, fname)) { - DirHandle *i = NULL; PHYSFS_Io *io = NULL; - - __PHYSFS_platformGrabMutex(stateLock); - - GOTO_IF(!searchPath, PHYSFS_ERR_NOT_FOUND, openReadEnd); + DirHandle *i; for (i = searchPath; i != NULL; i = i->next) { @@ -2633,27 +2723,26 @@ } /* if */ } /* for */ - GOTO_IF_ERRPASS(!io, openReadEnd); - - fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle)); - if (fh == NULL) + if (io) { - io->destroy(io); - GOTO(PHYSFS_ERR_OUT_OF_MEMORY, openReadEnd); - } /* if */ - - memset(fh, '\0', sizeof (FileHandle)); - fh->io = io; - fh->forReading = 1; - fh->dirHandle = i; - fh->next = openReadList; - openReadList = fh; + fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle)); + if (fh == NULL) + { + io->destroy(io); + PHYSFS_setErrorCode(PHYSFS_ERR_OUT_OF_MEMORY); + } /* if */ - openReadEnd: - __PHYSFS_platformReleaseMutex(stateLock); + memset(fh, '\0', sizeof (FileHandle)); + fh->io = io; + fh->forReading = 1; + fh->dirHandle = i; + fh->next = openReadList; + openReadList = fh; + } /* if */ } /* if */ - __PHYSFS_smallFree(fname); + __PHYSFS_platformReleaseMutex(stateLock); + __PHYSFS_smallFree(allocated_fname); return ((PHYSFS_File *) fh); } /* PHYSFS_openRead */ @@ -2662,7 +2751,6 @@ { FileHandle *prev = NULL; FileHandle *i; - int rc = 1; for (i = *list; i != NULL; i = i->next) { @@ -2670,9 +2758,19 @@ { PHYSFS_Io *io = handle->io; PHYSFS_uint8 *tmp = handle->buffer; - rc = PHYSFS_flush((PHYSFS_File *) handle); - if (!rc) - return -1; + + /* send our buffer to io... */ + if (!handle->forReading) + { + if (!PHYSFS_flush((PHYSFS_File *) handle)) + return -1; + + /* ...then have io send it to the disk... */ + else if (io->flush && !io->flush(io)) + return -1; + } /* if */ + + /* ...then close the underlying file. */ io->destroy(io); if (tmp != NULL) /* free any associated buffer. */ @@ -2970,21 +3068,19 @@ rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos); BAIL_IF_ERRPASS(rc <= 0, 0); fh->bufpos = fh->buffill = 0; - return io->flush ? io->flush(io) : 1; + return 1; } /* PHYSFS_flush */ int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat) { int retval = 0; + char *allocated_fname; char *fname; size_t len; BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0); BAIL_IF(!stat, PHYSFS_ERR_INVALID_ARGUMENT, 0); - len = strlen(_fname) + 1; - fname = (char *) __PHYSFS_smallAlloc(len); - BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0); /* set some sane defaults... */ stat->filesize = -1; @@ -2994,6 +3090,12 @@ stat->filetype = PHYSFS_FILETYPE_OTHER; stat->readonly = 1; + __PHYSFS_platformGrabMutex(stateLock); + len = strlen(_fname) + longest_root + 1; + allocated_fname = (char *) __PHYSFS_smallAlloc(len); + BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0); + fname = allocated_fname + longest_root; + if (sanitizePlatformIndependentPath(_fname, fname)) { if (*fname == '\0') @@ -3006,7 +3108,6 @@ { DirHandle *i; int exists = 0; - __PHYSFS_platformGrabMutex(stateLock); for (i = searchPath; ((i != NULL) && (!exists)); i = i->next) { char *arcfname = fname; @@ -3024,11 +3125,11 @@ exists = 1; } /* else if */ } /* for */ - __PHYSFS_platformReleaseMutex(stateLock); } /* else */ } /* if */ - __PHYSFS_smallFree(fname); + __PHYSFS_platformReleaseMutex(stateLock); + __PHYSFS_smallFree(allocated_fname); return retval; } /* PHYSFS_stat */ diff -Nru love-11.1/src/libraries/physfs/physfs.h love-11.3/src/libraries/physfs/physfs.h --- love-11.1/src/libraries/physfs/physfs.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/physfs/physfs.h 2019-10-27 13:44:49.000000000 +0000 @@ -225,11 +225,11 @@ #if defined(PHYSFS_DECL) /* do nothing. */ -#elif (defined _MSC_VER) +#elif defined(_MSC_VER) #define PHYSFS_DECL __declspec(dllexport) -#elif (defined __SUNPRO_C) +#elif defined(__SUNPRO_C) #define PHYSFS_DECL __global -#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun)) +#elif ((__GNUC__ >= 3) && (!defined(__EMX__)) && (!defined(sun))) #define PHYSFS_DECL __attribute__((visibility("default"))) #else #define PHYSFS_DECL @@ -433,8 +433,8 @@ #ifndef DOXYGEN_SHOULD_IGNORE_THIS #define PHYSFS_VER_MAJOR 3 -#define PHYSFS_VER_MINOR 0 -#define PHYSFS_VER_PATCH 1 +#define PHYSFS_VER_MINOR 1 +#define PHYSFS_VER_PATCH 0 #endif /* DOXYGEN_SHOULD_IGNORE_THIS */ @@ -3844,6 +3844,46 @@ /* Everything above this line is part of the PhysicsFS 2.1 API. */ + +/** + * \fn int PHYSFS_setRoot(const char *archive, const char *subdir) + * \brief Make a subdirectory of an archive its root directory. + * + * This lets you narrow down the accessible files in a specific archive. For + * example, if you have x.zip with a file in y/z.txt, mounted to /a, if you + * call PHYSFS_setRoot("x.zip", "/y"), then the call + * PHYSFS_openRead("/a/z.txt") will succeed. + * + * You can change an archive's root at any time, altering the interpolated + * file tree (depending on where paths shift, a different archive may be + * providing various files). If you set the root to NULL or "/", the + * archive will be treated as if no special root was set (as if the archive + * was just mounted normally). + * + * Changing the root only affects future operations on pathnames; a file + * that was opened from a path that changed due to a setRoot will not be + * affected. + * + * Setting a new root is not limited to archives in the search path; you may + * set one on the write dir, too, which might be useful if you have files + * open for write and thus can't change the write dir at the moment. + * + * It is not an error to set a subdirectory that does not exist to be the + * root of an archive; however, no files will be visible in this case. If + * the missing directories end up getting created (a mkdir to the physical + * filesystem, etc) then this will be reflected in the interpolated tree. + * + * \param archive dir/archive on which to change root. + * \param subdir new subdirectory to make the root of this archive. + * \return nonzero on success, zero on failure. Use + * PHYSFS_getLastErrorCode() to obtain the specific error. + */ +PHYSFS_DECL int PHYSFS_setRoot(const char *archive, const char *subdir); + + +/* Everything above this line is part of the PhysicsFS 3.1 API. */ + + #ifdef __cplusplus } #endif diff -Nru love-11.1/src/libraries/physfs/physfs_internal.h love-11.3/src/libraries/physfs/physfs_internal.h --- love-11.1/src/libraries/physfs/physfs_internal.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/physfs/physfs_internal.h 2019-10-27 13:44:49.000000000 +0000 @@ -162,35 +162,44 @@ #define free(x) Do not use free() directly. /* !!! FIXME: add alloca check here. */ + +/* by default, enable things, so builds can opt out of a few things they + want to avoid. But you can build with this #defined to 0 if you would + like to turn off everything except a handful of things you opt into. */ +#ifndef PHYSFS_SUPPORTS_DEFAULT +#define PHYSFS_SUPPORTS_DEFAULT 1 +#endif + + #ifndef PHYSFS_SUPPORTS_ZIP -#define PHYSFS_SUPPORTS_ZIP 1 +#define PHYSFS_SUPPORTS_ZIP PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_7Z -#define PHYSFS_SUPPORTS_7Z 1 +#define PHYSFS_SUPPORTS_7Z PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_GRP -#define PHYSFS_SUPPORTS_GRP 1 +#define PHYSFS_SUPPORTS_GRP PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_HOG -#define PHYSFS_SUPPORTS_HOG 1 +#define PHYSFS_SUPPORTS_HOG PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_MVL -#define PHYSFS_SUPPORTS_MVL 1 +#define PHYSFS_SUPPORTS_MVL PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_WAD -#define PHYSFS_SUPPORTS_WAD 1 +#define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_QPAK -#define PHYSFS_SUPPORTS_QPAK 1 +#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_SLB -#define PHYSFS_SUPPORTS_SLB 1 +#define PHYSFS_SUPPORTS_SLB PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_ISO9660 -#define PHYSFS_SUPPORTS_ISO9660 1 +#define PHYSFS_SUPPORTS_ISO9660 PHYSFS_SUPPORTS_DEFAULT #endif #ifndef PHYSFS_SUPPORTS_VDF -#define PHYSFS_SUPPORTS_VDF 1 +#define PHYSFS_SUPPORTS_VDF PHYSFS_SUPPORTS_DEFAULT #endif #if PHYSFS_SUPPORTS_7Z diff -Nru love-11.1/src/libraries/physfs/physfs_miniz.h love-11.3/src/libraries/physfs/physfs_miniz.h --- love-11.1/src/libraries/physfs/physfs_miniz.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/physfs/physfs_miniz.h 2019-10-27 13:44:49.000000000 +0000 @@ -699,3 +699,4 @@ For more information, please refer to */ + diff -Nru love-11.1/src/libraries/physfs/physfs_platform_windows.c love-11.3/src/libraries/physfs/physfs_platform_windows.c --- love-11.1/src/libraries/physfs/physfs_platform_windows.c 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/physfs/physfs_platform_windows.c 2019-10-27 13:44:49.000000000 +0000 @@ -566,18 +566,26 @@ else { DWORD psize = 0; - WCHAR dummy = 0; LPWSTR wstr = NULL; BOOL rc = 0; /* * Should fail. Will write the size of the profile path in * psize. Also note that the second parameter can't be - * NULL or the function fails. + * NULL or the function fails on Windows XP, but has to be NULL on + * Windows 10 or it will fail. :( */ - rc = pGetDir(accessToken, &dummy, &psize); + rc = pGetDir(accessToken, NULL, &psize); GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */ + if (psize == 0) /* probably on Windows XP, try a different way. */ + { + WCHAR x = 0; + rc = pGetDir(accessToken, &x, &psize); + GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */ + GOTO_IF(!psize, PHYSFS_ERR_OS_ERROR, done); /* Uhoh... */ + } /* if */ + /* Allocate memory for the profile directory */ wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR)); if (wstr != NULL) diff -Nru love-11.1/src/libraries/stb/stb_image.h love-11.3/src/libraries/stb/stb_image.h --- love-11.1/src/libraries/stb/stb_image.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/stb/stb_image.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ -/* stb_image - v2.16 - public domain image loader - http://nothings.org/stb_image.h - no warranty implied; use at your own risk +/* stb_image - v2.22 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk Do this: #define STB_IMAGE_IMPLEMENTATION @@ -48,6 +48,12 @@ RECENT REVISION HISTORY: + 2.22 (2019-03-04) gif fixes, fix warnings + 2.21 (2019-02-25) fix typo in comment + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs @@ -74,29 +80,31 @@ Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) github:urraka (animated gif) Junggon Kim (PNM comments) - Daniel Gibson (16-bit TGA) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) socks-the-fox (16-bit PNG) Jeremy Sawicki (handle all ImageNet JPGs) - Optimizations & bugfixes - Fabian "ryg" Giesen + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) Arseny Kapoulkine John-Mark Allen + Carmelo J Fdez-Aguera Bug & warning fixes Marc LeBlanc David Woo Guillaume George Martins Mozeiko Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan Dave Moore Roy Eltham Hayaki Saito Nathan Reed Won Chun Luke Graham Johan Duparc Nick Verigakis - the Horde3D community Thomas Ruf Ronny Chevalier Baldur Karlsson - Janez Zemva John Bartholomew Michal Cichon github:rlyeh - Jonathan Blow Ken Hamada Tero Hanninen github:romigrou - Laurent Gomila Cort Stratton Sergio Gonzalez github:svdijk - Aruelien Pocheville Thibault Reuille Cass Everitt github:snagar - Ryamond Barbiero Paul Du Bois Engin Manap github:Zelex - Michaelangel007@github Philipp Wiesemann Dale Weiler github:grim210 - Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:sammyhw - Blazej Dariusz Roszkowski Gregory Mullen github:phprus - Christian Floisand Kevin Schmidt github:poppolopoppo + the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar + Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex + Ryamond Barbiero Paul Du Bois Engin Manap github:grim210 + Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw + Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus + Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo + Christian Floisand Kevin Schmidt JR Smith github:darealshinji + Blazej Dariusz Roszkowski github:Michaelangel007 */ #ifndef STBI_INCLUDE_STB_IMAGE_H @@ -105,10 +113,8 @@ // DOCUMENTATION // // Limitations: -// - no 16-bit-per-channel PNG // - no 12-bit-per-channel JPEG // - no JPEGs with arithmetic coding -// - no 1-bit BMP // - GIF always returns *comp=4 // // Basic usage (see HDR discussion below for HDR usage): @@ -159,6 +165,16 @@ // // =========================================================================== // +// UNICODE: +// +// If compiling for Windows and you wish to use Unicode filenames, compile +// with +// #define STBI_WINDOWS_UTF8 +// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert +// Windows wchar_t filenames to utf8. +// +// =========================================================================== +// // Philosophy // // stb libraries are designed with the following priorities: @@ -169,12 +185,12 @@ // // Sometimes I let "good performance" creep up in priority over "easy to maintain", // and for best performance I may provide less-easy-to-use APIs that give higher -// performance, in addition to the easy to use ones. Nevertheless, it's important +// performance, in addition to the easy-to-use ones. Nevertheless, it's important // to keep in mind that from the standpoint of you, a client of this library, // all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. // // Some secondary priorities arise directly from the first two, some of which -// make more explicit reasons why performance can't be emphasized. +// provide more explicit reasons why performance can't be emphasized. // // - Portable ("ease of use") // - Small source code footprint ("easy to maintain") @@ -217,11 +233,10 @@ // // HDR image support (disable by defining STBI_NO_HDR) // -// stb_image now supports loading HDR images in general, and currently -// the Radiance .HDR file format, although the support is provided -// generically. You can still load any file through the existing interface; -// if you attempt to load an HDR file, it will be automatically remapped to -// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// stb_image supports loading HDR images in general, and currently the Radiance +// .HDR file format specifically. You can still load any file through the existing +// interface; if you attempt to load an HDR file, it will be automatically remapped +// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; // both of these constants can be reconfigured through this interface: // // stbi_hdr_to_ldr_gamma(2.2f); @@ -255,7 +270,7 @@ // // By default we convert iphone-formatted PNGs back to RGB, even though // they are internally encoded differently. You can disable this conversion -// by by calling stbi_convert_iphone_png_to_rgb(0), in which case +// by calling stbi_convert_iphone_png_to_rgb(0), in which case // you will always just get the native iphone "format" through (which // is BGR stored in RGB). // @@ -317,6 +332,7 @@ STBI_rgb_alpha = 4 }; +#include typedef unsigned char stbi_uc; typedef unsigned short stbi_us; @@ -324,11 +340,13 @@ extern "C" { #endif +#ifndef STBIDEF #ifdef STB_IMAGE_STATIC #define STBIDEF static #else #define STBIDEF extern #endif +#endif ////////////////////////////////////////////////////////////////////////////// // @@ -360,6 +378,14 @@ // for stbi_load_from_file, file pointer is left pointing immediately after image #endif +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +#endif + +#ifdef STBI_WINDOWS_UTF8 +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif + //////////////////////////////////// // // 16-bits-per-channel interface @@ -416,11 +442,14 @@ // get image dimensions & components without fully decoding STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); #ifndef STBI_NO_STDIO -STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); -STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); - +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit (char const *filename); +STBIDEF int stbi_is_16_bit_from_file(FILE *f); #endif @@ -504,7 +533,7 @@ #include #if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) -#include // ldexp +#include // ldexp, pow #endif #ifndef STBI_NO_STDIO @@ -516,6 +545,12 @@ #define STBI_ASSERT(x) assert(x) #endif +#ifdef __cplusplus +#define STBI_EXTERN extern "C" +#else +#define STBI_EXTERN extern +#endif + #ifndef _MSC_VER #ifdef __cplusplus @@ -640,14 +675,18 @@ #define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) static int stbi__sse2_available(void) { int info3 = stbi__cpuid3(); return ((info3 >> 26) & 1) != 0; } +#endif + #else // assume GCC-style if not VC++ #define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) static int stbi__sse2_available(void) { // If we're even attempting to compile this on GCC/Clang, that means @@ -656,6 +695,8 @@ return 1; } #endif + +#endif #endif // ARM NEON @@ -784,6 +825,7 @@ static int stbi__png_test(stbi__context *s); static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); #endif #ifndef STBI_NO_BMP @@ -802,6 +844,7 @@ static int stbi__psd_test(stbi__context *s); static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); #endif #ifndef STBI_NO_HDR @@ -819,6 +862,7 @@ #ifndef STBI_NO_GIF static int stbi__gif_test(stbi__context *s); static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); #endif @@ -893,11 +937,13 @@ } // returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) { return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); } +#endif // mallocs with size overflow checking static void *stbi__malloc_mad2(int a, int b, int add) @@ -912,11 +958,13 @@ return stbi__malloc(a*b*c + add); } +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) { if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; return stbi__malloc(a*b*c*d + add); } +#endif // stbi__err - error // stbi__errpf - error returning pointer to float @@ -1054,6 +1102,20 @@ } } +#ifndef STBI_NO_GIF +static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc *bytes = (stbi_uc *)image; + for (slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} +#endif + static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) { stbi__result_info ri; @@ -1103,7 +1165,7 @@ return (stbi__uint16 *) result; } -#ifndef STBI_NO_HDR +#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) { if (stbi__vertically_flip_on_load && result != NULL) { @@ -1115,10 +1177,38 @@ #ifndef STBI_NO_STDIO +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) +STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); +#endif + +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + static FILE *stbi__fopen(char const *filename, char const *mode) { FILE *f; -#if defined(_MSC_VER) && _MSC_VER >= 1400 +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) + return 0; + +#if _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 if (0 != fopen_s(&f, filename, mode)) f=0; #else @@ -1205,6 +1295,22 @@ return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); } +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_mem(&s,buffer,len); + + result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + } + + return result; +} +#endif + #ifndef STBI_NO_LINEAR static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) { @@ -1288,12 +1394,16 @@ return result; } -STBIDEF int stbi_is_hdr_from_file(FILE *f) +STBIDEF int stbi_is_hdr_from_file(FILE *f) { #ifndef STBI_NO_HDR + long pos = ftell(f); + int res; stbi__context s; stbi__start_file(&s,f); - return stbi__hdr_test(&s); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; #else STBI_NOTUSED(f); return 0; @@ -1491,18 +1601,18 @@ // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0], dest[1]=255; } break; + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; STBI__CASE(2,1) { dest[0]=src[0]; } break; STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = 255; } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]), dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; default: STBI_ASSERT(0); } #undef STBI__CASE @@ -1540,18 +1650,18 @@ // convert source image with img_n components to one with req_comp components; // avoid switch per pixel, so use switch per scanline and massive macros switch (STBI__COMBO(img_n, req_comp)) { - STBI__CASE(1,2) { dest[0]=src[0], dest[1]=0xffff; } break; + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=0xffff; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; STBI__CASE(2,1) { dest[0]=src[0]; } break; STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; - STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; } break; - STBI__CASE(3,4) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=0xffff; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = 0xffff; } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; - STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]), dest[1] = src[3]; } break; - STBI__CASE(4,3) { dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; default: STBI_ASSERT(0); } #undef STBI__CASE @@ -1575,7 +1685,11 @@ for (k=0; k < n; ++k) { output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); } - if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; + } + if (n < comp) { + for (i=0; i < x*y; ++i) { + output[i*comp + n] = data[i*comp + n]/255.0f; + } } STBI_FREE(data); return output; @@ -1705,7 +1819,8 @@ static int stbi__build_huffman(stbi__huffman *h, int *count) { - int i,j,k=0,code; + int i,j,k=0; + unsigned int code; // build size list for each symbol (from JPEG spec) for (i=0; i < 16; ++i) for (j=0; j < count[i]; ++j) @@ -1721,7 +1836,7 @@ if (h->size[k] == j) { while (h->size[k] == j) h->code[k++] = (stbi__uint16) (code++); - if (code-1 >= (1 << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); } // compute largest code + 1 for this size, preshifted as needed later h->maxcode[j] = code << (16-j); @@ -1765,7 +1880,7 @@ if (k < m) k += (~0U << magbits) + 1; // if the result is small enough, we can fit it in fast_ac table if (k >= -128 && k <= 127) - fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits)); + fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); } } } @@ -1774,7 +1889,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j) { do { - int b = j->nomore ? 0 : stbi__get8(j->s); + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); if (b == 0xff) { int c = stbi__get8(j->s); while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes @@ -1790,7 +1905,7 @@ } // (1 << n) - 1 -static stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; +static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; // decode a jpeg huffman value from the bitstream stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) @@ -1843,7 +1958,7 @@ } // bias[n] = (-1<rgb = 0; for (i=0; i < s->img_n; ++i) { - static unsigned char rgb[3] = { 'R', 'G', 'B' }; + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; z->img_comp[i].id = stbi__get8(s); if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) ++z->rgb; @@ -3093,8 +3208,8 @@ } else if (stbi__DNL(m)) { int Ld = stbi__get16be(j->s); stbi__uint32 NL = stbi__get16be(j->s); - if (Ld != 4) stbi__err("bad DNL len", "Corrupt JPEG"); - if (NL != j->s->img_y) stbi__err("bad DNL height", "Corrupt JPEG"); + if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); } else { if (!stbi__process_marker(j, m)) return 0; } @@ -3547,7 +3662,7 @@ int k; unsigned int i,j; stbi_uc *output; - stbi_uc *coutput[4]; + stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; stbi__resample res_comp[4]; @@ -3668,7 +3783,7 @@ if (n == 1) for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; else - for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } } } } @@ -3912,18 +4027,18 @@ return 1; } -static int stbi__zlength_base[31] = { +static const int stbi__zlength_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; -static int stbi__zlength_extra[31]= +static const int stbi__zlength_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; -static int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; -static int stbi__zdist_extra[32] = +static const int stbi__zdist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; static int stbi__parse_huffman_block(stbi__zbuf *a) @@ -3970,7 +4085,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) { - static stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; stbi__zhuffman z_codelength; stbi_uc lencodes[286+32+137];//padding for maximum single op stbi_uc codelength_sizes[19]; @@ -4229,7 +4344,7 @@ static int stbi__check_png_header(stbi__context *s) { - static stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; int i; for (i=0; i < 8; ++i) if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); @@ -4275,7 +4390,7 @@ return c; } -static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; // create the png data from post-deflated data static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) @@ -4295,8 +4410,10 @@ a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into if (!a->out) return stbi__err("outofmem", "Out of memory"); + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); img_width_bytes = (((img_n * x * depth) + 7) >> 3); img_len = (img_width_bytes + 1) * y; + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), // so just check for raw_len < img_len always. @@ -4675,12 +4792,12 @@ } } -#define STBI__PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) { stbi_uc palette[1024], pal_img_n=0; - stbi_uc has_trans=0, tc[3]; + stbi_uc has_trans=0, tc[3]={0}; stbi__uint16 tc16[3]; stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; int first=1,k,interlace=0, color=0, is_iphone=0; @@ -4912,6 +5029,19 @@ p.s = s; return stbi__png_info_raw(&p, x, y, comp); } + +static int stbi__png_is16(stbi__context *s) +{ + stbi__png p; + p.s = s; + if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if (p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} #endif // Microsoft/Windows BMP image @@ -4945,11 +5075,11 @@ { int n=0; if (z == 0) return -1; - if (z >= 0x10000) n += 16, z >>= 16; - if (z >= 0x00100) n += 8, z >>= 8; - if (z >= 0x00010) n += 4, z >>= 4; - if (z >= 0x00004) n += 2, z >>= 2; - if (z >= 0x00002) n += 1, z >>= 1; + if (z >= 0x10000) { n += 16; z >>= 16; } + if (z >= 0x00100) { n += 8; z >>= 8; } + if (z >= 0x00010) { n += 4; z >>= 4; } + if (z >= 0x00004) { n += 2; z >>= 2; } + if (z >= 0x00002) { n += 1; z >>= 1; } return n; } @@ -4963,21 +5093,27 @@ return a & 0xff; } -static int stbi__shiftsigned(int v, int shift, int bits) -{ - int result; - int z=0; - - if (shift < 0) v <<= -shift; - else v >>= shift; - result = v; - - z = bits; - while (z < 8) { - result += v >> z; - z += bits; - } - return result; +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(unsigned int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0,0,1,0,2,4,6,0, + }; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v >= 0 && v < 256); + v >>= (8-bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; } typedef struct @@ -5007,7 +5143,6 @@ } if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); info->bpp = stbi__get16le(s); - if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit"); if (hsz != 12) { int compress = stbi__get32le(s); if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); @@ -5125,29 +5260,49 @@ pal[i][3] = 255; } stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); - if (info.bpp == 4) width = (s->img_x + 1) >> 1; + if (info.bpp == 1) width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) width = (s->img_x + 1) >> 1; else if (info.bpp == 8) width = s->img_x; else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } pad = (-width)&3; - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=stbi__get8(s),v2=0; - if (info.bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - v = (info.bpp == 8) ? stbi__get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; + if (info.bpp == 1) { + for (j=0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for (i=0; i < (int) s->img_x; ++i) { + int color = (v>>bit_offset)&0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } else { + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); } - stbi__skip(s, pad); } } else { int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; @@ -5188,7 +5343,7 @@ int bpp = info.bpp; for (i=0; i < (int) s->img_x; ++i) { stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); - int a; + unsigned int a; out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); @@ -5212,7 +5367,7 @@ stbi_uc *p1 = out + j *s->img_x*target; stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i], p1[i] = p2[i], p2[i] = t; + t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } @@ -5236,14 +5391,14 @@ static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) { // only RGB or RGBA (incl. 16bit) or grey allowed - if(is_rgb16) *is_rgb16 = 0; + if (is_rgb16) *is_rgb16 = 0; switch(bits_per_pixel) { case 8: return STBI_grey; case 16: if(is_grey) return STBI_grey_alpha; - // else: fall-through + // fallthrough case 15: if(is_rgb16) *is_rgb16 = 1; - return STBI_rgb; - case 24: // fall-through + return STBI_rgb; + case 24: // fallthrough case 32: return bits_per_pixel/8; default: return 0; } @@ -5702,7 +5857,7 @@ // Else if n is 128, noop. // Endloop - // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, // which we're going to just skip. stbi__skip(s, h * channelCount * 2 ); @@ -6038,11 +6193,13 @@ typedef struct { int w,h; - stbi_uc *out, *old_out; // output buffer (always 4 components) - int flags, bgindex, ratio, transparent, eflags, delay; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned + stbi_uc *history; + int flags, bgindex, ratio, transparent, eflags; stbi_uc pal[256][4]; stbi_uc lpal[256][4]; - stbi__gif_lzw codes[4096]; + stbi__gif_lzw codes[8192]; stbi_uc *color_table; int parse, step; int lflags; @@ -6050,6 +6207,7 @@ int max_x, max_y; int cur_x, cur_y; int line_size; + int delay; } stbi__gif; static int stbi__gif_test_raw(stbi__context *s) @@ -6125,6 +6283,7 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) { stbi_uc *p, *c; + int idx; // recurse to decode the prefixes, since the linked-list is backwards, // and working backwards through an interleaved image would be nasty @@ -6133,10 +6292,12 @@ if (g->cur_y >= g->max_y) return; - p = &g->out[g->cur_x + g->cur_y]; - c = &g->color_table[g->codes[code].suffix * 4]; + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; - if (c[3] >= 128) { + c = &g->color_table[g->codes[code].suffix * 4]; + if (c[3] > 128) { // don't render transparent pixels; p[0] = c[2]; p[1] = c[1]; p[2] = c[0]; @@ -6210,11 +6371,16 @@ stbi__skip(s,len); return g->out; } else if (code <= avail) { - if (first) return stbi__errpuc("no clear code", "Corrupt GIF"); + if (first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } if (oldcode >= 0) { p = &g->codes[avail++]; - if (avail > 4096) return stbi__errpuc("too many codes", "Corrupt GIF"); + if (avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + p->prefix = (stbi__int16) oldcode; p->first = g->codes[oldcode].first; p->suffix = (code == avail) ? p->first : g->codes[code].first; @@ -6236,62 +6402,77 @@ } } -static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1) -{ - int x, y; - stbi_uc *c = g->pal[g->bgindex]; - for (y = y0; y < y1; y += 4 * g->w) { - for (x = x0; x < x1; x += 4) { - stbi_uc *p = &g->out[y + x]; - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = 0; - } - } -} - // this function is designed to support animated gifs, although stb_image doesn't support it -static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp) +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) { - int i; - stbi_uc *prev_out = 0; - - if (g->out == 0 && !stbi__gif_header(s, g, comp,0)) - return 0; // stbi__g_failure_reason set by stbi__gif_header + int dispose; + int first_frame; + int pi; + int pcount; + STBI_NOTUSED(req_comp); - if (!stbi__mad3sizes_valid(g->w, g->h, 4, 0)) - return stbi__errpuc("too large", "GIF too large"); + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if (g->out == 0) { + if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) + return stbi__errpuc("too large", "GIF image is too large"); + pcount = g->w * g->h; + g->out = (stbi_uc *) stbi__malloc(4 * pcount); + g->background = (stbi_uc *) stbi__malloc(4 * pcount); + g->history = (stbi_uc *) stbi__malloc(pcount); + if (!g->out || !g->background || !g->history) + return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "transparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to the color that was there the previous frame. + memset(g->out, 0x00, 4 * pcount); + memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) + memset(g->history, 0x00, pcount); // pixels that were affected previous frame + first_frame = 1; + } else { + // second frame - how do we dispoase of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; - prev_out = g->out; - g->out = (stbi_uc *) stbi__malloc_mad3(4, g->w, g->h, 0); - if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory"); + if ((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } - switch ((g->eflags & 0x1C) >> 2) { - case 0: // unspecified (also always used on 1st frame) - stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h); - break; - case 1: // do not dispose - if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); - g->old_out = prev_out; - break; - case 2: // dispose to background - if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h); - stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y); - break; - case 3: // dispose to previous - if (g->old_out) { - for (i = g->start_y; i < g->max_y; i += 4 * g->w) - memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x); + if (dispose == 3) { // use previous graphic + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + } } - break; + } else if (dispose == 2) { + // restore what was changed last frame to background before that frame; + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + } + } + } else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy( g->background, g->out, 4 * g->w * g->h ); } + // clear my history; + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + for (;;) { - switch (stbi__get8(s)) { + int tag = stbi__get8(s); + switch (tag) { case 0x2C: /* Image Descriptor */ { - int prev_trans = -1; stbi__int32 x, y, w, h; stbi_uc *o; @@ -6310,6 +6491,13 @@ g->cur_x = g->start_x; g->cur_y = g->start_y; + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if (w == 0) + g->cur_y = g->max_y; + g->lflags = stbi__get8(s); if (g->lflags & 0x40) { @@ -6324,19 +6512,24 @@ stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); g->color_table = (stbi_uc *) g->lpal; } else if (g->flags & 0x80) { - if (g->transparent >= 0 && (g->eflags & 0x01)) { - prev_trans = g->pal[g->transparent][3]; - g->pal[g->transparent][3] = 0; - } g->color_table = (stbi_uc *) g->pal; } else - return stbi__errpuc("missing color table", "Corrupt GIF"); - + return stbi__errpuc("missing color table", "Corrupt GIF"); + o = stbi__process_gif_raster(s, g); - if (o == NULL) return NULL; + if (!o) return NULL; - if (prev_trans != -1) - g->pal[g->transparent][3] = (stbi_uc) prev_trans; + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); + } + } + } return o; } @@ -6344,19 +6537,35 @@ case 0x21: // Comment Extension. { int len; - if (stbi__get8(s) == 0xF9) { // Graphic Control Extension. + int ext = stbi__get8(s); + if (ext == 0xF9) { // Graphic Control Extension. len = stbi__get8(s); if (len == 4) { g->eflags = stbi__get8(s); - g->delay = stbi__get16le(s); - g->transparent = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } } else { stbi__skip(s, len); break; } - } - while ((len = stbi__get8(s)) != 0) + } + while ((len = stbi__get8(s)) != 0) { stbi__skip(s, len); + } break; } @@ -6367,28 +6576,96 @@ return stbi__errpuc("unknown code", "Corrupt GIF"); } } +} - STBI_NOTUSED(req_comp); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + if (stbi__gif_test(s)) { + int layers = 0; + stbi_uc *u = 0; + stbi_uc *out = 0; + stbi_uc *two_back = 0; + stbi__gif g; + int stride; + memset(&g, 0, sizeof(g)); + if (delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if (u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if (out) { + out = (stbi_uc*) STBI_REALLOC( out, layers * stride ); + if (delays) { + *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); + } + } else { + out = (stbi_uc*)stbi__malloc( layers * stride ); + if (delays) { + *delays = (int*) stbi__malloc( layers * sizeof(int) ); + } + } + memcpy( out + ((layers - 1) * stride), u, stride ); + if (layers >= 2) { + two_back = out - 2 * stride; + } + + if (delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while (u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if (req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } } static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { stbi_uc *u = 0; - stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); - memset(g, 0, sizeof(*g)); + stbi__gif g; + memset(&g, 0, sizeof(g)); STBI_NOTUSED(ri); - u = stbi__gif_load_next(s, g, comp, req_comp); + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); if (u == (stbi_uc *) s) u = 0; // end of animated gif marker if (u) { - *x = g->w; - *y = g->h; + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. if (req_comp && req_comp != 4) - u = stbi__convert_format(u, 4, req_comp, g->w, g->h); + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } else if (g.out) { + // if there was an error and we allocated an image buffer, free it! + STBI_FREE(g.out); } - else if (g->out) - STBI_FREE(g->out); - STBI_FREE(g); + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + return u; } @@ -6667,7 +6944,7 @@ #ifndef STBI_NO_PSD static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) { - int channelCount, dummy; + int channelCount, dummy, depth; if (!x) x = &dummy; if (!y) y = &dummy; if (!comp) comp = &dummy; @@ -6687,7 +6964,8 @@ } *y = stbi__get32be(s); *x = stbi__get32be(s); - if (stbi__get16be(s) != 8) { + depth = stbi__get16be(s); + if (depth != 8 && depth != 16) { stbi__rewind( s ); return 0; } @@ -6698,6 +6976,33 @@ *comp = 4; return 1; } + +static int stbi__psd_is16(stbi__context *s) +{ + int channelCount, depth; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + (void) stbi__get32be(s); + (void) stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 16) { + stbi__rewind( s ); + return 0; + } + return 1; +} #endif #ifndef STBI_NO_PIC @@ -6928,6 +7233,19 @@ return stbi__err("unknown image type", "Image not of any known type, or corrupt"); } +static int stbi__is_16_main(stbi__context *s) +{ + #ifndef STBI_NO_PNG + if (stbi__png_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) return 1; + #endif + + return 0; +} + #ifndef STBI_NO_STDIO STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) { @@ -6949,6 +7267,27 @@ fseek(f,pos,SEEK_SET); return r; } + +STBIDEF int stbi_is_16_bit(char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE *f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f,pos,SEEK_SET); + return r; +} #endif // !STBI_NO_STDIO STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) @@ -6965,10 +7304,31 @@ return stbi__info_main(&s,x,y,comp); } +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + #endif // STB_IMAGE_IMPLEMENTATION /* revision history: + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings 2.16 (2017-07-23) all functions have 16-bit variants; STBI_NO_STDIO works again; compilation fixes; diff -Nru love-11.1/src/libraries/tinyexr/tinyexr.h love-11.3/src/libraries/tinyexr/tinyexr.h --- love-11.1/src/libraries/tinyexr/tinyexr.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/libraries/tinyexr/tinyexr.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /* -Copyright (c) 2014 - 2017, Syoyo Fujita +Copyright (c) 2014 - 2019, Syoyo Fujita and many contributors. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -115,6 +115,9 @@ #define TINYEXR_ERROR_CANT_OPEN_FILE (-6) #define TINYEXR_ERROR_UNSUPPORTED_FORMAT (-7) #define TINYEXR_ERROR_INVALID_HEADER (-8) +#define TINYEXR_ERROR_UNSUPPORTED_FEATURE (-9) +#define TINYEXR_ERROR_CANT_WRITE_FILE (-10) +#define TINYEXR_ERROR_SERIALZATION_FAILED (-11) // @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf } @@ -123,7 +126,8 @@ #define TINYEXR_PIXELTYPE_HALF (1) #define TINYEXR_PIXELTYPE_FLOAT (2) -#define TINYEXR_MAX_ATTRIBUTES (128) +#define TINYEXR_MAX_HEADER_ATTRIBUTES (1024) +#define TINYEXR_MAX_CUSTOM_ATTRIBUTES (128) #define TINYEXR_COMPRESSIONTYPE_NONE (0) #define TINYEXR_COMPRESSIONTYPE_RLE (1) @@ -205,7 +209,8 @@ // Custom attributes(exludes required attributes(e.g. `channels`, // `compression`, etc) int num_custom_attributes; - EXRAttribute custom_attributes[TINYEXR_MAX_ATTRIBUTES]; + EXRAttribute *custom_attributes; // array of EXRAttribute. size = + // `num_custom_attributes`. EXRChannelInfo *channels; // [num_channels] @@ -269,6 +274,13 @@ const char *filename, const char **err); // @deprecated { to be removed. } +// Simple wrapper API for ParseEXRHeaderFromFile. +// checking given file is a EXR file(by just look up header) +// @return TINYEXR_SUCCEES for EXR image, TINYEXR_ERROR_INVALID_HEADER for +// others +extern int IsEXR(const char *filename); + +// @deprecated { to be removed. } // Saves single-frame OpenEXR image. Assume EXR image contains RGB(A) channels. // components must be 1(Grayscale), 3(RGB) or 4(RGBA). // Input image format is: `float x width x height`, or `float x RGB(A) x width x @@ -276,9 +288,12 @@ // Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero // value. // Save image as fp32(FLOAT) format when `save_as_fp16` is 0. +// Use ZIP compression by default. +// Returns negative value and may set error string in `err` when there's an +// error extern int SaveEXR(const float *data, const int width, const int height, const int components, const int save_as_fp16, - const char *filename); + const char *filename, const char **err); // Initialize EXRHeader struct extern void InitEXRHeader(EXRHeader *exr_header); @@ -292,6 +307,9 @@ // Free's internal data of EXRImage struct extern int FreeEXRImage(EXRImage *exr_image); +// Free's error message +extern void FreeEXRErrorMessage(const char *msg); + // Parse EXR version header of a file. extern int ParseEXRVersionFromFile(EXRVersion *version, const char *filename); @@ -300,10 +318,14 @@ const unsigned char *memory, size_t size); // Parse single-part OpenEXR header from a file and initialize `EXRHeader`. +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int ParseEXRHeaderFromFile(EXRHeader *header, const EXRVersion *version, const char *filename, const char **err); // Parse single-part OpenEXR header from a memory and initialize `EXRHeader`. +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int ParseEXRHeaderFromMemory(EXRHeader *header, const EXRVersion *version, const unsigned char *memory, size_t size, @@ -311,6 +333,8 @@ // Parse multi-part OpenEXR headers from a file and initialize `EXRHeader*` // array. +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int ParseEXRMultipartHeaderFromFile(EXRHeader ***headers, int *num_headers, const EXRVersion *version, @@ -319,6 +343,8 @@ // Parse multi-part OpenEXR headers from a memory and initialize `EXRHeader*` // array +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int ParseEXRMultipartHeaderFromMemory(EXRHeader ***headers, int *num_headers, const EXRVersion *version, @@ -330,6 +356,8 @@ // Application can free EXRImage using `FreeEXRImage` // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int LoadEXRImageFromFile(EXRImage *image, const EXRHeader *header, const char *filename, const char **err); @@ -339,6 +367,8 @@ // Application can free EXRImage using `FreeEXRImage` // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int LoadEXRImageFromMemory(EXRImage *image, const EXRHeader *header, const unsigned char *memory, const size_t size, const char **err); @@ -349,6 +379,8 @@ // Application can free EXRImage using `FreeEXRImage` // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int LoadEXRMultipartImageFromFile(EXRImage *images, const EXRHeader **headers, unsigned int num_parts, @@ -361,6 +393,8 @@ // Application can free EXRImage using `FreeEXRImage` // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int LoadEXRMultipartImageFromMemory(EXRImage *images, const EXRHeader **headers, unsigned int num_parts, @@ -370,15 +404,19 @@ // Saves multi-channel, single-frame OpenEXR image to a file. // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int SaveEXRImageToFile(const EXRImage *image, const EXRHeader *exr_header, const char *filename, const char **err); // Saves multi-channel, single-frame OpenEXR image to a memory. // Image is compressed using EXRImage.compression value. -// Return the number of bytes if succes. -// Returns negative value and may set error string in `err` when there's an -// error +// Return the number of bytes if success. +// Return zero and will set error string in `err` when there's an +// error. +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern size_t SaveEXRImageToMemory(const EXRImage *image, const EXRHeader *exr_header, unsigned char **memory, const char **err); @@ -387,6 +425,8 @@ // Application must free memory of variables in DeepImage(image, offset_table) // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int LoadDeepEXR(DeepImage *out_image, const char *filename, const char **err); @@ -409,9 +449,11 @@ // RGB(A) channels. // Returns negative value and may set error string in `err` when there's an // error +// When there was an error message, Application must free `err` with +// FreeEXRErrorMessage() extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height, - const unsigned char *memory, size_t size, - const char **err); + const unsigned char *memory, size_t size, + const char **err); #ifdef __cplusplus } @@ -430,6 +472,9 @@ #include #include +// #include // debug + +#include #include #include @@ -444,7 +489,8 @@ #if TINYEXR_USE_MINIZ #else -// Issue #46. Please include your own zlib-compatible API header before including `tinyexr.h` +// Issue #46. Please include your own zlib-compatible API header before +// including `tinyexr.h` //#include "zlib.h" #endif @@ -485,9 +531,29 @@ #pragma clang diagnostic ignored "-Wc++11-extensions" #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wunused-function" +#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" +#pragma clang diagnostic ignored "-Wundef" + #if __has_warning("-Wcomma") #pragma clang diagnostic ignored "-Wcomma" #endif + +#if __has_warning("-Wmacro-redefined") +#pragma clang diagnostic ignored "-Wmacro-redefined" +#endif + +#if __has_warning("-Wcast-qual") +#pragma clang diagnostic ignored "-Wcast-qual" +#endif + +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#if __has_warning("-Wtautological-constant-compare") +#pragma clang diagnostic ignored "-Wtautological-constant-compare" +#endif + #endif /* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP @@ -2473,10 +2539,10 @@ tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; - const mz_uint8 *pIn_buf_cur = pIn_buf_next, - *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; - mz_uint8 *pOut_buf_cur = pOut_buf_next, - *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = + pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = + pOut_buf_next + *pOut_buf_size; size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 @@ -2948,9 +3014,8 @@ tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, - (flags & - ~(TINFL_FLAG_HAS_MORE_INPUT | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); in_buf_ofs += in_buf_size; if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) @@ -3075,7 +3140,9 @@ // Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted // values. -typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +typedef struct { + mz_uint16 m_key, m_sym_index; +} tdefl_sym_freq; static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1) { @@ -3542,10 +3609,9 @@ mz_uint saved_bit_buf, saved_bits_in; mz_uint8 *pSaved_output_buf; mz_bool comp_block_succeeded = MZ_FALSE; - int n, - use_raw_block = - ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && - (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + int n, use_raw_block = + ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && + (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) @@ -3575,9 +3641,8 @@ if (!use_raw_block) comp_block_succeeded = - tdefl_compress_block(d, - (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || - (d->m_total_lz_bytes < 48)); + tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || + (d->m_total_lz_bytes < 48)); // If the block gets expanded, forget the current contents of the output // buffer and send a raw block instead. @@ -4381,9 +4446,8 @@ // C and C99, so no big deal) #pragma warning(disable : 4244) // 'initializing': conversion from '__int64' to // 'int', possible loss of data -#pragma warning( \ - disable : 4267) // 'argument': conversion from '__int64' to 'int', - // possible loss of data +#pragma warning(disable : 4267) // 'argument': conversion from '__int64' to + // 'int', possible loss of data #pragma warning(disable : 4996) // 'strdup': The POSIX name for this item is // deprecated. Instead, use the ISO C and C++ // conformant name: _strdup. @@ -6887,9 +6951,7 @@ #ifdef _MSC_VER #pragma warning(pop) #endif - - -} +} // namespace miniz #else // Reuse MINIZ_LITTE_ENDIAN macro @@ -6914,8 +6976,26 @@ // return bint.c[0] == 1; //} +static void SetErrorMessage(const std::string &msg, const char **err) { + if (err) { +#ifdef _WIN32 + (*err) = _strdup(msg.c_str()); +#else + (*err) = strdup(msg.c_str()); +#endif + } +} + static const int kEXRVersionSize = 8; +static void cpy2(unsigned short *dst_val, const unsigned short *src_val) { + unsigned char *dst = reinterpret_cast(dst_val); + const unsigned char *src = reinterpret_cast(src_val); + + dst[0] = src[0]; + dst[1] = src[1]; +} + static void swap2(unsigned short *val) { #ifdef MINIZ_LITTLE_ENDIAN (void)val; @@ -6929,6 +7009,43 @@ #endif } +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" +#endif +static void cpy4(int *dst_val, const int *src_val) { + unsigned char *dst = reinterpret_cast(dst_val); + const unsigned char *src = reinterpret_cast(src_val); + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; +} + +static void cpy4(unsigned int *dst_val, const unsigned int *src_val) { + unsigned char *dst = reinterpret_cast(dst_val); + const unsigned char *src = reinterpret_cast(src_val); + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; +} + +static void cpy4(float *dst_val, const float *src_val) { + unsigned char *dst = reinterpret_cast(dst_val); + const unsigned char *src = reinterpret_cast(src_val); + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; +} +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + static void swap4(unsigned int *val) { #ifdef MINIZ_LITTLE_ENDIAN (void)val; @@ -6944,6 +7061,22 @@ #endif } +#if 0 +static void cpy8(tinyexr::tinyexr_uint64 *dst_val, const tinyexr::tinyexr_uint64 *src_val) { + unsigned char *dst = reinterpret_cast(dst_val); + const unsigned char *src = reinterpret_cast(src_val); + + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + dst[4] = src[4]; + dst[5] = src[5]; + dst[6] = src[6]; + dst[7] = src[7]; +} +#endif + static void swap8(tinyexr::tinyexr_uint64 *val) { #ifdef MINIZ_LITTLE_ENDIAN (void)val; @@ -7079,11 +7212,27 @@ // #define IMF_B44_COMPRESSION 6 // #define IMF_B44A_COMPRESSION 7 -static const char *ReadString(std::string *s, const char *ptr) { +#ifdef __clang__ +#pragma clang diagnostic push + +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#endif + +static const char *ReadString(std::string *s, const char *ptr, size_t len) { // Read untile NULL(\0). const char *p = ptr; const char *q = ptr; - while ((*q) != 0) q++; + while ((size_t(q - ptr) < len) && (*q) != 0) { + q++; + } + + if (size_t(q - ptr) >= len) { + (*s) = std::string(); + return NULL; + } (*s) = std::string(p, q); @@ -7120,6 +7269,24 @@ memcpy(&data_len, marker, sizeof(uint32_t)); tinyexr::swap4(reinterpret_cast(&data_len)); + if (data_len == 0) { + if ((*type).compare("string") == 0) { + // Accept empty string attribute. + + marker += sizeof(uint32_t); + size -= sizeof(uint32_t); + + *marker_size = name_len + 1 + type_len + 1 + sizeof(uint32_t); + + data->resize(1); + (*data)[0] = '\0'; + + return true; + } else { + return false; + } + } + marker += sizeof(uint32_t); size -= sizeof(uint32_t); @@ -7210,7 +7377,7 @@ } } HeaderInfo; -static void ReadChannelInfo(std::vector &channels, +static bool ReadChannelInfo(std::vector &channels, const std::vector &data) { const char *p = reinterpret_cast(&data.at(0)); @@ -7219,7 +7386,24 @@ break; } ChannelInfo info; - p = ReadString(&info.name, p); + + tinyexr_int64 data_len = static_cast(data.size()) - + (p - reinterpret_cast(data.data())); + if (data_len < 0) { + return false; + } + + p = ReadString(&info.name, p, size_t(data_len)); + if ((p == NULL) && (info.name.empty())) { + // Buffer overrun. Issue #51. + return false; + } + + const unsigned char *data_end = + reinterpret_cast(p) + 16; + if (data_end >= (data.data() + data.size())) { + return false; + } memcpy(&info.pixel_type, p, sizeof(int)); p += 4; @@ -7236,6 +7420,8 @@ channels.push_back(info); } + + return true; } static void WriteChannelInfo(std::vector &data, @@ -7361,25 +7547,27 @@ } } -static void DecompressZip(unsigned char *dst, +static bool DecompressZip(unsigned char *dst, unsigned long *uncompressed_size /* inout */, const unsigned char *src, unsigned long src_size) { if ((*uncompressed_size) == src_size) { // Data is not compressed(Issue 40). memcpy(dst, src, src_size); - return; + return true; } std::vector tmpBuf(*uncompressed_size); #if TINYEXR_USE_MINIZ int ret = miniz::mz_uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size); - assert(ret == miniz::MZ_OK); - (void)ret; + if (miniz::MZ_OK != ret) { + return false; + } #else int ret = uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size); - assert(ret == Z_OK); - (void)ret; + if (Z_OK != ret) { + return false; + } #endif // @@ -7419,6 +7607,8 @@ break; } } + + return true; } // RLE code from OpenEXR -------------------------------------- @@ -7435,15 +7625,13 @@ // C and C99, so no big deal) #pragma warning(disable : 4244) // 'initializing': conversion from '__int64' to // 'int', possible loss of data -#pragma warning( \ - disable : 4267) // 'argument': conversion from '__int64' to 'int', - // possible loss of data +#pragma warning(disable : 4267) // 'argument': conversion from '__int64' to + // 'int', possible loss of data #pragma warning(disable : 4996) // 'strdup': The POSIX name for this item is // deprecated. Instead, use the ISO C and C++ // conformant name: _strdup. #endif - const int MIN_RUN_LENGTH = 3; const int MAX_RUN_LENGTH = 127; @@ -7512,7 +7700,8 @@ int count = -(static_cast(*in++)); inLength -= count + 1; - if (0 > (maxLength -= count)) return 0; + // Fixes #116: Add bounds check to in buffer. + if ((0 > (maxLength -= count)) || (inLength < 0)) return 0; memcpy(out, in, count); out += count; @@ -7606,13 +7795,19 @@ } } -static void DecompressRle(unsigned char *dst, +static bool DecompressRle(unsigned char *dst, const unsigned long uncompressed_size, const unsigned char *src, unsigned long src_size) { if (uncompressed_size == src_size) { // Data is not compressed(Issue 40). memcpy(dst, src, src_size); - return; + return true; + } + + // Workaround for issue #112. + // TODO(syoyo): Add more robust out-of-bounds check in `rleUncompress`. + if (src_size <= 2) { + return false; } std::vector tmpBuf(uncompressed_size); @@ -7621,8 +7816,9 @@ static_cast(uncompressed_size), reinterpret_cast(src), reinterpret_cast(&tmpBuf.at(0))); - assert(ret == static_cast(uncompressed_size)); - (void)ret; + if (ret != static_cast(uncompressed_size)) { + return false; + } // // Apply EXR-specific? postprocess. Grabbed from OpenEXR's @@ -7661,6 +7857,8 @@ break; } } + + return true; } #if TINYEXR_USE_PIZ @@ -7673,6 +7871,12 @@ #pragma clang diagnostic ignored "-Wsign-conversion" #pragma clang diagnostic ignored "-Wc++11-extensions" #pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" + +#if __has_warning("-Wcast-qual") +#pragma clang diagnostic ignored "-Wcast-qual" +#endif + #endif // @@ -8150,8 +8354,8 @@ // for all array entries. // - int hlink[HUF_ENCSIZE]; - long long *fHeap[HUF_ENCSIZE]; + std::vector hlink(HUF_ENCSIZE); + std::vector fHeap(HUF_ENCSIZE); *im = 0; @@ -8210,8 +8414,8 @@ std::make_heap(&fHeap[0], &fHeap[nf], FHeapCompare()); - long long scode[HUF_ENCSIZE]; - memset(scode, 0, sizeof(long long) * HUF_ENCSIZE); + std::vector scode(HUF_ENCSIZE); + memset(scode.data(), 0, sizeof(long long) * HUF_ENCSIZE); while (nf > 1) { // @@ -8283,8 +8487,8 @@ // code table from scode into frq. // - hufCanonicalCodeTable(scode); - memcpy(frq, scode, sizeof(long long) * HUF_ENCSIZE); + hufCanonicalCodeTable(scode.data()); + memcpy(frq, scode.data(), sizeof(long long) * HUF_ENCSIZE); } // @@ -8620,26 +8824,63 @@ lc += 8; \ } -#define getCode(po, rlc, c, lc, in, out, oe) \ - { \ - if (po == rlc) { \ - if (lc < 8) getChar(c, lc, in); \ - \ - lc -= 8; \ - \ - unsigned char cs = (c >> lc); \ - \ - if (out + cs > oe) return false; \ - \ - unsigned short s = out[-1]; \ - \ - while (cs-- > 0) *out++ = s; \ - } else if (out < oe) { \ - *out++ = po; \ - } else { \ - return false; \ - } \ +#if 0 +#define getCode(po, rlc, c, lc, in, out, ob, oe) \ + { \ + if (po == rlc) { \ + if (lc < 8) getChar(c, lc, in); \ + \ + lc -= 8; \ + \ + unsigned char cs = (c >> lc); \ + \ + if (out + cs > oe) return false; \ + \ + /* TinyEXR issue 78 */ \ + unsigned short s = out[-1]; \ + \ + while (cs-- > 0) *out++ = s; \ + } else if (out < oe) { \ + *out++ = po; \ + } else { \ + return false; \ + } \ + } +#else +static bool getCode(int po, int rlc, long long &c, int &lc, const char *&in, + const char *in_end, unsigned short *&out, + const unsigned short *ob, const unsigned short *oe) { + (void)ob; + if (po == rlc) { + if (lc < 8) { + /* TinyEXR issue 78 */ + if ((in + 1) >= in_end) { + return false; + } + + getChar(c, lc, in); + } + + lc -= 8; + + unsigned char cs = (c >> lc); + + if (out + cs > oe) return false; + + // Bounds check for safety + // Issue 100. + if ((out - 1) < ob) return false; + unsigned short s = out[-1]; + + while (cs-- > 0) *out++ = s; + } else if (out < oe) { + *out++ = po; + } else { + return false; } + return true; +} +#endif // // Decode (uncompress) ni bits based on encoding & decoding tables: @@ -8655,8 +8896,8 @@ { long long c = 0; int lc = 0; - unsigned short *outb = out; - unsigned short *oe = out + no; + unsigned short *outb = out; // begin + unsigned short *oe = out + no; // end const char *ie = in + (ni + 7) / 8; // input byte size // @@ -8679,7 +8920,16 @@ // lc -= pl.len; - getCode(pl.lit, rlc, c, lc, in, out, oe); + // std::cout << "lit = " << pl.lit << std::endl; + // std::cout << "rlc = " << rlc << std::endl; + // std::cout << "c = " << c << std::endl; + // std::cout << "lc = " << lc << std::endl; + // std::cout << "in = " << in << std::endl; + // std::cout << "out = " << out << std::endl; + // std::cout << "oe = " << oe << std::endl; + if (!getCode(pl.lit, rlc, c, lc, in, ie, out, outb, oe)) { + return false; + } } else { if (!pl.p) { return false; @@ -8706,7 +8956,9 @@ // lc -= l; - getCode(pl.p[j], rlc, c, lc, in, out, oe); + if (!getCode(pl.p[j], rlc, c, lc, in, ie, out, outb, oe)) { + return false; + } break; } } @@ -8733,7 +8985,9 @@ if (pl.len) { lc -= pl.len; - getCode(pl.lit, rlc, c, lc, in, out, oe); + if (!getCode(pl.lit, rlc, c, lc, in, ie, out, outb, oe)) { + return false; + } } else { return false; // invalidCode(); // wrong (long) code @@ -8748,7 +9002,7 @@ return true; } -static void countFrequencies(long long freq[HUF_ENCSIZE], +static void countFrequencies(std::vector &freq, const unsigned short data[/*n*/], int n) { for (int i = 0; i < HUF_ENCSIZE; ++i) freq[i] = 0; @@ -8779,21 +9033,21 @@ char compressed[]) { if (nRaw == 0) return 0; - long long freq[HUF_ENCSIZE]; + std::vector freq(HUF_ENCSIZE); countFrequencies(freq, raw, nRaw); int im = 0; int iM = 0; - hufBuildEncTable(freq, &im, &iM); + hufBuildEncTable(freq.data(), &im, &iM); char *tableStart = compressed + 20; char *tableEnd = tableStart; - hufPackEncTable(freq, im, iM, &tableEnd); + hufPackEncTable(freq.data(), im, iM, &tableEnd); int tableLength = tableEnd - tableStart; char *dataStart = tableEnd; - int nBits = hufEncode(freq, raw, nRaw, iM, dataStart); + int nBits = hufEncode(freq.data(), raw, nRaw, iM, dataStart); int data_length = (nBits + 7) / 8; writeUInt(compressed, im); @@ -8806,9 +9060,9 @@ } static bool hufUncompress(const char compressed[], int nCompressed, - unsigned short raw[], int nRaw) { + std::vector *raw) { if (nCompressed == 0) { - if (nRaw != 0) return false; + if (raw->size() != 0) return false; return false; } @@ -8849,7 +9103,8 @@ } hufBuildDecTable(&freq.at(0), im, iM, &hdec.at(0)); - hufDecode(&freq.at(0), &hdec.at(0), ptr, nBits, iM, nRaw, raw); + hufDecode(&freq.at(0), &hdec.at(0), ptr, nBits, iM, raw->size(), + raw->data()); } // catch (...) //{ @@ -8934,12 +9189,11 @@ #pragma warning(pop) #endif - static bool CompressPiz(unsigned char *outPtr, unsigned int *outSize, const unsigned char *inPtr, size_t inSize, const std::vector &channelInfo, int data_width, int num_lines) { - unsigned char bitmap[BITMAP_SIZE]; + std::vector bitmap(BITMAP_SIZE); unsigned short minNonZero; unsigned short maxNonZero; @@ -8990,12 +9244,12 @@ } } - bitmapFromData(&tmpBuffer.at(0), static_cast(tmpBuffer.size()), bitmap, - minNonZero, maxNonZero); + bitmapFromData(&tmpBuffer.at(0), static_cast(tmpBuffer.size()), + bitmap.data(), minNonZero, maxNonZero); - unsigned short lut[USHORT_RANGE]; - unsigned short maxValue = forwardLutFromBitmap(bitmap, lut); - applyLut(lut, &tmpBuffer.at(0), static_cast(tmpBuffer.size())); + std::vector lut(USHORT_RANGE); + unsigned short maxValue = forwardLutFromBitmap(bitmap.data(), lut.data()); + applyLut(lut.data(), &tmpBuffer.at(0), static_cast(tmpBuffer.size())); // // Store range compression info in _outBuffer @@ -9065,7 +9319,7 @@ return true; } - unsigned char bitmap[BITMAP_SIZE]; + std::vector bitmap(BITMAP_SIZE); unsigned short minNonZero; unsigned short maxNonZero; @@ -9075,11 +9329,13 @@ return false; #endif - memset(bitmap, 0, BITMAP_SIZE); + memset(bitmap.data(), 0, BITMAP_SIZE); const unsigned char *ptr = inPtr; - minNonZero = *(reinterpret_cast(ptr)); - maxNonZero = *(reinterpret_cast(ptr + 2)); + // minNonZero = *(reinterpret_cast(ptr)); + tinyexr::cpy2(&minNonZero, reinterpret_cast(ptr)); + // maxNonZero = *(reinterpret_cast(ptr + 2)); + tinyexr::cpy2(&maxNonZero, reinterpret_cast(ptr + 2)); ptr += 4; if (maxNonZero >= BITMAP_SIZE) { @@ -9092,9 +9348,9 @@ ptr += maxNonZero - minNonZero + 1; } - unsigned short lut[USHORT_RANGE]; - memset(lut, 0, sizeof(unsigned short) * USHORT_RANGE); - unsigned short maxValue = reverseLutFromBitmap(bitmap, lut); + std::vector lut(USHORT_RANGE); + memset(lut.data(), 0, sizeof(unsigned short) * USHORT_RANGE); + unsigned short maxValue = reverseLutFromBitmap(bitmap.data(), lut.data()); // // Huffman decoding @@ -9102,12 +9358,16 @@ int length; - length = *(reinterpret_cast(ptr)); + // length = *(reinterpret_cast(ptr)); + tinyexr::cpy4(&length, reinterpret_cast(ptr)); ptr += sizeof(int); + if (size_t((ptr - inPtr) + length) > inLen) { + return false; + } + std::vector tmpBuffer(tmpBufSize); - hufUncompress(reinterpret_cast(ptr), length, &tmpBuffer.at(0), - static_cast(tmpBufSize)); + hufUncompress(reinterpret_cast(ptr), length, &tmpBuffer); // // Wavelet decoding @@ -9148,7 +9408,7 @@ // Expand the pixel data to their original range // - applyLut(lut, &tmpBuffer.at(0), static_cast(tmpBufSize)); + applyLut(lut.data(), &tmpBuffer.at(0), static_cast(tmpBufSize)); for (int y = 0; y < num_lines; y++) { for (size_t i = 0; i < channelData.size(); ++i) { @@ -9373,7 +9633,8 @@ // ----------------------------------------------------------------- // -static void DecodePixelData(/* out */ unsigned char **out_images, +// TODO(syoyo): Refactor function arguments. +static bool DecodePixelData(/* out */ unsigned char **out_images, const int *requested_pixel_types, const unsigned char *data_ptr, size_t data_len, int compression_type, int line_order, int width, @@ -9385,6 +9646,11 @@ const std::vector &channel_offset_list) { if (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { // PIZ #if TINYEXR_USE_PIZ + if ((width == 0) || (num_lines == 0) || (pixel_data_size == 0)) { + // Invalid input #90 + return false; + } + // Allocate original data size. std::vector outBuf(static_cast( static_cast(width * num_lines) * pixel_data_size)); @@ -9394,8 +9660,9 @@ reinterpret_cast(&outBuf.at(0)), data_ptr, tmpBufLen, data_len, static_cast(num_channels), channels, width, num_lines); - assert(ret); - (void)ret; + if (!ret) { + return false; + } // For PIZ_COMPRESSION: // pixel sample data for channel 0 for scanline 0 @@ -9416,7 +9683,10 @@ for (size_t u = 0; u < static_cast(width); u++) { FP16 hf; - hf.u = line_ptr[u]; + // hf.u = line_ptr[u]; + // use `cpy` to avoid unaligned memory access when compiler's + // optimization is on. + tinyexr::cpy2(&(hf.u), line_ptr + u); tinyexr::swap2(reinterpret_cast(&hf.u)); @@ -9437,16 +9707,18 @@ } else { // HALF -> FLOAT FP32 f32 = half_to_float(hf); float *image = reinterpret_cast(out_images)[c]; + size_t offset = 0; if (line_order == 0) { - image += (static_cast(line_no) + v) * + offset = (static_cast(line_no) + v) * static_cast(x_stride) + u; } else { - image += static_cast( + offset = static_cast( (height - 1 - (line_no + static_cast(v)))) * static_cast(x_stride) + u; } + image += offset; *image = f32.f; } } @@ -9459,7 +9731,9 @@ &outBuf.at(v * pixel_data_size * static_cast(width) + channel_offset_list[c] * static_cast(width))); for (size_t u = 0; u < static_cast(width); u++) { - unsigned int val = line_ptr[u]; + unsigned int val; + // val = line_ptr[u]; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(&val); @@ -9485,7 +9759,9 @@ v * pixel_data_size * static_cast(x_stride) + channel_offset_list[c] * static_cast(x_stride))); for (size_t u = 0; u < static_cast(width); u++) { - float val = line_ptr[u]; + float val; + // val = line_ptr[u]; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(reinterpret_cast(&val)); @@ -9509,6 +9785,7 @@ } #else assert(0 && "PIZ is enabled in this build"); + return false; #endif } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS || @@ -9520,9 +9797,11 @@ unsigned long dstLen = static_cast(outBuf.size()); assert(dstLen > 0); - tinyexr::DecompressZip(reinterpret_cast(&outBuf.at(0)), - &dstLen, data_ptr, - static_cast(data_len)); + if (!tinyexr::DecompressZip( + reinterpret_cast(&outBuf.at(0)), &dstLen, data_ptr, + static_cast(data_len))) { + return false; + } // For ZIP_COMPRESSION: // pixel sample data for channel 0 for scanline 0 @@ -9544,7 +9823,8 @@ for (size_t u = 0; u < static_cast(width); u++) { tinyexr::FP16 hf; - hf.u = line_ptr[u]; + // hf.u = line_ptr[u]; + tinyexr::cpy2(&(hf.u), line_ptr + u); tinyexr::swap2(reinterpret_cast(&hf.u)); @@ -9565,16 +9845,19 @@ } else { // HALF -> FLOAT tinyexr::FP32 f32 = half_to_float(hf); float *image = reinterpret_cast(out_images)[c]; + size_t offset = 0; if (line_order == 0) { - image += (static_cast(line_no) + v) * + offset = (static_cast(line_no) + v) * static_cast(x_stride) + u; } else { - image += (static_cast(height) - 1U - + offset = (static_cast(height) - 1U - (static_cast(line_no) + v)) * static_cast(x_stride) + u; } + image += offset; + *image = f32.f; } } @@ -9587,7 +9870,9 @@ &outBuf.at(v * pixel_data_size * static_cast(width) + channel_offset_list[c] * static_cast(width))); for (size_t u = 0; u < static_cast(width); u++) { - unsigned int val = line_ptr[u]; + unsigned int val; + // val = line_ptr[u]; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(&val); @@ -9613,7 +9898,9 @@ &outBuf.at(v * pixel_data_size * static_cast(width) + channel_offset_list[c] * static_cast(width))); for (size_t u = 0; u < static_cast(width); u++) { - float val = line_ptr[u]; + float val; + // val = line_ptr[u]; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(reinterpret_cast(&val)); @@ -9633,6 +9920,7 @@ } } else { assert(0); + return false; } } } else if (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) { @@ -9642,10 +9930,15 @@ pixel_data_size); unsigned long dstLen = static_cast(outBuf.size()); - assert(dstLen > 0); - tinyexr::DecompressRle(reinterpret_cast(&outBuf.at(0)), + if (dstLen == 0) { + return false; + } + + if (!tinyexr::DecompressRle(reinterpret_cast(&outBuf.at(0)), dstLen, data_ptr, - static_cast(data_len)); + static_cast(data_len))) { + return false; + } // For RLE_COMPRESSION: // pixel sample data for channel 0 for scanline 0 @@ -9667,7 +9960,8 @@ for (size_t u = 0; u < static_cast(width); u++) { tinyexr::FP16 hf; - hf.u = line_ptr[u]; + // hf.u = line_ptr[u]; + tinyexr::cpy2(&(hf.u), line_ptr + u); tinyexr::swap2(reinterpret_cast(&hf.u)); @@ -9710,7 +10004,9 @@ &outBuf.at(v * pixel_data_size * static_cast(width) + channel_offset_list[c] * static_cast(width))); for (size_t u = 0; u < static_cast(width); u++) { - unsigned int val = line_ptr[u]; + unsigned int val; + // val = line_ptr[u]; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(&val); @@ -9736,7 +10032,9 @@ &outBuf.at(v * pixel_data_size * static_cast(width) + channel_offset_list[c] * static_cast(width))); for (size_t u = 0; u < static_cast(width); u++) { - float val = line_ptr[u]; + float val; + // val = line_ptr[u]; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(reinterpret_cast(&val)); @@ -9756,6 +10054,7 @@ } } else { assert(0); + return false; } } } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { @@ -9764,7 +10063,7 @@ if (!FindZFPCompressionParam(&zfp_compression_param, attributes, num_attributes)) { assert(0); - return; + return false; } // Allocate original data size. @@ -9798,7 +10097,8 @@ &outBuf.at(v * pixel_data_size * static_cast(width) + channel_offset_list[c] * static_cast(width))); for (size_t u = 0; u < static_cast(width); u++) { - float val = line_ptr[u]; + float val; + tinyexr::cpy4(&val, line_ptr + u); tinyexr::swap4(reinterpret_cast(&val)); @@ -9818,6 +10118,7 @@ } } else { assert(0); + return false; } } #else @@ -9825,94 +10126,130 @@ (void)num_attributes; (void)num_channels; assert(0); + return false; #endif } else if (compression_type == TINYEXR_COMPRESSIONTYPE_NONE) { for (size_t c = 0; c < num_channels; c++) { - if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { - const unsigned short *line_ptr = - reinterpret_cast( - data_ptr + - c * static_cast(width) * sizeof(unsigned short)); - - if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { - unsigned short *outLine = - reinterpret_cast(out_images[c]); - if (line_order == 0) { - outLine += y * x_stride; - } else { - outLine += (height - 1 - y) * x_stride; - } + for (size_t v = 0; v < static_cast(num_lines); v++) { + if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) { + const unsigned short *line_ptr = + reinterpret_cast( + data_ptr + v * pixel_data_size * size_t(width) + + channel_offset_list[c] * static_cast(width)); + + if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { + unsigned short *outLine = + reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += (size_t(y) + v) * size_t(x_stride); + } else { + outLine += + (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride); + } - for (int u = 0; u < width; u++) { - tinyexr::FP16 hf; + for (int u = 0; u < width; u++) { + tinyexr::FP16 hf; - hf.u = line_ptr[u]; + // hf.u = line_ptr[u]; + tinyexr::cpy2(&(hf.u), line_ptr + u); - tinyexr::swap2(reinterpret_cast(&hf.u)); + tinyexr::swap2(reinterpret_cast(&hf.u)); + + outLine[u] = hf.u; + } + } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { + float *outLine = reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += (size_t(y) + v) * size_t(x_stride); + } else { + outLine += + (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride); + } + + if (reinterpret_cast(line_ptr + width) > + (data_ptr + data_len)) { + // Insufficient data size + return false; + } + + for (int u = 0; u < width; u++) { + tinyexr::FP16 hf; + + // address may not be aliged. use byte-wise copy for safety.#76 + // hf.u = line_ptr[u]; + tinyexr::cpy2(&(hf.u), line_ptr + u); + + tinyexr::swap2(reinterpret_cast(&hf.u)); - outLine[u] = hf.u; + tinyexr::FP32 f32 = half_to_float(hf); + + outLine[u] = f32.f; + } + } else { + assert(0); + return false; } - } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { + const float *line_ptr = reinterpret_cast( + data_ptr + v * pixel_data_size * size_t(width) + + channel_offset_list[c] * static_cast(width)); + float *outLine = reinterpret_cast(out_images[c]); if (line_order == 0) { - outLine += y * x_stride; + outLine += (size_t(y) + v) * size_t(x_stride); } else { - outLine += (height - 1 - y) * x_stride; + outLine += + (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride); } - for (int u = 0; u < width; u++) { - tinyexr::FP16 hf; - - hf.u = line_ptr[u]; - - tinyexr::swap2(reinterpret_cast(&hf.u)); - - tinyexr::FP32 f32 = half_to_float(hf); - - outLine[u] = f32.f; + if (reinterpret_cast(line_ptr + width) > + (data_ptr + data_len)) { + // Insufficient data size + return false; } - } else { - assert(0); - } - } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) { - const float *line_ptr = reinterpret_cast( - data_ptr + c * static_cast(width) * sizeof(float)); - float *outLine = reinterpret_cast(out_images[c]); - if (line_order == 0) { - outLine += y * x_stride; - } else { - outLine += (height - 1 - y) * x_stride; - } + for (int u = 0; u < width; u++) { + float val; + tinyexr::cpy4(&val, line_ptr + u); - for (int u = 0; u < width; u++) { - float val = line_ptr[u]; + tinyexr::swap4(reinterpret_cast(&val)); - tinyexr::swap4(reinterpret_cast(&val)); + outLine[u] = val; + } + } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { + const unsigned int *line_ptr = reinterpret_cast( + data_ptr + v * pixel_data_size * size_t(width) + + channel_offset_list[c] * static_cast(width)); - outLine[u] = val; - } - } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) { - const unsigned int *line_ptr = reinterpret_cast( - data_ptr + c * static_cast(width) * sizeof(unsigned int)); + unsigned int *outLine = + reinterpret_cast(out_images[c]); + if (line_order == 0) { + outLine += (size_t(y) + v) * size_t(x_stride); + } else { + outLine += + (size_t(height) - 1 - (size_t(y) + v)) * size_t(x_stride); + } - unsigned int *outLine = reinterpret_cast(out_images[c]); - if (line_order == 0) { - outLine += y * x_stride; - } else { - outLine += (height - 1 - y) * x_stride; - } + for (int u = 0; u < width; u++) { + if (reinterpret_cast(line_ptr + u) >= + (data_ptr + data_len)) { + // Corrupsed data? + return false; + } - for (int u = 0; u < width; u++) { - unsigned int val = line_ptr[u]; + unsigned int val; + tinyexr::cpy4(&val, line_ptr + u); - tinyexr::swap4(reinterpret_cast(&val)); + tinyexr::swap4(reinterpret_cast(&val)); - outLine[u] = val; + outLine[u] = val; + } } } } } + + return true; } static void DecodeTiledPixelData( @@ -9948,7 +10285,7 @@ num_channels, channels, channel_offset_list); } -static void ComputeChannelLayout(std::vector *channel_offset_list, +static bool ComputeChannelLayout(std::vector *channel_offset_list, int *pixel_data_size, size_t *channel_offset, int num_channels, const EXRChannelInfo *channels) { @@ -9969,9 +10306,11 @@ (*pixel_data_size) += sizeof(unsigned int); (*channel_offset) += sizeof(unsigned int); } else { - assert(0); + // ??? + return false; } } + return true; } static unsigned char **AllocateImage(int num_channels, @@ -10079,8 +10418,11 @@ // Read attributes size_t orig_size = size; - for (;;) { + for (size_t nattr = 0; nattr < TINYEXR_MAX_HEADER_ATTRIBUTES; nattr++) { if (0 == size) { + if (err) { + (*err) += "Insufficient data size for attributes.\n"; + } return TINYEXR_ERROR_INVALID_DATA; } else if (marker[0] == '\0') { size--; @@ -10093,6 +10435,9 @@ size_t marker_size; if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size, marker, size)) { + if (err) { + (*err) += "Failed to read attribute.\n"; + } return TINYEXR_ERROR_INVALID_DATA; } marker += marker_size; @@ -10161,11 +10506,16 @@ // xSampling: int // ySampling: int - ReadChannelInfo(info->channels, data); + if (!ReadChannelInfo(info->channels, data)) { + if (err) { + (*err) += "Failed to parse channel info.\n"; + } + return TINYEXR_ERROR_INVALID_DATA; + } if (info->channels.size() < 1) { if (err) { - (*err) = "# of channels is zero."; + (*err) += "# of channels is zero.\n"; } return TINYEXR_ERROR_INVALID_DATA; } @@ -10173,59 +10523,72 @@ has_channels = true; } else if (attr_name.compare("dataWindow") == 0) { - memcpy(&info->data_window[0], &data.at(0), sizeof(int)); - memcpy(&info->data_window[1], &data.at(4), sizeof(int)); - memcpy(&info->data_window[2], &data.at(8), sizeof(int)); - memcpy(&info->data_window[3], &data.at(12), sizeof(int)); - tinyexr::swap4(reinterpret_cast(&info->data_window[0])); - tinyexr::swap4(reinterpret_cast(&info->data_window[1])); - tinyexr::swap4(reinterpret_cast(&info->data_window[2])); - tinyexr::swap4(reinterpret_cast(&info->data_window[3])); - - has_data_window = true; + if (data.size() >= 16) { + memcpy(&info->data_window[0], &data.at(0), sizeof(int)); + memcpy(&info->data_window[1], &data.at(4), sizeof(int)); + memcpy(&info->data_window[2], &data.at(8), sizeof(int)); + memcpy(&info->data_window[3], &data.at(12), sizeof(int)); + tinyexr::swap4(reinterpret_cast(&info->data_window[0])); + tinyexr::swap4(reinterpret_cast(&info->data_window[1])); + tinyexr::swap4(reinterpret_cast(&info->data_window[2])); + tinyexr::swap4(reinterpret_cast(&info->data_window[3])); + has_data_window = true; + } } else if (attr_name.compare("displayWindow") == 0) { - memcpy(&info->display_window[0], &data.at(0), sizeof(int)); - memcpy(&info->display_window[1], &data.at(4), sizeof(int)); - memcpy(&info->display_window[2], &data.at(8), sizeof(int)); - memcpy(&info->display_window[3], &data.at(12), sizeof(int)); - tinyexr::swap4( - reinterpret_cast(&info->display_window[0])); - tinyexr::swap4( - reinterpret_cast(&info->display_window[1])); - tinyexr::swap4( - reinterpret_cast(&info->display_window[2])); - tinyexr::swap4( - reinterpret_cast(&info->display_window[3])); + if (data.size() >= 16) { + memcpy(&info->display_window[0], &data.at(0), sizeof(int)); + memcpy(&info->display_window[1], &data.at(4), sizeof(int)); + memcpy(&info->display_window[2], &data.at(8), sizeof(int)); + memcpy(&info->display_window[3], &data.at(12), sizeof(int)); + tinyexr::swap4( + reinterpret_cast(&info->display_window[0])); + tinyexr::swap4( + reinterpret_cast(&info->display_window[1])); + tinyexr::swap4( + reinterpret_cast(&info->display_window[2])); + tinyexr::swap4( + reinterpret_cast(&info->display_window[3])); - has_display_window = true; + has_display_window = true; + } } else if (attr_name.compare("lineOrder") == 0) { - info->line_order = static_cast(data[0]); - has_line_order = true; + if (data.size() >= 1) { + info->line_order = static_cast(data[0]); + has_line_order = true; + } } else if (attr_name.compare("pixelAspectRatio") == 0) { - memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float)); - tinyexr::swap4( - reinterpret_cast(&info->pixel_aspect_ratio)); - has_pixel_aspect_ratio = true; + if (data.size() >= sizeof(float)) { + memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float)); + tinyexr::swap4( + reinterpret_cast(&info->pixel_aspect_ratio)); + has_pixel_aspect_ratio = true; + } } else if (attr_name.compare("screenWindowCenter") == 0) { - memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float)); - memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float)); - tinyexr::swap4( - reinterpret_cast(&info->screen_window_center[0])); - tinyexr::swap4( - reinterpret_cast(&info->screen_window_center[1])); - has_screen_window_center = true; + if (data.size() >= 8) { + memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float)); + memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float)); + tinyexr::swap4( + reinterpret_cast(&info->screen_window_center[0])); + tinyexr::swap4( + reinterpret_cast(&info->screen_window_center[1])); + has_screen_window_center = true; + } } else if (attr_name.compare("screenWindowWidth") == 0) { - memcpy(&info->screen_window_width, &data.at(0), sizeof(float)); - tinyexr::swap4( - reinterpret_cast(&info->screen_window_width)); + if (data.size() >= sizeof(float)) { + memcpy(&info->screen_window_width, &data.at(0), sizeof(float)); + tinyexr::swap4( + reinterpret_cast(&info->screen_window_width)); - has_screen_window_width = true; + has_screen_window_width = true; + } } else if (attr_name.compare("chunkCount") == 0) { - memcpy(&info->chunk_count, &data.at(0), sizeof(int)); - tinyexr::swap4(reinterpret_cast(&info->chunk_count)); + if (data.size() >= sizeof(int)) { + memcpy(&info->chunk_count, &data.at(0), sizeof(int)); + tinyexr::swap4(reinterpret_cast(&info->chunk_count)); + } } else { - // Custom attribute(up to TINYEXR_MAX_ATTRIBUTES) - if (info->attributes.size() < TINYEXR_MAX_ATTRIBUTES) { + // Custom attribute(up to TINYEXR_MAX_CUSTOM_ATTRIBUTES) + if (info->attributes.size() < TINYEXR_MAX_CUSTOM_ATTRIBUTES) { EXRAttribute attrib; #ifdef _MSC_VER strncpy_s(attrib.name, attr_name.c_str(), 255); @@ -10268,7 +10631,7 @@ } if (!has_data_window) { - ss_err << "\"dataWindow\" attribute not found in the header." + ss_err << "\"dataWindow\" attribute not found in the header or invalid." << std::endl; } @@ -10333,7 +10696,7 @@ #else strncpy(exr_header->channels[c].name, info.channels[c].name.c_str(), 255); #endif - // manually add '\0' for safety. + // manually add '\0' for safety. exr_header->channels[c].name[255] = '\0'; exr_header->channels[c].pixel_type = info.channels[c].pixel_type; @@ -10355,15 +10718,30 @@ exr_header->requested_pixel_types[c] = info.channels[c].pixel_type; } - assert(info.attributes.size() < TINYEXR_MAX_ATTRIBUTES); exr_header->num_custom_attributes = static_cast(info.attributes.size()); - for (size_t i = 0; i < info.attributes.size(); i++) { - memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name, 256); - memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, 256); - exr_header->custom_attributes[i].size = info.attributes[i].size; - // Just copy poiner - exr_header->custom_attributes[i].value = info.attributes[i].value; + if (exr_header->num_custom_attributes > 0) { + // TODO(syoyo): Report warning when # of attributes exceeds + // `TINYEXR_MAX_CUSTOM_ATTRIBUTES` + if (exr_header->num_custom_attributes > TINYEXR_MAX_CUSTOM_ATTRIBUTES) { + exr_header->num_custom_attributes = TINYEXR_MAX_CUSTOM_ATTRIBUTES; + } + + exr_header->custom_attributes = static_cast(malloc( + sizeof(EXRAttribute) * size_t(exr_header->num_custom_attributes))); + + for (size_t i = 0; i < info.attributes.size(); i++) { + memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name, + 256); + memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, + 256); + exr_header->custom_attributes[i].size = info.attributes[i].size; + // Just copy poiner + exr_header->custom_attributes[i].value = info.attributes[i].value; + } + + } else { + exr_header->custom_attributes = NULL; } exr_header->header_len = info.header_len; @@ -10371,7 +10749,8 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, const std::vector &offsets, - const unsigned char *head) { + const unsigned char *head, const size_t size, + std::string *err) { int num_channels = exr_header->num_channels; int num_scanline_blocks = 1; @@ -10386,32 +10765,89 @@ int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1; int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1; + if ((data_width < 0) || (data_height < 0)) { + if (err) { + std::stringstream ss; + ss << "Invalid data width or data height: " << data_width << ", " + << data_height << std::endl; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_DATA; + } + + // Do not allow too large data_width and data_height. header invalid? + { + const int threshold = 1024 * 8192; // heuristics + if ((data_width > threshold) || (data_height > threshold)) { + if (err) { + std::stringstream ss; + ss << "data_with or data_height too large. data_width: " << data_width + << ", " + << "data_height = " << data_height << std::endl; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_DATA; + } + } + size_t num_blocks = offsets.size(); std::vector channel_offset_list; int pixel_data_size = 0; size_t channel_offset = 0; - tinyexr::ComputeChannelLayout(&channel_offset_list, &pixel_data_size, - &channel_offset, num_channels, - exr_header->channels); + if (!tinyexr::ComputeChannelLayout(&channel_offset_list, &pixel_data_size, + &channel_offset, num_channels, + exr_header->channels)) { + if (err) { + (*err) += "Failed to compute channel layout.\n"; + } + return TINYEXR_ERROR_INVALID_DATA; + } - bool invalid_data = false; + bool invalid_data = false; // TODO(LTE): Use atomic lock for MT safety. if (exr_header->tiled) { - size_t num_tiles = offsets.size(); // = # of blocks + // value check + if (exr_header->tile_size_x < 0) { + if (err) { + std::stringstream ss; + ss << "Invalid tile size x : " << exr_header->tile_size_x << "\n"; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_HEADER; + } - exr_image->tiles = static_cast( - malloc(sizeof(EXRTile) * static_cast(num_tiles))); + if (exr_header->tile_size_y < 0) { + if (err) { + std::stringstream ss; + ss << "Invalid tile size y : " << exr_header->tile_size_y << "\n"; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_HEADER; + } + + size_t num_tiles = offsets.size(); // = # of blocks + + exr_image->tiles = static_cast( + calloc(sizeof(EXRTile), static_cast(num_tiles))); for (size_t tile_idx = 0; tile_idx < num_tiles; tile_idx++) { // Allocate memory for each tile. exr_image->tiles[tile_idx].images = tinyexr::AllocateImage( num_channels, exr_header->channels, exr_header->requested_pixel_types, - data_width, data_height); + exr_header->tile_size_x, exr_header->tile_size_y); // 16 byte: tile coordinates // 4 byte : data size // ~ : data(uncompressed or compressed) + if (offsets[tile_idx] + sizeof(int) * 5 > size) { + if (err) { + (*err) += "Insufficient data size.\n"; + } + return TINYEXR_ERROR_INVALID_DATA; + } + + size_t data_size = size_t(size - (offsets[tile_idx] + sizeof(int) * 5)); const unsigned char *data_ptr = reinterpret_cast(head + offsets[tile_idx]); @@ -10423,14 +10859,24 @@ tinyexr::swap4(reinterpret_cast(&tile_coordinates[3])); // @todo{ LoD } - assert(tile_coordinates[2] == 0); - assert(tile_coordinates[3] == 0); + if (tile_coordinates[2] != 0) { + return TINYEXR_ERROR_UNSUPPORTED_FEATURE; + } + if (tile_coordinates[3] != 0) { + return TINYEXR_ERROR_UNSUPPORTED_FEATURE; + } int data_len; memcpy(&data_len, data_ptr + 16, sizeof(int)); // 16 = sizeof(tile_coordinates) tinyexr::swap4(reinterpret_cast(&data_len)); - assert(data_len >= 4); + + if (data_len < 4 || size_t(data_len) > data_size) { + if (err) { + (*err) += "Insufficient data length.\n"; + } + return TINYEXR_ERROR_INVALID_DATA; + } // Move to data addr: 20 = 16 + 4; data_ptr += 20; @@ -10458,6 +10904,21 @@ } } else { // scanline format + // Don't allow too large image(256GB * pixel_data_size or more). Workaround + // for #104. + size_t total_data_len = + size_t(data_width) * size_t(data_height) * size_t(num_channels); + if ((total_data_len == 0) || (total_data_len >= 0x4000000000)) { + if (err) { + std::stringstream ss; + ss << "Image data size is zero or too large: width = " << data_width + << ", height = " << data_height << ", channels = " << num_channels + << std::endl; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_DATA; + } + exr_image->images = tinyexr::AllocateImage( num_channels, exr_header->channels, exr_header->requested_pixel_types, data_width, data_height); @@ -10467,47 +10928,82 @@ #endif for (int y = 0; y < static_cast(num_blocks); y++) { size_t y_idx = static_cast(y); - const unsigned char *data_ptr = - reinterpret_cast(head + offsets[y_idx]); - // 4 byte: scan line - // 4 byte: data size - // ~ : pixel data(uncompressed or compressed) - int line_no; - memcpy(&line_no, data_ptr, sizeof(int)); - int data_len; - memcpy(&data_len, data_ptr + 4, sizeof(int)); - tinyexr::swap4(reinterpret_cast(&line_no)); - tinyexr::swap4(reinterpret_cast(&data_len)); - int end_line_no = (std::min)(line_no + num_scanline_blocks, - (exr_header->data_window[3] + 1)); + if (offsets[y_idx] + sizeof(int) * 2 > size) { + invalid_data = true; + } else { + // 4 byte: scan line + // 4 byte: data size + // ~ : pixel data(uncompressed or compressed) + size_t data_size = size_t(size - (offsets[y_idx] + sizeof(int) * 2)); + const unsigned char *data_ptr = + reinterpret_cast(head + offsets[y_idx]); + + int line_no; + memcpy(&line_no, data_ptr, sizeof(int)); + int data_len; + memcpy(&data_len, data_ptr + 4, sizeof(int)); + tinyexr::swap4(reinterpret_cast(&line_no)); + tinyexr::swap4(reinterpret_cast(&data_len)); + + if (size_t(data_len) > data_size) { + invalid_data = true; + } else if (data_len == 0) { + // TODO(syoyo): May be ok to raise the threshold for example `data_len + // < 4` + invalid_data = true; + } else { + // line_no may be negative. + int end_line_no = (std::min)(line_no + num_scanline_blocks, + (exr_header->data_window[3] + 1)); - int num_lines = end_line_no - line_no; - assert(num_lines > 0); + int num_lines = end_line_no - line_no; - // Move to data addr: 8 = 4 + 4; - data_ptr += 8; + if (num_lines <= 0) { + invalid_data = true; + } else { + // Move to data addr: 8 = 4 + 4; + data_ptr += 8; - // Adjust line_no with data_window.bmin.y - line_no -= exr_header->data_window[1]; + // Adjust line_no with data_window.bmin.y - if (line_no < 0) { - invalid_data = true; - } else { - tinyexr::DecodePixelData( - exr_image->images, exr_header->requested_pixel_types, data_ptr, - static_cast(data_len), exr_header->compression_type, - exr_header->line_order, data_width, data_height, data_width, y, - line_no, num_lines, static_cast(pixel_data_size), - static_cast(exr_header->num_custom_attributes), - exr_header->custom_attributes, - static_cast(exr_header->num_channels), exr_header->channels, - channel_offset_list); + // overflow check + tinyexr_int64 lno = static_cast(line_no) - static_cast(exr_header->data_window[1]); + if (lno > std::numeric_limits::max()) { + line_no = -1; // invalid + } else if (lno < -std::numeric_limits::max()) { + line_no = -1; // invalid + } else { + line_no -= exr_header->data_window[1]; + } + + if (line_no < 0) { + invalid_data = true; + } else { + if (!tinyexr::DecodePixelData( + exr_image->images, exr_header->requested_pixel_types, + data_ptr, static_cast(data_len), + exr_header->compression_type, exr_header->line_order, + data_width, data_height, data_width, y, line_no, + num_lines, static_cast(pixel_data_size), + static_cast(exr_header->num_custom_attributes), + exr_header->custom_attributes, + static_cast(exr_header->num_channels), + exr_header->channels, channel_offset_list)) { + invalid_data = true; + } + } + } + } } } // omp parallel } if (invalid_data) { + if (err) { + std::stringstream ss; + (*err) += "Invalid data found when decoding pixels.\n"; + } return TINYEXR_ERROR_INVALID_DATA; } @@ -10537,7 +11033,7 @@ for (size_t i = 0; i < n; i++) { size_t offset = static_cast(marker - head); // Offset should not exceed whole EXR file/data size. - if (offset >= size) { + if ((offset + sizeof(tinyexr::tinyexr_uint64)) >= size) { return false; } @@ -10568,9 +11064,7 @@ const char **err) { if (exr_image == NULL || exr_header == NULL || head == NULL || marker == NULL || (size <= tinyexr::kEXRVersionSize)) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage("Invalid argument for DecodeEXRImage().", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -10583,11 +11077,41 @@ num_scanline_blocks = 16; } - int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1; - int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1; + int data_width = exr_header->data_window[2] - exr_header->data_window[0]; + if (data_width >= std::numeric_limits::max()) { + // Issue 63 + tinyexr::SetErrorMessage("Invalid data width value", err); + return TINYEXR_ERROR_INVALID_DATA; + } + data_width++; + + int data_height = exr_header->data_window[3] - exr_header->data_window[1]; + if (data_height >= std::numeric_limits::max()) { + tinyexr::SetErrorMessage("Invalid data height value", err); + return TINYEXR_ERROR_INVALID_DATA; + } + data_height++; + + if ((data_width < 0) || (data_height < 0)) { + tinyexr::SetErrorMessage("data width or data height is negative.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + + // Do not allow too large data_width and data_height. header invalid? + { + const int threshold = 1024 * 8192; // heuristics + if (data_width > threshold) { + tinyexr::SetErrorMessage("data width too large.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + if (data_height > threshold) { + tinyexr::SetErrorMessage("data height too large.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + } // Read offset tables. - size_t num_blocks; + size_t num_blocks = 0; if (exr_header->chunk_count > 0) { // Use `chunkCount` attribute. @@ -10621,12 +11145,16 @@ for (size_t y = 0; y < num_blocks; y++) { tinyexr::tinyexr_uint64 offset; + // Issue #81 + if ((marker + sizeof(tinyexr_uint64)) >= (head + size)) { + tinyexr::SetErrorMessage("Insufficient data size in offset table.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + memcpy(&offset, marker, sizeof(tinyexr::tinyexr_uint64)); tinyexr::swap8(&offset); if (offset >= size) { - if (err) { - (*err) = "Invalid offset value."; - } + tinyexr::SetErrorMessage("Invalid offset value in DecodeEXRImage.", err); return TINYEXR_ERROR_INVALID_DATA; } marker += sizeof(tinyexr::tinyexr_uint64); // = 8 @@ -10649,15 +11177,37 @@ // OK break; } else { - if (err) { - (*err) = "Cannot reconstruct lineOffset table."; - } + tinyexr::SetErrorMessage( + "Cannot reconstruct lineOffset table in DecodeEXRImage.", err); return TINYEXR_ERROR_INVALID_DATA; } } } - return DecodeChunk(exr_image, exr_header, offsets, head); + { + std::string e; + int ret = DecodeChunk(exr_image, exr_header, offsets, head, size, &e); + + if (ret != TINYEXR_SUCCESS) { + if (!e.empty()) { + tinyexr::SetErrorMessage(e, err); + } + + // release memory(if exists) + if ((exr_header->num_channels > 0) && exr_image && exr_image->images) { + for (size_t c = 0; c < size_t(exr_header->num_channels); c++) { + if (exr_image->images[c]) { + free(exr_image->images[c]); + exr_image->images[c] = NULL; + } + } + free(exr_image->images); + exr_image->images = NULL; + } + } + + return ret; + } } } // namespace tinyexr @@ -10665,9 +11215,7 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename, const char **err) { if (out_rgba == NULL) { - if (err) { - (*err) = "Invalid argument.\n"; - } + tinyexr::SetErrorMessage("Invalid argument for LoadEXR()", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -10680,13 +11228,14 @@ { int ret = ParseEXRVersionFromFile(&exr_version, filename); if (ret != TINYEXR_SUCCESS) { + tinyexr::SetErrorMessage("Invalid EXR header.", err); return ret; } if (exr_version.multipart || exr_version.non_image) { - if (err) { - (*err) = "Loading multipart or DeepImage is not supported yet.\n"; - } + tinyexr::SetErrorMessage( + "Loading multipart or DeepImage is not supported in LoadEXR() API", + err); return TINYEXR_ERROR_INVALID_DATA; // @fixme. } } @@ -10694,6 +11243,7 @@ { int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, err); if (ret != TINYEXR_SUCCESS) { + FreeEXRHeader(&exr_header); return ret; } } @@ -10708,6 +11258,7 @@ { int ret = LoadEXRImageFromFile(&exr_image, &exr_header, filename, err); if (ret != TINYEXR_SUCCESS) { + FreeEXRHeader(&exr_header); return ret; } } @@ -10729,62 +11280,128 @@ } } - if ((idxA == 0) && (idxR == -1) && (idxG == -1) && (idxB == -1)) { - // Alpha channel only. + if (exr_header.num_channels == 1) { + // Grayscale channel only. (*out_rgba) = reinterpret_cast( malloc(4 * sizeof(float) * static_cast(exr_image.width) * static_cast(exr_image.height))); - for (int i = 0; i < exr_image.width * exr_image.height; i++) { - const float val = reinterpret_cast(exr_image.images)[0][i]; - (*out_rgba)[4 * i + 0] = val; - (*out_rgba)[4 * i + 1] = val; - (*out_rgba)[4 * i + 2] = val; - (*out_rgba)[4 * i + 3] = val; + + if (exr_header.tiled) { + for (int it = 0; it < exr_image.num_tiles; it++) { + for (int j = 0; j < exr_header.tile_size_y; j++) { + for (int i = 0; i < exr_header.tile_size_x; i++) { + const int ii = + exr_image.tiles[it].offset_x * exr_header.tile_size_x + i; + const int jj = + exr_image.tiles[it].offset_y * exr_header.tile_size_y + j; + const int idx = ii + jj * exr_image.width; + + // out of region check. + if (ii >= exr_image.width) { + continue; + } + if (jj >= exr_image.height) { + continue; + } + const int srcIdx = i + j * exr_header.tile_size_x; + unsigned char **src = exr_image.tiles[it].images; + (*out_rgba)[4 * idx + 0] = + reinterpret_cast(src)[0][srcIdx]; + (*out_rgba)[4 * idx + 1] = + reinterpret_cast(src)[0][srcIdx]; + (*out_rgba)[4 * idx + 2] = + reinterpret_cast(src)[0][srcIdx]; + (*out_rgba)[4 * idx + 3] = + reinterpret_cast(src)[0][srcIdx]; + } + } + } + } else { + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + const float val = reinterpret_cast(exr_image.images)[0][i]; + (*out_rgba)[4 * i + 0] = val; + (*out_rgba)[4 * i + 1] = val; + (*out_rgba)[4 * i + 2] = val; + (*out_rgba)[4 * i + 3] = val; + } } } else { // Assume RGB(A) if (idxR == -1) { - if (err) { - (*err) = "R channel not found\n"; - } + tinyexr::SetErrorMessage("R channel not found", err); // @todo { free exr_image } + FreeEXRHeader(&exr_header); return TINYEXR_ERROR_INVALID_DATA; } if (idxG == -1) { - if (err) { - (*err) = "G channel not found\n"; - } + tinyexr::SetErrorMessage("G channel not found", err); // @todo { free exr_image } + FreeEXRHeader(&exr_header); return TINYEXR_ERROR_INVALID_DATA; } if (idxB == -1) { - if (err) { - (*err) = "B channel not found\n"; - } + tinyexr::SetErrorMessage("B channel not found", err); // @todo { free exr_image } + FreeEXRHeader(&exr_header); return TINYEXR_ERROR_INVALID_DATA; } (*out_rgba) = reinterpret_cast( malloc(4 * sizeof(float) * static_cast(exr_image.width) * static_cast(exr_image.height))); - for (int i = 0; i < exr_image.width * exr_image.height; i++) { - (*out_rgba)[4 * i + 0] = - reinterpret_cast(exr_image.images)[idxR][i]; - (*out_rgba)[4 * i + 1] = - reinterpret_cast(exr_image.images)[idxG][i]; - (*out_rgba)[4 * i + 2] = - reinterpret_cast(exr_image.images)[idxB][i]; - if (idxA != -1) { - (*out_rgba)[4 * i + 3] = - reinterpret_cast(exr_image.images)[idxA][i]; - } else { - (*out_rgba)[4 * i + 3] = 1.0; + if (exr_header.tiled) { + for (int it = 0; it < exr_image.num_tiles; it++) { + for (int j = 0; j < exr_header.tile_size_y; j++) { + for (int i = 0; i < exr_header.tile_size_x; i++) { + const int ii = + exr_image.tiles[it].offset_x * exr_header.tile_size_x + i; + const int jj = + exr_image.tiles[it].offset_y * exr_header.tile_size_y + j; + const int idx = ii + jj * exr_image.width; + + // out of region check. + if (ii >= exr_image.width) { + continue; + } + if (jj >= exr_image.height) { + continue; + } + const int srcIdx = i + j * exr_header.tile_size_x; + unsigned char **src = exr_image.tiles[it].images; + (*out_rgba)[4 * idx + 0] = + reinterpret_cast(src)[idxR][srcIdx]; + (*out_rgba)[4 * idx + 1] = + reinterpret_cast(src)[idxG][srcIdx]; + (*out_rgba)[4 * idx + 2] = + reinterpret_cast(src)[idxB][srcIdx]; + if (idxA != -1) { + (*out_rgba)[4 * idx + 3] = + reinterpret_cast(src)[idxA][srcIdx]; + } else { + (*out_rgba)[4 * idx + 3] = 1.0; + } + } + } + } + } else { + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + (*out_rgba)[4 * i + 0] = + reinterpret_cast(exr_image.images)[idxR][i]; + (*out_rgba)[4 * i + 1] = + reinterpret_cast(exr_image.images)[idxG][i]; + (*out_rgba)[4 * i + 2] = + reinterpret_cast(exr_image.images)[idxB][i]; + if (idxA != -1) { + (*out_rgba)[4 * i + 3] = + reinterpret_cast(exr_image.images)[idxA][i]; + } else { + (*out_rgba)[4 * i + 3] = 1.0; + } } } } @@ -10798,19 +11415,32 @@ return TINYEXR_SUCCESS; } +int IsEXR(const char *filename) { + EXRVersion exr_version; + + int ret = ParseEXRVersionFromFile(&exr_version, filename); + if (ret != TINYEXR_SUCCESS) { + return TINYEXR_ERROR_INVALID_HEADER; + } + + return TINYEXR_SUCCESS; +} + int ParseEXRHeaderFromMemory(EXRHeader *exr_header, const EXRVersion *version, const unsigned char *memory, size_t size, const char **err) { if (memory == NULL || exr_header == NULL) { - if (err) { - (*err) = "Invalid argument.\n"; - } + tinyexr::SetErrorMessage( + "Invalid argument. `memory` or `exr_header` argument is null in " + "ParseEXRHeaderFromMemory()", + err); // Invalid argument return TINYEXR_ERROR_INVALID_ARGUMENT; } if (size < tinyexr::kEXRVersionSize) { + tinyexr::SetErrorMessage("Insufficient header/data size.\n", err); return TINYEXR_ERROR_INVALID_DATA; } @@ -10825,11 +11455,7 @@ if (ret != TINYEXR_SUCCESS) { if (err && !err_str.empty()) { -#ifdef _WIN32 - (*err) = _strdup(err_str.c_str()); // May leak -#else - (*err) = strdup(err_str.c_str()); // May leak -#endif + tinyexr::SetErrorMessage(err_str, err); } } @@ -10842,12 +11468,10 @@ } int LoadEXRFromMemory(float **out_rgba, int *width, int *height, - const unsigned char *memory, size_t size, - const char **err) { + const unsigned char *memory, size_t size, + const char **err) { if (out_rgba == NULL || memory == NULL) { - if (err) { - (*err) = "Invalid argument.\n"; - } + tinyexr::SetErrorMessage("Invalid argument for LoadEXRFromMemory", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -10859,6 +11483,7 @@ int ret = ParseEXRVersionFromMemory(&exr_version, memory, size); if (ret != TINYEXR_SUCCESS) { + tinyexr::SetErrorMessage("Failed to parse EXR version", err); return ret; } @@ -10866,13 +11491,13 @@ if (ret != TINYEXR_SUCCESS) { return ret; } - + // Read HALF channel as FLOAT. for (int i = 0; i < exr_header.num_channels; i++) { if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) { exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; } - } + } InitEXRImage(&exr_image); ret = LoadEXRImageFromMemory(&exr_image, &exr_header, memory, size, err); @@ -10897,49 +11522,129 @@ } } - if (idxR == -1) { - if (err) { - (*err) = "R channel not found\n"; + // TODO(syoyo): Refactor removing same code as used in LoadEXR(). + if (exr_header.num_channels == 1) { + // Grayscale channel only. + + (*out_rgba) = reinterpret_cast( + malloc(4 * sizeof(float) * static_cast(exr_image.width) * + static_cast(exr_image.height))); + + if (exr_header.tiled) { + for (int it = 0; it < exr_image.num_tiles; it++) { + for (int j = 0; j < exr_header.tile_size_y; j++) { + for (int i = 0; i < exr_header.tile_size_x; i++) { + const int ii = + exr_image.tiles[it].offset_x * exr_header.tile_size_x + i; + const int jj = + exr_image.tiles[it].offset_y * exr_header.tile_size_y + j; + const int idx = ii + jj * exr_image.width; + + // out of region check. + if (ii >= exr_image.width) { + continue; + } + if (jj >= exr_image.height) { + continue; + } + const int srcIdx = i + j * exr_header.tile_size_x; + unsigned char **src = exr_image.tiles[it].images; + (*out_rgba)[4 * idx + 0] = + reinterpret_cast(src)[0][srcIdx]; + (*out_rgba)[4 * idx + 1] = + reinterpret_cast(src)[0][srcIdx]; + (*out_rgba)[4 * idx + 2] = + reinterpret_cast(src)[0][srcIdx]; + (*out_rgba)[4 * idx + 3] = + reinterpret_cast(src)[0][srcIdx]; + } + } + } + } else { + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + const float val = reinterpret_cast(exr_image.images)[0][i]; + (*out_rgba)[4 * i + 0] = val; + (*out_rgba)[4 * i + 1] = val; + (*out_rgba)[4 * i + 2] = val; + (*out_rgba)[4 * i + 3] = val; + } } - // @todo { free exr_image } - return TINYEXR_ERROR_INVALID_DATA; - } + } else { + // TODO(syoyo): Support non RGBA image. - if (idxG == -1) { - if (err) { - (*err) = "G channel not found\n"; + if (idxR == -1) { + tinyexr::SetErrorMessage("R channel not found", err); + + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; } - // @todo { free exr_image } - return TINYEXR_ERROR_INVALID_DATA; - } - if (idxB == -1) { - if (err) { - (*err) = "B channel not found\n"; + if (idxG == -1) { + tinyexr::SetErrorMessage("G channel not found", err); + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; } - // @todo { free exr_image } - return TINYEXR_ERROR_INVALID_DATA; - } - (*out_rgba) = reinterpret_cast( - malloc(4 * sizeof(float) * static_cast(exr_image.width) * - static_cast(exr_image.height))); - - for (int i = 0; i < exr_image.width * exr_image.height; i++) { - (*out_rgba)[4 * i + 0] = - reinterpret_cast(exr_image.images)[idxR][i]; - (*out_rgba)[4 * i + 1] = - reinterpret_cast(exr_image.images)[idxG][i]; - (*out_rgba)[4 * i + 2] = - reinterpret_cast(exr_image.images)[idxB][i]; - if (idxA != -1) { - (*out_rgba)[4 * i + 3] = - reinterpret_cast(exr_image.images)[idxA][i]; - } - else { - (*out_rgba)[4 * i + 3] = 1.0; - } + if (idxB == -1) { + tinyexr::SetErrorMessage("B channel not found", err); + // @todo { free exr_image } + return TINYEXR_ERROR_INVALID_DATA; + } + + (*out_rgba) = reinterpret_cast( + malloc(4 * sizeof(float) * static_cast(exr_image.width) * + static_cast(exr_image.height))); + + if (exr_header.tiled) { + for (int it = 0; it < exr_image.num_tiles; it++) { + for (int j = 0; j < exr_header.tile_size_y; j++) + for (int i = 0; i < exr_header.tile_size_x; i++) { + const int ii = + exr_image.tiles[it].offset_x * exr_header.tile_size_x + i; + const int jj = + exr_image.tiles[it].offset_y * exr_header.tile_size_y + j; + const int idx = ii + jj * exr_image.width; + + // out of region check. + if (ii >= exr_image.width) { + continue; + } + if (jj >= exr_image.height) { + continue; + } + const int srcIdx = i + j * exr_header.tile_size_x; + unsigned char **src = exr_image.tiles[it].images; + (*out_rgba)[4 * idx + 0] = + reinterpret_cast(src)[idxR][srcIdx]; + (*out_rgba)[4 * idx + 1] = + reinterpret_cast(src)[idxG][srcIdx]; + (*out_rgba)[4 * idx + 2] = + reinterpret_cast(src)[idxB][srcIdx]; + if (idxA != -1) { + (*out_rgba)[4 * idx + 3] = + reinterpret_cast(src)[idxA][srcIdx]; + } else { + (*out_rgba)[4 * idx + 3] = 1.0; + } + } + } + } else { + for (int i = 0; i < exr_image.width * exr_image.height; i++) { + (*out_rgba)[4 * i + 0] = + reinterpret_cast(exr_image.images)[idxR][i]; + (*out_rgba)[4 * i + 1] = + reinterpret_cast(exr_image.images)[idxG][i]; + (*out_rgba)[4 * i + 2] = + reinterpret_cast(exr_image.images)[idxB][i]; + if (idxA != -1) { + (*out_rgba)[4 * i + 3] = + reinterpret_cast(exr_image.images)[idxA][i]; + } else { + (*out_rgba)[4 * i + 3] = 1.0; + } + } + } } (*width) = exr_image.width; @@ -10954,9 +11659,7 @@ int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header, const char *filename, const char **err) { if (exr_image == NULL) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage("Invalid argument for LoadEXRImageFromFile", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -10967,9 +11670,7 @@ FILE *fp = fopen(filename, "rb"); #endif if (!fp) { - if (err) { - (*err) = "Cannot read file."; - } + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); return TINYEXR_ERROR_CANT_OPEN_FILE; } @@ -10979,6 +11680,12 @@ filesize = static_cast(ftell(fp)); fseek(fp, 0, SEEK_SET); + if (filesize < 16) { + tinyexr::SetErrorMessage("File size too short " + std::string(filename), + err); + return TINYEXR_ERROR_INVALID_FILE; + } + std::vector buf(filesize); // @todo { use mmap } { size_t ret; @@ -10997,16 +11704,13 @@ const char **err) { if (exr_image == NULL || memory == NULL || (size < tinyexr::kEXRVersionSize)) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage("Invalid argument for LoadEXRImageFromMemory", + err); return TINYEXR_ERROR_INVALID_ARGUMENT; } if (exr_header->header_len == 0) { - if (err) { - (*err) = "EXRHeader is not initialized."; - } + tinyexr::SetErrorMessage("EXRHeader variable is not initialized.", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -11023,26 +11727,22 @@ unsigned char **memory_out, const char **err) { if (exr_image == NULL || memory_out == NULL || exr_header->compression_type < 0) { - if (err) { - (*err) = "Invalid argument."; - } - return 0; // @fixme + tinyexr::SetErrorMessage("Invalid argument for SaveEXRImageToMemory", err); + return 0; } #if !TINYEXR_USE_PIZ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { - if (err) { - (*err) = "PIZ compression is not supported in this build."; - } + tinyexr::SetErrorMessage("PIZ compression is not supported in this build", + err); return 0; } #endif #if !TINYEXR_USE_ZFP if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { - if (err) { - (*err) = "ZFP compression is not supported in this build."; - } + tinyexr::SetErrorMessage("ZFP compression is not supported in this build", + err); return 0; } #endif @@ -11050,9 +11750,8 @@ #if TINYEXR_USE_ZFP for (size_t i = 0; i < static_cast(exr_header->num_channels); i++) { if (exr_header->requested_pixel_types[i] != TINYEXR_PIXELTYPE_FLOAT) { - if (err) { - (*err) = "Pixel type must be FLOAT for ZFP compression."; - } + tinyexr::SetErrorMessage("Pixel type must be FLOAT for ZFP compression", + err); return 0; } } @@ -11200,8 +11899,6 @@ sizeof( tinyexr::tinyexr_int64); // sizeof(header) + sizeof(offsetTable) - std::vector data; - std::vector > data_list( static_cast(num_blocks)); std::vector channel_offset_list( @@ -11262,6 +11959,11 @@ if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { for (int y = 0; y < h; y++) { + // Assume increasing Y + float *line_ptr = reinterpret_cast(&buf.at( + static_cast(pixel_data_size * y * exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); for (int x = 0; x < exr_image->width; x++) { tinyexr::FP16 h16; h16.u = reinterpret_cast( @@ -11271,30 +11973,27 @@ tinyexr::swap4(reinterpret_cast(&f32.f)); - // Assume increasing Y - float *line_ptr = reinterpret_cast(&buf.at( - static_cast(pixel_data_size * y * exr_image->width) + - channel_offset_list[c] * - static_cast(exr_image->width))); - line_ptr[x] = f32.f; + // line_ptr[x] = f32.f; + tinyexr::cpy4(line_ptr + x, &(f32.f)); } } } else if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { for (int y = 0; y < h; y++) { + // Assume increasing Y + unsigned short *line_ptr = reinterpret_cast( + &buf.at(static_cast(pixel_data_size * y * + exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); for (int x = 0; x < exr_image->width; x++) { unsigned short val = reinterpret_cast( exr_image->images)[c][(y + start_y) * exr_image->width + x]; tinyexr::swap2(&val); - // Assume increasing Y - unsigned short *line_ptr = reinterpret_cast( - &buf.at(static_cast(pixel_data_size * y * - exr_image->width) + - channel_offset_list[c] * - static_cast(exr_image->width))); - line_ptr[x] = val; + // line_ptr[x] = val; + tinyexr::cpy2(line_ptr + x, &val); } } } else { @@ -11304,6 +12003,12 @@ } else if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) { for (int y = 0; y < h; y++) { + // Assume increasing Y + unsigned short *line_ptr = reinterpret_cast( + &buf.at(static_cast(pixel_data_size * y * + exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); for (int x = 0; x < exr_image->width; x++) { tinyexr::FP32 f32; f32.f = reinterpret_cast( @@ -11314,30 +12019,26 @@ tinyexr::swap2(reinterpret_cast(&h16.u)); - // Assume increasing Y - unsigned short *line_ptr = reinterpret_cast( - &buf.at(static_cast(pixel_data_size * y * - exr_image->width) + - channel_offset_list[c] * - static_cast(exr_image->width))); - line_ptr[x] = h16.u; + // line_ptr[x] = h16.u; + tinyexr::cpy2(line_ptr + x, &(h16.u)); } } } else if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) { for (int y = 0; y < h; y++) { + // Assume increasing Y + float *line_ptr = reinterpret_cast(&buf.at( + static_cast(pixel_data_size * y * exr_image->width) + + channel_offset_list[c] * + static_cast(exr_image->width))); for (int x = 0; x < exr_image->width; x++) { float val = reinterpret_cast( exr_image->images)[c][(y + start_y) * exr_image->width + x]; tinyexr::swap4(reinterpret_cast(&val)); - // Assume increasing Y - float *line_ptr = reinterpret_cast(&buf.at( - static_cast(pixel_data_size * y * exr_image->width) + - channel_offset_list[c] * - static_cast(exr_image->width))); - line_ptr[x] = val; + // line_ptr[x] = val; + tinyexr::cpy4(line_ptr + x, &val); } } } else { @@ -11345,18 +12046,18 @@ } } else if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_UINT) { for (int y = 0; y < h; y++) { + // Assume increasing Y + unsigned int *line_ptr = reinterpret_cast(&buf.at( + static_cast(pixel_data_size * y * exr_image->width) + + channel_offset_list[c] * static_cast(exr_image->width))); for (int x = 0; x < exr_image->width; x++) { unsigned int val = reinterpret_cast( exr_image->images)[c][(y + start_y) * exr_image->width + x]; tinyexr::swap4(&val); - // Assume increasing Y - unsigned int *line_ptr = reinterpret_cast(&buf.at( - static_cast(pixel_data_size * y * exr_image->width) + - channel_offset_list[c] * - static_cast(exr_image->width))); - line_ptr[x] = val; + // line_ptr[x] = val; + tinyexr::cpy4(line_ptr + x, &val); } } } @@ -11436,9 +12137,9 @@ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { #if TINYEXR_USE_PIZ unsigned int bufLen = - 1024 + static_cast( - 1.2 * static_cast( - buf.size())); // @fixme { compute good bound. } + 8192 + static_cast( + 2 * static_cast( + buf.size())); // @fixme { compute good bound. } std::vector block(bufLen); unsigned int outSize = static_cast(block.size()); @@ -11497,13 +12198,12 @@ } // omp parallel for (size_t i = 0; i < static_cast(num_blocks); i++) { - data.insert(data.end(), data_list[i].begin(), data_list[i].end()); - offsets[i] = offset; tinyexr::swap8(reinterpret_cast(&offsets[i])); offset += data_list[i].size(); } + size_t totalSize = static_cast(offset); { memory.insert( memory.end(), reinterpret_cast(&offsets.at(0)), @@ -11511,41 +12211,44 @@ sizeof(tinyexr::tinyexr_uint64) * static_cast(num_blocks)); } - { memory.insert(memory.end(), data.begin(), data.end()); } - - assert(memory.size() > 0); + if (memory.size() == 0) { + tinyexr::SetErrorMessage("Output memory size is zero", err); + return 0; + } - (*memory_out) = static_cast(malloc(memory.size())); + (*memory_out) = static_cast(malloc(totalSize)); memcpy((*memory_out), &memory.at(0), memory.size()); + unsigned char *memory_ptr = *memory_out + memory.size(); - return memory.size(); // OK + for (size_t i = 0; i < static_cast(num_blocks); i++) { + memcpy(memory_ptr, &data_list[i].at(0), data_list[i].size()); + memory_ptr += data_list[i].size(); + } + + return totalSize; // OK } int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header, const char *filename, const char **err) { if (exr_image == NULL || filename == NULL || exr_header->compression_type < 0) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage("Invalid argument for SaveEXRImageToFile", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } #if !TINYEXR_USE_PIZ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { - if (err) { - (*err) = "PIZ compression is not supported in this build."; - } - return 0; + tinyexr::SetErrorMessage("PIZ compression is not supported in this build", + err); + return TINYEXR_ERROR_UNSUPPORTED_FEATURE; } #endif #if !TINYEXR_USE_ZFP if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) { - if (err) { - (*err) = "ZFP compression is not supported in this build."; - } - return 0; + tinyexr::SetErrorMessage("ZFP compression is not supported in this build", + err); + return TINYEXR_ERROR_UNSUPPORTED_FEATURE; } #endif @@ -11556,48 +12259,51 @@ FILE *fp = fopen(filename, "wb"); #endif if (!fp) { - if (err) { - (*err) = "Cannot write a file."; - } - return TINYEXR_ERROR_CANT_OPEN_FILE; + tinyexr::SetErrorMessage("Cannot write a file", err); + return TINYEXR_ERROR_CANT_WRITE_FILE; } unsigned char *mem = NULL; size_t mem_size = SaveEXRImageToMemory(exr_image, exr_header, &mem, err); + if (mem_size == 0) { + return TINYEXR_ERROR_SERIALZATION_FAILED; + } + size_t written_size = 0; if ((mem_size > 0) && mem) { - fwrite(mem, 1, mem_size, fp); + written_size = fwrite(mem, 1, mem_size, fp); } free(mem); fclose(fp); + if (written_size != mem_size) { + tinyexr::SetErrorMessage("Cannot write a file", err); + return TINYEXR_ERROR_CANT_WRITE_FILE; + } + return TINYEXR_SUCCESS; } int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { if (deep_image == NULL) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage("Invalid argument for LoadDeepEXR", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } #ifdef _MSC_VER FILE *fp = NULL; errno_t errcode = fopen_s(&fp, filename, "rb"); - if ((!errcode) || (!fp)) { - if (err) { - (*err) = "Cannot read file."; - } + if ((0 != errcode) || (!fp)) { + tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename), + err); return TINYEXR_ERROR_CANT_OPEN_FILE; } #else FILE *fp = fopen(filename, "rb"); if (!fp) { - if (err) { - (*err) = "Cannot read file."; - } + tinyexr::SetErrorMessage("Cannot read a file " + std::string(filename), + err); return TINYEXR_ERROR_CANT_OPEN_FILE; } #endif @@ -11610,9 +12316,8 @@ if (filesize == 0) { fclose(fp); - if (err) { - (*err) = "File size is zero."; - } + tinyexr::SetErrorMessage("File size is zero : " + std::string(filename), + err); return TINYEXR_ERROR_INVALID_FILE; } @@ -11633,9 +12338,7 @@ const char header[] = {0x76, 0x2f, 0x31, 0x01}; if (memcmp(marker, header, 4) != 0) { - if (err) { - (*err) = "Invalid magic number."; - } + tinyexr::SetErrorMessage("Invalid magic number", err); return TINYEXR_ERROR_INVALID_MAGIC_NUMBER; } marker += 4; @@ -11646,9 +12349,7 @@ // ver 2.0, scanline, deep bit on(0x800) // must be [2, 0, 0, 0] if (marker[0] != 2 || marker[1] != 8 || marker[2] != 0 || marker[3] != 0) { - if (err) { - (*err) = "Unsupported version or scanline."; - } + tinyexr::SetErrorMessage("Unsupported version or scanline", err); return TINYEXR_ERROR_UNSUPPORTED_FORMAT; } @@ -11681,6 +12382,9 @@ size_t marker_size; if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size, marker, size)) { + std::stringstream ss; + ss << "Failed to parse attribute\n"; + tinyexr::SetErrorMessage(ss.str(), err); return TINYEXR_ERROR_INVALID_DATA; } marker += marker_size; @@ -11689,9 +12393,9 @@ if (attr_name.compare("compression") == 0) { compression_type = data[0]; if (compression_type > TINYEXR_COMPRESSIONTYPE_PIZ) { - if (err) { - (*err) = "Unsupported compression type."; - } + std::stringstream ss; + ss << "Unsupported compression type : " << compression_type; + tinyexr::SetErrorMessage(ss.str(), err); return TINYEXR_ERROR_UNSUPPORTED_FORMAT; } @@ -11707,14 +12411,15 @@ // xSampling: int // ySampling: int - tinyexr::ReadChannelInfo(channels, data); + if (!tinyexr::ReadChannelInfo(channels, data)) { + tinyexr::SetErrorMessage("Failed to parse channel info", err); + return TINYEXR_ERROR_INVALID_DATA; + } num_channels = static_cast(channels.size()); if (num_channels < 1) { - if (err) { - (*err) = "Invalid channels format."; - } + tinyexr::SetErrorMessage("Invalid channels format", err); return TINYEXR_ERROR_INVALID_DATA; } @@ -11786,9 +12491,7 @@ #endif // OK } else { - if (err) { - (*err) = "Unsupported format."; - } + tinyexr::SetErrorMessage("Unsupported compression format", err); return TINYEXR_ERROR_UNSUPPORTED_FORMAT; } @@ -11844,9 +12547,12 @@ { unsigned long dstLen = static_cast(pixelOffsetTable.size() * sizeof(int)); - tinyexr::DecompressZip( - reinterpret_cast(&pixelOffsetTable.at(0)), &dstLen, - data_ptr + 28, static_cast(packedOffsetTableSize)); + if (!tinyexr::DecompressZip( + reinterpret_cast(&pixelOffsetTable.at(0)), + &dstLen, data_ptr + 28, + static_cast(packedOffsetTableSize))) { + return false; + } assert(dstLen == pixelOffsetTable.size() * sizeof(int)); for (size_t i = 0; i < static_cast(data_width); i++) { @@ -11861,10 +12567,12 @@ { unsigned long dstLen = static_cast(unpackedSampleDataSize); if (dstLen) { - tinyexr::DecompressZip( - reinterpret_cast(&sample_data.at(0)), &dstLen, - data_ptr + 28 + packedOffsetTableSize, - static_cast(packedSampleDataSize)); + if (!tinyexr::DecompressZip( + reinterpret_cast(&sample_data.at(0)), &dstLen, + data_ptr + 28 + packedOffsetTableSize, + static_cast(packedSampleDataSize))) { + return false; + } assert(dstLen == static_cast(unpackedSampleDataSize)); } } @@ -11911,8 +12619,10 @@ if (channels[c].pixel_type == 0) { // UINT for (size_t x = 0; x < static_cast(samples_per_line); x++) { - unsigned int ui = *reinterpret_cast( + unsigned int ui; + unsigned int *src_ptr = reinterpret_cast( &sample_data.at(size_t(data_offset) + x * sizeof(int))); + tinyexr::cpy4(&ui, src_ptr); deep_image->image[c][y][x] = static_cast(ui); // @fixme } data_offset += @@ -11920,16 +12630,19 @@ } else if (channels[c].pixel_type == 1) { // half for (size_t x = 0; x < static_cast(samples_per_line); x++) { tinyexr::FP16 f16; - f16.u = *reinterpret_cast( + const unsigned short *src_ptr = reinterpret_cast( &sample_data.at(size_t(data_offset) + x * sizeof(short))); + tinyexr::cpy2(&(f16.u), src_ptr); tinyexr::FP32 f32 = half_to_float(f16); deep_image->image[c][y][x] = f32.f; } data_offset += sizeof(short) * static_cast(samples_per_line); } else { // float for (size_t x = 0; x < static_cast(samples_per_line); x++) { - float f = *reinterpret_cast( + float f; + const float *src_ptr = reinterpret_cast( &sample_data.at(size_t(data_offset) + x * sizeof(float))); + tinyexr::cpy4(&f, src_ptr); deep_image->image[c][y][x] = f; } data_offset += sizeof(float) * static_cast(samples_per_line); @@ -11970,6 +12683,13 @@ exr_image->num_tiles = 0; } +void FreeEXRErrorMessage(const char *msg) { + if (msg) { + free(reinterpret_cast(const_cast(msg))); + } + return; +} + void InitEXRHeader(EXRHeader *exr_header) { if (exr_header == NULL) { return; @@ -12001,6 +12721,10 @@ } } + if (exr_header->custom_attributes) { + free(exr_header->custom_attributes); + } + return TINYEXR_SUCCESS; } @@ -12030,6 +12754,7 @@ free(exr_image->tiles[tid].images); } } + free(exr_image->tiles); } return TINYEXR_SUCCESS; @@ -12038,9 +12763,8 @@ int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version, const char *filename, const char **err) { if (exr_header == NULL || exr_version == NULL || filename == NULL) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage("Invalid argument for ParseEXRHeaderFromFile", + err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -12051,9 +12775,7 @@ FILE *fp = fopen(filename, "rb"); #endif if (!fp) { - if (err) { - (*err) = "Cannot read file."; - } + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); return TINYEXR_ERROR_CANT_OPEN_FILE; } @@ -12071,9 +12793,8 @@ fclose(fp); if (ret != filesize) { - if (err) { - (*err) = "fread error."; - } + tinyexr::SetErrorMessage("fread() error on " + std::string(filename), + err); return TINYEXR_ERROR_INVALID_FILE; } } @@ -12090,10 +12811,13 @@ if (memory == NULL || exr_headers == NULL || num_headers == NULL || exr_version == NULL) { // Invalid argument + tinyexr::SetErrorMessage( + "Invalid argument for ParseEXRMultipartHeaderFromMemory", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } if (size < tinyexr::kEXRVersionSize) { + tinyexr::SetErrorMessage("Data size too short", err); return TINYEXR_ERROR_INVALID_DATA; } @@ -12112,13 +12836,7 @@ marker, marker_size); if (ret != TINYEXR_SUCCESS) { - if (err) { -#ifdef _WIN32 - (*err) = _strdup(err_str.c_str()); // may leak -#else - (*err) = strdup(err_str.c_str()); // may leak -#endif - } + tinyexr::SetErrorMessage(err_str, err); return ret; } @@ -12129,9 +12847,8 @@ // `chunkCount` must exist in the header. if (info.chunk_count == 0) { - if (err) { - (*err) = "`chunkCount' attribute is not found in the header."; - } + tinyexr::SetErrorMessage( + "`chunkCount' attribute is not found in the header.", err); return TINYEXR_ERROR_INVALID_DATA; } @@ -12166,9 +12883,8 @@ const char *filename, const char **err) { if (exr_headers == NULL || num_headers == NULL || exr_version == NULL || filename == NULL) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage( + "Invalid argument for ParseEXRMultipartHeaderFromFile()", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -12179,9 +12895,7 @@ FILE *fp = fopen(filename, "rb"); #endif if (!fp) { - if (err) { - (*err) = "Cannot read file."; - } + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); return TINYEXR_ERROR_CANT_OPEN_FILE; } @@ -12199,9 +12913,7 @@ fclose(fp); if (ret != filesize) { - if (err) { - (*err) = "fread error."; - } + tinyexr::SetErrorMessage("`fread' error. file may be corrupted.", err); return TINYEXR_ERROR_INVALID_FILE; } } @@ -12310,9 +13022,8 @@ const size_t size, const char **err) { if (exr_images == NULL || exr_headers == NULL || num_parts == 0 || memory == NULL || (size <= tinyexr::kEXRVersionSize)) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage( + "Invalid argument for LoadEXRMultipartImageFromMemory()", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -12320,9 +13031,7 @@ size_t total_header_size = 0; for (unsigned int i = 0; i < num_parts; i++) { if (exr_headers[i]->header_len == 0) { - if (err) { - (*err) = "EXRHeader is not initialized."; - } + tinyexr::SetErrorMessage("EXRHeader variable is not initialized.", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -12357,9 +13066,8 @@ tinyexr::swap8(&offset); if (offset >= size) { - if (err) { - (*err) = "Invalid offset size."; - } + tinyexr::SetErrorMessage("Invalid offset size in EXR header chunks.", + err); return TINYEXR_ERROR_INVALID_DATA; } @@ -12384,14 +13092,19 @@ tinyexr::swap4(&part_no); if (part_no != i) { - assert(0); + tinyexr::SetErrorMessage("Invalid `part number' in EXR header chunks.", + err); return TINYEXR_ERROR_INVALID_DATA; } } + std::string e; int ret = tinyexr::DecodeChunk(&exr_images[i], exr_headers[i], offset_table, - memory); + memory, size, &e); if (ret != TINYEXR_SUCCESS) { + if (!e.empty()) { + tinyexr::SetErrorMessage(e, err); + } return ret; } } @@ -12404,9 +13117,8 @@ unsigned int num_parts, const char *filename, const char **err) { if (exr_images == NULL || exr_headers == NULL || num_parts == 0) { - if (err) { - (*err) = "Invalid argument."; - } + tinyexr::SetErrorMessage( + "Invalid argument for LoadEXRMultipartImageFromFile", err); return TINYEXR_ERROR_INVALID_ARGUMENT; } @@ -12417,9 +13129,7 @@ FILE *fp = fopen(filename, "rb"); #endif if (!fp) { - if (err) { - (*err) = "Cannot read file."; - } + tinyexr::SetErrorMessage("Cannot read file " + std::string(filename), err); return TINYEXR_ERROR_CANT_OPEN_FILE; } @@ -12443,20 +13153,27 @@ } int SaveEXR(const float *data, int width, int height, int components, - const int save_as_fp16, const char *outfilename) { + const int save_as_fp16, const char *outfilename, const char **err) { if ((components == 1) || components == 3 || components == 4) { // OK } else { + std::stringstream ss; + ss << "Unsupported component value : " << components << std::endl; + + tinyexr::SetErrorMessage(ss.str(), err); return TINYEXR_ERROR_INVALID_ARGUMENT; } - // Assume at least 16x16 pixels. - if (width < 16) return TINYEXR_ERROR_INVALID_ARGUMENT; - if (height < 16) return TINYEXR_ERROR_INVALID_ARGUMENT; - EXRHeader header; InitEXRHeader(&header); + if ((width < 16) && (height < 16)) { + // No compression for small image. + header.compression_type = TINYEXR_COMPRESSIONTYPE_NONE; + } else { + header.compression_type = TINYEXR_COMPRESSIONTYPE_ZIP; + } + EXRImage image; InitEXRImage(&image); @@ -12562,8 +13279,7 @@ } } - const char *err; - int ret = SaveEXRImageToFile(&image, &header, outfilename, &err); + int ret = SaveEXRImageToFile(&image, &header, outfilename, err); if (ret != TINYEXR_SUCCESS) { return ret; } @@ -12575,5 +13291,10 @@ return ret; } +#ifdef __clang__ +// zero-as-null-ppinter-constant +#pragma clang diagnostic pop +#endif + #endif // TINYEXR_IMPLEMENTATION_DEIFNED #endif // TINYEXR_IMPLEMENTATION diff -Nru love-11.1/src/love.cpp love-11.3/src/love.cpp --- love-11.1/src/love.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/love.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -19,6 +19,7 @@ **/ #include "common/version.h" +#include "common/runtime.h" #include "modules/love/love.h" #include @@ -214,7 +215,7 @@ lua_newthread(L); lua_pushvalue(L, -2); int stackpos = lua_gettop(L); - while (lua_resume(L, 0) == LUA_YIELD) + while (love::luax_resume(L, 0) == LUA_YIELD) lua_pop(L, lua_gettop(L) - stackpos); retval = 0; diff -Nru love-11.1/src/Makefile.am love-11.3/src/Makefile.am --- love-11.1/src/Makefile.am 2018-04-15 18:31:51.000000000 +0000 +++ love-11.3/src/Makefile.am 2019-10-27 13:45:09.000000000 +0000 @@ -44,16 +44,14 @@ ./common/EnumMap.h \ ./common/Exception.cpp \ ./common/Exception.h \ - ./common/halffloat.cpp \ - ./common/halffloat.h \ + ./common/floattypes.cpp \ + ./common/floattypes.h \ ./common/int.h \ ./common/ios.h \ ./common/macosx.h \ ./common/math.h \ ./common/Matrix.cpp \ ./common/Matrix.h \ - ./common/Memoizer.cpp \ - ./common/Memoizer.h \ ./common/memory.cpp \ ./common/memory.h \ ./common/Module.cpp \ @@ -141,6 +139,7 @@ ./modules/data/wrap_CompressedData.h \ ./modules/data/wrap_Data.cpp \ ./modules/data/wrap_Data.h \ + ./modules/data/wrap_Data.lua \ ./modules/data/wrap_DataModule.cpp \ ./modules/data/wrap_DataModule.h \ ./modules/data/wrap_DataView.cpp \ @@ -271,6 +270,7 @@ ./modules/graphics/wrap_Graphics.cpp \ ./modules/graphics/wrap_Graphics.h \ ./modules/graphics/wrap_Graphics.lua \ + ./modules/graphics/wrap_GraphicsShader.lua \ ./modules/graphics/wrap_Image.cpp \ ./modules/graphics/wrap_Image.h \ ./modules/graphics/wrap_Mesh.cpp \ @@ -487,6 +487,8 @@ ./modules/sound/Decoder.h \ ./modules/sound/lullaby/CoreAudioDecoder.cpp \ ./modules/sound/lullaby/CoreAudioDecoder.h \ + ./modules/sound/lullaby/FLACDecoder.cpp \ + ./modules/sound/lullaby/FLACDecoder.h \ ./modules/sound/lullaby/GmeDecoder.cpp \ ./modules/sound/lullaby/GmeDecoder.h \ ./modules/sound/lullaby/ModPlugDecoder.cpp \ @@ -680,6 +682,9 @@ ./libraries/ddsparse/ddsparse.cpp \ ./libraries/ddsparse/ddsparse.h +liblove_library_dr_flac = \ + ./libraries/dr_flac/dr_flac.h + liblove_library_enet = \ ./libraries/enet/enet.cpp \ ./libraries/enet/libenet/callbacks.c \ @@ -722,6 +727,8 @@ ./libraries/glslang/glslang/Include/revision.h \ ./libraries/glslang/glslang/Include/ShHandle.h \ ./libraries/glslang/glslang/Include/Types.h \ + ./libraries/glslang/glslang/MachineIndependent/attribute.cpp \ + ./libraries/glslang/glslang/MachineIndependent/attribute.h \ ./libraries/glslang/glslang/MachineIndependent/Constant.cpp \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h \ @@ -743,6 +750,8 @@ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp \ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.h \ ./libraries/glslang/glslang/MachineIndependent/parseVersions.h \ + ./libraries/glslang/glslang/MachineIndependent/pch.cpp \ + ./libraries/glslang/glslang/MachineIndependent/pch.h \ ./libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp \ @@ -1000,6 +1009,10 @@ liblove_la_SOURCES += $(liblove_library_ddsparse) endif +if LOVE_LIBRARY_DR_FLAC +liblove_la_SOURCES += $(liblove_library_dr_flac) +endif + if LOVE_LIBRARY_ENET liblove_la_SOURCES += $(liblove_library_enet) endif diff -Nru love-11.1/src/Makefile.in love-11.3/src/Makefile.in --- love-11.1/src/Makefile.in 2018-04-15 18:32:01.000000000 +0000 +++ love-11.3/src/Makefile.in 2019-10-27 13:45:21.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -119,20 +119,21 @@ @LOVE_MODULE_WINDOW_TRUE@am__append_22 = $(liblove_module_window) @LOVE_LIBRARY_BOX2D_TRUE@am__append_23 = $(liblove_library_Box2D) @LOVE_LIBRARY_DDSPARSE_TRUE@am__append_24 = $(liblove_library_ddsparse) -@LOVE_LIBRARY_ENET_TRUE@am__append_25 = $(liblove_library_enet) -@LOVE_LIBRARY_GLAD_TRUE@am__append_26 = $(liblove_library_glad) -@LOVE_LIBRARY_GLSLANG_TRUE@am__append_27 = $(liblove_library_glslang) -@LOVE_LIBRARY_LODEPNG_TRUE@am__append_28 = $(liblove_library_lodepng) -@LOVE_LIBRARY_LUA53_TRUE@am__append_29 = $(liblove_library_lua53) -@LOVE_LIBRARY_LUASOCKET_TRUE@am__append_30 = $(liblove_library_luasocket) -@LOVE_LIBRARY_LZ4_TRUE@am__append_31 = $(liblove_library_lz4) -@LOVE_LIBRARY_NOISE1234_TRUE@am__append_32 = $(liblove_library_noise1234) -@LOVE_LIBRARY_PHYSFS_TRUE@am__append_33 = $(liblove_library_physfs) -@LOVE_LIBRARY_STB_TRUE@am__append_34 = $(liblove_library_stb) -@LOVE_LIBRARY_TINYEXR_TRUE@am__append_35 = $(liblove_library_tinyexr) -@LOVE_LIBRARY_UTF8_TRUE@am__append_36 = $(liblove_library_utf8) -@LOVE_LIBRARY_WUFF_TRUE@am__append_37 = $(liblove_library_Wuff) -@LOVE_LIBRARY_XXHASH_TRUE@am__append_38 = $(liblove_library_xxHash) +@LOVE_LIBRARY_DR_FLAC_TRUE@am__append_25 = $(liblove_library_dr_flac) +@LOVE_LIBRARY_ENET_TRUE@am__append_26 = $(liblove_library_enet) +@LOVE_LIBRARY_GLAD_TRUE@am__append_27 = $(liblove_library_glad) +@LOVE_LIBRARY_GLSLANG_TRUE@am__append_28 = $(liblove_library_glslang) +@LOVE_LIBRARY_LODEPNG_TRUE@am__append_29 = $(liblove_library_lodepng) +@LOVE_LIBRARY_LUA53_TRUE@am__append_30 = $(liblove_library_lua53) +@LOVE_LIBRARY_LUASOCKET_TRUE@am__append_31 = $(liblove_library_luasocket) +@LOVE_LIBRARY_LZ4_TRUE@am__append_32 = $(liblove_library_lz4) +@LOVE_LIBRARY_NOISE1234_TRUE@am__append_33 = $(liblove_library_noise1234) +@LOVE_LIBRARY_PHYSFS_TRUE@am__append_34 = $(liblove_library_physfs) +@LOVE_LIBRARY_STB_TRUE@am__append_35 = $(liblove_library_stb) +@LOVE_LIBRARY_TINYEXR_TRUE@am__append_36 = $(liblove_library_tinyexr) +@LOVE_LIBRARY_UTF8_TRUE@am__append_37 = $(liblove_library_utf8) +@LOVE_LIBRARY_WUFF_TRUE@am__append_38 = $(liblove_library_Wuff) +@LOVE_LIBRARY_XXHASH_TRUE@am__append_39 = $(liblove_library_xxHash) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/platform/unix/m4/libtool.m4 \ @@ -152,6 +153,8 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" +PROGRAMS = $(bin_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -179,7 +182,6 @@ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = liblove_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -192,25 +194,24 @@ ./common/delay.cpp ./common/delay.h ./common/deprecation.cpp \ ./common/deprecation.h ./common/EnumMap.h \ ./common/Exception.cpp ./common/Exception.h \ - ./common/halffloat.cpp ./common/halffloat.h ./common/int.h \ + ./common/floattypes.cpp ./common/floattypes.h ./common/int.h \ ./common/ios.h ./common/macosx.h ./common/math.h \ - ./common/Matrix.cpp ./common/Matrix.h ./common/Memoizer.cpp \ - ./common/Memoizer.h ./common/memory.cpp ./common/memory.h \ - ./common/Module.cpp ./common/Module.h ./common/Object.cpp \ - ./common/Object.h ./common/Optional.h ./common/pixelformat.cpp \ - ./common/pixelformat.h ./common/Reference.cpp \ - ./common/Reference.h ./common/runtime.cpp ./common/runtime.h \ - ./common/Stream.cpp ./common/Stream.h ./common/StringMap.cpp \ - ./common/StringMap.h ./common/types.cpp ./common/types.h \ - ./common/utf8.cpp ./common/utf8.h ./common/Variant.cpp \ - ./common/Variant.h ./common/Vector.cpp ./common/Vector.h \ - ./common/version.h ./scripts/auto.lua ./scripts/boot.lua \ - ./scripts/boot.lua.h ./scripts/nogame.lua \ - ./scripts/nogame.lua.h ./modules/audio/Audio.cpp \ - ./modules/audio/Audio.h ./modules/audio/Effect.cpp \ - ./modules/audio/Effect.h ./modules/audio/Filter.cpp \ - ./modules/audio/Filter.h ./modules/audio/null/Audio.cpp \ - ./modules/audio/null/Audio.h \ + ./common/Matrix.cpp ./common/Matrix.h ./common/memory.cpp \ + ./common/memory.h ./common/Module.cpp ./common/Module.h \ + ./common/Object.cpp ./common/Object.h ./common/Optional.h \ + ./common/pixelformat.cpp ./common/pixelformat.h \ + ./common/Reference.cpp ./common/Reference.h \ + ./common/runtime.cpp ./common/runtime.h ./common/Stream.cpp \ + ./common/Stream.h ./common/StringMap.cpp ./common/StringMap.h \ + ./common/types.cpp ./common/types.h ./common/utf8.cpp \ + ./common/utf8.h ./common/Variant.cpp ./common/Variant.h \ + ./common/Vector.cpp ./common/Vector.h ./common/version.h \ + ./scripts/auto.lua ./scripts/boot.lua ./scripts/boot.lua.h \ + ./scripts/nogame.lua ./scripts/nogame.lua.h \ + ./modules/audio/Audio.cpp ./modules/audio/Audio.h \ + ./modules/audio/Effect.cpp ./modules/audio/Effect.h \ + ./modules/audio/Filter.cpp ./modules/audio/Filter.h \ + ./modules/audio/null/Audio.cpp ./modules/audio/null/Audio.h \ ./modules/audio/null/RecordingDevice.cpp \ ./modules/audio/null/RecordingDevice.h \ ./modules/audio/null/Source.cpp ./modules/audio/null/Source.h \ @@ -243,6 +244,7 @@ ./modules/data/wrap_CompressedData.cpp \ ./modules/data/wrap_CompressedData.h \ ./modules/data/wrap_Data.cpp ./modules/data/wrap_Data.h \ + ./modules/data/wrap_Data.lua \ ./modules/data/wrap_DataModule.cpp \ ./modules/data/wrap_DataModule.h \ ./modules/data/wrap_DataView.cpp \ @@ -338,6 +340,7 @@ ./modules/graphics/wrap_Graphics.cpp \ ./modules/graphics/wrap_Graphics.h \ ./modules/graphics/wrap_Graphics.lua \ + ./modules/graphics/wrap_GraphicsShader.lua \ ./modules/graphics/wrap_Image.cpp \ ./modules/graphics/wrap_Image.h \ ./modules/graphics/wrap_Mesh.cpp \ @@ -515,6 +518,8 @@ ./modules/sound/Decoder.cpp ./modules/sound/Decoder.h \ ./modules/sound/lullaby/CoreAudioDecoder.cpp \ ./modules/sound/lullaby/CoreAudioDecoder.h \ + ./modules/sound/lullaby/FLACDecoder.cpp \ + ./modules/sound/lullaby/FLACDecoder.h \ ./modules/sound/lullaby/GmeDecoder.cpp \ ./modules/sound/lullaby/GmeDecoder.h \ ./modules/sound/lullaby/ModPlugDecoder.cpp \ @@ -662,8 +667,8 @@ ./libraries/Box2D/Rope/b2Rope.cpp \ ./libraries/Box2D/Rope/b2Rope.h ./libraries/ddsparse/ddsinfo.h \ ./libraries/ddsparse/ddsparse.cpp \ - ./libraries/ddsparse/ddsparse.h ./libraries/enet/enet.cpp \ - ./libraries/enet/libenet/callbacks.c \ + ./libraries/ddsparse/ddsparse.h ./libraries/dr_flac/dr_flac.h \ + ./libraries/enet/enet.cpp ./libraries/enet/libenet/callbacks.c \ ./libraries/enet/libenet/compress.c \ ./libraries/enet/libenet/host.c \ ./libraries/enet/libenet/include/enet/callbacks.h \ @@ -697,6 +702,8 @@ ./libraries/glslang/glslang/Include/revision.h \ ./libraries/glslang/glslang/Include/ShHandle.h \ ./libraries/glslang/glslang/Include/Types.h \ + ./libraries/glslang/glslang/MachineIndependent/attribute.cpp \ + ./libraries/glslang/glslang/MachineIndependent/attribute.h \ ./libraries/glslang/glslang/MachineIndependent/Constant.cpp \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h \ @@ -718,6 +725,8 @@ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp \ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.h \ ./libraries/glslang/glslang/MachineIndependent/parseVersions.h \ + ./libraries/glslang/glslang/MachineIndependent/pch.cpp \ + ./libraries/glslang/glslang/MachineIndependent/pch.h \ ./libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp \ @@ -1022,6 +1031,7 @@ @LOVE_NOMPG123_FALSE@ ./modules/sound/lullaby/Mpg123Decoder.lo am__objects_28 = ./modules/sound/Decoder.lo \ ./modules/sound/lullaby/CoreAudioDecoder.lo \ + ./modules/sound/lullaby/FLACDecoder.lo \ ./modules/sound/lullaby/GmeDecoder.lo \ ./modules/sound/lullaby/ModPlugDecoder.lo \ ./modules/sound/lullaby/Sound.lo \ @@ -1106,7 +1116,9 @@ @LOVE_LIBRARY_BOX2D_TRUE@am__objects_43 = $(am__objects_42) am__objects_44 = ./libraries/ddsparse/ddsparse.lo @LOVE_LIBRARY_DDSPARSE_TRUE@am__objects_45 = $(am__objects_44) -am__objects_46 = ./libraries/enet/enet.lo \ +am__objects_46 = +@LOVE_LIBRARY_DR_FLAC_TRUE@am__objects_47 = $(am__objects_46) +am__objects_48 = ./libraries/enet/enet.lo \ ./libraries/enet/libenet/callbacks.lo \ ./libraries/enet/libenet/compress.lo \ ./libraries/enet/libenet/host.lo \ @@ -1116,12 +1128,13 @@ ./libraries/enet/libenet/protocol.lo \ ./libraries/enet/libenet/unix.lo \ ./libraries/enet/libenet/win32.lo -@LOVE_LIBRARY_ENET_TRUE@am__objects_47 = $(am__objects_46) -am__objects_48 = ./libraries/glad/glad.lo -@LOVE_LIBRARY_GLAD_TRUE@am__objects_49 = $(am__objects_48) -am__objects_50 = \ +@LOVE_LIBRARY_ENET_TRUE@am__objects_49 = $(am__objects_48) +am__objects_50 = ./libraries/glad/glad.lo +@LOVE_LIBRARY_GLAD_TRUE@am__objects_51 = $(am__objects_50) +am__objects_52 = \ ./libraries/glslang/glslang/GenericCodeGen/CodeGen.lo \ ./libraries/glslang/glslang/GenericCodeGen/Link.lo \ + ./libraries/glslang/glslang/MachineIndependent/attribute.lo \ ./libraries/glslang/glslang/MachineIndependent/Constant.lo \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.lo \ ./libraries/glslang/glslang/MachineIndependent/InfoSink.lo \ @@ -1135,6 +1148,7 @@ ./libraries/glslang/glslang/MachineIndependent/parseConst.lo \ ./libraries/glslang/glslang/MachineIndependent/ParseContextBase.lo \ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.lo \ + ./libraries/glslang/glslang/MachineIndependent/pch.lo \ ./libraries/glslang/glslang/MachineIndependent/PoolAlloc.lo \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.lo \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.lo \ @@ -1150,13 +1164,13 @@ ./libraries/glslang/glslang/MachineIndependent/Versions.lo \ ./libraries/glslang/glslang/OSDependent/Unix/ossource.lo \ ./libraries/glslang/OGLCompilersDLL/InitializeDll.lo -@LOVE_LIBRARY_GLSLANG_TRUE@am__objects_51 = $(am__objects_50) -am__objects_52 = ./libraries/lodepng/lodepng.lo -@LOVE_LIBRARY_LODEPNG_TRUE@am__objects_53 = $(am__objects_52) -am__objects_54 = ./libraries/lua53/lstrlib.lo \ +@LOVE_LIBRARY_GLSLANG_TRUE@am__objects_53 = $(am__objects_52) +am__objects_54 = ./libraries/lodepng/lodepng.lo +@LOVE_LIBRARY_LODEPNG_TRUE@am__objects_55 = $(am__objects_54) +am__objects_56 = ./libraries/lua53/lstrlib.lo \ ./libraries/lua53/lutf8lib.lo -@LOVE_LIBRARY_LUA53_TRUE@am__objects_55 = $(am__objects_54) -am__objects_56 = ./libraries/luasocket/libluasocket/auxiliar.lo \ +@LOVE_LIBRARY_LUA53_TRUE@am__objects_57 = $(am__objects_56) +am__objects_58 = ./libraries/luasocket/libluasocket/auxiliar.lo \ ./libraries/luasocket/libluasocket/buffer.lo \ ./libraries/luasocket/libluasocket/compat.lo \ ./libraries/luasocket/libluasocket/except.lo \ @@ -1175,13 +1189,13 @@ ./libraries/luasocket/libluasocket/unixudp.lo \ ./libraries/luasocket/libluasocket/usocket.lo \ ./libraries/luasocket/luasocket.lo -@LOVE_LIBRARY_LUASOCKET_TRUE@am__objects_57 = $(am__objects_56) -am__objects_58 = ./libraries/lz4/lz4.lo ./libraries/lz4/lz4hc.lo -@LOVE_LIBRARY_LZ4_TRUE@am__objects_59 = $(am__objects_58) -am__objects_60 = ./libraries/noise1234/noise1234.lo \ +@LOVE_LIBRARY_LUASOCKET_TRUE@am__objects_59 = $(am__objects_58) +am__objects_60 = ./libraries/lz4/lz4.lo ./libraries/lz4/lz4hc.lo +@LOVE_LIBRARY_LZ4_TRUE@am__objects_61 = $(am__objects_60) +am__objects_62 = ./libraries/noise1234/noise1234.lo \ ./libraries/noise1234/simplexnoise1234.lo -@LOVE_LIBRARY_NOISE1234_TRUE@am__objects_61 = $(am__objects_60) -am__objects_62 = ./libraries/physfs/physfs_archiver_7z.lo \ +@LOVE_LIBRARY_NOISE1234_TRUE@am__objects_63 = $(am__objects_62) +am__objects_64 = ./libraries/physfs/physfs_archiver_7z.lo \ ./libraries/physfs/physfs_archiver_dir.lo \ ./libraries/physfs/physfs_archiver_grp.lo \ ./libraries/physfs/physfs_archiver_hog.lo \ @@ -1203,22 +1217,21 @@ ./libraries/physfs/physfs_platform_windows.lo \ ./libraries/physfs/physfs_platform_winrt.lo \ ./libraries/physfs/physfs_unicode.lo -@LOVE_LIBRARY_PHYSFS_TRUE@am__objects_63 = $(am__objects_62) -am__objects_64 = -@LOVE_LIBRARY_STB_TRUE@am__objects_65 = $(am__objects_64) -@LOVE_LIBRARY_TINYEXR_TRUE@am__objects_66 = $(am__objects_64) -@LOVE_LIBRARY_UTF8_TRUE@am__objects_67 = $(am__objects_64) -am__objects_68 = ./libraries/Wuff/wuff.lo \ +@LOVE_LIBRARY_PHYSFS_TRUE@am__objects_65 = $(am__objects_64) +@LOVE_LIBRARY_STB_TRUE@am__objects_66 = $(am__objects_46) +@LOVE_LIBRARY_TINYEXR_TRUE@am__objects_67 = $(am__objects_46) +@LOVE_LIBRARY_UTF8_TRUE@am__objects_68 = $(am__objects_46) +am__objects_69 = ./libraries/Wuff/wuff.lo \ ./libraries/Wuff/wuff_convert.lo \ ./libraries/Wuff/wuff_internal.lo \ ./libraries/Wuff/wuff_memory.lo -@LOVE_LIBRARY_WUFF_TRUE@am__objects_69 = $(am__objects_68) -am__objects_70 = ./libraries/xxHash/xxhash.lo -@LOVE_LIBRARY_XXHASH_TRUE@am__objects_71 = $(am__objects_70) +@LOVE_LIBRARY_WUFF_TRUE@am__objects_70 = $(am__objects_69) +am__objects_71 = ./libraries/xxHash/xxhash.lo +@LOVE_LIBRARY_XXHASH_TRUE@am__objects_72 = $(am__objects_71) am_liblove_la_OBJECTS = ./common/android.lo ./common/b64.lo \ ./common/Data.lo ./common/delay.lo ./common/deprecation.lo \ - ./common/Exception.lo ./common/halffloat.lo ./common/Matrix.lo \ - ./common/Memoizer.lo ./common/memory.lo ./common/Module.lo \ + ./common/Exception.lo ./common/floattypes.lo \ + ./common/Matrix.lo ./common/memory.lo ./common/Module.lo \ ./common/Object.lo ./common/pixelformat.lo \ ./common/Reference.lo ./common/runtime.lo ./common/Stream.lo \ ./common/StringMap.lo ./common/types.lo ./common/utf8.lo \ @@ -1234,7 +1247,7 @@ $(am__objects_53) $(am__objects_55) $(am__objects_57) \ $(am__objects_59) $(am__objects_61) $(am__objects_63) \ $(am__objects_65) $(am__objects_66) $(am__objects_67) \ - $(am__objects_69) $(am__objects_71) + $(am__objects_68) $(am__objects_70) $(am__objects_72) liblove_la_OBJECTS = $(am_liblove_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -1243,11 +1256,10 @@ liblove_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(liblove_la_LDFLAGS) $(LDFLAGS) -o $@ -PROGRAMS = $(bin_PROGRAMS) am__love_SOURCES_DIST = love.cpp ./common/macosx.mm -@LOVE_BUILD_EXE_TRUE@@LOVE_TARGET_OSX_TRUE@am__objects_72 = ./common/macosx.$(OBJEXT) +@LOVE_BUILD_EXE_TRUE@@LOVE_TARGET_OSX_TRUE@am__objects_73 = ./common/macosx.$(OBJEXT) @LOVE_BUILD_EXE_TRUE@am_love_OBJECTS = love.$(OBJEXT) \ -@LOVE_BUILD_EXE_TRUE@ $(am__objects_72) +@LOVE_BUILD_EXE_TRUE@ $(am__objects_73) love_OBJECTS = $(am_love_OBJECTS) @LOVE_BUILD_EXE_TRUE@love_DEPENDENCIES = liblove.la \ @LOVE_BUILD_EXE_TRUE@ $(am__DEPENDENCIES_1) @@ -1268,7 +1280,383 @@ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/platform/unix/depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/love.Po ./common/$(DEPDIR)/Data.Plo \ + ./common/$(DEPDIR)/Exception.Plo ./common/$(DEPDIR)/Matrix.Plo \ + ./common/$(DEPDIR)/Module.Plo ./common/$(DEPDIR)/Object.Plo \ + ./common/$(DEPDIR)/Reference.Plo ./common/$(DEPDIR)/Stream.Plo \ + ./common/$(DEPDIR)/StringMap.Plo \ + ./common/$(DEPDIR)/Variant.Plo ./common/$(DEPDIR)/Vector.Plo \ + ./common/$(DEPDIR)/android.Plo ./common/$(DEPDIR)/b64.Plo \ + ./common/$(DEPDIR)/delay.Plo \ + ./common/$(DEPDIR)/deprecation.Plo \ + ./common/$(DEPDIR)/floattypes.Plo ./common/$(DEPDIR)/macosx.Po \ + ./common/$(DEPDIR)/memory.Plo \ + ./common/$(DEPDIR)/pixelformat.Plo \ + ./common/$(DEPDIR)/runtime.Plo ./common/$(DEPDIR)/types.Plo \ + ./common/$(DEPDIR)/utf8.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2BroadPhase.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2CollideCircle.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2CollideEdge.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2CollidePolygon.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2Collision.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2Distance.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2DynamicTree.Plo \ + ./libraries/Box2D/Collision/$(DEPDIR)/b2TimeOfImpact.Plo \ + ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2ChainShape.Plo \ + ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2CircleShape.Plo \ + ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2EdgeShape.Plo \ + ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2PolygonShape.Plo \ + ./libraries/Box2D/Common/$(DEPDIR)/b2BlockAllocator.Plo \ + ./libraries/Box2D/Common/$(DEPDIR)/b2Draw.Plo \ + ./libraries/Box2D/Common/$(DEPDIR)/b2Math.Plo \ + ./libraries/Box2D/Common/$(DEPDIR)/b2Settings.Plo \ + ./libraries/Box2D/Common/$(DEPDIR)/b2StackAllocator.Plo \ + ./libraries/Box2D/Common/$(DEPDIR)/b2Timer.Plo \ + ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Body.Plo \ + ./libraries/Box2D/Dynamics/$(DEPDIR)/b2ContactManager.Plo \ + ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Fixture.Plo \ + ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Island.Plo \ + ./libraries/Box2D/Dynamics/$(DEPDIR)/b2World.Plo \ + ./libraries/Box2D/Dynamics/$(DEPDIR)/b2WorldCallbacks.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndCircleContact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndPolygonContact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2CircleContact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2Contact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ContactSolver.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndCircleContact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndPolygonContact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonAndCircleContact.Plo \ + ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonContact.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2DistanceJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2FrictionJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2GearJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2Joint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MotorJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MouseJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PrismaticJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PulleyJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RevoluteJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RopeJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WeldJoint.Plo \ + ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WheelJoint.Plo \ + ./libraries/Box2D/Rope/$(DEPDIR)/b2Rope.Plo \ + ./libraries/Wuff/$(DEPDIR)/wuff.Plo \ + ./libraries/Wuff/$(DEPDIR)/wuff_convert.Plo \ + ./libraries/Wuff/$(DEPDIR)/wuff_internal.Plo \ + ./libraries/Wuff/$(DEPDIR)/wuff_memory.Plo \ + ./libraries/ddsparse/$(DEPDIR)/ddsparse.Plo \ + ./libraries/enet/$(DEPDIR)/enet.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/callbacks.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/compress.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/host.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/list.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/packet.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/peer.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/protocol.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/unix.Plo \ + ./libraries/enet/libenet/$(DEPDIR)/win32.Plo \ + ./libraries/glad/$(DEPDIR)/glad.Plo \ + ./libraries/glslang/OGLCompilersDLL/$(DEPDIR)/InitializeDll.Plo \ + ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/CodeGen.Plo \ + ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/Link.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Constant.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/InfoSink.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Initialize.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/IntermTraverse.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Intermediate.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseContextBase.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseHelper.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/PoolAlloc.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/RemoveTree.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Scan.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ShaderLang.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/SymbolTable.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Versions.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/attribute.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/glslang_tab.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/intermOut.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/iomapper.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/limits.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/linkValidate.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/parseConst.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/pch.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/propagateNoContraction.Plo \ + ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/reflection.Plo \ + ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/Pp.Plo \ + ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpAtom.Plo \ + ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpContext.Plo \ + ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpScanner.Plo \ + ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpTokens.Plo \ + ./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR)/ossource.Plo \ + ./libraries/lodepng/$(DEPDIR)/lodepng.Plo \ + ./libraries/lua53/$(DEPDIR)/lstrlib.Plo \ + ./libraries/lua53/$(DEPDIR)/lutf8lib.Plo \ + ./libraries/luasocket/$(DEPDIR)/luasocket.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/auxiliar.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/buffer.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/compat.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/except.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/inet.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/io.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/luasocket.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/mime.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/options.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/select.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/serial.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/tcp.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/timeout.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/udp.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/unix.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/unixtcp.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/unixudp.Plo \ + ./libraries/luasocket/libluasocket/$(DEPDIR)/usocket.Plo \ + ./libraries/lz4/$(DEPDIR)/lz4.Plo \ + ./libraries/lz4/$(DEPDIR)/lz4hc.Plo \ + ./libraries/noise1234/$(DEPDIR)/noise1234.Plo \ + ./libraries/noise1234/$(DEPDIR)/simplexnoise1234.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_7z.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_dir.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_grp.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_hog.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_iso9660.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_mvl.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_qpak.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_slb.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_unpacked.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_vdf.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_wad.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_archiver_zip.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_byteorder.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_haiku.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_os2.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_posix.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_qnx.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_unix.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_windows.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_platform_winrt.Plo \ + ./libraries/physfs/$(DEPDIR)/physfs_unicode.Plo \ + ./libraries/xxHash/$(DEPDIR)/xxhash.Plo \ + ./modules/audio/$(DEPDIR)/Audio.Plo \ + ./modules/audio/$(DEPDIR)/Effect.Plo \ + ./modules/audio/$(DEPDIR)/Filter.Plo \ + ./modules/audio/$(DEPDIR)/RecordingDevice.Plo \ + ./modules/audio/$(DEPDIR)/Source.Plo \ + ./modules/audio/$(DEPDIR)/wrap_Audio.Plo \ + ./modules/audio/$(DEPDIR)/wrap_RecordingDevice.Plo \ + ./modules/audio/$(DEPDIR)/wrap_Source.Plo \ + ./modules/audio/null/$(DEPDIR)/Audio.Plo \ + ./modules/audio/null/$(DEPDIR)/RecordingDevice.Plo \ + ./modules/audio/null/$(DEPDIR)/Source.Plo \ + ./modules/audio/openal/$(DEPDIR)/Audio.Plo \ + ./modules/audio/openal/$(DEPDIR)/Effect.Plo \ + ./modules/audio/openal/$(DEPDIR)/Filter.Plo \ + ./modules/audio/openal/$(DEPDIR)/Pool.Plo \ + ./modules/audio/openal/$(DEPDIR)/RecordingDevice.Plo \ + ./modules/audio/openal/$(DEPDIR)/Source.Plo \ + ./modules/data/$(DEPDIR)/ByteData.Plo \ + ./modules/data/$(DEPDIR)/CompressedData.Plo \ + ./modules/data/$(DEPDIR)/Compressor.Plo \ + ./modules/data/$(DEPDIR)/DataModule.Plo \ + ./modules/data/$(DEPDIR)/DataView.Plo \ + ./modules/data/$(DEPDIR)/HashFunction.Plo \ + ./modules/data/$(DEPDIR)/wrap_ByteData.Plo \ + ./modules/data/$(DEPDIR)/wrap_CompressedData.Plo \ + ./modules/data/$(DEPDIR)/wrap_Data.Plo \ + ./modules/data/$(DEPDIR)/wrap_DataModule.Plo \ + ./modules/data/$(DEPDIR)/wrap_DataView.Plo \ + ./modules/event/$(DEPDIR)/Event.Plo \ + ./modules/event/$(DEPDIR)/wrap_Event.Plo \ + ./modules/event/sdl/$(DEPDIR)/Event.Plo \ + ./modules/filesystem/$(DEPDIR)/DroppedFile.Plo \ + ./modules/filesystem/$(DEPDIR)/File.Plo \ + ./modules/filesystem/$(DEPDIR)/FileData.Plo \ + ./modules/filesystem/$(DEPDIR)/Filesystem.Plo \ + ./modules/filesystem/$(DEPDIR)/wrap_DroppedFile.Plo \ + ./modules/filesystem/$(DEPDIR)/wrap_File.Plo \ + ./modules/filesystem/$(DEPDIR)/wrap_FileData.Plo \ + ./modules/filesystem/$(DEPDIR)/wrap_Filesystem.Plo \ + ./modules/filesystem/physfs/$(DEPDIR)/File.Plo \ + ./modules/filesystem/physfs/$(DEPDIR)/Filesystem.Plo \ + ./modules/font/$(DEPDIR)/BMFontRasterizer.Plo \ + ./modules/font/$(DEPDIR)/Font.Plo \ + ./modules/font/$(DEPDIR)/GlyphData.Plo \ + ./modules/font/$(DEPDIR)/ImageRasterizer.Plo \ + ./modules/font/$(DEPDIR)/Rasterizer.Plo \ + ./modules/font/$(DEPDIR)/TrueTypeRasterizer.Plo \ + ./modules/font/$(DEPDIR)/wrap_Font.Plo \ + ./modules/font/$(DEPDIR)/wrap_GlyphData.Plo \ + ./modules/font/$(DEPDIR)/wrap_Rasterizer.Plo \ + ./modules/font/freetype/$(DEPDIR)/Font.Plo \ + ./modules/font/freetype/$(DEPDIR)/TrueTypeRasterizer.Plo \ + ./modules/graphics/$(DEPDIR)/Buffer.Plo \ + ./modules/graphics/$(DEPDIR)/Canvas.Plo \ + ./modules/graphics/$(DEPDIR)/Deprecations.Plo \ + ./modules/graphics/$(DEPDIR)/Drawable.Plo \ + ./modules/graphics/$(DEPDIR)/Font.Plo \ + ./modules/graphics/$(DEPDIR)/Graphics.Plo \ + ./modules/graphics/$(DEPDIR)/Image.Plo \ + ./modules/graphics/$(DEPDIR)/Mesh.Plo \ + ./modules/graphics/$(DEPDIR)/ParticleSystem.Plo \ + ./modules/graphics/$(DEPDIR)/Polyline.Plo \ + ./modules/graphics/$(DEPDIR)/Quad.Plo \ + ./modules/graphics/$(DEPDIR)/Shader.Plo \ + ./modules/graphics/$(DEPDIR)/ShaderStage.Plo \ + ./modules/graphics/$(DEPDIR)/SpriteBatch.Plo \ + ./modules/graphics/$(DEPDIR)/StreamBuffer.Plo \ + ./modules/graphics/$(DEPDIR)/Text.Plo \ + ./modules/graphics/$(DEPDIR)/Texture.Plo \ + ./modules/graphics/$(DEPDIR)/Video.Plo \ + ./modules/graphics/$(DEPDIR)/Volatile.Plo \ + ./modules/graphics/$(DEPDIR)/depthstencil.Plo \ + ./modules/graphics/$(DEPDIR)/vertex.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Canvas.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Font.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Graphics.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Image.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Mesh.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_ParticleSystem.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Quad.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Shader.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_SpriteBatch.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Text.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Texture.Plo \ + ./modules/graphics/$(DEPDIR)/wrap_Video.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/Buffer.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/Canvas.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/FenceSync.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/Graphics.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/Image.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/OpenGL.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/Shader.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/ShaderStage.Plo \ + ./modules/graphics/opengl/$(DEPDIR)/StreamBuffer.Plo \ + ./modules/image/$(DEPDIR)/CompressedImageData.Plo \ + ./modules/image/$(DEPDIR)/CompressedSlice.Plo \ + ./modules/image/$(DEPDIR)/FormatHandler.Plo \ + ./modules/image/$(DEPDIR)/Image.Plo \ + ./modules/image/$(DEPDIR)/ImageData.Plo \ + ./modules/image/$(DEPDIR)/ImageDataBase.Plo \ + ./modules/image/$(DEPDIR)/wrap_CompressedImageData.Plo \ + ./modules/image/$(DEPDIR)/wrap_Image.Plo \ + ./modules/image/$(DEPDIR)/wrap_ImageData.Plo \ + ./modules/image/magpie/$(DEPDIR)/ASTCHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/EXRHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/KTXHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/PKMHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/PNGHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/PVRHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/STBHandler.Plo \ + ./modules/image/magpie/$(DEPDIR)/ddsHandler.Plo \ + ./modules/joystick/$(DEPDIR)/Joystick.Plo \ + ./modules/joystick/$(DEPDIR)/wrap_Joystick.Plo \ + ./modules/joystick/$(DEPDIR)/wrap_JoystickModule.Plo \ + ./modules/joystick/sdl/$(DEPDIR)/Joystick.Plo \ + ./modules/joystick/sdl/$(DEPDIR)/JoystickModule.Plo \ + ./modules/keyboard/$(DEPDIR)/Keyboard.Plo \ + ./modules/keyboard/$(DEPDIR)/wrap_Keyboard.Plo \ + ./modules/keyboard/sdl/$(DEPDIR)/Keyboard.Plo \ + ./modules/love/$(DEPDIR)/love.Plo \ + ./modules/math/$(DEPDIR)/BezierCurve.Plo \ + ./modules/math/$(DEPDIR)/MathModule.Plo \ + ./modules/math/$(DEPDIR)/RandomGenerator.Plo \ + ./modules/math/$(DEPDIR)/Transform.Plo \ + ./modules/math/$(DEPDIR)/wrap_BezierCurve.Plo \ + ./modules/math/$(DEPDIR)/wrap_Math.Plo \ + ./modules/math/$(DEPDIR)/wrap_RandomGenerator.Plo \ + ./modules/math/$(DEPDIR)/wrap_Transform.Plo \ + ./modules/mouse/$(DEPDIR)/Cursor.Plo \ + ./modules/mouse/$(DEPDIR)/wrap_Cursor.Plo \ + ./modules/mouse/$(DEPDIR)/wrap_Mouse.Plo \ + ./modules/mouse/sdl/$(DEPDIR)/Cursor.Plo \ + ./modules/mouse/sdl/$(DEPDIR)/Mouse.Plo \ + ./modules/physics/$(DEPDIR)/Body.Plo \ + ./modules/physics/$(DEPDIR)/Joint.Plo \ + ./modules/physics/$(DEPDIR)/Shape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/Body.Plo \ + ./modules/physics/box2d/$(DEPDIR)/ChainShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/CircleShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/Contact.Plo \ + ./modules/physics/box2d/$(DEPDIR)/DistanceJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/EdgeShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/Fixture.Plo \ + ./modules/physics/box2d/$(DEPDIR)/FrictionJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/GearJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/Joint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/MotorJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/MouseJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/Physics.Plo \ + ./modules/physics/box2d/$(DEPDIR)/PolygonShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/PrismaticJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/PulleyJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/RevoluteJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/RopeJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/Shape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/WeldJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/WheelJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/World.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_Body.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_ChainShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_CircleShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_Contact.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_DistanceJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_EdgeShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_Fixture.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_FrictionJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_GearJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_Joint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_MotorJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_MouseJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_Physics.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_PolygonShape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_PrismaticJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_PulleyJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_RevoluteJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_RopeJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_Shape.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_WeldJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_WheelJoint.Plo \ + ./modules/physics/box2d/$(DEPDIR)/wrap_World.Plo \ + ./modules/sound/$(DEPDIR)/Decoder.Plo \ + ./modules/sound/$(DEPDIR)/Sound.Plo \ + ./modules/sound/$(DEPDIR)/SoundData.Plo \ + ./modules/sound/$(DEPDIR)/wrap_Decoder.Plo \ + ./modules/sound/$(DEPDIR)/wrap_Sound.Plo \ + ./modules/sound/$(DEPDIR)/wrap_SoundData.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/CoreAudioDecoder.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/FLACDecoder.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/GmeDecoder.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/ModPlugDecoder.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/Mpg123Decoder.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/Sound.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/VorbisDecoder.Plo \ + ./modules/sound/lullaby/$(DEPDIR)/WaveDecoder.Plo \ + ./modules/system/$(DEPDIR)/System.Plo \ + ./modules/system/$(DEPDIR)/wrap_System.Plo \ + ./modules/system/sdl/$(DEPDIR)/System.Plo \ + ./modules/thread/$(DEPDIR)/Channel.Plo \ + ./modules/thread/$(DEPDIR)/LuaThread.Plo \ + ./modules/thread/$(DEPDIR)/ThreadModule.Plo \ + ./modules/thread/$(DEPDIR)/threads.Plo \ + ./modules/thread/$(DEPDIR)/wrap_Channel.Plo \ + ./modules/thread/$(DEPDIR)/wrap_LuaThread.Plo \ + ./modules/thread/$(DEPDIR)/wrap_ThreadModule.Plo \ + ./modules/thread/sdl/$(DEPDIR)/Thread.Plo \ + ./modules/thread/sdl/$(DEPDIR)/threads.Plo \ + ./modules/timer/$(DEPDIR)/Timer.Plo \ + ./modules/timer/$(DEPDIR)/wrap_Timer.Plo \ + ./modules/touch/$(DEPDIR)/wrap_Touch.Plo \ + ./modules/touch/sdl/$(DEPDIR)/Touch.Plo \ + ./modules/video/$(DEPDIR)/VideoStream.Plo \ + ./modules/video/$(DEPDIR)/wrap_Video.Plo \ + ./modules/video/$(DEPDIR)/wrap_VideoStream.Plo \ + ./modules/video/theora/$(DEPDIR)/OggDemuxer.Plo \ + ./modules/video/theora/$(DEPDIR)/TheoraVideoStream.Plo \ + ./modules/video/theora/$(DEPDIR)/Video.Plo \ + ./modules/window/$(DEPDIR)/Window.Plo \ + ./modules/window/$(DEPDIR)/wrap_Window.Plo \ + ./modules/window/sdl/$(DEPDIR)/Window.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -1346,7 +1734,7 @@ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - distdir + distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is @@ -1564,33 +1952,32 @@ ./common/delay.cpp ./common/delay.h ./common/deprecation.cpp \ ./common/deprecation.h ./common/EnumMap.h \ ./common/Exception.cpp ./common/Exception.h \ - ./common/halffloat.cpp ./common/halffloat.h ./common/int.h \ + ./common/floattypes.cpp ./common/floattypes.h ./common/int.h \ ./common/ios.h ./common/macosx.h ./common/math.h \ - ./common/Matrix.cpp ./common/Matrix.h ./common/Memoizer.cpp \ - ./common/Memoizer.h ./common/memory.cpp ./common/memory.h \ - ./common/Module.cpp ./common/Module.h ./common/Object.cpp \ - ./common/Object.h ./common/Optional.h ./common/pixelformat.cpp \ - ./common/pixelformat.h ./common/Reference.cpp \ - ./common/Reference.h ./common/runtime.cpp ./common/runtime.h \ - ./common/Stream.cpp ./common/Stream.h ./common/StringMap.cpp \ - ./common/StringMap.h ./common/types.cpp ./common/types.h \ - ./common/utf8.cpp ./common/utf8.h ./common/Variant.cpp \ - ./common/Variant.h ./common/Vector.cpp ./common/Vector.h \ - ./common/version.h ./scripts/auto.lua ./scripts/boot.lua \ - ./scripts/boot.lua.h ./scripts/nogame.lua \ - ./scripts/nogame.lua.h $(am__append_3) $(am__append_4) \ - $(am__append_5) $(am__append_6) $(am__append_7) \ - $(am__append_8) $(am__append_9) $(am__append_10) \ - $(am__append_11) $(am__append_12) $(am__append_13) \ - $(am__append_14) $(am__append_15) $(am__append_16) \ - $(am__append_17) $(am__append_18) $(am__append_19) \ - $(am__append_20) $(am__append_21) $(am__append_22) \ - $(am__append_23) $(am__append_24) $(am__append_25) \ - $(am__append_26) $(am__append_27) $(am__append_28) \ - $(am__append_29) $(am__append_30) $(am__append_31) \ - $(am__append_32) $(am__append_33) $(am__append_34) \ - $(am__append_35) $(am__append_36) $(am__append_37) \ - $(am__append_38) + ./common/Matrix.cpp ./common/Matrix.h ./common/memory.cpp \ + ./common/memory.h ./common/Module.cpp ./common/Module.h \ + ./common/Object.cpp ./common/Object.h ./common/Optional.h \ + ./common/pixelformat.cpp ./common/pixelformat.h \ + ./common/Reference.cpp ./common/Reference.h \ + ./common/runtime.cpp ./common/runtime.h ./common/Stream.cpp \ + ./common/Stream.h ./common/StringMap.cpp ./common/StringMap.h \ + ./common/types.cpp ./common/types.h ./common/utf8.cpp \ + ./common/utf8.h ./common/Variant.cpp ./common/Variant.h \ + ./common/Vector.cpp ./common/Vector.h ./common/version.h \ + ./scripts/auto.lua ./scripts/boot.lua ./scripts/boot.lua.h \ + ./scripts/nogame.lua ./scripts/nogame.lua.h $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_7) $(am__append_8) $(am__append_9) \ + $(am__append_10) $(am__append_11) $(am__append_12) \ + $(am__append_13) $(am__append_14) $(am__append_15) \ + $(am__append_16) $(am__append_17) $(am__append_18) \ + $(am__append_19) $(am__append_20) $(am__append_21) \ + $(am__append_22) $(am__append_23) $(am__append_24) \ + $(am__append_25) $(am__append_26) $(am__append_27) \ + $(am__append_28) $(am__append_29) $(am__append_30) \ + $(am__append_31) $(am__append_32) $(am__append_33) \ + $(am__append_34) $(am__append_35) $(am__append_36) \ + $(am__append_37) $(am__append_38) $(am__append_39) liblove_module_audio = \ ./modules/audio/Audio.cpp \ ./modules/audio/Audio.h \ @@ -1646,6 +2033,7 @@ ./modules/data/wrap_CompressedData.h \ ./modules/data/wrap_Data.cpp \ ./modules/data/wrap_Data.h \ + ./modules/data/wrap_Data.lua \ ./modules/data/wrap_DataModule.cpp \ ./modules/data/wrap_DataModule.h \ ./modules/data/wrap_DataView.cpp \ @@ -1776,6 +2164,7 @@ ./modules/graphics/wrap_Graphics.cpp \ ./modules/graphics/wrap_Graphics.h \ ./modules/graphics/wrap_Graphics.lua \ + ./modules/graphics/wrap_GraphicsShader.lua \ ./modules/graphics/wrap_Image.cpp \ ./modules/graphics/wrap_Image.h \ ./modules/graphics/wrap_Mesh.cpp \ @@ -1991,6 +2380,8 @@ ./modules/sound/Decoder.h \ ./modules/sound/lullaby/CoreAudioDecoder.cpp \ ./modules/sound/lullaby/CoreAudioDecoder.h \ + ./modules/sound/lullaby/FLACDecoder.cpp \ + ./modules/sound/lullaby/FLACDecoder.h \ ./modules/sound/lullaby/GmeDecoder.cpp \ ./modules/sound/lullaby/GmeDecoder.h \ ./modules/sound/lullaby/ModPlugDecoder.cpp \ @@ -2174,6 +2565,9 @@ ./libraries/ddsparse/ddsparse.cpp \ ./libraries/ddsparse/ddsparse.h +liblove_library_dr_flac = \ + ./libraries/dr_flac/dr_flac.h + liblove_library_enet = \ ./libraries/enet/enet.cpp \ ./libraries/enet/libenet/callbacks.c \ @@ -2216,6 +2610,8 @@ ./libraries/glslang/glslang/Include/revision.h \ ./libraries/glslang/glslang/Include/ShHandle.h \ ./libraries/glslang/glslang/Include/Types.h \ + ./libraries/glslang/glslang/MachineIndependent/attribute.cpp \ + ./libraries/glslang/glslang/MachineIndependent/attribute.h \ ./libraries/glslang/glslang/MachineIndependent/Constant.cpp \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp \ ./libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h \ @@ -2237,6 +2633,8 @@ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp \ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.h \ ./libraries/glslang/glslang/MachineIndependent/parseVersions.h \ + ./libraries/glslang/glslang/MachineIndependent/pch.cpp \ + ./libraries/glslang/glslang/MachineIndependent/pch.h \ ./libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp \ ./libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp \ @@ -2427,8 +2825,8 @@ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -2439,6 +2837,55 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @@ -2492,12 +2939,10 @@ common/$(DEPDIR)/$(am__dirstamp) ./common/Exception.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) -./common/halffloat.lo: common/$(am__dirstamp) \ +./common/floattypes.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) ./common/Matrix.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) -./common/Memoizer.lo: common/$(am__dirstamp) \ - common/$(DEPDIR)/$(am__dirstamp) ./common/memory.lo: common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) ./common/Module.lo: common/$(am__dirstamp) \ @@ -3127,6 +3572,9 @@ ./modules/sound/lullaby/CoreAudioDecoder.lo: \ modules/sound/lullaby/$(am__dirstamp) \ modules/sound/lullaby/$(DEPDIR)/$(am__dirstamp) +./modules/sound/lullaby/FLACDecoder.lo: \ + modules/sound/lullaby/$(am__dirstamp) \ + modules/sound/lullaby/$(DEPDIR)/$(am__dirstamp) ./modules/sound/lullaby/GmeDecoder.lo: \ modules/sound/lullaby/$(am__dirstamp) \ modules/sound/lullaby/$(DEPDIR)/$(am__dirstamp) @@ -3528,6 +3976,9 @@ libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR) @: > libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp) +./libraries/glslang/glslang/MachineIndependent/attribute.lo: \ + libraries/glslang/glslang/MachineIndependent/$(am__dirstamp) \ + libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp) ./libraries/glslang/glslang/MachineIndependent/Constant.lo: \ libraries/glslang/glslang/MachineIndependent/$(am__dirstamp) \ libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp) @@ -3567,6 +4018,9 @@ ./libraries/glslang/glslang/MachineIndependent/ParseHelper.lo: \ libraries/glslang/glslang/MachineIndependent/$(am__dirstamp) \ libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp) +./libraries/glslang/glslang/MachineIndependent/pch.lo: \ + libraries/glslang/glslang/MachineIndependent/$(am__dirstamp) \ + libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp) ./libraries/glslang/glslang/MachineIndependent/PoolAlloc.lo: \ libraries/glslang/glslang/MachineIndependent/$(am__dirstamp) \ libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/$(am__dirstamp) @@ -3830,55 +4284,6 @@ liblove.la: $(liblove_la_OBJECTS) $(liblove_la_DEPENDENCIES) $(EXTRA_liblove_la_DEPENDENCIES) $(AM_V_CXXLD)$(liblove_la_LINK) -rpath $(libdir) $(liblove_la_OBJECTS) $(liblove_la_LIBADD) $(LIBS) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list ./common/macosx.$(OBJEXT): common/$(am__dirstamp) \ common/$(DEPDIR)/$(am__dirstamp) @@ -4018,388 +4423,396 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/love.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Exception.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Matrix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Memoizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Module.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Object.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Reference.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Stream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/StringMap.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Variant.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Vector.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/android.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/b64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/delay.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/deprecation.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/halffloat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/macosx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/memory.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/pixelformat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/runtime.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/types.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/utf8.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2BroadPhase.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2CollideCircle.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2CollideEdge.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2CollidePolygon.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2Collision.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2Distance.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2DynamicTree.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2TimeOfImpact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2ChainShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2CircleShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2EdgeShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2PolygonShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2BlockAllocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Draw.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Math.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Settings.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2StackAllocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Timer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2Body.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2ContactManager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2Fixture.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2Island.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2World.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2WorldCallbacks.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndCircleContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndPolygonContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2CircleContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2Contact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ContactSolver.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndCircleContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndPolygonContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonAndCircleContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonContact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2DistanceJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2FrictionJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2GearJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2Joint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MotorJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MouseJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PrismaticJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PulleyJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RevoluteJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RopeJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WeldJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WheelJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Rope/$(DEPDIR)/b2Rope.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff_convert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff_internal.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff_memory.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/ddsparse/$(DEPDIR)/ddsparse.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/$(DEPDIR)/enet.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/callbacks.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/compress.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/host.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/list.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/packet.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/peer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/protocol.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/unix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/win32.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glad/$(DEPDIR)/glad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/OGLCompilersDLL/$(DEPDIR)/InitializeDll.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/CodeGen.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/Link.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Constant.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/InfoSink.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Initialize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/IntermTraverse.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Intermediate.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseContextBase.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseHelper.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/PoolAlloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/RemoveTree.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Scan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ShaderLang.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/SymbolTable.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Versions.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/glslang_tab.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/intermOut.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/iomapper.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/limits.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/linkValidate.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/parseConst.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/propagateNoContraction.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/reflection.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/Pp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpAtom.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpContext.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpScanner.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpTokens.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR)/ossource.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lodepng/$(DEPDIR)/lodepng.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lua53/$(DEPDIR)/lstrlib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lua53/$(DEPDIR)/lutf8lib.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/$(DEPDIR)/luasocket.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/auxiliar.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/buffer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/compat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/except.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/inet.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/io.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/luasocket.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/mime.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/options.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/select.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/serial.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/tcp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/timeout.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/udp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/unix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/unixtcp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/unixudp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/usocket.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lz4/$(DEPDIR)/lz4.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lz4/$(DEPDIR)/lz4hc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/noise1234/$(DEPDIR)/noise1234.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/noise1234/$(DEPDIR)/simplexnoise1234.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_7z.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_dir.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_grp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_hog.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_iso9660.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_mvl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_qpak.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_slb.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_unpacked.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_vdf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_wad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_zip.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_byteorder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_haiku.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_os2.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_qnx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_unix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_windows.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_winrt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_unicode.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./libraries/xxHash/$(DEPDIR)/xxhash.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Audio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Effect.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Filter.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/RecordingDevice.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Source.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/wrap_Audio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/wrap_RecordingDevice.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/wrap_Source.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/null/$(DEPDIR)/Audio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/null/$(DEPDIR)/RecordingDevice.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/null/$(DEPDIR)/Source.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Audio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Effect.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Filter.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Pool.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/RecordingDevice.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Source.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/ByteData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/CompressedData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/Compressor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/DataModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/DataView.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/HashFunction.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_ByteData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_CompressedData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_Data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_DataModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_DataView.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/event/$(DEPDIR)/Event.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/event/$(DEPDIR)/wrap_Event.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/event/sdl/$(DEPDIR)/Event.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/DroppedFile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/File.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/FileData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/Filesystem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_DroppedFile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_File.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_FileData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_Filesystem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/physfs/$(DEPDIR)/File.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/physfs/$(DEPDIR)/Filesystem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/BMFontRasterizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/Font.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/GlyphData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/ImageRasterizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/Rasterizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/TrueTypeRasterizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/wrap_Font.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/wrap_GlyphData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/wrap_Rasterizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/freetype/$(DEPDIR)/Font.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/freetype/$(DEPDIR)/TrueTypeRasterizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Buffer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Canvas.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Deprecations.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Drawable.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Font.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Graphics.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Image.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Mesh.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/ParticleSystem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Polyline.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Quad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Shader.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/ShaderStage.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/SpriteBatch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/StreamBuffer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Text.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Texture.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Video.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Volatile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/depthstencil.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/vertex.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Canvas.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Font.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Graphics.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Image.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Mesh.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_ParticleSystem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Quad.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Shader.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_SpriteBatch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Text.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Texture.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Video.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Buffer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Canvas.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/FenceSync.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Graphics.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Image.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/OpenGL.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Shader.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/ShaderStage.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/StreamBuffer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/CompressedImageData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/CompressedSlice.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/FormatHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/Image.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/ImageData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/ImageDataBase.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/wrap_CompressedImageData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/wrap_Image.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/wrap_ImageData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/ASTCHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/EXRHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/KTXHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/PKMHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/PNGHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/PVRHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/STBHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/ddsHandler.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/$(DEPDIR)/Joystick.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/$(DEPDIR)/wrap_Joystick.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/$(DEPDIR)/wrap_JoystickModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/sdl/$(DEPDIR)/Joystick.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/sdl/$(DEPDIR)/JoystickModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/keyboard/$(DEPDIR)/Keyboard.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/keyboard/$(DEPDIR)/wrap_Keyboard.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/keyboard/sdl/$(DEPDIR)/Keyboard.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/love/$(DEPDIR)/love.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/BezierCurve.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/MathModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/RandomGenerator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/Transform.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_BezierCurve.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_Math.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_RandomGenerator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_Transform.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/$(DEPDIR)/Cursor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/$(DEPDIR)/wrap_Cursor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/$(DEPDIR)/wrap_Mouse.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/sdl/$(DEPDIR)/Cursor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/sdl/$(DEPDIR)/Mouse.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/$(DEPDIR)/Body.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/$(DEPDIR)/Joint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/$(DEPDIR)/Shape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Body.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/ChainShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/CircleShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Contact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/DistanceJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/EdgeShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Fixture.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/FrictionJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/GearJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Joint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/MotorJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/MouseJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Physics.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/PolygonShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/PrismaticJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/PulleyJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/RevoluteJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/RopeJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Shape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/WeldJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/WheelJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/World.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Body.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_ChainShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_CircleShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Contact.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_DistanceJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_EdgeShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Fixture.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_FrictionJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_GearJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Joint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_MotorJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_MouseJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Physics.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_PolygonShape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_PrismaticJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_PulleyJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_RevoluteJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_RopeJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Shape.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_WeldJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_WheelJoint.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_World.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/Decoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/Sound.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/SoundData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/wrap_Decoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/wrap_Sound.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/wrap_SoundData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/CoreAudioDecoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/GmeDecoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/ModPlugDecoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/Mpg123Decoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/Sound.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/VorbisDecoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/WaveDecoder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/system/$(DEPDIR)/System.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/system/$(DEPDIR)/wrap_System.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/system/sdl/$(DEPDIR)/System.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/Channel.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/LuaThread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/ThreadModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/threads.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/wrap_Channel.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/wrap_LuaThread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/wrap_ThreadModule.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/sdl/$(DEPDIR)/Thread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/sdl/$(DEPDIR)/threads.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/timer/$(DEPDIR)/Timer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/timer/$(DEPDIR)/wrap_Timer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/touch/$(DEPDIR)/wrap_Touch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/touch/sdl/$(DEPDIR)/Touch.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/$(DEPDIR)/VideoStream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/$(DEPDIR)/wrap_Video.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/$(DEPDIR)/wrap_VideoStream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/theora/$(DEPDIR)/OggDemuxer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/theora/$(DEPDIR)/TheoraVideoStream.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/theora/$(DEPDIR)/Video.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/window/$(DEPDIR)/Window.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/window/$(DEPDIR)/wrap_Window.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./modules/window/sdl/$(DEPDIR)/Window.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/love.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Exception.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Matrix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Module.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Object.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Reference.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Stream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/StringMap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Variant.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/Vector.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/android.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/b64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/delay.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/deprecation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/floattypes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/macosx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/memory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/pixelformat.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/runtime.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/types.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./common/$(DEPDIR)/utf8.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2BroadPhase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2CollideCircle.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2CollideEdge.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2CollidePolygon.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2Collision.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2Distance.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2DynamicTree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/$(DEPDIR)/b2TimeOfImpact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2ChainShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2CircleShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2EdgeShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2PolygonShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2BlockAllocator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Draw.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Math.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Settings.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2StackAllocator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Common/$(DEPDIR)/b2Timer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2Body.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2ContactManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2Fixture.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2Island.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2World.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/$(DEPDIR)/b2WorldCallbacks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndCircleContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndPolygonContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2CircleContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2Contact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ContactSolver.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndCircleContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndPolygonContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonAndCircleContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonContact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2DistanceJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2FrictionJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2GearJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2Joint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MotorJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MouseJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PrismaticJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PulleyJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RevoluteJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RopeJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WeldJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WheelJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Box2D/Rope/$(DEPDIR)/b2Rope.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff_convert.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff_internal.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/Wuff/$(DEPDIR)/wuff_memory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/ddsparse/$(DEPDIR)/ddsparse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/$(DEPDIR)/enet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/callbacks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/compress.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/host.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/list.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/packet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/peer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/protocol.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/unix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/enet/libenet/$(DEPDIR)/win32.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glad/$(DEPDIR)/glad.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/OGLCompilersDLL/$(DEPDIR)/InitializeDll.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/CodeGen.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/Link.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Constant.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/InfoSink.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Initialize.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/IntermTraverse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Intermediate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseContextBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseHelper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/PoolAlloc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/RemoveTree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Scan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ShaderLang.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/SymbolTable.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Versions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/attribute.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/glslang_tab.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/intermOut.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/iomapper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/limits.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/linkValidate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/parseConst.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/pch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/propagateNoContraction.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/reflection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/Pp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpAtom.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpContext.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpScanner.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpTokens.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR)/ossource.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lodepng/$(DEPDIR)/lodepng.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lua53/$(DEPDIR)/lstrlib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lua53/$(DEPDIR)/lutf8lib.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/$(DEPDIR)/luasocket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/auxiliar.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/buffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/compat.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/except.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/inet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/io.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/luasocket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/mime.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/options.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/select.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/serial.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/tcp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/timeout.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/udp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/unix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/unixtcp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/unixudp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/luasocket/libluasocket/$(DEPDIR)/usocket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lz4/$(DEPDIR)/lz4.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/lz4/$(DEPDIR)/lz4hc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/noise1234/$(DEPDIR)/noise1234.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/noise1234/$(DEPDIR)/simplexnoise1234.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_7z.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_dir.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_grp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_hog.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_iso9660.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_mvl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_qpak.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_slb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_unpacked.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_vdf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_wad.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_archiver_zip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_byteorder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_haiku.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_os2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_posix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_qnx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_unix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_windows.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_platform_winrt.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/physfs/$(DEPDIR)/physfs_unicode.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./libraries/xxHash/$(DEPDIR)/xxhash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Audio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Effect.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Filter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/RecordingDevice.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/Source.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/wrap_Audio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/wrap_RecordingDevice.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/$(DEPDIR)/wrap_Source.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/null/$(DEPDIR)/Audio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/null/$(DEPDIR)/RecordingDevice.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/null/$(DEPDIR)/Source.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Audio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Effect.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Filter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Pool.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/RecordingDevice.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/audio/openal/$(DEPDIR)/Source.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/ByteData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/CompressedData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/Compressor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/DataModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/DataView.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/HashFunction.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_ByteData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_CompressedData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_Data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_DataModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/data/$(DEPDIR)/wrap_DataView.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/event/$(DEPDIR)/Event.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/event/$(DEPDIR)/wrap_Event.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/event/sdl/$(DEPDIR)/Event.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/DroppedFile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/File.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/FileData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/Filesystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_DroppedFile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_File.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_FileData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/$(DEPDIR)/wrap_Filesystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/physfs/$(DEPDIR)/File.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/filesystem/physfs/$(DEPDIR)/Filesystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/BMFontRasterizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/Font.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/GlyphData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/ImageRasterizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/Rasterizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/TrueTypeRasterizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/wrap_Font.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/wrap_GlyphData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/$(DEPDIR)/wrap_Rasterizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/freetype/$(DEPDIR)/Font.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/font/freetype/$(DEPDIR)/TrueTypeRasterizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Buffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Canvas.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Deprecations.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Drawable.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Font.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Graphics.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Image.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Mesh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/ParticleSystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Polyline.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Quad.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Shader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/ShaderStage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/SpriteBatch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/StreamBuffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Text.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Texture.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Video.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/Volatile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/depthstencil.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/vertex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Canvas.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Font.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Graphics.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Image.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Mesh.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_ParticleSystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Quad.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Shader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_SpriteBatch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Text.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Texture.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/$(DEPDIR)/wrap_Video.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Buffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Canvas.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/FenceSync.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Graphics.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Image.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/OpenGL.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/Shader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/ShaderStage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/graphics/opengl/$(DEPDIR)/StreamBuffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/CompressedImageData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/CompressedSlice.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/FormatHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/Image.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/ImageData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/ImageDataBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/wrap_CompressedImageData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/wrap_Image.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/$(DEPDIR)/wrap_ImageData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/ASTCHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/EXRHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/KTXHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/PKMHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/PNGHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/PVRHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/STBHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/image/magpie/$(DEPDIR)/ddsHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/$(DEPDIR)/Joystick.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/$(DEPDIR)/wrap_Joystick.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/$(DEPDIR)/wrap_JoystickModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/sdl/$(DEPDIR)/Joystick.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/joystick/sdl/$(DEPDIR)/JoystickModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/keyboard/$(DEPDIR)/Keyboard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/keyboard/$(DEPDIR)/wrap_Keyboard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/keyboard/sdl/$(DEPDIR)/Keyboard.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/love/$(DEPDIR)/love.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/BezierCurve.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/MathModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/RandomGenerator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/Transform.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_BezierCurve.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_Math.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_RandomGenerator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/math/$(DEPDIR)/wrap_Transform.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/$(DEPDIR)/Cursor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/$(DEPDIR)/wrap_Cursor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/$(DEPDIR)/wrap_Mouse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/sdl/$(DEPDIR)/Cursor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/mouse/sdl/$(DEPDIR)/Mouse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/$(DEPDIR)/Body.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/$(DEPDIR)/Joint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/$(DEPDIR)/Shape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Body.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/ChainShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/CircleShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Contact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/DistanceJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/EdgeShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Fixture.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/FrictionJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/GearJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Joint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/MotorJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/MouseJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Physics.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/PolygonShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/PrismaticJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/PulleyJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/RevoluteJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/RopeJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/Shape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/WeldJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/WheelJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/World.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Body.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_ChainShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_CircleShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Contact.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_DistanceJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_EdgeShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Fixture.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_FrictionJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_GearJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Joint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_MotorJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_MouseJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Physics.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_PolygonShape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_PrismaticJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_PulleyJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_RevoluteJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_RopeJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_Shape.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_WeldJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_WheelJoint.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/physics/box2d/$(DEPDIR)/wrap_World.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/Decoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/Sound.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/SoundData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/wrap_Decoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/wrap_Sound.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/$(DEPDIR)/wrap_SoundData.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/CoreAudioDecoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/FLACDecoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/GmeDecoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/ModPlugDecoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/Mpg123Decoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/Sound.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/VorbisDecoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/sound/lullaby/$(DEPDIR)/WaveDecoder.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/system/$(DEPDIR)/System.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/system/$(DEPDIR)/wrap_System.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/system/sdl/$(DEPDIR)/System.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/Channel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/LuaThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/ThreadModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/threads.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/wrap_Channel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/wrap_LuaThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/$(DEPDIR)/wrap_ThreadModule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/sdl/$(DEPDIR)/Thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/thread/sdl/$(DEPDIR)/threads.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/timer/$(DEPDIR)/Timer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/timer/$(DEPDIR)/wrap_Timer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/touch/$(DEPDIR)/wrap_Touch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/touch/sdl/$(DEPDIR)/Touch.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/$(DEPDIR)/VideoStream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/$(DEPDIR)/wrap_Video.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/$(DEPDIR)/wrap_VideoStream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/theora/$(DEPDIR)/OggDemuxer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/theora/$(DEPDIR)/TheoraVideoStream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/video/theora/$(DEPDIR)/Video.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/window/$(DEPDIR)/Window.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/window/$(DEPDIR)/wrap_Window.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./modules/window/sdl/$(DEPDIR)/Window.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -4641,7 +5054,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -4698,12 +5114,12 @@ done check-am: all-am check: check-recursive -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) +all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) install-binPROGRAMS: install-libLTLIBRARIES installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \ + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -4868,7 +5284,390 @@ clean-libtool mostlyclean-am distclean: distclean-recursive - -rm -rf ./$(DEPDIR) ./common/$(DEPDIR) ./libraries/Box2D/Collision/$(DEPDIR) ./libraries/Box2D/Collision/Shapes/$(DEPDIR) ./libraries/Box2D/Common/$(DEPDIR) ./libraries/Box2D/Dynamics/$(DEPDIR) ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR) ./libraries/Box2D/Dynamics/Joints/$(DEPDIR) ./libraries/Box2D/Rope/$(DEPDIR) ./libraries/Wuff/$(DEPDIR) ./libraries/ddsparse/$(DEPDIR) ./libraries/enet/$(DEPDIR) ./libraries/enet/libenet/$(DEPDIR) ./libraries/glad/$(DEPDIR) ./libraries/glslang/OGLCompilersDLL/$(DEPDIR) ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR) ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR) ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR) ./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR) ./libraries/lodepng/$(DEPDIR) ./libraries/lua53/$(DEPDIR) ./libraries/luasocket/$(DEPDIR) ./libraries/luasocket/libluasocket/$(DEPDIR) ./libraries/lz4/$(DEPDIR) ./libraries/noise1234/$(DEPDIR) ./libraries/physfs/$(DEPDIR) ./libraries/xxHash/$(DEPDIR) ./modules/audio/$(DEPDIR) ./modules/audio/null/$(DEPDIR) ./modules/audio/openal/$(DEPDIR) ./modules/data/$(DEPDIR) ./modules/event/$(DEPDIR) ./modules/event/sdl/$(DEPDIR) ./modules/filesystem/$(DEPDIR) ./modules/filesystem/physfs/$(DEPDIR) ./modules/font/$(DEPDIR) ./modules/font/freetype/$(DEPDIR) ./modules/graphics/$(DEPDIR) ./modules/graphics/opengl/$(DEPDIR) ./modules/image/$(DEPDIR) ./modules/image/magpie/$(DEPDIR) ./modules/joystick/$(DEPDIR) ./modules/joystick/sdl/$(DEPDIR) ./modules/keyboard/$(DEPDIR) ./modules/keyboard/sdl/$(DEPDIR) ./modules/love/$(DEPDIR) ./modules/math/$(DEPDIR) ./modules/mouse/$(DEPDIR) ./modules/mouse/sdl/$(DEPDIR) ./modules/physics/$(DEPDIR) ./modules/physics/box2d/$(DEPDIR) ./modules/sound/$(DEPDIR) ./modules/sound/lullaby/$(DEPDIR) ./modules/system/$(DEPDIR) ./modules/system/sdl/$(DEPDIR) ./modules/thread/$(DEPDIR) ./modules/thread/sdl/$(DEPDIR) ./modules/timer/$(DEPDIR) ./modules/touch/$(DEPDIR) ./modules/touch/sdl/$(DEPDIR) ./modules/video/$(DEPDIR) ./modules/video/theora/$(DEPDIR) ./modules/window/$(DEPDIR) ./modules/window/sdl/$(DEPDIR) + -rm -f ./$(DEPDIR)/love.Po + -rm -f ./common/$(DEPDIR)/Data.Plo + -rm -f ./common/$(DEPDIR)/Exception.Plo + -rm -f ./common/$(DEPDIR)/Matrix.Plo + -rm -f ./common/$(DEPDIR)/Module.Plo + -rm -f ./common/$(DEPDIR)/Object.Plo + -rm -f ./common/$(DEPDIR)/Reference.Plo + -rm -f ./common/$(DEPDIR)/Stream.Plo + -rm -f ./common/$(DEPDIR)/StringMap.Plo + -rm -f ./common/$(DEPDIR)/Variant.Plo + -rm -f ./common/$(DEPDIR)/Vector.Plo + -rm -f ./common/$(DEPDIR)/android.Plo + -rm -f ./common/$(DEPDIR)/b64.Plo + -rm -f ./common/$(DEPDIR)/delay.Plo + -rm -f ./common/$(DEPDIR)/deprecation.Plo + -rm -f ./common/$(DEPDIR)/floattypes.Plo + -rm -f ./common/$(DEPDIR)/macosx.Po + -rm -f ./common/$(DEPDIR)/memory.Plo + -rm -f ./common/$(DEPDIR)/pixelformat.Plo + -rm -f ./common/$(DEPDIR)/runtime.Plo + -rm -f ./common/$(DEPDIR)/types.Plo + -rm -f ./common/$(DEPDIR)/utf8.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2BroadPhase.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2CollideCircle.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2CollideEdge.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2CollidePolygon.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2Collision.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2Distance.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2DynamicTree.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2TimeOfImpact.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2ChainShape.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2CircleShape.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2EdgeShape.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2PolygonShape.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2BlockAllocator.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Draw.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Math.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Settings.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2StackAllocator.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Timer.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Body.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2ContactManager.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Fixture.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Island.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2World.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2WorldCallbacks.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndCircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndPolygonContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2CircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2Contact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ContactSolver.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndCircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndPolygonContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonAndCircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2DistanceJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2FrictionJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2GearJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2Joint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MotorJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MouseJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PrismaticJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PulleyJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RevoluteJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RopeJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WeldJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WheelJoint.Plo + -rm -f ./libraries/Box2D/Rope/$(DEPDIR)/b2Rope.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff_convert.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff_internal.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff_memory.Plo + -rm -f ./libraries/ddsparse/$(DEPDIR)/ddsparse.Plo + -rm -f ./libraries/enet/$(DEPDIR)/enet.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/callbacks.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/compress.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/host.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/list.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/packet.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/peer.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/protocol.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/unix.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/win32.Plo + -rm -f ./libraries/glad/$(DEPDIR)/glad.Plo + -rm -f ./libraries/glslang/OGLCompilersDLL/$(DEPDIR)/InitializeDll.Plo + -rm -f ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/CodeGen.Plo + -rm -f ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/Link.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Constant.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/InfoSink.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Initialize.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/IntermTraverse.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Intermediate.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseContextBase.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseHelper.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/PoolAlloc.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/RemoveTree.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Scan.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ShaderLang.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/SymbolTable.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Versions.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/attribute.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/glslang_tab.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/intermOut.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/iomapper.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/limits.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/linkValidate.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/parseConst.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/pch.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/propagateNoContraction.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/reflection.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/Pp.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpAtom.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpContext.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpScanner.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpTokens.Plo + -rm -f ./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR)/ossource.Plo + -rm -f ./libraries/lodepng/$(DEPDIR)/lodepng.Plo + -rm -f ./libraries/lua53/$(DEPDIR)/lstrlib.Plo + -rm -f ./libraries/lua53/$(DEPDIR)/lutf8lib.Plo + -rm -f ./libraries/luasocket/$(DEPDIR)/luasocket.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/auxiliar.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/buffer.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/compat.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/except.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/inet.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/io.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/luasocket.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/mime.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/options.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/select.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/serial.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/tcp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/timeout.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/udp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/unix.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/unixtcp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/unixudp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/usocket.Plo + -rm -f ./libraries/lz4/$(DEPDIR)/lz4.Plo + -rm -f ./libraries/lz4/$(DEPDIR)/lz4hc.Plo + -rm -f ./libraries/noise1234/$(DEPDIR)/noise1234.Plo + -rm -f ./libraries/noise1234/$(DEPDIR)/simplexnoise1234.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_7z.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_dir.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_grp.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_hog.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_iso9660.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_mvl.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_qpak.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_slb.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_unpacked.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_vdf.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_wad.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_zip.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_byteorder.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_haiku.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_os2.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_posix.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_qnx.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_unix.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_windows.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_winrt.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_unicode.Plo + -rm -f ./libraries/xxHash/$(DEPDIR)/xxhash.Plo + -rm -f ./modules/audio/$(DEPDIR)/Audio.Plo + -rm -f ./modules/audio/$(DEPDIR)/Effect.Plo + -rm -f ./modules/audio/$(DEPDIR)/Filter.Plo + -rm -f ./modules/audio/$(DEPDIR)/RecordingDevice.Plo + -rm -f ./modules/audio/$(DEPDIR)/Source.Plo + -rm -f ./modules/audio/$(DEPDIR)/wrap_Audio.Plo + -rm -f ./modules/audio/$(DEPDIR)/wrap_RecordingDevice.Plo + -rm -f ./modules/audio/$(DEPDIR)/wrap_Source.Plo + -rm -f ./modules/audio/null/$(DEPDIR)/Audio.Plo + -rm -f ./modules/audio/null/$(DEPDIR)/RecordingDevice.Plo + -rm -f ./modules/audio/null/$(DEPDIR)/Source.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Audio.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Effect.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Filter.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Pool.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/RecordingDevice.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Source.Plo + -rm -f ./modules/data/$(DEPDIR)/ByteData.Plo + -rm -f ./modules/data/$(DEPDIR)/CompressedData.Plo + -rm -f ./modules/data/$(DEPDIR)/Compressor.Plo + -rm -f ./modules/data/$(DEPDIR)/DataModule.Plo + -rm -f ./modules/data/$(DEPDIR)/DataView.Plo + -rm -f ./modules/data/$(DEPDIR)/HashFunction.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_ByteData.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_CompressedData.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_Data.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_DataModule.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_DataView.Plo + -rm -f ./modules/event/$(DEPDIR)/Event.Plo + -rm -f ./modules/event/$(DEPDIR)/wrap_Event.Plo + -rm -f ./modules/event/sdl/$(DEPDIR)/Event.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/DroppedFile.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/File.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/FileData.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/Filesystem.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_DroppedFile.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_File.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_FileData.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_Filesystem.Plo + -rm -f ./modules/filesystem/physfs/$(DEPDIR)/File.Plo + -rm -f ./modules/filesystem/physfs/$(DEPDIR)/Filesystem.Plo + -rm -f ./modules/font/$(DEPDIR)/BMFontRasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/Font.Plo + -rm -f ./modules/font/$(DEPDIR)/GlyphData.Plo + -rm -f ./modules/font/$(DEPDIR)/ImageRasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/Rasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/TrueTypeRasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/wrap_Font.Plo + -rm -f ./modules/font/$(DEPDIR)/wrap_GlyphData.Plo + -rm -f ./modules/font/$(DEPDIR)/wrap_Rasterizer.Plo + -rm -f ./modules/font/freetype/$(DEPDIR)/Font.Plo + -rm -f ./modules/font/freetype/$(DEPDIR)/TrueTypeRasterizer.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Buffer.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Canvas.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Deprecations.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Drawable.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Font.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Graphics.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Image.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Mesh.Plo + -rm -f ./modules/graphics/$(DEPDIR)/ParticleSystem.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Polyline.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Quad.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Shader.Plo + -rm -f ./modules/graphics/$(DEPDIR)/ShaderStage.Plo + -rm -f ./modules/graphics/$(DEPDIR)/SpriteBatch.Plo + -rm -f ./modules/graphics/$(DEPDIR)/StreamBuffer.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Text.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Texture.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Video.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Volatile.Plo + -rm -f ./modules/graphics/$(DEPDIR)/depthstencil.Plo + -rm -f ./modules/graphics/$(DEPDIR)/vertex.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Canvas.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Font.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Graphics.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Image.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Mesh.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_ParticleSystem.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Quad.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Shader.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_SpriteBatch.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Text.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Texture.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Video.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Buffer.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Canvas.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/FenceSync.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Graphics.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Image.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/OpenGL.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Shader.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/ShaderStage.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/StreamBuffer.Plo + -rm -f ./modules/image/$(DEPDIR)/CompressedImageData.Plo + -rm -f ./modules/image/$(DEPDIR)/CompressedSlice.Plo + -rm -f ./modules/image/$(DEPDIR)/FormatHandler.Plo + -rm -f ./modules/image/$(DEPDIR)/Image.Plo + -rm -f ./modules/image/$(DEPDIR)/ImageData.Plo + -rm -f ./modules/image/$(DEPDIR)/ImageDataBase.Plo + -rm -f ./modules/image/$(DEPDIR)/wrap_CompressedImageData.Plo + -rm -f ./modules/image/$(DEPDIR)/wrap_Image.Plo + -rm -f ./modules/image/$(DEPDIR)/wrap_ImageData.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/ASTCHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/EXRHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/KTXHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/PKMHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/PNGHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/PVRHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/STBHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/ddsHandler.Plo + -rm -f ./modules/joystick/$(DEPDIR)/Joystick.Plo + -rm -f ./modules/joystick/$(DEPDIR)/wrap_Joystick.Plo + -rm -f ./modules/joystick/$(DEPDIR)/wrap_JoystickModule.Plo + -rm -f ./modules/joystick/sdl/$(DEPDIR)/Joystick.Plo + -rm -f ./modules/joystick/sdl/$(DEPDIR)/JoystickModule.Plo + -rm -f ./modules/keyboard/$(DEPDIR)/Keyboard.Plo + -rm -f ./modules/keyboard/$(DEPDIR)/wrap_Keyboard.Plo + -rm -f ./modules/keyboard/sdl/$(DEPDIR)/Keyboard.Plo + -rm -f ./modules/love/$(DEPDIR)/love.Plo + -rm -f ./modules/math/$(DEPDIR)/BezierCurve.Plo + -rm -f ./modules/math/$(DEPDIR)/MathModule.Plo + -rm -f ./modules/math/$(DEPDIR)/RandomGenerator.Plo + -rm -f ./modules/math/$(DEPDIR)/Transform.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_BezierCurve.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_Math.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_RandomGenerator.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_Transform.Plo + -rm -f ./modules/mouse/$(DEPDIR)/Cursor.Plo + -rm -f ./modules/mouse/$(DEPDIR)/wrap_Cursor.Plo + -rm -f ./modules/mouse/$(DEPDIR)/wrap_Mouse.Plo + -rm -f ./modules/mouse/sdl/$(DEPDIR)/Cursor.Plo + -rm -f ./modules/mouse/sdl/$(DEPDIR)/Mouse.Plo + -rm -f ./modules/physics/$(DEPDIR)/Body.Plo + -rm -f ./modules/physics/$(DEPDIR)/Joint.Plo + -rm -f ./modules/physics/$(DEPDIR)/Shape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Body.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/ChainShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/CircleShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Contact.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/DistanceJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/EdgeShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Fixture.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/FrictionJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/GearJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Joint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/MotorJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/MouseJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Physics.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/PolygonShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/PrismaticJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/PulleyJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/RevoluteJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/RopeJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Shape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/WeldJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/WheelJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/World.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Body.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_ChainShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_CircleShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Contact.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_DistanceJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_EdgeShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Fixture.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_FrictionJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_GearJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Joint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_MotorJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_MouseJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Physics.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_PolygonShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_PrismaticJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_PulleyJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_RevoluteJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_RopeJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Shape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_WeldJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_WheelJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_World.Plo + -rm -f ./modules/sound/$(DEPDIR)/Decoder.Plo + -rm -f ./modules/sound/$(DEPDIR)/Sound.Plo + -rm -f ./modules/sound/$(DEPDIR)/SoundData.Plo + -rm -f ./modules/sound/$(DEPDIR)/wrap_Decoder.Plo + -rm -f ./modules/sound/$(DEPDIR)/wrap_Sound.Plo + -rm -f ./modules/sound/$(DEPDIR)/wrap_SoundData.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/CoreAudioDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/FLACDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/GmeDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/ModPlugDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/Mpg123Decoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/Sound.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/VorbisDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/WaveDecoder.Plo + -rm -f ./modules/system/$(DEPDIR)/System.Plo + -rm -f ./modules/system/$(DEPDIR)/wrap_System.Plo + -rm -f ./modules/system/sdl/$(DEPDIR)/System.Plo + -rm -f ./modules/thread/$(DEPDIR)/Channel.Plo + -rm -f ./modules/thread/$(DEPDIR)/LuaThread.Plo + -rm -f ./modules/thread/$(DEPDIR)/ThreadModule.Plo + -rm -f ./modules/thread/$(DEPDIR)/threads.Plo + -rm -f ./modules/thread/$(DEPDIR)/wrap_Channel.Plo + -rm -f ./modules/thread/$(DEPDIR)/wrap_LuaThread.Plo + -rm -f ./modules/thread/$(DEPDIR)/wrap_ThreadModule.Plo + -rm -f ./modules/thread/sdl/$(DEPDIR)/Thread.Plo + -rm -f ./modules/thread/sdl/$(DEPDIR)/threads.Plo + -rm -f ./modules/timer/$(DEPDIR)/Timer.Plo + -rm -f ./modules/timer/$(DEPDIR)/wrap_Timer.Plo + -rm -f ./modules/touch/$(DEPDIR)/wrap_Touch.Plo + -rm -f ./modules/touch/sdl/$(DEPDIR)/Touch.Plo + -rm -f ./modules/video/$(DEPDIR)/VideoStream.Plo + -rm -f ./modules/video/$(DEPDIR)/wrap_Video.Plo + -rm -f ./modules/video/$(DEPDIR)/wrap_VideoStream.Plo + -rm -f ./modules/video/theora/$(DEPDIR)/OggDemuxer.Plo + -rm -f ./modules/video/theora/$(DEPDIR)/TheoraVideoStream.Plo + -rm -f ./modules/video/theora/$(DEPDIR)/Video.Plo + -rm -f ./modules/window/$(DEPDIR)/Window.Plo + -rm -f ./modules/window/$(DEPDIR)/wrap_Window.Plo + -rm -f ./modules/window/sdl/$(DEPDIR)/Window.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -4914,7 +5713,390 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) ./common/$(DEPDIR) ./libraries/Box2D/Collision/$(DEPDIR) ./libraries/Box2D/Collision/Shapes/$(DEPDIR) ./libraries/Box2D/Common/$(DEPDIR) ./libraries/Box2D/Dynamics/$(DEPDIR) ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR) ./libraries/Box2D/Dynamics/Joints/$(DEPDIR) ./libraries/Box2D/Rope/$(DEPDIR) ./libraries/Wuff/$(DEPDIR) ./libraries/ddsparse/$(DEPDIR) ./libraries/enet/$(DEPDIR) ./libraries/enet/libenet/$(DEPDIR) ./libraries/glad/$(DEPDIR) ./libraries/glslang/OGLCompilersDLL/$(DEPDIR) ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR) ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR) ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR) ./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR) ./libraries/lodepng/$(DEPDIR) ./libraries/lua53/$(DEPDIR) ./libraries/luasocket/$(DEPDIR) ./libraries/luasocket/libluasocket/$(DEPDIR) ./libraries/lz4/$(DEPDIR) ./libraries/noise1234/$(DEPDIR) ./libraries/physfs/$(DEPDIR) ./libraries/xxHash/$(DEPDIR) ./modules/audio/$(DEPDIR) ./modules/audio/null/$(DEPDIR) ./modules/audio/openal/$(DEPDIR) ./modules/data/$(DEPDIR) ./modules/event/$(DEPDIR) ./modules/event/sdl/$(DEPDIR) ./modules/filesystem/$(DEPDIR) ./modules/filesystem/physfs/$(DEPDIR) ./modules/font/$(DEPDIR) ./modules/font/freetype/$(DEPDIR) ./modules/graphics/$(DEPDIR) ./modules/graphics/opengl/$(DEPDIR) ./modules/image/$(DEPDIR) ./modules/image/magpie/$(DEPDIR) ./modules/joystick/$(DEPDIR) ./modules/joystick/sdl/$(DEPDIR) ./modules/keyboard/$(DEPDIR) ./modules/keyboard/sdl/$(DEPDIR) ./modules/love/$(DEPDIR) ./modules/math/$(DEPDIR) ./modules/mouse/$(DEPDIR) ./modules/mouse/sdl/$(DEPDIR) ./modules/physics/$(DEPDIR) ./modules/physics/box2d/$(DEPDIR) ./modules/sound/$(DEPDIR) ./modules/sound/lullaby/$(DEPDIR) ./modules/system/$(DEPDIR) ./modules/system/sdl/$(DEPDIR) ./modules/thread/$(DEPDIR) ./modules/thread/sdl/$(DEPDIR) ./modules/timer/$(DEPDIR) ./modules/touch/$(DEPDIR) ./modules/touch/sdl/$(DEPDIR) ./modules/video/$(DEPDIR) ./modules/video/theora/$(DEPDIR) ./modules/window/$(DEPDIR) ./modules/window/sdl/$(DEPDIR) + -rm -f ./$(DEPDIR)/love.Po + -rm -f ./common/$(DEPDIR)/Data.Plo + -rm -f ./common/$(DEPDIR)/Exception.Plo + -rm -f ./common/$(DEPDIR)/Matrix.Plo + -rm -f ./common/$(DEPDIR)/Module.Plo + -rm -f ./common/$(DEPDIR)/Object.Plo + -rm -f ./common/$(DEPDIR)/Reference.Plo + -rm -f ./common/$(DEPDIR)/Stream.Plo + -rm -f ./common/$(DEPDIR)/StringMap.Plo + -rm -f ./common/$(DEPDIR)/Variant.Plo + -rm -f ./common/$(DEPDIR)/Vector.Plo + -rm -f ./common/$(DEPDIR)/android.Plo + -rm -f ./common/$(DEPDIR)/b64.Plo + -rm -f ./common/$(DEPDIR)/delay.Plo + -rm -f ./common/$(DEPDIR)/deprecation.Plo + -rm -f ./common/$(DEPDIR)/floattypes.Plo + -rm -f ./common/$(DEPDIR)/macosx.Po + -rm -f ./common/$(DEPDIR)/memory.Plo + -rm -f ./common/$(DEPDIR)/pixelformat.Plo + -rm -f ./common/$(DEPDIR)/runtime.Plo + -rm -f ./common/$(DEPDIR)/types.Plo + -rm -f ./common/$(DEPDIR)/utf8.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2BroadPhase.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2CollideCircle.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2CollideEdge.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2CollidePolygon.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2Collision.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2Distance.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2DynamicTree.Plo + -rm -f ./libraries/Box2D/Collision/$(DEPDIR)/b2TimeOfImpact.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2ChainShape.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2CircleShape.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2EdgeShape.Plo + -rm -f ./libraries/Box2D/Collision/Shapes/$(DEPDIR)/b2PolygonShape.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2BlockAllocator.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Draw.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Math.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Settings.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2StackAllocator.Plo + -rm -f ./libraries/Box2D/Common/$(DEPDIR)/b2Timer.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Body.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2ContactManager.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Fixture.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2Island.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2World.Plo + -rm -f ./libraries/Box2D/Dynamics/$(DEPDIR)/b2WorldCallbacks.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndCircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ChainAndPolygonContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2CircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2Contact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2ContactSolver.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndCircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2EdgeAndPolygonContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonAndCircleContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Contacts/$(DEPDIR)/b2PolygonContact.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2DistanceJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2FrictionJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2GearJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2Joint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MotorJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2MouseJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PrismaticJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2PulleyJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RevoluteJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2RopeJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WeldJoint.Plo + -rm -f ./libraries/Box2D/Dynamics/Joints/$(DEPDIR)/b2WheelJoint.Plo + -rm -f ./libraries/Box2D/Rope/$(DEPDIR)/b2Rope.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff_convert.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff_internal.Plo + -rm -f ./libraries/Wuff/$(DEPDIR)/wuff_memory.Plo + -rm -f ./libraries/ddsparse/$(DEPDIR)/ddsparse.Plo + -rm -f ./libraries/enet/$(DEPDIR)/enet.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/callbacks.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/compress.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/host.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/list.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/packet.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/peer.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/protocol.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/unix.Plo + -rm -f ./libraries/enet/libenet/$(DEPDIR)/win32.Plo + -rm -f ./libraries/glad/$(DEPDIR)/glad.Plo + -rm -f ./libraries/glslang/OGLCompilersDLL/$(DEPDIR)/InitializeDll.Plo + -rm -f ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/CodeGen.Plo + -rm -f ./libraries/glslang/glslang/GenericCodeGen/$(DEPDIR)/Link.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Constant.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/InfoSink.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Initialize.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/IntermTraverse.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Intermediate.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseContextBase.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ParseHelper.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/PoolAlloc.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/RemoveTree.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Scan.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/ShaderLang.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/SymbolTable.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/Versions.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/attribute.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/glslang_tab.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/intermOut.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/iomapper.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/limits.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/linkValidate.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/parseConst.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/pch.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/propagateNoContraction.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/$(DEPDIR)/reflection.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/Pp.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpAtom.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpContext.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpScanner.Plo + -rm -f ./libraries/glslang/glslang/MachineIndependent/preprocessor/$(DEPDIR)/PpTokens.Plo + -rm -f ./libraries/glslang/glslang/OSDependent/Unix/$(DEPDIR)/ossource.Plo + -rm -f ./libraries/lodepng/$(DEPDIR)/lodepng.Plo + -rm -f ./libraries/lua53/$(DEPDIR)/lstrlib.Plo + -rm -f ./libraries/lua53/$(DEPDIR)/lutf8lib.Plo + -rm -f ./libraries/luasocket/$(DEPDIR)/luasocket.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/auxiliar.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/buffer.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/compat.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/except.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/inet.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/io.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/luasocket.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/mime.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/options.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/select.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/serial.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/tcp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/timeout.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/udp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/unix.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/unixtcp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/unixudp.Plo + -rm -f ./libraries/luasocket/libluasocket/$(DEPDIR)/usocket.Plo + -rm -f ./libraries/lz4/$(DEPDIR)/lz4.Plo + -rm -f ./libraries/lz4/$(DEPDIR)/lz4hc.Plo + -rm -f ./libraries/noise1234/$(DEPDIR)/noise1234.Plo + -rm -f ./libraries/noise1234/$(DEPDIR)/simplexnoise1234.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_7z.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_dir.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_grp.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_hog.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_iso9660.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_mvl.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_qpak.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_slb.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_unpacked.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_vdf.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_wad.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_archiver_zip.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_byteorder.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_haiku.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_os2.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_posix.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_qnx.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_unix.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_windows.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_platform_winrt.Plo + -rm -f ./libraries/physfs/$(DEPDIR)/physfs_unicode.Plo + -rm -f ./libraries/xxHash/$(DEPDIR)/xxhash.Plo + -rm -f ./modules/audio/$(DEPDIR)/Audio.Plo + -rm -f ./modules/audio/$(DEPDIR)/Effect.Plo + -rm -f ./modules/audio/$(DEPDIR)/Filter.Plo + -rm -f ./modules/audio/$(DEPDIR)/RecordingDevice.Plo + -rm -f ./modules/audio/$(DEPDIR)/Source.Plo + -rm -f ./modules/audio/$(DEPDIR)/wrap_Audio.Plo + -rm -f ./modules/audio/$(DEPDIR)/wrap_RecordingDevice.Plo + -rm -f ./modules/audio/$(DEPDIR)/wrap_Source.Plo + -rm -f ./modules/audio/null/$(DEPDIR)/Audio.Plo + -rm -f ./modules/audio/null/$(DEPDIR)/RecordingDevice.Plo + -rm -f ./modules/audio/null/$(DEPDIR)/Source.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Audio.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Effect.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Filter.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Pool.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/RecordingDevice.Plo + -rm -f ./modules/audio/openal/$(DEPDIR)/Source.Plo + -rm -f ./modules/data/$(DEPDIR)/ByteData.Plo + -rm -f ./modules/data/$(DEPDIR)/CompressedData.Plo + -rm -f ./modules/data/$(DEPDIR)/Compressor.Plo + -rm -f ./modules/data/$(DEPDIR)/DataModule.Plo + -rm -f ./modules/data/$(DEPDIR)/DataView.Plo + -rm -f ./modules/data/$(DEPDIR)/HashFunction.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_ByteData.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_CompressedData.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_Data.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_DataModule.Plo + -rm -f ./modules/data/$(DEPDIR)/wrap_DataView.Plo + -rm -f ./modules/event/$(DEPDIR)/Event.Plo + -rm -f ./modules/event/$(DEPDIR)/wrap_Event.Plo + -rm -f ./modules/event/sdl/$(DEPDIR)/Event.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/DroppedFile.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/File.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/FileData.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/Filesystem.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_DroppedFile.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_File.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_FileData.Plo + -rm -f ./modules/filesystem/$(DEPDIR)/wrap_Filesystem.Plo + -rm -f ./modules/filesystem/physfs/$(DEPDIR)/File.Plo + -rm -f ./modules/filesystem/physfs/$(DEPDIR)/Filesystem.Plo + -rm -f ./modules/font/$(DEPDIR)/BMFontRasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/Font.Plo + -rm -f ./modules/font/$(DEPDIR)/GlyphData.Plo + -rm -f ./modules/font/$(DEPDIR)/ImageRasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/Rasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/TrueTypeRasterizer.Plo + -rm -f ./modules/font/$(DEPDIR)/wrap_Font.Plo + -rm -f ./modules/font/$(DEPDIR)/wrap_GlyphData.Plo + -rm -f ./modules/font/$(DEPDIR)/wrap_Rasterizer.Plo + -rm -f ./modules/font/freetype/$(DEPDIR)/Font.Plo + -rm -f ./modules/font/freetype/$(DEPDIR)/TrueTypeRasterizer.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Buffer.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Canvas.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Deprecations.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Drawable.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Font.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Graphics.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Image.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Mesh.Plo + -rm -f ./modules/graphics/$(DEPDIR)/ParticleSystem.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Polyline.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Quad.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Shader.Plo + -rm -f ./modules/graphics/$(DEPDIR)/ShaderStage.Plo + -rm -f ./modules/graphics/$(DEPDIR)/SpriteBatch.Plo + -rm -f ./modules/graphics/$(DEPDIR)/StreamBuffer.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Text.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Texture.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Video.Plo + -rm -f ./modules/graphics/$(DEPDIR)/Volatile.Plo + -rm -f ./modules/graphics/$(DEPDIR)/depthstencil.Plo + -rm -f ./modules/graphics/$(DEPDIR)/vertex.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Canvas.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Font.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Graphics.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Image.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Mesh.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_ParticleSystem.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Quad.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Shader.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_SpriteBatch.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Text.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Texture.Plo + -rm -f ./modules/graphics/$(DEPDIR)/wrap_Video.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Buffer.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Canvas.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/FenceSync.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Graphics.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Image.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/OpenGL.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/Shader.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/ShaderStage.Plo + -rm -f ./modules/graphics/opengl/$(DEPDIR)/StreamBuffer.Plo + -rm -f ./modules/image/$(DEPDIR)/CompressedImageData.Plo + -rm -f ./modules/image/$(DEPDIR)/CompressedSlice.Plo + -rm -f ./modules/image/$(DEPDIR)/FormatHandler.Plo + -rm -f ./modules/image/$(DEPDIR)/Image.Plo + -rm -f ./modules/image/$(DEPDIR)/ImageData.Plo + -rm -f ./modules/image/$(DEPDIR)/ImageDataBase.Plo + -rm -f ./modules/image/$(DEPDIR)/wrap_CompressedImageData.Plo + -rm -f ./modules/image/$(DEPDIR)/wrap_Image.Plo + -rm -f ./modules/image/$(DEPDIR)/wrap_ImageData.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/ASTCHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/EXRHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/KTXHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/PKMHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/PNGHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/PVRHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/STBHandler.Plo + -rm -f ./modules/image/magpie/$(DEPDIR)/ddsHandler.Plo + -rm -f ./modules/joystick/$(DEPDIR)/Joystick.Plo + -rm -f ./modules/joystick/$(DEPDIR)/wrap_Joystick.Plo + -rm -f ./modules/joystick/$(DEPDIR)/wrap_JoystickModule.Plo + -rm -f ./modules/joystick/sdl/$(DEPDIR)/Joystick.Plo + -rm -f ./modules/joystick/sdl/$(DEPDIR)/JoystickModule.Plo + -rm -f ./modules/keyboard/$(DEPDIR)/Keyboard.Plo + -rm -f ./modules/keyboard/$(DEPDIR)/wrap_Keyboard.Plo + -rm -f ./modules/keyboard/sdl/$(DEPDIR)/Keyboard.Plo + -rm -f ./modules/love/$(DEPDIR)/love.Plo + -rm -f ./modules/math/$(DEPDIR)/BezierCurve.Plo + -rm -f ./modules/math/$(DEPDIR)/MathModule.Plo + -rm -f ./modules/math/$(DEPDIR)/RandomGenerator.Plo + -rm -f ./modules/math/$(DEPDIR)/Transform.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_BezierCurve.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_Math.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_RandomGenerator.Plo + -rm -f ./modules/math/$(DEPDIR)/wrap_Transform.Plo + -rm -f ./modules/mouse/$(DEPDIR)/Cursor.Plo + -rm -f ./modules/mouse/$(DEPDIR)/wrap_Cursor.Plo + -rm -f ./modules/mouse/$(DEPDIR)/wrap_Mouse.Plo + -rm -f ./modules/mouse/sdl/$(DEPDIR)/Cursor.Plo + -rm -f ./modules/mouse/sdl/$(DEPDIR)/Mouse.Plo + -rm -f ./modules/physics/$(DEPDIR)/Body.Plo + -rm -f ./modules/physics/$(DEPDIR)/Joint.Plo + -rm -f ./modules/physics/$(DEPDIR)/Shape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Body.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/ChainShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/CircleShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Contact.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/DistanceJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/EdgeShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Fixture.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/FrictionJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/GearJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Joint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/MotorJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/MouseJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Physics.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/PolygonShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/PrismaticJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/PulleyJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/RevoluteJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/RopeJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/Shape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/WeldJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/WheelJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/World.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Body.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_ChainShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_CircleShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Contact.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_DistanceJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_EdgeShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Fixture.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_FrictionJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_GearJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Joint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_MotorJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_MouseJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Physics.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_PolygonShape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_PrismaticJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_PulleyJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_RevoluteJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_RopeJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_Shape.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_WeldJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_WheelJoint.Plo + -rm -f ./modules/physics/box2d/$(DEPDIR)/wrap_World.Plo + -rm -f ./modules/sound/$(DEPDIR)/Decoder.Plo + -rm -f ./modules/sound/$(DEPDIR)/Sound.Plo + -rm -f ./modules/sound/$(DEPDIR)/SoundData.Plo + -rm -f ./modules/sound/$(DEPDIR)/wrap_Decoder.Plo + -rm -f ./modules/sound/$(DEPDIR)/wrap_Sound.Plo + -rm -f ./modules/sound/$(DEPDIR)/wrap_SoundData.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/CoreAudioDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/FLACDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/GmeDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/ModPlugDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/Mpg123Decoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/Sound.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/VorbisDecoder.Plo + -rm -f ./modules/sound/lullaby/$(DEPDIR)/WaveDecoder.Plo + -rm -f ./modules/system/$(DEPDIR)/System.Plo + -rm -f ./modules/system/$(DEPDIR)/wrap_System.Plo + -rm -f ./modules/system/sdl/$(DEPDIR)/System.Plo + -rm -f ./modules/thread/$(DEPDIR)/Channel.Plo + -rm -f ./modules/thread/$(DEPDIR)/LuaThread.Plo + -rm -f ./modules/thread/$(DEPDIR)/ThreadModule.Plo + -rm -f ./modules/thread/$(DEPDIR)/threads.Plo + -rm -f ./modules/thread/$(DEPDIR)/wrap_Channel.Plo + -rm -f ./modules/thread/$(DEPDIR)/wrap_LuaThread.Plo + -rm -f ./modules/thread/$(DEPDIR)/wrap_ThreadModule.Plo + -rm -f ./modules/thread/sdl/$(DEPDIR)/Thread.Plo + -rm -f ./modules/thread/sdl/$(DEPDIR)/threads.Plo + -rm -f ./modules/timer/$(DEPDIR)/Timer.Plo + -rm -f ./modules/timer/$(DEPDIR)/wrap_Timer.Plo + -rm -f ./modules/touch/$(DEPDIR)/wrap_Touch.Plo + -rm -f ./modules/touch/sdl/$(DEPDIR)/Touch.Plo + -rm -f ./modules/video/$(DEPDIR)/VideoStream.Plo + -rm -f ./modules/video/$(DEPDIR)/wrap_Video.Plo + -rm -f ./modules/video/$(DEPDIR)/wrap_VideoStream.Plo + -rm -f ./modules/video/theora/$(DEPDIR)/OggDemuxer.Plo + -rm -f ./modules/video/theora/$(DEPDIR)/TheoraVideoStream.Plo + -rm -f ./modules/video/theora/$(DEPDIR)/Video.Plo + -rm -f ./modules/window/$(DEPDIR)/Window.Plo + -rm -f ./modules/window/$(DEPDIR)/wrap_Window.Plo + -rm -f ./modules/window/sdl/$(DEPDIR)/Window.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -4935,10 +6117,10 @@ .MAKE: $(am__recursive_targets) install-am install-strip -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-binPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ diff -Nru love-11.1/src/modules/audio/Audio.cpp love-11.3/src/modules/audio/Audio.cpp --- love-11.1/src/modules/audio/Audio.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Audio.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -21,8 +21,10 @@ #include "Audio.h" #include "common/config.h" -#ifdef LOVE_IOS +#if defined(LOVE_IOS) #include "common/ios.h" +#elif defined(LOVE_ANDROID) +#include "common/android.h" #endif namespace love @@ -30,11 +32,46 @@ namespace audio { +static bool requestRecPermission = false; + +void setRequestRecordingPermission(bool rec) +{ + requestRecPermission = rec; +} + +bool getRequestRecordingPermission() +{ + return requestRecPermission; +} + +bool hasRecordingPermission() +{ +#if defined(LOVE_ANDROID) + return love::android::hasRecordingPermission(); +#else + // Always available(?) + return true; +#endif +} + +void requestRecordingPermission() +{ +#ifdef LOVE_ANDROID + love::android::requestRecordingPermission(); +#endif +} + +void showRecordingPermissionMissingDialog() +{ +#ifdef LOVE_ANDROID + love::android::showRecordingPermissionMissingDialog(); +#endif +} + bool Audio::setMixWithSystem(bool mix) { #ifdef LOVE_IOS - love::ios::setAudioMixWithOthers(mix); - return true; + return love::ios::setAudioMixWithOthers(mix); #else LOVE_UNUSED(mix); return false; diff -Nru love-11.1/src/modules/audio/Audio.h love-11.3/src/modules/audio/Audio.h --- love-11.1/src/modules/audio/Audio.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Audio.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -45,6 +45,34 @@ namespace audio { +/* + * In some platforms (notably Android), recording from mic + * requires user permission. This function sets whetever to + * request the permission later or not. + */ +void setRequestRecordingPermission(bool rec); + +/* + * Gets whetever recording permission will be requested. + */ +bool getRequestRecordingPermission(); + +/* + * Gets whetever recording permission is granted. + */ +bool hasRecordingPermission(); + +/* + * Request recording permission. This is blocking function. + */ +void requestRecordingPermission(); + +/* + * In case recording permission is not granted, this + * function shows the dialog about the recording permission. + */ +void showRecordingPermissionMissingDialog(); + /** * The Audio module is responsible for playing back raw sound samples. **/ @@ -261,7 +289,7 @@ * Sets whether audio from other apps mixes with love.audio or is muted, * on supported platforms. **/ - bool setMixWithSystem(bool mix); + static bool setMixWithSystem(bool mix); private: diff -Nru love-11.1/src/modules/audio/Effect.cpp love-11.3/src/modules/audio/Effect.cpp --- love-11.1/src/modules/audio/Effect.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Effect.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/Effect.h love-11.3/src/modules/audio/Effect.h --- love-11.1/src/modules/audio/Effect.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Effect.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/Filter.cpp love-11.3/src/modules/audio/Filter.cpp --- love-11.1/src/modules/audio/Filter.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Filter.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/Filter.h love-11.3/src/modules/audio/Filter.h --- love-11.1/src/modules/audio/Filter.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Filter.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/null/Audio.cpp love-11.3/src/modules/audio/null/Audio.cpp --- love-11.1/src/modules/audio/null/Audio.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/null/Audio.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/null/Audio.h love-11.3/src/modules/audio/null/Audio.h --- love-11.1/src/modules/audio/null/Audio.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/null/Audio.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/null/RecordingDevice.cpp love-11.3/src/modules/audio/null/RecordingDevice.cpp --- love-11.1/src/modules/audio/null/RecordingDevice.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/null/RecordingDevice.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/null/RecordingDevice.h love-11.3/src/modules/audio/null/RecordingDevice.h --- love-11.1/src/modules/audio/null/RecordingDevice.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/null/RecordingDevice.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/null/Source.cpp love-11.3/src/modules/audio/null/Source.cpp --- love-11.1/src/modules/audio/null/Source.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/null/Source.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -90,11 +90,11 @@ return volume; } -void Source::seek(float, Source::Unit) +void Source::seek(double, Source::Unit) { } -float Source::tell(Source::Unit) +double Source::tell(Source::Unit) { return 0.0f; } diff -Nru love-11.1/src/modules/audio/null/Source.h love-11.3/src/modules/audio/null/Source.h --- love-11.1/src/modules/audio/null/Source.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/null/Source.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -50,8 +50,8 @@ virtual float getPitch() const; virtual void setVolume(float volume); virtual float getVolume() const; - virtual void seek(float offset, Unit unit); - virtual float tell(Unit unit); + virtual void seek(double offset, Unit unit); + virtual double tell(Unit unit); virtual double getDuration(Unit unit); virtual void setPosition(float *v); virtual void getPosition(float *v) const; diff -Nru love-11.1/src/modules/audio/openal/Audio.cpp love-11.3/src/modules/audio/openal/Audio.cpp --- love-11.1/src/modules/audio/openal/Audio.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Audio.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -101,6 +101,15 @@ love::thread::disableSignals(); #endif + // Before opening new device, check if recording + // is requested. + if (getRequestRecordingPermission()) + { + if (!hasRecordingPermission()) + // Request recording permission on some OSes. + requestRecordingPermission(); + } + // Passing null for default device. device = alcOpenDevice(nullptr); @@ -402,6 +411,15 @@ std::vector devnames; std::vector devices; + // If recording permission is not granted, inform user about it + // and return empty list. + if (!hasRecordingPermission() && getRequestRecordingPermission()) + { + showRecordingPermissionMissingDialog(); + capture.clear(); + return capture; + } + std::string defaultname(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)); //no device name obtained from AL, fallback to reading from device diff -Nru love-11.1/src/modules/audio/openal/Audio.h love-11.3/src/modules/audio/openal/Audio.h --- love-11.1/src/modules/audio/openal/Audio.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Audio.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/Filter.cpp love-11.3/src/modules/audio/openal/Filter.cpp --- love-11.1/src/modules/audio/openal/Filter.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Filter.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/Filter.h love-11.3/src/modules/audio/openal/Filter.h --- love-11.1/src/modules/audio/openal/Filter.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Filter.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/Pool.cpp love-11.3/src/modules/audio/openal/Pool.cpp --- love-11.1/src/modules/audio/openal/Pool.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Pool.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/Pool.h love-11.3/src/modules/audio/openal/Pool.h --- love-11.1/src/modules/audio/openal/Pool.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Pool.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/RecordingDevice.cpp love-11.3/src/modules/audio/openal/RecordingDevice.cpp --- love-11.1/src/modules/audio/openal/RecordingDevice.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/RecordingDevice.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/RecordingDevice.h love-11.3/src/modules/audio/openal/RecordingDevice.h --- love-11.1/src/modules/audio/openal/RecordingDevice.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/RecordingDevice.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/openal/Source.cpp love-11.3/src/modules/audio/openal/Source.cpp --- love-11.1/src/modules/audio/openal/Source.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Source.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -137,7 +137,7 @@ setFloatv(velocity, z); setFloatv(direction, z); - for (unsigned int i = 0; i < (unsigned int)audiomodule()->getMaxSourceEffects(); i++) + for (int i = 0; i < audiomodule()->getMaxSourceEffects(); i++) slotlist.push(i); } @@ -172,7 +172,7 @@ setFloatv(velocity, z); setFloatv(direction, z); - for (unsigned int i = 0; i < (unsigned int)audiomodule()->getMaxSourceEffects(); i++) + for (int i = 0; i < audiomodule()->getMaxSourceEffects(); i++) slotlist.push(i); } @@ -212,7 +212,7 @@ setFloatv(velocity, z); setFloatv(direction, z); - for (unsigned int i = 0; i < (unsigned int)audiomodule()->getMaxSourceEffects(); i++) + for (int i = 0; i < audiomodule()->getMaxSourceEffects(); i++) slotlist.push(i); } @@ -232,7 +232,6 @@ , maxDistance(s.maxDistance) , cone(s.cone) , offsetSamples(0) - , offsetSeconds(0) , sampleRate(s.sampleRate) , channels(s.channels) , bitDepth(s.bitDepth) @@ -274,7 +273,7 @@ setFloatv(velocity, s.velocity); setFloatv(direction, s.direction); - for (unsigned int i = 0; i < (unsigned int)audiomodule()->getMaxSourceEffects(); i++) + for (int i = 0; i < audiomodule()->getMaxSourceEffects(); i++) { // filter out already taken slots bool push = true; @@ -397,28 +396,38 @@ if (!isFinished()) { ALint processed; - ALuint buffers[MAX_BUFFERS]; - float curOffsetSamples, curOffsetSecs, newOffsetSamples, newOffsetSecs; - int freq = decoder->getSampleRate(); + alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); - alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples); - curOffsetSecs = curOffsetSamples / freq; + // It would theoretically be better to unqueue all processed + // buffers in a single call to alSourceUnqueueBuffers, but on + // iOS I observed occasional (every ~5-10 seconds) pops in the + // streaming source test I was using, when doing that. Perhaps + // there was a bug in this code when I was testing, or maybe + // this code runs into the same problem but now it's much harder + // to reproduce. The test I used is the play-stop-play .love + // from https://bitbucket.org/rude/love/issues/1484/ + while (processed--) + { + int curOffsetSamples; + alGetSourcei(source, AL_SAMPLE_OFFSET, &curOffsetSamples); - alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); - alSourceUnqueueBuffers(source, processed, buffers); + ALuint buffer; + alSourceUnqueueBuffers(source, 1, &buffer); - alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples); - newOffsetSecs = newOffsetSamples / freq; + int newOffsetSamples; + alGetSourcei(source, AL_SAMPLE_OFFSET, &newOffsetSamples); - offsetSamples += (curOffsetSamples - newOffsetSamples); - offsetSeconds += (curOffsetSecs - newOffsetSecs); + offsetSamples += (curOffsetSamples - newOffsetSamples); - for (unsigned int i = 0; i < (unsigned int)processed; i++) - unusedBuffers.push(buffers[i]); + if (streamAtomic(buffer, decoder.get()) > 0) + alSourceQueueBuffers(source, 1, &buffer); + else + unusedBuffers.push(buffer); + } while (!unusedBuffers.empty()) { - auto b = unusedBuffers.top(); + ALuint b = unusedBuffers.top(); if (streamAtomic(b, decoder.get()) > 0) { alSourceQueueBuffers(source, 1, &b); @@ -439,7 +448,7 @@ alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); alSourceUnqueueBuffers(source, processed, buffers); - for (unsigned int i = 0; i < (unsigned int)processed; i++) + for (int i = 0; i < processed; i++) { ALint size; alGetBufferi(buffers[i], AL_SIZE, &size); @@ -497,22 +506,23 @@ return volume; } -void Source::seek(float offset, Source::Unit unit) +void Source::seek(double offset, Source::Unit unit) { Lock l = pool->lock(); - float offsetSamples, offsetSeconds; + int offsetSamples = 0; + double offsetSeconds = 0.0f; switch (unit) { case Source::UNIT_SAMPLES: - offsetSamples = offset; - offsetSeconds = offset / sampleRate; + offsetSamples = (int) offset; + offsetSeconds = offset / (double) sampleRate; break; case Source::UNIT_SECONDS: default: offsetSeconds = offset; - offsetSamples = offset * sampleRate; + offsetSamples = (int) (offset * sampleRate); break; } @@ -522,7 +532,7 @@ case TYPE_STATIC: if (valid) { - alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples); + alSourcei(source, AL_SAMPLE_OFFSET, offsetSamples); offsetSamples = offsetSeconds = 0; } break; @@ -542,7 +552,7 @@ case TYPE_QUEUE: if (valid) { - alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples); + alSourcei(source, AL_SAMPLE_OFFSET, offsetSamples); offsetSamples = offsetSeconds = 0; } else @@ -563,12 +573,13 @@ } if (unusedBuffers.empty()) offsetSamples = 0; - offsetSeconds = offsetSamples / sampleRate; + offsetSeconds = offsetSamples / (double) sampleRate; } break; case TYPE_MAX_ENUM: break; } + if (wasPlaying && (alGetError() == AL_INVALID_VALUE || (sourceType == TYPE_STREAM && !isPlaying()))) { stop(); @@ -576,32 +587,25 @@ play(); return; } + this->offsetSamples = offsetSamples; - this->offsetSeconds = offsetSeconds; } -float Source::tell(Source::Unit unit) +double Source::tell(Source::Unit unit) { Lock l = pool->lock(); - float offset = 0.0f; + int offset = 0; - switch (unit) - { - case Source::UNIT_SAMPLES: - if (valid) - alGetSourcef(source, AL_SAMPLE_OFFSET, &offset); - offset += offsetSamples; - break; - case Source::UNIT_SECONDS: - default: - if (valid) - alGetSourcef(source, AL_SEC_OFFSET, &offset); - offset += offsetSeconds; - break; - } + if (valid) + alGetSourcei(source, AL_SAMPLE_OFFSET, &offset); - return offset; + offset += offsetSamples; + + if (unit == UNIT_SECONDS) + return offset / (double) sampleRate; + else + return offset; } double Source::getDuration(Unit unit) @@ -863,6 +867,9 @@ case TYPE_MAX_ENUM: break; } + + // Seek to the current/pending offset. + alSourcei(source, AL_SAMPLE_OFFSET, offsetSamples); } void Source::teardownAtomic() @@ -873,31 +880,33 @@ break; case TYPE_STREAM: { - ALint queued; - ALuint buffer; + ALint queued = 0; + ALuint buffers[MAX_BUFFERS]; - decoder->seek(0); - // drain buffers - //since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array + // Some decoders (e.g. ModPlug) can rewind() more reliably than seek(0). + decoder->rewind(); + + // Drain buffers. + // NOTE: The Apple implementation of OpenAL on iOS doesn't return + // correct buffer ids for single alSourceUnqueueBuffers calls past the + // first queued buffer, so we must unqueue them all at once. alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - for (unsigned int i = 0; i < (unsigned int)queued; i++) - { - alSourceUnqueueBuffers(source, 1, &buffer); - unusedBuffers.push(buffer); - } + alSourceUnqueueBuffers(source, queued, buffers); + + for (int i = 0; i < queued; i++) + unusedBuffers.push(buffers[i]); break; } case TYPE_QUEUE: { ALint queued; - ALuint buffer; + ALuint buffers[MAX_BUFFERS]; alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - for (unsigned int i = (unsigned int)queued; i > 0; i--) - { - alSourceUnqueueBuffers(source, 1, &buffer); - unusedBuffers.push(buffer); - } + alSourceUnqueueBuffers(source, queued, buffers); + + for (int i = 0; i < queued; i++) + unusedBuffers.push(buffers[i]); break; } case TYPE_MAX_ENUM: @@ -908,7 +917,7 @@ toLoop = 0; valid = false; - offsetSamples = offsetSeconds = 0; + offsetSamples = 0; } bool Source::playAtomic(ALuint source) @@ -929,19 +938,16 @@ if (!isPlaying()) success = false; } - else if (success) - { - alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples); - success = alGetError() == AL_NO_ERROR; - } if (!success) { valid = true; //stop() needs source to be valid stop(); } + + // Static sources: reset the pending offset since it's not valid anymore. if (sourceType != TYPE_STREAM) - offsetSamples = offsetSeconds = 0; + offsetSamples = 0; return success; } @@ -1026,7 +1032,7 @@ source->valid = source->valid || success; if (success && source->sourceType != TYPE_STREAM) - source->offsetSamples = source->offsetSeconds = 0; + source->offsetSamples = 0; } return success; @@ -1171,7 +1177,6 @@ if (--toLoop == 0) { offsetSamples = 0; - offsetSeconds = 0; } } diff -Nru love-11.1/src/modules/audio/openal/Source.h love-11.3/src/modules/audio/openal/Source.h --- love-11.1/src/modules/audio/openal/Source.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/openal/Source.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -115,8 +115,8 @@ virtual float getPitch() const; virtual void setVolume(float volume); virtual float getVolume() const; - virtual void seek(float offset, Unit unit); - virtual float tell(Unit unit); + virtual void seek(double offset, Unit unit); + virtual double tell(Unit unit); virtual double getDuration(Unit unit); virtual void setPosition(float *v); virtual void getPosition(float *v) const; @@ -213,8 +213,7 @@ float outerHighGain = 1.0f; } cone; - float offsetSamples = 0.0f; - float offsetSeconds = 0.0f; + int offsetSamples = 0; int sampleRate = 0; int channels = 0; diff -Nru love-11.1/src/modules/audio/RecordingDevice.cpp love-11.3/src/modules/audio/RecordingDevice.cpp --- love-11.1/src/modules/audio/RecordingDevice.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/RecordingDevice.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/RecordingDevice.h love-11.3/src/modules/audio/RecordingDevice.h --- love-11.1/src/modules/audio/RecordingDevice.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/RecordingDevice.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/Source.cpp love-11.3/src/modules/audio/Source.cpp --- love-11.1/src/modules/audio/Source.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Source.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/Source.h love-11.3/src/modules/audio/Source.h --- love-11.1/src/modules/audio/Source.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/Source.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -72,8 +72,8 @@ virtual void setVolume(float volume) = 0; virtual float getVolume() const = 0; - virtual void seek(float offset, Unit unit) = 0; - virtual float tell(Unit unit) = 0; + virtual void seek(double offset, Unit unit) = 0; + virtual double tell(Unit unit) = 0; virtual double getDuration(Unit unit) = 0; // all float * v must be of size 3 diff -Nru love-11.1/src/modules/audio/wrap_Audio.cpp love-11.3/src/modules/audio/wrap_Audio.cpp --- love-11.1/src/modules/audio/wrap_Audio.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/wrap_Audio.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -52,6 +52,9 @@ const char *stypestr = luaL_checkstring(L, 2); if (stypestr && !Source::getConstant(stypestr, stype)) return luax_enumerror(L, "source type", Source::getConstants(stype), stypestr); + + if (stype == Source::TYPE_QUEUE) + return luaL_error(L, "Cannot create queueable sources using newSource. Use newQueueableSource instead."); } if (lua_isstring(L, 1) || luax_istype(L, 1, love::filesystem::File::type) || luax_istype(L, 1, love::filesystem::FileData::type)) @@ -523,7 +526,7 @@ int w_setMixWithSystem(lua_State *L) { - luax_pushboolean(L, instance()->setMixWithSystem(luax_checkboolean(L, 1))); + luax_pushboolean(L, Audio::setMixWithSystem(luax_checkboolean(L, 1))); return 1; } diff -Nru love-11.1/src/modules/audio/wrap_Audio.h love-11.3/src/modules/audio/wrap_Audio.h --- love-11.1/src/modules/audio/wrap_Audio.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/wrap_Audio.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/wrap_RecordingDevice.cpp love-11.3/src/modules/audio/wrap_RecordingDevice.cpp --- love-11.1/src/modules/audio/wrap_RecordingDevice.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/wrap_RecordingDevice.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/wrap_RecordingDevice.h love-11.3/src/modules/audio/wrap_RecordingDevice.h --- love-11.1/src/modules/audio/wrap_RecordingDevice.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/wrap_RecordingDevice.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/audio/wrap_Source.cpp love-11.3/src/modules/audio/wrap_Source.cpp --- love-11.1/src/modules/audio/wrap_Source.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/wrap_Source.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -71,10 +71,11 @@ { Source *t = luax_checksource(L, 1); float p = (float)luaL_checknumber(L, 2); + if (p != p) + return luaL_error(L, "Pitch cannot be NaN."); if (p > std::numeric_limits::max() || - p < std::numeric_limits::min() || - p != p) - return luaL_error(L, "Pitch has to be finite and not NaN."); + p <= 0.0f) + return luaL_error(L, "Pitch has to be non-zero, positive, finite number."); t->setPitch(p); return 0; } @@ -104,7 +105,7 @@ int w_Source_seek(lua_State *L) { Source *t = luax_checksource(L, 1); - float offset = (float)luaL_checknumber(L, 2); + double offset = luaL_checknumber(L, 2); if (offset < 0) return luaL_argerror(L, 2, "can't seek to a negative position"); @@ -338,6 +339,13 @@ return 0; } +int w_Source_getAirAbsorption(lua_State *L) +{ + Source *t = luax_checksource(L, 1); + luax_catchexcept(L, [&](){ lua_pushnumber(L, t->getAirAbsorptionFactor()); }); + return 1; +} + int w_Source_getChannelCount(lua_State *L) { Source *t = luax_checksource(L, 1); @@ -464,8 +472,10 @@ Source *t = luax_checksource(L, 1); const char *namestr = luaL_checkstring(L, 2); + const bool isBool = lua_gettop(L) >= 3 && lua_isboolean(L, 3); + // :setEffect(effect, false) = clear effect - if (lua_gettop(L) == 3 && lua_isboolean(L, 3) && !lua_toboolean(L, 3)) + if (isBool && !lua_toboolean(L, 3)) { luax_catchexcept(L, [&]() { lua_pushboolean(L, t->unsetEffect(namestr)); }); return 1; @@ -473,10 +483,11 @@ std::map params; - if (setFilterReadFilter(L, 3, params) == 1) - luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setEffect(namestr, params)); }); - else + // :setEffect(effect, [true]) = set effect without filter + if (isBool || setFilterReadFilter(L, 3, params) == 0) luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setEffect(namestr)); }); + else + luax_catchexcept(L, [&]() { lua_pushboolean(L, t->setEffect(namestr, params)); }); return 1; } @@ -487,13 +498,20 @@ std::map params; if (!t->getEffect(namestr, params)) - return 0; + { + luax_pushboolean(L, false); + return 1; + } + + luax_pushboolean(L, true); + // No filter associated, return nil as second argument if (params.size() == 0) - return 0; + return 1; + // Return filter settings as second argument getFilterWriteFilter(L, 3, params); - return 1; + return 2; } int w_Source_getActiveEffects(lua_State *L) @@ -628,6 +646,8 @@ { "getAttenuationDistances", w_Source_getAttenuationDistances }, { "setRolloff", w_Source_setRolloff }, { "getRolloff", w_Source_getRolloff }, + { "setAirAbsorption", w_Source_setAirAbsorption }, + { "getAirAbsorption", w_Source_getAirAbsorption }, { "getChannelCount", w_Source_getChannelCount }, diff -Nru love-11.1/src/modules/audio/wrap_Source.h love-11.3/src/modules/audio/wrap_Source.h --- love-11.1/src/modules/audio/wrap_Source.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/audio/wrap_Source.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/ByteData.cpp love-11.3/src/modules/data/ByteData.cpp --- love-11.1/src/modules/data/ByteData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/ByteData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/ByteData.h love-11.3/src/modules/data/ByteData.h --- love-11.1/src/modules/data/ByteData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/ByteData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/CompressedData.cpp love-11.3/src/modules/data/CompressedData.cpp --- love-11.1/src/modules/data/CompressedData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/CompressedData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/CompressedData.h love-11.3/src/modules/data/CompressedData.h --- love-11.1/src/modules/data/CompressedData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/CompressedData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/Compressor.cpp love-11.3/src/modules/data/Compressor.cpp --- love-11.1/src/modules/data/Compressor.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/Compressor.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/Compressor.h love-11.3/src/modules/data/Compressor.h --- love-11.1/src/modules/data/Compressor.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/Compressor.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/DataModule.cpp love-11.3/src/modules/data/DataModule.cpp --- love-11.1/src/modules/data/DataModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/DataModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -213,12 +213,8 @@ hashfunction->hash(function, input, size, output); } -DataModule DataModule::instance; - DataModule::DataModule() { - // prevent the runtime from free()-ing this - retain(); } DataModule::~DataModule() diff -Nru love-11.1/src/modules/data/DataModule.h love-11.3/src/modules/data/DataModule.h --- love-11.1/src/modules/data/DataModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/DataModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -114,6 +114,7 @@ { public: + DataModule(); virtual ~DataModule(); // Implements Module. @@ -125,12 +126,6 @@ ByteData *newByteData(const void *d, size_t size); ByteData *newByteData(void *d, size_t size, bool own); - static DataModule instance; - -private: - - DataModule(); - }; // DataModule } // data diff -Nru love-11.1/src/modules/data/DataView.cpp love-11.3/src/modules/data/DataView.cpp --- love-11.1/src/modules/data/DataView.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/DataView.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/DataView.h love-11.3/src/modules/data/DataView.h --- love-11.1/src/modules/data/DataView.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/DataView.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/HashFunction.cpp love-11.3/src/modules/data/HashFunction.cpp --- love-11.1/src/modules/data/HashFunction.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/HashFunction.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -79,17 +79,20 @@ uint32 c0 = 0x98badcfe; uint32 d0 = 0x10325476; - // Do the required padding - uint64 paddedLength = length; - if (length % 64 < 56) - paddedLength += 56-length%64; - if (length % 64 > 56) - paddedLength += 120-length%64; - uint8 *padded = new uint8[paddedLength+8]; + //Do the required padding (MD5, SHA1 and SHA2 use the same padding) + uint64 paddedLength = length + 1; //Consider the appended bit + if (paddedLength % 64 < 56) + paddedLength += 56 - paddedLength % 64; + if (paddedLength % 64 > 56) + paddedLength += 120 - paddedLength % 64; + + uint8 *padded = new uint8[paddedLength + 8]; memcpy(padded, input, length); - memset(padded+length, 0, paddedLength-length); + memset(padded + length, 0, paddedLength - length); padded[length] = 0x80; - *((uint64*) &padded[paddedLength]) = length*8; + + //Now we need the length in bits + *((uint64*) &padded[paddedLength]) = length * 8; paddedLength += 8; for (uint64 i = 0; i < paddedLength; i += 64) @@ -177,7 +180,7 @@ /** * The following implementation was based on the text, not the code listings, - * in RFC3174. I believe this means no copyright other than that of the LÖVE + * in RFC3174. I believe this means no copyright other than that of the L�VE * Development Team applies. **/ class SHA1 : public HashFunction @@ -197,21 +200,22 @@ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; - // Same padding as for md5, but then big-endian - uint64 paddedLength = length; - if (length % 64 < 56) - paddedLength += 56-length%64; - if (length % 64 > 56) - paddedLength += 120-length%64; - uint8 *padded = new uint8[paddedLength+8]; + //Do the required padding (MD5, SHA1 and SHA2 use the same padding) + uint64 paddedLength = length + 1; //Consider the appended bit + if (paddedLength % 64 < 56) + paddedLength += 56 - paddedLength % 64; + if (paddedLength % 64 > 56) + paddedLength += 120 - paddedLength % 64; + + uint8 *padded = new uint8[paddedLength + 8]; memcpy(padded, input, length); - memset(padded+length, 0, paddedLength-length); + memset(padded + length, 0, paddedLength - length); padded[length] = 0x80; - // Now we need the length in bits + // Now we need the length in bits (big endian) length *= 8; for (int i = 0; i < 8; ++i, ++paddedLength) - padded[paddedLength] = (length >> (56-i*8)) & 0xFF; + padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF; // Allocate our extended words uint32 words[80]; @@ -299,21 +303,22 @@ if (!isSupported(function)) throw love::Exception("Hash function not supported by SHA-224/SHA-256 implementation"); - // Same padding as for sha1 - uint64 paddedLength = length; - if (length % 64 < 56) - paddedLength += 56-length%64; - if (length % 64 > 56) - paddedLength += 120-length%64; - uint8 *padded = new uint8[paddedLength+8]; + //Do the required padding (MD5, SHA1 and SHA2 use the same padding) + uint64 paddedLength = length + 1; //Consider the appended bit + if (paddedLength % 64 < 56) + paddedLength += 56 - paddedLength % 64; + if (paddedLength % 64 > 56) + paddedLength += 120 - paddedLength % 64; + + uint8 *padded = new uint8[paddedLength + 8]; memcpy(padded, input, length); - memset(padded+length, 0, paddedLength-length); + memset(padded + length, 0, paddedLength - length); padded[length] = 0x80; - // Now we need the length in bits + // Now we need the length in bits (big endian) length *= 8; for (int i = 0; i < 8; ++i, ++paddedLength) - padded[paddedLength] = (length >> (56-i*8)) & 0xFF; + padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF; uint32 intermediate[8]; if (function == FUNCTION_SHA224) @@ -429,7 +434,7 @@ /** * This implementation was based on the description in RFC-6234. **/ -// SHA-2: SHA-224 and SHA-256 +// SHA-2: SHA-384 and SHA-512 class SHA512 : public HashFunction { private: @@ -454,22 +459,24 @@ else memcpy(intermediates, initial512, sizeof(intermediates)); - uint64 paddedLength = length; - if (length % 128 < 112) - paddedLength += 112-length%128; - if (length % 128 > 112) - paddedLength += 240-length%128; - uint8 *padded = new uint8[paddedLength+16]; + //Do the required padding + uint64 paddedLength = length + 1; //Consider the appended bit + if (paddedLength % 128 < 112) + paddedLength += 112 - paddedLength % 128; + if (paddedLength % 128 > 112) + paddedLength += 240 - paddedLength % 128; + + uint8 *padded = new uint8[paddedLength + 16]; paddedLength += 8; memcpy(padded, input, length); - memset(padded+length, 0, paddedLength-length); + memset(padded + length, 0, paddedLength - length); padded[length] = 0x80; - // Now we need the length in bits, note we only write a 64-bit int, so + // Now we need the length in bits (big endian), note we only write a 64-bit int, so // we have filled the first 8 bytes with zeroes length *= 8; for (int i = 0; i < 8; ++i, ++paddedLength) - padded[paddedLength] = (length >> (56-i*8)) & 0xFF; + padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF; // Allocate our extended words uint64 words[80]; @@ -608,6 +615,7 @@ return nullptr; // No default for compiler warnings } + return nullptr; } bool HashFunction::getConstant(const char *in, Function &out) diff -Nru love-11.1/src/modules/data/HashFunction.h love-11.3/src/modules/data/HashFunction.h --- love-11.1/src/modules/data/HashFunction.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/HashFunction.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/wrap_ByteData.cpp love-11.3/src/modules/data/wrap_ByteData.cpp --- love-11.1/src/modules/data/wrap_ByteData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_ByteData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -39,6 +39,7 @@ int luaopen_bytedata(lua_State *L) { luax_register_type(L, &ByteData::type, w_Data_functions, w_ByteData_functions, nullptr); + love::data::luax_rundatawrapper(L, ByteData::type); return 0; } diff -Nru love-11.1/src/modules/data/wrap_ByteData.h love-11.3/src/modules/data/wrap_ByteData.h --- love-11.1/src/modules/data/wrap_ByteData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_ByteData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/wrap_CompressedData.cpp love-11.3/src/modules/data/wrap_CompressedData.cpp --- love-11.1/src/modules/data/wrap_CompressedData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_CompressedData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -63,7 +63,9 @@ extern "C" int luaopen_compresseddata(lua_State *L) { - return luax_register_type(L, &CompressedData::type, w_Data_functions, w_CompressedData_functions, nullptr); + int ret = luax_register_type(L, &CompressedData::type, w_Data_functions, w_CompressedData_functions, nullptr); + love::data::luax_rundatawrapper(L, CompressedData::type); + return ret; } } // data diff -Nru love-11.1/src/modules/data/wrap_CompressedData.h love-11.3/src/modules/data/wrap_CompressedData.h --- love-11.1/src/modules/data/wrap_CompressedData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_CompressedData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/wrap_Data.cpp love-11.3/src/modules/data/wrap_Data.cpp --- love-11.1/src/modules/data/wrap_Data.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_Data.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -20,6 +20,11 @@ #include "wrap_Data.h" +// Put the Lua code directly into a raw string literal. +static const char data_lua[] = +#include "wrap_Data.lua" +; + namespace love { namespace data @@ -44,6 +49,13 @@ return 1; } +// Placeholder, overridden by the FFI code when the FFI is available. +int w_Data_getFFIPointer(lua_State *L) +{ + lua_pushnil(L); + return 1; +} + int w_Data_getSize(lua_State *L) { Data *t = luax_checkdata(L, 1); @@ -51,18 +63,40 @@ return 1; } +// C functions in a struct, necessary for the FFI versions of Data methods. +struct FFI_Data +{ + void *(*getFFIPointer)(Proxy *p); +}; + +static FFI_Data ffifuncs = +{ + [](Proxy *p) -> void * // getFFIPointer + { + auto data = luax_ffi_checktype(p); + return data != nullptr ? data->getData() : nullptr; + } +}; + const luaL_Reg w_Data_functions[] = { { "getString", w_Data_getString }, { "getPointer", w_Data_getPointer }, + { "getFFIPointer", w_Data_getFFIPointer }, { "getSize", w_Data_getSize }, { 0, 0 } }; +void luax_rundatawrapper(lua_State *L, const love::Type &type) +{ + luax_runwrapper(L, data_lua, sizeof(data_lua), "Data.lua", type, &ffifuncs); +} + int luaopen_data(lua_State *L) { - luax_register_type(L, &Data::type, w_Data_functions, nullptr); - return 0; + int n = luax_register_type(L, &Data::type, w_Data_functions, nullptr); + luax_rundatawrapper(L, Data::type); + return n; } } // data diff -Nru love-11.1/src/modules/data/wrap_Data.h love-11.3/src/modules/data/wrap_Data.h --- love-11.1/src/modules/data/wrap_Data.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_Data.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -29,6 +29,7 @@ namespace data { +void luax_rundatawrapper(lua_State *L, const love::Type &type); Data *luax_checkdata(lua_State *L, int idx); int luaopen_data(lua_State *L); extern const luaL_Reg w_Data_functions[]; diff -Nru love-11.1/src/modules/data/wrap_Data.lua love-11.3/src/modules/data/wrap_Data.lua --- love-11.1/src/modules/data/wrap_Data.lua 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/modules/data/wrap_Data.lua 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,55 @@ +R"luastring"--( +-- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string. +-- There is a matching delimiter at the bottom of the file. + +--[[ +Copyright (c) 2006-2019 LOVE Development Team + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +--]] + +local Data_mt, ffifuncspointer_str = ... +local Data = Data_mt.__index + +local type, error = type, error + +if type(jit) ~= "table" then return end + +local status, ffi = pcall(require, "ffi") +if not status then return end + +pcall(ffi.cdef, [[ +typedef struct Proxy Proxy; + +typedef struct FFI_Data +{ + void *(*getFFIPointer)(Proxy *p); +} FFI_Data; +]]) + +local ffifuncs = ffi.cast("const FFI_Data **", ffifuncspointer_str)[0] + +-- Overwrite placeholder method with the FFI implementation. + +function Data:getFFIPointer() + -- TODO: This should ideally be handled inside the C function + if self == nil then error("bad argument #1 to 'getFFIPointer' (Data expected, got no value)", 2) end + return ffifuncs.getFFIPointer(self) +end + +-- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string. +--)luastring"--" diff -Nru love-11.1/src/modules/data/wrap_DataModule.cpp love-11.3/src/modules/data/wrap_DataModule.cpp --- love-11.1/src/modules/data/wrap_DataModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_DataModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -41,6 +41,8 @@ namespace data { +#define instance() (Module::getInstance(Module::M_DATA)) + ContainerType luax_checkcontainertype(lua_State *L, int idx) { const char *str = luaL_checkstring(L, idx); @@ -60,7 +62,8 @@ if (offset < 0 || size < 0) return luaL_error(L, "DataView offset and size must not be negative."); - DataView *d = DataModule::instance.newDataView(data, (size_t) offset, (size_t) size); + DataView *d; + luax_catchexcept(L, [&]() { d = instance()->newDataView(data, (size_t) offset, (size_t) size); }); luax_pushtype(L, d); d->release(); @@ -89,20 +92,20 @@ return luaL_error(L, "Offset and size arguments must fit within the given Data's size."); const char *bytes = (const char *) data->getData() + offset; - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData(bytes, (size_t) size); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData(bytes, (size_t) size); }); } else if (lua_type(L, 1) == LUA_TSTRING) { size_t size = 0; const char *data = luaL_checklstring(L, 1, &size); - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData(data, size); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData(data, size); }); } else { lua_Integer size = luaL_checkinteger(L, 1); if (size <= 0) return luaL_error(L, "Data size must be a positive number."); - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData((size_t) size); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData((size_t) size); }); } luax_pushtype(L, d); @@ -171,7 +174,7 @@ if (luax_istype(L, 3, Data::type)) { - Data *data = luax_checktype(L, 2); + Data *data = luax_checktype(L, 3); cbytes = (const char *) data->getData(); compressedsize = data->getSize(); } @@ -184,7 +187,7 @@ if (ctype == CONTAINER_DATA) { ByteData *data = nullptr; - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(rawbytes, rawsize, true); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(rawbytes, rawsize, true); }); luax_pushtype(L, Data::type, data); data->release(); } @@ -228,9 +231,9 @@ { ByteData *data = nullptr; if (dst != nullptr) - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(dst, dstlen, true); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(dst, dstlen, true); }); else - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(0); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(0); }); luax_pushtype(L, Data::type, data); data->release(); @@ -277,9 +280,9 @@ { ByteData *data = nullptr; if (dst != nullptr) - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(dst, dstlen, true); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(dst, dstlen, true); }); else - luax_catchexcept(L, [&]() { data = DataModule::instance.newByteData(0); }); + luax_catchexcept(L, [&]() { data = instance()->newByteData(0); }); luax_pushtype(L, Data::type, data); data->release(); @@ -331,7 +334,7 @@ if (ctype == CONTAINER_DATA) { Data *d = nullptr; - luax_catchexcept(L, [&]() { d = DataModule::instance.newByteData(b.nelems); }); + luax_catchexcept(L, [&]() { d = instance()->newByteData(b.nelems); }); memcpy(d->getData(), b.ptr, d->getSize()); lua53_cleanupbuffer(&b); @@ -392,10 +395,16 @@ extern "C" int luaopen_love_data(lua_State *L) { - DataModule::instance.retain(); + DataModule *instance = instance(); + if (instance == nullptr) + { + luax_catchexcept(L, [&](){ instance = new DataModule(); }); + } + else + instance->retain(); WrappedModule w; - w.module = &DataModule::instance; + w.module = instance; w.name = "data"; w.type = &Module::type; w.functions = functions; diff -Nru love-11.1/src/modules/data/wrap_DataModule.h love-11.3/src/modules/data/wrap_DataModule.h --- love-11.1/src/modules/data/wrap_DataModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_DataModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/data/wrap_DataView.cpp love-11.3/src/modules/data/wrap_DataView.cpp --- love-11.1/src/modules/data/wrap_DataView.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_DataView.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -39,6 +39,7 @@ int luaopen_dataview(lua_State *L) { luax_register_type(L, &DataView::type, w_Data_functions, w_DataView_functions, nullptr); + love::data::luax_rundatawrapper(L, DataView::type); return 0; } diff -Nru love-11.1/src/modules/data/wrap_DataView.h love-11.3/src/modules/data/wrap_DataView.h --- love-11.1/src/modules/data/wrap_DataView.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/data/wrap_DataView.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/event/Event.cpp love-11.3/src/modules/event/Event.cpp --- love-11.1/src/modules/event/Event.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/Event.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/event/Event.h love-11.3/src/modules/event/Event.h --- love-11.1/src/modules/event/Event.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/Event.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -49,10 +49,8 @@ int toLua(lua_State *L); static Message *fromLua(lua_State *L, int n); -private: - - std::string name; - std::vector args; + const std::string name; + const std::vector args; }; // Message diff -Nru love-11.1/src/modules/event/sdl/Event.cpp love-11.3/src/modules/event/sdl/Event.cpp --- love-11.1/src/modules/event/sdl/Event.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/sdl/Event.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -369,6 +369,41 @@ case SDL_WINDOWEVENT: msg = convertWindowEvent(e); break; +#if SDL_VERSION_ATLEAST(2, 0, 9) + case SDL_DISPLAYEVENT: + if (e.display.event == SDL_DISPLAYEVENT_ORIENTATION) + { + auto orientation = window::Window::ORIENTATION_UNKNOWN; + switch ((SDL_DisplayOrientation) e.display.data1) + { + case SDL_ORIENTATION_UNKNOWN: + default: + orientation = window::Window::ORIENTATION_UNKNOWN; + break; + case SDL_ORIENTATION_LANDSCAPE: + orientation = window::Window::ORIENTATION_LANDSCAPE; + break; + case SDL_ORIENTATION_LANDSCAPE_FLIPPED: + orientation = window::Window::ORIENTATION_LANDSCAPE_FLIPPED; + break; + case SDL_ORIENTATION_PORTRAIT: + orientation = window::Window::ORIENTATION_PORTRAIT; + break; + case SDL_ORIENTATION_PORTRAIT_FLIPPED: + orientation = window::Window::ORIENTATION_PORTRAIT_FLIPPED; + break; + } + + if (!window::Window::getConstant(orientation, txt)) + txt = "unknown"; + + vargs.emplace_back((double)(e.display.display + 1)); + vargs.emplace_back(txt); + + msg = new Message("displayrotated", vargs); + } + break; +#endif case SDL_DROPFILE: filesystem = Module::getInstance(Module::M_FILESYSTEM); if (filesystem != nullptr) diff -Nru love-11.1/src/modules/event/sdl/Event.h love-11.3/src/modules/event/sdl/Event.h --- love-11.1/src/modules/event/sdl/Event.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/sdl/Event.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/event/wrap_Event.cpp love-11.3/src/modules/event/wrap_Event.cpp --- love-11.1/src/modules/event/wrap_Event.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/wrap_Event.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/event/wrap_Event.h love-11.3/src/modules/event/wrap_Event.h --- love-11.1/src/modules/event/wrap_Event.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/wrap_Event.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/event/wrap_Event.lua love-11.3/src/modules/event/wrap_Event.lua --- love-11.1/src/modules/event/wrap_Event.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/event/wrap_Event.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/DroppedFile.cpp love-11.3/src/modules/filesystem/DroppedFile.cpp --- love-11.1/src/modules/filesystem/DroppedFile.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/DroppedFile.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/DroppedFile.h love-11.3/src/modules/filesystem/DroppedFile.h --- love-11.1/src/modules/filesystem/DroppedFile.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/DroppedFile.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/File.cpp love-11.3/src/modules/filesystem/File.cpp --- love-11.1/src/modules/filesystem/File.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/File.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/FileData.cpp love-11.3/src/modules/filesystem/FileData.cpp --- love-11.1/src/modules/filesystem/FileData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/FileData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/FileData.h love-11.3/src/modules/filesystem/FileData.h --- love-11.1/src/modules/filesystem/FileData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/FileData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/File.h love-11.3/src/modules/filesystem/File.h --- love-11.1/src/modules/filesystem/File.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/File.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/Filesystem.cpp love-11.3/src/modules/filesystem/Filesystem.cpp --- love-11.1/src/modules/filesystem/Filesystem.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/Filesystem.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/Filesystem.h love-11.3/src/modules/filesystem/Filesystem.h --- love-11.1/src/modules/filesystem/Filesystem.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/Filesystem.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/physfs/File.cpp love-11.3/src/modules/filesystem/physfs/File.cpp --- love-11.1/src/modules/filesystem/physfs/File.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/physfs/File.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/physfs/File.h love-11.3/src/modules/filesystem/physfs/File.h --- love-11.1/src/modules/filesystem/physfs/File.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/physfs/File.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/physfs/Filesystem.cpp love-11.3/src/modules/filesystem/physfs/Filesystem.cpp --- love-11.1/src/modules/filesystem/physfs/Filesystem.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/physfs/Filesystem.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/physfs/Filesystem.h love-11.3/src/modules/filesystem/physfs/Filesystem.h --- love-11.1/src/modules/filesystem/physfs/Filesystem.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/physfs/Filesystem.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/wrap_DroppedFile.cpp love-11.3/src/modules/filesystem/wrap_DroppedFile.cpp --- love-11.1/src/modules/filesystem/wrap_DroppedFile.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_DroppedFile.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/wrap_DroppedFile.h love-11.3/src/modules/filesystem/wrap_DroppedFile.h --- love-11.1/src/modules/filesystem/wrap_DroppedFile.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_DroppedFile.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/wrap_File.cpp love-11.3/src/modules/filesystem/wrap_File.cpp --- love-11.1/src/modules/filesystem/wrap_File.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_File.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -132,21 +132,14 @@ return luax_ioError(L, "%s", e.what()); } - int nret = 0; - if (ctype == love::data::CONTAINER_DATA) - { luax_pushtype(L, d.get()); - nret = 1; - } else - { lua_pushlstring(L, (const char *) d->getData(), d->getSize()); - lua_pushinteger(L, d->getSize()); - nret = 2; - } - return nret; + lua_pushinteger(L, d->getSize()); + + return 2; } int w_File_write(lua_State *L) diff -Nru love-11.1/src/modules/filesystem/wrap_FileData.cpp love-11.3/src/modules/filesystem/wrap_FileData.cpp --- love-11.1/src/modules/filesystem/wrap_FileData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_FileData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -66,7 +66,9 @@ extern "C" int luaopen_filedata(lua_State *L) { - return luax_register_type(L, &FileData::type, data::w_Data_functions, w_FileData_functions, nullptr); + int ret = luax_register_type(L, &FileData::type, data::w_Data_functions, w_FileData_functions, nullptr); + love::data::luax_rundatawrapper(L, FileData::type); + return ret; } } // filesystem diff -Nru love-11.1/src/modules/filesystem/wrap_FileData.h love-11.3/src/modules/filesystem/wrap_FileData.h --- love-11.1/src/modules/filesystem/wrap_FileData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_FileData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/wrap_File.h love-11.3/src/modules/filesystem/wrap_File.h --- love-11.1/src/modules/filesystem/wrap_File.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_File.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/filesystem/wrap_Filesystem.cpp love-11.3/src/modules/filesystem/wrap_Filesystem.cpp --- love-11.1/src/modules/filesystem/wrap_Filesystem.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_Filesystem.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -138,6 +138,7 @@ bool append = luax_optboolean(L, startidx + 1, false); luax_pushboolean(L, instance()->mount(data, archive.c_str(), mountpoint, append)); + return 1; } else if (luax_istype(L, 1, DroppedFile::type)) { @@ -213,7 +214,10 @@ file = instance()->newFile(filename); } else + { file = luax_checkfile(L, idx); + file->retain(); + } return file; } @@ -226,7 +230,6 @@ if (lua_isstring(L, idx) || luax_istype(L, idx, File::type)) { file = luax_getfile(L, idx); - file->retain(); } else if (luax_istype(L, idx, FileData::type)) { @@ -259,7 +262,6 @@ if (lua_isstring(L, idx) || luax_istype(L, idx, File::type)) { file = luax_getfile(L, idx); - file->retain(); } else if (luax_istype(L, idx, Data::type)) { @@ -488,24 +490,17 @@ if (data == nullptr) return luax_ioError(L, "File could not be read."); - int nret = 0; - if (ctype == love::data::CONTAINER_DATA) - { luax_pushtype(L, data); - nret = 1; - } else - { lua_pushlstring(L, (const char *) data->getData(), data->getSize()); - lua_pushinteger(L, data->getSize()); - nret = 2; - } + + lua_pushinteger(L, data->getSize()); // Lua has a copy now, so we can free it. data->release(); - return nret; + return 2; } static int w_write_or_append(lua_State *L, File::Mode mode) @@ -727,7 +722,7 @@ int loader(lua_State *L) { - std::string modulename = luax_tostring(L, 1); + std::string modulename = luax_checkstring(L, 1); for (char &c : modulename) { @@ -768,7 +763,7 @@ int extloader(lua_State *L) { - const char *filename = lua_tostring(L, -1); + std::string filename = luax_checkstring(L, 1); std::string tokenized_name(filename); std::string tokenized_function(filename); diff -Nru love-11.1/src/modules/filesystem/wrap_Filesystem.h love-11.3/src/modules/filesystem/wrap_Filesystem.h --- love-11.1/src/modules/filesystem/wrap_Filesystem.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/filesystem/wrap_Filesystem.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/BMFontRasterizer.cpp love-11.3/src/modules/font/BMFontRasterizer.cpp --- love-11.1/src/modules/font/BMFontRasterizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/BMFontRasterizer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/BMFontRasterizer.h love-11.3/src/modules/font/BMFontRasterizer.h --- love-11.1/src/modules/font/BMFontRasterizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/BMFontRasterizer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/Font.cpp love-11.3/src/modules/font/Font.cpp --- love-11.1/src/modules/font/Font.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/Font.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/Font.h love-11.3/src/modules/font/Font.h --- love-11.1/src/modules/font/Font.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/Font.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/freetype/Font.cpp love-11.3/src/modules/font/freetype/Font.cpp --- love-11.1/src/modules/font/freetype/Font.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/freetype/Font.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/freetype/Font.h love-11.3/src/modules/font/freetype/Font.h --- love-11.1/src/modules/font/freetype/Font.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/freetype/Font.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/freetype/TrueTypeRasterizer.cpp love-11.3/src/modules/font/freetype/TrueTypeRasterizer.cpp --- love-11.1/src/modules/font/freetype/TrueTypeRasterizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/freetype/TrueTypeRasterizer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/freetype/TrueTypeRasterizer.h love-11.3/src/modules/font/freetype/TrueTypeRasterizer.h --- love-11.1/src/modules/font/freetype/TrueTypeRasterizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/freetype/TrueTypeRasterizer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/GlyphData.cpp love-11.3/src/modules/font/GlyphData.cpp --- love-11.1/src/modules/font/GlyphData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/GlyphData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/GlyphData.h love-11.3/src/modules/font/GlyphData.h --- love-11.1/src/modules/font/GlyphData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/GlyphData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/ImageRasterizer.cpp love-11.3/src/modules/font/ImageRasterizer.cpp --- love-11.1/src/modules/font/ImageRasterizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/ImageRasterizer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -29,7 +29,7 @@ namespace font { -static_assert(sizeof(Color) == 4, "sizeof(Color) must equal 4 bytes!"); +static_assert(sizeof(Color32) == 4, "sizeof(Color32) must equal 4 bytes!"); ImageRasterizer::ImageRasterizer(love::image::ImageData *data, uint32 *glyphs, int numglyphs, int extraspacing, float dpiscale) : imageData(data) @@ -76,17 +76,17 @@ // We don't want another thread modifying our ImageData mid-copy. love::thread::Lock lock(imageData->getMutex()); - Color *gdpixels = (Color *) g->getData(); - const Color *imagepixels = (const Color *) imageData->getData(); + Color32 *gdpixels = (Color32 *) g->getData(); + const Color32 *imagepixels = (const Color32 *) imageData->getData(); // copy glyph pixels from imagedata to glyphdata for (int i = 0; i < g->getWidth() * g->getHeight(); i++) { - Color p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))]; + Color32 p = imagepixels[it->second.x + (i % gm.width) + (imageData->getWidth() * (i / gm.width))]; // Use transparency instead of the spacer color if (p == spacer) - gdpixels[i] = Color(0, 0, 0, 0); + gdpixels[i] = Color32(0, 0, 0, 0); else gdpixels[i] = p; } @@ -96,7 +96,7 @@ void ImageRasterizer::load() { - const Color *pixels = (const Color *) imageData->getData(); + auto pixels = (const Color32 *) imageData->getData(); int imgw = imageData->getWidth(); int imgh = imageData->getHeight(); diff -Nru love-11.1/src/modules/font/ImageRasterizer.h love-11.3/src/modules/font/ImageRasterizer.h --- love-11.1/src/modules/font/ImageRasterizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/ImageRasterizer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -76,7 +76,7 @@ std::map imageGlyphs; // Color used to identify glyph separation in the source ImageData - Color spacer; + Color32 spacer; }; // ImageRasterizer diff -Nru love-11.1/src/modules/font/Rasterizer.cpp love-11.3/src/modules/font/Rasterizer.cpp --- love-11.1/src/modules/font/Rasterizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/Rasterizer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/Rasterizer.h love-11.3/src/modules/font/Rasterizer.h --- love-11.1/src/modules/font/Rasterizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/Rasterizer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/TrueTypeRasterizer.cpp love-11.3/src/modules/font/TrueTypeRasterizer.cpp --- love-11.1/src/modules/font/TrueTypeRasterizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/TrueTypeRasterizer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/TrueTypeRasterizer.h love-11.3/src/modules/font/TrueTypeRasterizer.h --- love-11.1/src/modules/font/TrueTypeRasterizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/TrueTypeRasterizer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/wrap_Font.cpp love-11.3/src/modules/font/wrap_Font.cpp --- love-11.1/src/modules/font/wrap_Font.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/wrap_Font.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/wrap_Font.h love-11.3/src/modules/font/wrap_Font.h --- love-11.1/src/modules/font/wrap_Font.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/wrap_Font.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/wrap_GlyphData.cpp love-11.3/src/modules/font/wrap_GlyphData.cpp --- love-11.1/src/modules/font/wrap_GlyphData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/wrap_GlyphData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -141,7 +141,9 @@ extern "C" int luaopen_glyphdata(lua_State *L) { - return luax_register_type(L, &GlyphData::type, data::w_Data_functions, w_GlyphData_functions, nullptr); + int ret = luax_register_type(L, &GlyphData::type, data::w_Data_functions, w_GlyphData_functions, nullptr); + love::data::luax_rundatawrapper(L, GlyphData::type); + return ret; } } // font diff -Nru love-11.1/src/modules/font/wrap_GlyphData.h love-11.3/src/modules/font/wrap_GlyphData.h --- love-11.1/src/modules/font/wrap_GlyphData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/wrap_GlyphData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/wrap_Rasterizer.cpp love-11.3/src/modules/font/wrap_Rasterizer.cpp --- love-11.1/src/modules/font/wrap_Rasterizer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/wrap_Rasterizer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/font/wrap_Rasterizer.h love-11.3/src/modules/font/wrap_Rasterizer.h --- love-11.1/src/modules/font/wrap_Rasterizer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/font/wrap_Rasterizer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Buffer.cpp love-11.3/src/modules/graphics/Buffer.cpp --- love-11.1/src/modules/graphics/Buffer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Buffer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Buffer.h love-11.3/src/modules/graphics/Buffer.h --- love-11.1/src/modules/graphics/Buffer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Buffer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Canvas.cpp love-11.3/src/modules/graphics/Canvas.cpp --- love-11.1/src/modules/graphics/Canvas.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Canvas.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -45,8 +45,6 @@ depth = settings.layers; else if (texType == TEXTURE_2D_ARRAY) layers = settings.layers; - else - layers = 1; if (width <= 0 || height <= 0 || layers <= 0) throw love::Exception("Canvas dimensions must be greater than 0."); @@ -139,26 +137,15 @@ if (gfx != nullptr && gfx->isCanvasActive(this)) throw love::Exception("Canvas:newImageData cannot be called while that Canvas is currently active."); - PixelFormat dataformat; - switch (getPixelFormat()) - { - case PIXELFORMAT_RGB10A2: // FIXME: Conversions aren't supported in GLES - dataformat = PIXELFORMAT_RGBA16; - break; - case PIXELFORMAT_R16F: - case PIXELFORMAT_RG16F: - case PIXELFORMAT_RGBA16F: - case PIXELFORMAT_RG11B10F: // FIXME: Conversions aren't supported in GLES - dataformat = PIXELFORMAT_RGBA16F; - break; - case PIXELFORMAT_R32F: - case PIXELFORMAT_RG32F: - case PIXELFORMAT_RGBA32F: - dataformat = PIXELFORMAT_RGBA32F; - break; - default: + PixelFormat dataformat = getPixelFormat(); + if (dataformat == PIXELFORMAT_sRGBA8) dataformat = PIXELFORMAT_RGBA8; - break; + + if (!image::ImageData::validPixelFormat(dataformat)) + { + const char *formatname = "unknown"; + love::getConstant(dataformat, formatname); + throw love::Exception("ImageData with the '%s' pixel format is not supported.", formatname); } return module->newImageData(r.w, r.h, dataformat); diff -Nru love-11.1/src/modules/graphics/Canvas.h love-11.3/src/modules/graphics/Canvas.h --- love-11.1/src/modules/graphics/Canvas.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Canvas.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** -* Copyright (c) 2006-2018 LOVE Development Team +* Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Deprecations.cpp love-11.3/src/modules/graphics/Deprecations.cpp --- love-11.1/src/modules/graphics/Deprecations.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Deprecations.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Deprecations.h love-11.3/src/modules/graphics/Deprecations.h --- love-11.1/src/modules/graphics/Deprecations.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Deprecations.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/depthstencil.cpp love-11.3/src/modules/graphics/depthstencil.cpp --- love-11.1/src/modules/graphics/depthstencil.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/depthstencil.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/depthstencil.h love-11.3/src/modules/graphics/depthstencil.h --- love-11.1/src/modules/graphics/depthstencil.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/depthstencil.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Drawable.cpp love-11.3/src/modules/graphics/Drawable.cpp --- love-11.1/src/modules/graphics/Drawable.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Drawable.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Drawable.h love-11.3/src/modules/graphics/Drawable.h --- love-11.1/src/modules/graphics/Drawable.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Drawable.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Font.cpp love-11.3/src/modules/graphics/Font.cpp --- love-11.1/src/modules/graphics/Font.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Font.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** -* Copyright (c) 2006-2018 LOVE Development Team +* Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -152,12 +152,24 @@ image = gfx->newImage(TEXTURE_2D, pixelFormat, size.width, size.height, 1, settings); image->setFilter(filter); - // Initialize the texture with transparent black. - size_t bpp = getPixelFormatSize(pixelFormat); - std::vector emptydata(size.width * size.height * bpp, 0); + { + size_t bpp = getPixelFormatSize(pixelFormat); + size_t pixelcount = size.width * size.height; + + // Initialize the texture with transparent white for Luminance-Alpha + // formats (since we keep luminance constant and vary alpha in those + // glyphs), and transparent black otherwise. + std::vector emptydata(pixelcount * bpp, 0); + + if (pixelFormat == PIXELFORMAT_LA8) + { + for (size_t i = 0; i < pixelcount; i++) + emptydata[i * 2 + 0] = 255; + } - Rect rect = {0, 0, size.width, size.height}; - image->replacePixels(emptydata.data(), emptydata.size(), 0, 0, rect, false); + Rect rect = {0, 0, size.width, size.height}; + image->replacePixels(emptydata.data(), emptydata.size(), 0, 0, rect, false); + } images.emplace_back(image, Acquire::NORETAIN); @@ -263,7 +275,7 @@ double tX = (double) textureX, tY = (double) textureY; double tWidth = (double) textureWidth, tHeight = (double) textureHeight; - Color c(255, 255, 255, 255); + Color32 c(255, 255, 255, 255); // Extrude the quad borders by 1 pixel. We have an extra pixel of // transparent padding in the texture atlas, so the quad extrusion will @@ -409,7 +421,7 @@ Colorf linearconstantcolor = gammaCorrectColor(constantcolor); - Color curcolor = toColor(constantcolor); + Color32 curcolor = toColor32(constantcolor); int curcolori = -1; int ncolors = (int) codepoints.colors.size(); @@ -430,7 +442,7 @@ c *= linearconstantcolor; unGammaCorrectColor(c); - curcolor = toColor(c); + curcolor = toColor32(c); } if (g == '\n') @@ -456,7 +468,7 @@ // If findGlyph invalidates the texture cache, re-start the loop. if (cacheid != textureCacheID) { - i = 0; + i = -1; // The next iteration will increment this to 0. maxwidth = 0; dx = offset.x; dy = offset.y; @@ -464,7 +476,7 @@ vertices.resize(vertstartsize); prevglyph = 0; curcolori = -1; - curcolor = toColor(constantcolor); + curcolor = toColor32(constantcolor); continue; } diff -Nru love-11.1/src/modules/graphics/Font.h love-11.3/src/modules/graphics/Font.h --- love-11.1/src/modules/graphics/Font.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Font.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Graphics.cpp love-11.3/src/modules/graphics/Graphics.cpp --- love-11.1/src/modules/graphics/Graphics.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Graphics.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -1122,7 +1122,7 @@ return; Attributes attributes; - Buffers buffers; + BufferBindings buffers; size_t usedsizes[3] = {0, 0, 0}; @@ -1140,7 +1140,7 @@ sbstate.vbMap[i] = StreamBuffer::MapInfo(); } - if (attributes.enablebits == 0) + if (attributes.enableBits == 0) return; Colorf nc = getColor(); @@ -1275,7 +1275,7 @@ else t.transformXY0((Vector3 *) data.stream[0], positions, cmd.vertexCount); - Color *colordata = (Color *) data.stream[1]; + Color32 *colordata = (Color32 *) data.stream[1]; if (colors) { @@ -1290,18 +1290,18 @@ gammaCorrectColor(ci); ci *= nc; unGammaCorrectColor(ci); - colordata[i] = toColor(ci); + colordata[i] = toColor32(ci); } } else { for (int i = 0; i < cmd.vertexCount; i++) - colordata[i] = toColor(nc * colors[i]); + colordata[i] = toColor32(nc * colors[i]); } } else { - Color c = toColor(getColor()); + Color32 c = toColor32(getColor()); for (int i = 0; i < cmd.vertexCount; i++) colordata[i] = c; @@ -1571,8 +1571,8 @@ else t.transformXY0((Vector3 *) data.stream[0], coords, cmd.vertexCount); - Color c = toColor(getColor()); - Color *colordata = (Color *) data.stream[1]; + Color32 c = toColor32(getColor()); + Color32 *colordata = (Color32 *) data.stream[1]; for (int i = 0; i < cmd.vertexCount; i++) colordata[i] = c; } diff -Nru love-11.1/src/modules/graphics/Graphics.h love-11.3/src/modules/graphics/Graphics.h --- love-11.1/src/modules/graphics/Graphics.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Graphics.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -255,7 +255,7 @@ PrimitiveType primitiveType = PRIMITIVE_TRIANGLES; const vertex::Attributes *attributes; - const vertex::Buffers *buffers; + const vertex::BufferBindings *buffers; int vertexStart = 0; int vertexCount = 0; @@ -266,7 +266,7 @@ // TODO: This should be moved out to a state transition API? CullMode cullMode = CULL_NONE; - DrawCommand(const vertex::Attributes *attribs, const vertex::Buffers *buffers) + DrawCommand(const vertex::Attributes *attribs, const vertex::BufferBindings *buffers) : attributes(attribs) , buffers(buffers) {} @@ -277,7 +277,7 @@ PrimitiveType primitiveType = PRIMITIVE_TRIANGLES; const vertex::Attributes *attributes; - const vertex::Buffers *buffers; + const vertex::BufferBindings *buffers; int indexCount = 0; int instanceCount = 1; @@ -291,7 +291,7 @@ // TODO: This should be moved out to a state transition API? CullMode cullMode = CULL_NONE; - DrawIndexedCommand(const vertex::Attributes *attribs, const vertex::Buffers *buffers, Resource *indexbuffer) + DrawIndexedCommand(const vertex::Attributes *attribs, const vertex::BufferBindings *buffers, Resource *indexbuffer) : attributes(attribs) , buffers(buffers) , indexBuffer(indexbuffer) @@ -371,6 +371,7 @@ RenderTarget() : canvas(nullptr) , slice(0) + , mipmap(0) {} bool operator != (const RenderTarget &other) const @@ -829,7 +830,7 @@ **/ virtual bool isCanvasFormatSupported(PixelFormat format) const = 0; virtual bool isCanvasFormatSupported(PixelFormat format, bool readable) const = 0; - virtual bool isImageFormatSupported(PixelFormat format) const = 0; + virtual bool isImageFormatSupported(PixelFormat format, bool sRGB = false) const = 0; /** * Gets the renderer used by love.graphics. @@ -869,7 +870,7 @@ virtual void draw(const DrawCommand &cmd) = 0; virtual void draw(const DrawIndexedCommand &cmd) = 0; - virtual void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::Buffers &buffers, Texture *texture) = 0; + virtual void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, Texture *texture) = 0; void flushStreamDraws(); StreamVertexData requestStreamDraw(const StreamDrawCommand &command); diff -Nru love-11.1/src/modules/graphics/Image.cpp love-11.3/src/modules/graphics/Image.cpp --- love-11.1/src/modules/graphics/Image.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Image.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -43,8 +43,6 @@ { if (validatedata && data.validate() == MIPMAPS_DATA) mipmapsType = MIPMAPS_DATA; - - ++imageCount; } Image::Image(TextureType textype, PixelFormat format, int width, int height, int slices, const Settings &settings) @@ -80,6 +78,19 @@ void Image::init(PixelFormat fmt, int w, int h, const Settings &settings) { + Graphics *gfx = Module::getInstance(Module::M_GRAPHICS); + if (gfx != nullptr && !gfx->isImageFormatSupported(fmt, sRGB)) + { + const char *str; + if (love::getConstant(fmt, str)) + { + throw love::Exception("Cannot create image: " + "%s%s images are not supported on this system.", sRGB ? "sRGB " : "", str); + } + else + throw love::Exception("cannot create image: format is not supported on this system."); + } + pixelWidth = w; pixelHeight = h; @@ -97,6 +108,8 @@ filter.mipmap = defaultMipmapFilter; initQuad(); + + ++imageCount; } void Image::uploadImageData(love::image::ImageDataBase *d, int level, int slice, int x, int y) diff -Nru love-11.1/src/modules/graphics/Image.h love-11.3/src/modules/graphics/Image.h --- love-11.1/src/modules/graphics/Image.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Image.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Mesh.cpp love-11.3/src/modules/graphics/Mesh.cpp --- love-11.1/src/modules/graphics/Mesh.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Mesh.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -34,7 +34,7 @@ namespace graphics { -static const char *getBuiltinAttribName(VertexAttribID attribid) +static const char *getBuiltinAttribName(BuiltinVertexAttribute attribid) { const char *name = ""; vertex::getConstant(attribid, name); @@ -61,10 +61,10 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage) : vertexFormat(vertexformat) - , vbo(nullptr) + , vertexBuffer(nullptr) , vertexCount(0) , vertexStride(0) - , ibo(nullptr) + , indexBuffer(nullptr) , useIndexBuffer(false) , indexCount(0) , indexDataType(INDEX_UINT16) @@ -81,17 +81,17 @@ if (vertexCount == 0) throw love::Exception("Data size is too small for specified vertex attribute formats."); - vbo = gfx->newBuffer(datasize, data, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); + vertexBuffer = gfx->newBuffer(datasize, data, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); vertexScratchBuffer = new char[vertexStride]; } Mesh::Mesh(graphics::Graphics *gfx, const std::vector &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage) : vertexFormat(vertexformat) - , vbo(nullptr) + , vertexBuffer(nullptr) , vertexCount((size_t) vertexcount) , vertexStride(0) - , ibo(nullptr) + , indexBuffer(nullptr) , useIndexBuffer(false) , indexCount(0) , indexDataType(vertex::getIndexDataTypeFromMax(vertexcount)) @@ -107,20 +107,20 @@ size_t buffersize = vertexCount * vertexStride; - vbo = gfx->newBuffer(buffersize, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); + vertexBuffer = gfx->newBuffer(buffersize, nullptr, BUFFER_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ); // Initialize the buffer's contents to 0. - memset(vbo->map(), 0, buffersize); - vbo->setMappedRangeModified(0, vbo->getSize()); - vbo->unmap(); + memset(vertexBuffer->map(), 0, buffersize); + vertexBuffer->setMappedRangeModified(0, vertexBuffer->getSize()); + vertexBuffer->unmap(); vertexScratchBuffer = new char[vertexStride]; } Mesh::~Mesh() { - delete vbo; - delete ibo; + delete vertexBuffer; + delete indexBuffer; delete vertexScratchBuffer; for (const auto &attrib : attachedAttributes) @@ -184,10 +184,10 @@ size_t offset = vertindex * vertexStride; size_t size = std::min(datasize, vertexStride); - uint8 *bufferdata = (uint8 *) vbo->map(); + uint8 *bufferdata = (uint8 *) vertexBuffer->map(); memcpy(bufferdata + offset, data, size); - vbo->setMappedRangeModified(offset, size); + vertexBuffer->setMappedRangeModified(offset, size); } size_t Mesh::getVertex(size_t vertindex, void *data, size_t datasize) @@ -198,8 +198,8 @@ size_t offset = vertindex * vertexStride; size_t size = std::min(datasize, vertexStride); - // We're relying on vbo->map() returning read/write data... ew. - const uint8 *bufferdata = (const uint8 *) vbo->map(); + // We're relying on map() returning read/write data... ew. + const uint8 *bufferdata = (const uint8 *) vertexBuffer->map(); memcpy(data, bufferdata + offset, size); return size; @@ -221,10 +221,10 @@ size_t offset = vertindex * vertexStride + getAttributeOffset(attribindex); size_t size = std::min(datasize, attributeSizes[attribindex]); - uint8 *bufferdata = (uint8 *) vbo->map(); + uint8 *bufferdata = (uint8 *) vertexBuffer->map(); memcpy(bufferdata + offset, data, size); - vbo->setMappedRangeModified(offset, size); + vertexBuffer->setMappedRangeModified(offset, size); } size_t Mesh::getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize) @@ -238,8 +238,8 @@ size_t offset = vertindex * vertexStride + getAttributeOffset(attribindex); size_t size = std::min(datasize, attributeSizes[attribindex]); - // We're relying on vbo->map() returning read/write data... ew. - const uint8 *bufferdata = (const uint8 *) vbo->map(); + // We're relying on map() returning read/write data... ew. + const uint8 *bufferdata = (const uint8 *) vertexBuffer->map(); memcpy(data, bufferdata + offset, size); return size; @@ -363,21 +363,21 @@ void *Mesh::mapVertexData() { - return vbo->map(); + return vertexBuffer->map(); } void Mesh::unmapVertexData(size_t modifiedoffset, size_t modifiedsize) { - vbo->setMappedRangeModified(modifiedoffset, modifiedsize); - vbo->unmap(); + vertexBuffer->setMappedRangeModified(modifiedoffset, modifiedsize); + vertexBuffer->unmap(); } void Mesh::flush() { - vbo->unmap(); + vertexBuffer->unmap(); - if (ibo != nullptr) - ibo->unmap(); + if (indexBuffer != nullptr) + indexBuffer->unmap(); } /** @@ -406,25 +406,25 @@ // Calculate the size in bytes of the index buffer data. size_t size = map.size() * vertex::getIndexDataSize(datatype); - if (ibo && size > ibo->getSize()) + if (indexBuffer && size > indexBuffer->getSize()) { - delete ibo; - ibo = nullptr; + delete indexBuffer; + indexBuffer = nullptr; } - if (!ibo && size > 0) + if (!indexBuffer && size > 0) { auto gfx = Module::getInstance(Module::M_GRAPHICS); - ibo = gfx->newBuffer(size, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ); + indexBuffer = gfx->newBuffer(size, nullptr, BUFFER_INDEX, vertexBuffer->getUsage(), Buffer::MAP_READ); } useIndexBuffer = true; indexCount = map.size(); - if (!ibo || indexCount == 0) + if (!indexBuffer || indexCount == 0) return; - Buffer::Mapper ibomap(*ibo); + Buffer::Mapper ibomap(*indexBuffer); // Fill the buffer with the index values from the vector. switch (datatype) @@ -443,24 +443,24 @@ void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize) { - if (ibo && datasize > ibo->getSize()) + if (indexBuffer && datasize > indexBuffer->getSize()) { - delete ibo; - ibo = nullptr; + delete indexBuffer; + indexBuffer = nullptr; } - if (!ibo && datasize > 0) + if (!indexBuffer && datasize > 0) { auto gfx = Module::getInstance(Module::M_GRAPHICS); - ibo = gfx->newBuffer(datasize, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ); + indexBuffer = gfx->newBuffer(datasize, nullptr, BUFFER_INDEX, vertexBuffer->getUsage(), Buffer::MAP_READ); } indexCount = datasize / vertex::getIndexDataSize(datatype); - if (!ibo || indexCount == 0) + if (!indexBuffer || indexCount == 0) return; - Buffer::Mapper ibomap(*ibo); + Buffer::Mapper ibomap(*indexBuffer); memcpy(ibomap.get(), data, datasize); useIndexBuffer = true; @@ -491,11 +491,11 @@ map.clear(); map.reserve(indexCount); - if (!ibo || indexCount == 0) + if (!indexBuffer || indexCount == 0) return true; // We unmap the buffer in Mesh::draw, Mesh::setVertexMap, and Mesh::flush. - void *buffer = ibo->map(); + void *buffer = indexBuffer->map(); // Fill the vector from the buffer. switch (indexDataType) @@ -588,7 +588,7 @@ Shader::current->checkMainTexture(texture); vertex::Attributes attributes; - vertex::Buffers buffers; + vertex::BufferBindings buffers; int activebuffers = 0; @@ -602,7 +602,7 @@ // If the attribute is one of the LOVE-defined ones, use the constant // attribute index for it, otherwise query the index from the shader. - VertexAttribID builtinattrib; + BuiltinVertexAttribute builtinattrib; if (vertex::getConstant(attrib.first.c_str(), builtinattrib)) attributeindex = (int) builtinattrib; else if (Shader::current) @@ -611,7 +611,7 @@ if (attributeindex >= 0) { // Make sure the buffer isn't mapped (sends data to GPU if needed.) - mesh->vbo->unmap(); + mesh->vertexBuffer->unmap(); const auto &formats = mesh->getVertexFormat(); const auto &format = formats[attrib.second.index]; @@ -619,10 +619,11 @@ uint16 offset = (uint16) mesh->getAttributeOffset(attrib.second.index); uint16 stride = (uint16) mesh->getVertexStride(); - attributes.set(attributeindex, format.type, format.components, offset, stride, activebuffers, attrib.second.step); + attributes.set(attributeindex, format.type, (uint8) format.components, offset, activebuffers); + attributes.setBufferLayout(activebuffers, stride, attrib.second.step); // TODO: Ideally we want to reuse buffers with the same stride+step. - buffers.set(activebuffers, mesh->vbo, 0); + buffers.set(activebuffers, mesh->vertexBuffer, 0); activebuffers++; } } @@ -633,12 +634,12 @@ Graphics::TempTransform transform(gfx, m); - if (useIndexBuffer && ibo != nullptr && indexCount > 0) + if (useIndexBuffer && indexBuffer != nullptr && indexCount > 0) { // Make sure the index buffer isn't mapped (sends data to GPU if needed.) - ibo->unmap(); + indexBuffer->unmap(); - Graphics::DrawIndexedCommand cmd(&attributes, &buffers, ibo); + Graphics::DrawIndexedCommand cmd(&attributes, &buffers, indexBuffer); cmd.primitiveType = primitiveType; cmd.indexType = indexDataType; diff -Nru love-11.1/src/modules/graphics/Mesh.h love-11.3/src/modules/graphics/Mesh.h --- love-11.1/src/modules/graphics/Mesh.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Mesh.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -196,7 +196,7 @@ std::unordered_map attachedAttributes; // Vertex buffer, for the vertex data. - Buffer *vbo; + Buffer *vertexBuffer; size_t vertexCount; size_t vertexStride; @@ -205,7 +205,7 @@ char *vertexScratchBuffer; // Index buffer, for the vertex map. - Buffer *ibo; + Buffer *indexBuffer; bool useIndexBuffer; size_t indexCount; IndexDataType indexDataType; diff -Nru love-11.1/src/modules/graphics/opengl/Buffer.cpp love-11.3/src/modules/graphics/opengl/Buffer.cpp --- love-11.1/src/modules/graphics/opengl/Buffer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Buffer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/opengl/Buffer.h love-11.3/src/modules/graphics/opengl/Buffer.h --- love-11.1/src/modules/graphics/opengl/Buffer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Buffer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/opengl/Canvas.cpp love-11.3/src/modules/graphics/opengl/Canvas.cpp --- love-11.1/src/modules/graphics/opengl/Canvas.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Canvas.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -41,6 +41,17 @@ if (texture != 0) { + if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0)) + { + // glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3. + GLenum none = GL_NONE; + if (GLAD_ES_VERSION_3_0) + glDrawBuffers(1, &none); + else + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + bool unusedSRGB = false; OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, unusedSRGB); @@ -109,6 +120,17 @@ glGenFramebuffers(1, &fbo); gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo); + if (isPixelFormatDepthStencil(pixelformat) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0)) + { + // glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3. + GLenum none = GL_NONE; + if (GLAD_ES_VERSION_3_0) + glDrawBuffers(1, &none); + else + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + glGenRenderbuffers(1, &buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer); @@ -590,6 +612,15 @@ return supported; } +void Canvas::resetFormatSupport() +{ + for (int i = 0; i < (int)PIXELFORMAT_MAX_ENUM; i++) + { + checkedFormats[i].readable = false; + checkedFormats[i].nonreadable = false; + } +} + } // opengl } // graphics } // love diff -Nru love-11.1/src/modules/graphics/opengl/Canvas.h love-11.3/src/modules/graphics/opengl/Canvas.h --- love-11.1/src/modules/graphics/opengl/Canvas.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Canvas.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -66,11 +66,6 @@ return renderbuffer != 0 ? renderbuffer : texture; } - inline GLenum getStatus() const - { - return status; - } - inline GLuint getFBO() const { return fbo; @@ -81,6 +76,7 @@ static bool isMultiFormatMultiCanvasSupported(); static bool isFormatSupported(PixelFormat format, bool readable); static bool isFormatSupported(PixelFormat format); + static void resetFormatSupport(); private: diff -Nru love-11.1/src/modules/graphics/opengl/FenceSync.cpp love-11.3/src/modules/graphics/opengl/FenceSync.cpp --- love-11.1/src/modules/graphics/opengl/FenceSync.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/FenceSync.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/opengl/FenceSync.h love-11.3/src/modules/graphics/opengl/FenceSync.h --- love-11.1/src/modules/graphics/opengl/FenceSync.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/FenceSync.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -38,7 +38,7 @@ { public: - FenceSync() {} + FenceSync() : sync(0) {} ~FenceSync(); bool fence(); diff -Nru love-11.1/src/modules/graphics/opengl/Graphics.cpp love-11.3/src/modules/graphics/opengl/Graphics.cpp --- love-11.1/src/modules/graphics/opengl/Graphics.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Graphics.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -59,6 +59,7 @@ , mainVAO(0) { gl = OpenGL(); + Canvas::resetFormatSupport(); auto window = getInstance(M_WINDOW); @@ -342,7 +343,7 @@ ++drawCalls; } -static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::Buffers &buffers, int vertexcount) +static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::BufferBindings &buffers, int vertexcount) { // TODO: Figure out a better way to avoid touching the same buffer multiple // times, if multiple attributes share the buffer. @@ -355,16 +356,17 @@ auto &attrib = attributes.attribs[i]; - uint32 bufferbit = 1u << attrib.bufferindex; + uint32 bufferbit = 1u << attrib.bufferIndex; if ((touchedbuffers & bufferbit) == 0) { touchedbuffers |= bufferbit; - buffers.info[attrib.bufferindex].offset += attrib.stride * vertexcount; + const auto &layout = attributes.bufferLayouts[attrib.bufferIndex]; + buffers.info[attrib.bufferIndex].offset += layout.stride * vertexcount; } } } -void Graphics::drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::Buffers &buffers, love::graphics::Texture *texture) +void Graphics::drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, love::graphics::Texture *texture) { const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX; const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4; @@ -393,7 +395,7 @@ } else { - vertex::Buffers bufferscopy = buffers; + vertex::BufferBindings bufferscopy = buffers; if (start > 0) advanceVertexOffsets(attributes, bufferscopy, start * 4); @@ -820,6 +822,7 @@ else { int msaa = targets.getFirstTarget().canvas->getMSAA(); + bool hasDS = targets.depthStencil.canvas != nullptr; glGenFramebuffers(1, &fbo); gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo); @@ -864,11 +867,21 @@ for (const auto &rt : targets.colors) attachCanvas(rt); - if (targets.depthStencil.canvas != nullptr) + if (hasDS) attachCanvas(targets.depthStencil); if (ncolortargets > 1) glDrawBuffers(ncolortargets, drawbuffers); + else if (ncolortargets == 0 && hasDS && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0)) + { + // glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3. + GLenum none = GL_NONE; + if (GLAD_ES_VERSION_3_0) + glDrawBuffers(1, &none); + else + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); @@ -1397,9 +1410,9 @@ return Canvas::isFormatSupported(format, readable); } -bool Graphics::isImageFormatSupported(PixelFormat format) const +bool Graphics::isImageFormatSupported(PixelFormat format, bool sRGB) const { - return Image::isFormatSupported(format); + return Image::isFormatSupported(format, sRGB); } Shader::Language Graphics::getShaderLanguageTarget() const diff -Nru love-11.1/src/modules/graphics/opengl/Graphics.h love-11.3/src/modules/graphics/opengl/Graphics.h --- love-11.1/src/modules/graphics/opengl/Graphics.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Graphics.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,7 @@ void draw(const DrawCommand &cmd) override; void draw(const DrawIndexedCommand &cmd) override; - void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::Buffers &buffers, Texture *texture) override; + void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, Texture *texture) override; void clear(OptionalColorf color, OptionalInt stencil, OptionalDouble depth) override; void clear(const std::vector &colors, OptionalInt stencil, OptionalDouble depth) override; @@ -106,7 +106,7 @@ bool isCanvasFormatSupported(PixelFormat format) const override; bool isCanvasFormatSupported(PixelFormat format, bool readable) const override; - bool isImageFormatSupported(PixelFormat format) const override; + bool isImageFormatSupported(PixelFormat format, bool sRGB) const override; Renderer getRenderer() const override; RendererInfo getRendererInfo() const override; diff -Nru love-11.1/src/modules/graphics/opengl/Image.cpp love-11.3/src/modules/graphics/opengl/Image.cpp --- love-11.1/src/modules/graphics/opengl/Image.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Image.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -185,22 +185,8 @@ OpenGL::TempDebugGroup debuggroup("Image load"); - if (!OpenGL::isPixelFormatSupported(format, false, true, sRGB)) - { - const char *str; - if (love::getConstant(format, str)) - { - throw love::Exception("Cannot create image: " - "%s%s images are not supported on this system.", sRGB ? "sRGB " : "", str); - } - else - throw love::Exception("cannot create image: format is not supported on this system."); - } - else if (!isCompressed()) + if (!isCompressed()) { - if (sRGB && !hasSRGBSupport()) - throw love::Exception("sRGB images are not supported on this system."); - // GL_EXT_sRGB doesn't support glGenerateMipmap for sRGB textures. if (sRGB && (GLAD_ES_VERSION_2_0 && GLAD_EXT_sRGB && !GLAD_ES_VERSION_3_0) && mipmapsType != MIPMAPS_DATA) @@ -365,14 +351,9 @@ return true; } -bool Image::isFormatSupported(PixelFormat pixelformat) -{ - return OpenGL::isPixelFormatSupported(pixelformat, false, true, false); -} - -bool Image::hasSRGBSupport() +bool Image::isFormatSupported(PixelFormat pixelformat, bool sRGB) { - return GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB; + return OpenGL::isPixelFormatSupported(pixelformat, false, true, sRGB); } } // opengl diff -Nru love-11.1/src/modules/graphics/opengl/Image.h love-11.3/src/modules/graphics/opengl/Image.h --- love-11.1/src/modules/graphics/opengl/Image.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Image.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -54,8 +54,7 @@ bool setMipmapSharpness(float sharpness) override; - static bool isFormatSupported(PixelFormat pixelformat); - static bool hasSRGBSupport(); + static bool isFormatSupported(PixelFormat pixelformat, bool sRGB); private: diff -Nru love-11.1/src/modules/graphics/opengl/OpenGL.cpp love-11.3/src/modules/graphics/opengl/OpenGL.cpp --- love-11.1/src/modules/graphics/opengl/OpenGL.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/OpenGL.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,6 +23,7 @@ #include "OpenGL.h" #include "Shader.h" +#include "Canvas.h" #include "common/Exception.h" #include "graphics/Graphics.h" @@ -156,6 +157,18 @@ } #endif +#ifdef LOVE_WINDOWS + if (getVendor() == VENDOR_AMD) + { + // Radeon HD drivers switched from "ATI Radeon" to "AMD Radeon" around + // the 7000 series. We'll assume this bug doesn't affect those newer + // GPUs / drivers. + const char *device = (const char *) glGetString(GL_RENDERER); + if (strstr(device, "ATI Radeon HD ") || strstr(device, "ATI Mobility Radeon HD")) + bugs.texStorageBreaksSubImage = true; + } +#endif + contextInitialized = true; return true; @@ -176,13 +189,9 @@ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxvertexattribs); state.enabledAttribArrays = (uint32) ((1ull << uint32(maxvertexattribs)) - 1); + state.instancedAttribArrays = 0; - if (GLAD_ES_VERSION_3_0 || isCoreProfile()) - state.instancedAttribArrays = state.enabledAttribArrays; - else - state.instancedAttribArrays = 0; - - setVertexAttributes(vertex::Attributes(), vertex::Buffers()); + setVertexAttributes(vertex::Attributes(), vertex::BufferBindings()); // Get the current viewport. glGetIntegerv(GL_VIEWPORT, (GLint *) &state.viewport.x); @@ -252,6 +261,13 @@ createDefaultTexture(); contextInitialized = true; + +#ifdef LOVE_ANDROID + // This can't be done in initContext with the rest of the bug checks because + // Canvas::isFormatSupported relies on state initialized here / after init. + if (GLAD_ES_VERSION_3_0 && !Canvas::isFormatSupported(PIXELFORMAT_R8)) + bugs.brokenR8PixelFormat = true; +#endif } void OpenGL::deInitContext() @@ -282,7 +298,7 @@ // http://feedback.wildfiregames.com/report/opengl/feature/GL_VENDOR // http://stackoverflow.com/questions/2093594/opengl-extensions-available-on-different-android-devices - // http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_VENDOR + // https://opengl.gpuinfo.org/displaycapability.php?name=GL_VENDOR if (strstr(vstr, "ATI Technologies") || strstr(vstr, "AMD") || strstr(vstr, "Advanced Micro Devices")) vendor = VENDOR_AMD; else if (strstr(vstr, "NVIDIA")) @@ -677,49 +693,60 @@ } } -void OpenGL::setVertexAttributes(const vertex::Attributes &attributes, const vertex::Buffers &buffers) +void OpenGL::setVertexAttributes(const vertex::Attributes &attributes, const vertex::BufferBindings &buffers) { - uint32 enablediff = attributes.enablebits ^ state.enabledAttribArrays; - uint32 instancediff = attributes.instancebits ^ state.instancedAttribArrays; + uint32 enablediff = attributes.enableBits ^ state.enabledAttribArrays; + uint32 instanceattribbits = 0; + uint32 allbits = attributes.enableBits | state.enabledAttribArrays; - for (uint32 i = 0; i < vertex::Attributes::MAX; i++) + uint32 i = 0; + while (allbits) { uint32 bit = 1u << i; if (enablediff & bit) { - if (attributes.enablebits & bit) + if (attributes.enableBits & bit) glEnableVertexAttribArray(i); else glDisableVertexAttribArray(i); } - if (instancediff & bit) - glVertexAttribDivisor(i, (attributes.instancebits & bit) != 0 ? 1 : 0); - - if (attributes.enablebits & bit) + if (attributes.enableBits & bit) { const auto &attrib = attributes.attribs[i]; - const auto &bufferinfo = buffers.info[attrib.bufferindex]; + const auto &layout = attributes.bufferLayouts[attrib.bufferIndex]; + const auto &bufferinfo = buffers.info[attrib.bufferIndex]; + + uint32 bufferbit = 1u << attrib.bufferIndex; + uint32 divisor = (attributes.instanceBits & bufferbit) != 0 ? 1 : 0; + uint32 divisorbit = divisor << i; + instanceattribbits |= divisorbit; + + if ((state.instancedAttribArrays & bit) ^ divisorbit) + glVertexAttribDivisor(i, divisor); GLboolean normalized = GL_FALSE; GLenum gltype = getGLVertexDataType(attrib.type, normalized); - const void *offsetpointer = reinterpret_cast(bufferinfo.offset + attrib.offsetfromvertex); + const void *offsetpointer = reinterpret_cast(bufferinfo.offset + attrib.offsetFromVertex); bindBuffer(BUFFER_VERTEX, (GLuint) bufferinfo.buffer->getHandle()); - glVertexAttribPointer(i, attrib.components, gltype, normalized, attrib.stride, offsetpointer); + glVertexAttribPointer(i, attrib.components, gltype, normalized, layout.stride, offsetpointer); } + + i++; + allbits >>= 1; } - state.enabledAttribArrays = attributes.enablebits; - state.instancedAttribArrays = attributes.instancebits; + state.enabledAttribArrays = attributes.enableBits; + state.instancedAttribArrays = instanceattribbits | (state.instancedAttribArrays & (~attributes.enableBits)); // glDisableVertexAttribArray will make the constant value for a vertex // attribute undefined. We rely on the per-vertex color attribute being // white when no per-vertex color is used, so we set it here. // FIXME: Is there a better place to do this? - if ((enablediff & ATTRIBFLAG_COLOR) && !(attributes.enablebits & ATTRIBFLAG_COLOR)) + if ((enablediff & ATTRIBFLAG_COLOR) && !(attributes.enableBits & ATTRIBFLAG_COLOR)) glVertexAttrib4f(ATTRIB_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); } @@ -1168,6 +1195,9 @@ supportsTexStorage = true; #endif + if (gl.bugs.texStorageBreaksSubImage) + supportsTexStorage = false; + return supportsTexStorage; } @@ -1300,7 +1330,8 @@ switch (pixelformat) { case PIXELFORMAT_R8: - if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg) + if ((GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg) + && !gl.bugs.brokenR8PixelFormat) { f.internalformat = GL_R8; f.externalformat = GL_RED; @@ -1630,7 +1661,7 @@ break; default: - printf("Unhandled pixel format when converting to OpenGL enums!"); + printf("Unhandled pixel format %d when converting to OpenGL enums!", pixelformat); break; } @@ -1690,7 +1721,9 @@ if (rendertarget) return false; else - return (GLAD_VERSION_1_1 && GLAD_EXT_texture_rg) || (GLAD_EXT_texture_norm16 && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg)); + return GLAD_VERSION_3_0 + || (GLAD_VERSION_1_1 && GLAD_ARB_texture_rg) + || (GLAD_EXT_texture_norm16 && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg)); case PIXELFORMAT_RGBA16: if (rendertarget) return false; diff -Nru love-11.1/src/modules/graphics/opengl/OpenGL.h love-11.3/src/modules/graphics/opengl/OpenGL.h --- love-11.1/src/modules/graphics/opengl/OpenGL.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/OpenGL.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -160,6 +160,24 @@ bool clientWaitSyncStalls; /** + * glTexStorage on some older AMD/ATI graphics drivers on Windows seems + * to break subsequent sub-rectangle glTexSubImage calls after an + * initial full-size one (determined after some investigation with an + * affected user on Discord.) + * https://bitbucket.org/rude/love/issues/1436/bug-with-lovegraphicsprint-on-older-ati + * + **/ + bool texStorageBreaksSubImage; + + /** + * An Android device with an Adreno 630 (supposedly GLES3.2-capable) + * fails with GL_INVALID_OPERATION in glTexImage2D if the image is + * GL_R8, despite the GLES 3.0 spec mandating support for that format. + * It's possible more Adreno GPUs / drivers are affected as well. + **/ + bool brokenR8PixelFormat; + + /** * Other bugs which have workarounds that don't use conditional code at * the moment: * @@ -219,7 +237,7 @@ /** * Set all vertex attribute state. **/ - void setVertexAttributes(const vertex::Attributes &attributes, const vertex::Buffers &buffers); + void setVertexAttributes(const vertex::Attributes &attributes, const vertex::BufferBindings &buffers); /** * Wrapper for glCullFace which eliminates redundant state setting. diff -Nru love-11.1/src/modules/graphics/opengl/Shader.cpp love-11.3/src/modules/graphics/opengl/Shader.cpp --- love-11.1/src/modules/graphics/opengl/Shader.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Shader.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -148,6 +148,7 @@ if (oldu != olduniforms.end()) { u.data = oldu->second.data; + u.dataSize = oldu->second.dataSize; u.textures = oldu->second.textures; updateUniform(&u, u.count, true); @@ -332,7 +333,7 @@ for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++) { const char *name = nullptr; - if (vertex::getConstant((VertexAttribID) i, name)) + if (vertex::getConstant((BuiltinVertexAttribute) i, name)) glBindAttribLocation(program, i, (const GLchar *) name); } @@ -355,7 +356,7 @@ for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++) { const char *name = nullptr; - if (vertex::getConstant(VertexAttribID(i), name)) + if (vertex::getConstant(BuiltinVertexAttribute(i), name)) builtinAttributes[i] = glGetAttribLocation(program, name); else builtinAttributes[i] = -1; diff -Nru love-11.1/src/modules/graphics/opengl/Shader.h love-11.3/src/modules/graphics/opengl/Shader.h --- love-11.1/src/modules/graphics/opengl/Shader.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/Shader.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/opengl/ShaderStage.cpp love-11.3/src/modules/graphics/opengl/ShaderStage.cpp --- love-11.1/src/modules/graphics/opengl/ShaderStage.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/ShaderStage.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/opengl/ShaderStage.h love-11.3/src/modules/graphics/opengl/ShaderStage.h --- love-11.1/src/modules/graphics/opengl/ShaderStage.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/ShaderStage.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/opengl/StreamBuffer.cpp love-11.3/src/modules/graphics/opengl/StreamBuffer.cpp --- love-11.1/src/modules/graphics/opengl/StreamBuffer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/StreamBuffer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -36,8 +36,9 @@ namespace opengl { -static const int BUFFER_FRAMES = 3; -static const int MAX_SYNCS_PER_FRAME = 4; +// Typically this should be 3 frames, but we only do per-frame syncing right now +// so we add an extra frame to reduce the (small) chance of stalls. +static const int BUFFER_FRAMES = 4; class StreamBufferClientMemory final : public love::graphics::StreamBuffer { @@ -62,11 +63,6 @@ delete[] data; } - size_t getUsableSize() const override - { - return bufferSize; - } - MapInfo map(size_t /*minsize*/) override { return MapInfo(data, bufferSize); @@ -95,8 +91,7 @@ , vbo(0) , glMode(OpenGL::getGLBufferType(mode)) , data(nullptr) - , offset(0) - , frameOffset(0) + , orphan(false) { try { @@ -116,40 +111,36 @@ delete[] data; } - size_t getUsableSize() const override - { - return bufferSize - frameOffset; - } - - MapInfo map(size_t minsize) override + MapInfo map(size_t /*minsize*/) override { - if (offset + minsize > bufferSize) + if (orphan) { - offset = 0; - frameOffset = 0; + orphan = false; + frameGPUReadOffset = 0; gl.bindBuffer(mode, vbo); glBufferData(glMode, bufferSize, nullptr, GL_STREAM_DRAW); } - return MapInfo(data, bufferSize - offset); + return MapInfo(data, bufferSize - frameGPUReadOffset); } size_t unmap(size_t usedsize) override { gl.bindBuffer(mode, vbo); - glBufferSubData(glMode, offset, usedsize, data); - return offset; + glBufferSubData(glMode, frameGPUReadOffset, usedsize, data); + return frameGPUReadOffset; } void markUsed(size_t usedsize) override { - offset += usedsize; - frameOffset += usedsize; + frameGPUReadOffset += usedsize; } void nextFrame() override { - frameOffset = 0; + // Orphan the buffer before its first use in the next frame. + frameGPUReadOffset = 0; + orphan = true; } ptrdiff_t getHandle() const override { return vbo; } @@ -163,8 +154,8 @@ gl.bindBuffer(mode, vbo); glBufferData(glMode, bufferSize, nullptr, GL_STREAM_DRAW); - offset = 0; - frameOffset = 0; + frameGPUReadOffset = 0; + orphan = false; return true; } @@ -185,8 +176,7 @@ uint8 *data; - size_t offset; - size_t frameOffset; + bool orphan; }; // StreamBufferSubDataOrphan @@ -196,9 +186,7 @@ StreamBufferSync(BufferType type, size_t size) : love::graphics::StreamBuffer(type, size) - , syncSize((size + MAX_SYNCS_PER_FRAME - 1) / MAX_SYNCS_PER_FRAME) , frameIndex(0) - , frameGPUReadOffset(0) , syncs() {} @@ -206,7 +194,9 @@ void nextFrame() override { - getCurrentSync()->fence(); + // Insert a GPU fence for this frame's section of the data, we'll wait + // for it when we try to map that data for writing in subsequent frames. + syncs[frameIndex].fence(); frameIndex = (frameIndex + 1) % BUFFER_FRAMES; frameGPUReadOffset = 0; @@ -214,31 +204,15 @@ void markUsed(size_t usedsize) override { - int firstSyncIndex = frameGPUReadOffset / syncSize; - int lastSyncIndex = std::min((frameGPUReadOffset + usedsize), bufferSize - 1) / syncSize; - - // Insert fences for all sync buckets completely filled by this section - // of the data. The last bucket before the end of the frame will also be - // handled by nextFrame(). - for (int i = firstSyncIndex; i < lastSyncIndex; i++) - syncs[frameIndex * MAX_SYNCS_PER_FRAME + i].fence(); - + // We insert a fence for all data from this frame at the end of the + // frame (in nextFrame), rather than doing anything more fine-grained. frameGPUReadOffset += usedsize; } protected: - const size_t syncSize; - int frameIndex; - size_t frameGPUReadOffset; - - FenceSync syncs[MAX_SYNCS_PER_FRAME * BUFFER_FRAMES]; - - FenceSync *getCurrentSync() - { - return &syncs[frameIndex * MAX_SYNCS_PER_FRAME + frameGPUReadOffset / syncSize]; - } + FenceSync syncs[BUFFER_FRAMES]; }; // StreamBufferSync @@ -259,27 +233,16 @@ unloadVolatile(); } - size_t getUsableSize() const override - { - return bufferSize - frameGPUReadOffset; - } - MapInfo map(size_t /*minsize*/) override { gl.bindBuffer(mode, vbo); + // Make sure this frame's section of the buffer is done being used. + syncs[frameIndex].cpuWait(); + MapInfo info; info.size = bufferSize - frameGPUReadOffset; - int firstSyncIndex = frameGPUReadOffset / syncSize; - int lastSyncIndex = (bufferSize - 1) / syncSize; - - // We're mapping the full range of space left in the buffer, so we - // need to wait on all of it... - // FIXME: is it even worth it to have multiple sync objects per frame? - for (int i = firstSyncIndex; i <= lastSyncIndex; i++) - syncs[frameIndex * MAX_SYNCS_PER_FRAME + i].cpuWait(); - GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT; size_t mapoffset = (frameIndex * bufferSize) + frameGPUReadOffset; @@ -337,11 +300,14 @@ { public: - StreamBufferPersistentMapSync(BufferType type, size_t size) + // Coherent mapping is supposedly faster on intel/nvidia aside from a couple + // old nvidia GPUs. + StreamBufferPersistentMapSync(BufferType type, size_t size, bool coherent = true) : StreamBufferSync(type, size) , vbo(0) , glMode(OpenGL::getGLBufferType(mode)) , data(nullptr) + , coherent(coherent) { loadVolatile(); } @@ -351,26 +317,14 @@ unloadVolatile(); } - size_t getUsableSize() const override - { - return bufferSize - frameGPUReadOffset; - } - MapInfo map(size_t /*minsize*/) override { + // Make sure this frame's section of the buffer is done being used. + syncs[frameIndex].cpuWait(); + MapInfo info; info.size = bufferSize - frameGPUReadOffset; info.data = data + (frameIndex * bufferSize) + frameGPUReadOffset; - - int firstSyncIndex = frameGPUReadOffset / syncSize; - int lastSyncIndex = (bufferSize - 1) / syncSize; - - // We're mapping the full range of space left in the buffer, so we - // need to wait on all of it... - // FIXME: is it even worth it to have multiple sync objects per frame? - for (int i = firstSyncIndex; i <= lastSyncIndex; i++) - syncs[frameIndex * MAX_SYNCS_PER_FRAME + i].cpuWait(); - return info; } @@ -378,8 +332,11 @@ { size_t offset = (frameIndex * bufferSize) + frameGPUReadOffset; - gl.bindBuffer(mode, vbo); - glFlushMappedBufferRange(glMode, offset, usedsize); + if (!coherent) + { + gl.bindBuffer(mode, vbo); + glFlushMappedBufferRange(glMode, offset, usedsize); + } return offset; } @@ -395,7 +352,10 @@ gl.bindBuffer(mode, vbo); GLbitfield storageflags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT; - GLbitfield mapflags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT; + GLbitfield mapflags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT; + + storageflags |= (coherent ? GL_MAP_COHERENT_BIT : 0); + mapflags |= (coherent ? GL_MAP_COHERENT_BIT : GL_MAP_FLUSH_EXPLICIT_BIT); glBufferStorage(glMode, bufferSize * BUFFER_FRAMES, nullptr, storageflags); data = (uint8 *) glMapBufferRange(glMode, 0, bufferSize * BUFFER_FRAMES, mapflags); @@ -425,6 +385,7 @@ GLuint vbo; GLenum glMode; uint8 *data; + bool coherent; }; // StreamBufferPersistentMapSync @@ -454,36 +415,20 @@ alignedFree(data); } - size_t getUsableSize() const override - { - return bufferSize - frameGPUReadOffset; - } - MapInfo map(size_t /*minsize*/) override { + // Make sure this frame's section of the buffer is done being used. + syncs[frameIndex].cpuWait(); + MapInfo info; info.size = bufferSize - frameGPUReadOffset; info.data = data + (frameIndex * bufferSize) + frameGPUReadOffset; - - int firstSyncIndex = frameGPUReadOffset / syncSize; - int lastSyncIndex = (bufferSize - 1) / syncSize; - - // We're mapping the full range of space left in the buffer, so we - // need to wait on all of it... - // FIXME: is it even worth it to have multiple sync objects per frame? - for (int i = firstSyncIndex; i <= lastSyncIndex; i++) - syncs[frameIndex * MAX_SYNCS_PER_FRAME + i].cpuWait(); - return info; } - size_t unmap(size_t usedsize) override + size_t unmap(size_t /*usedsize*/) override { size_t offset = (frameIndex * bufferSize) + frameGPUReadOffset; - - gl.bindBuffer(mode, vbo); - glFlushMappedBufferRange(glMode, offset, usedsize); - return offset; } @@ -546,6 +491,16 @@ return new StreamBufferPinnedMemory(mode, size); else if (GLAD_VERSION_4_4 || GLAD_ARB_buffer_storage) return new StreamBufferPersistentMapSync(mode, size); + + // Most modern drivers have a separate internal thread which queues + // GL commands for the GPU. The queue causes mapping to stall until + // the items in the queue are flushed, which makes this approach + // slow on most drivers. On macOS, having a separate driver thread + // is opt-in via an API, and we don't do it, so we can use this + // instead of the (potentially slower) SubData approach. +#ifdef LOVE_MACOSX + return new StreamBufferMapSync(mode, size); +#endif } return new StreamBufferSubDataOrphan(mode, size); diff -Nru love-11.1/src/modules/graphics/opengl/StreamBuffer.h love-11.3/src/modules/graphics/opengl/StreamBuffer.h --- love-11.1/src/modules/graphics/opengl/StreamBuffer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/opengl/StreamBuffer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/ParticleSystem.cpp love-11.3/src/modules/graphics/ParticleSystem.cpp --- love-11.1/src/modules/graphics/ParticleSystem.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/ParticleSystem.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -1062,7 +1062,7 @@ // Particle colors are stored as floats (0-1) but vertex colors are // unsigned bytes (0-255). - Color c = toColor(p->color); + Color32 c = toColor32(p->color); // set the texture coordinate and color data for particle vertices for (int v = 0; v < 4; v++) @@ -1076,11 +1076,11 @@ p = p->next; } - Graphics::TempTransform transform(gfx, m); - buffer->unmap(); - vertex::Buffers vertexbuffers; + Graphics::TempTransform transform(gfx, m); + + vertex::BufferBindings vertexbuffers; vertexbuffers.set(0, buffer, 0); gfx->drawQuads(0, pCount, vertexAttributes, vertexbuffers, texture); diff -Nru love-11.1/src/modules/graphics/ParticleSystem.h love-11.3/src/modules/graphics/ParticleSystem.h --- love-11.1/src/modules/graphics/ParticleSystem.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/ParticleSystem.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Polyline.cpp love-11.3/src/modules/graphics/Polyline.cpp --- love-11.1/src/modules/graphics/Polyline.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Polyline.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -241,7 +241,7 @@ } // cramers rule - Vector2 nt= t.getNormal(hw / len_t); + Vector2 nt = t.getNormal(hw / len_t); float lambda = Vector2::cross((nt - ns), t) / det; Vector2 d = ns + s * lambda; @@ -286,7 +286,7 @@ { size_t k = vertex_count - i - 1; overdraw[vertex_count + i] = vertices[k]; - overdraw[vertex_count + i+1] = vertices[k] + normals[k] * (pixel_size / normals[i].getLength()); + overdraw[vertex_count + i+1] = vertices[k] + normals[k] * (pixel_size / normals[k].getLength()); } // if not looping, the outer overdraw vertices need to be displaced @@ -367,51 +367,75 @@ void Polyline::draw(love::graphics::Graphics *gfx) { + const Matrix4 &t = gfx->getTransform(); + bool is2D = t.isAffine2DTransform(); + Color32 curcolor = toColor32(gfx->getColor()); + + int overdraw_start = (int) overdraw_vertex_start; + int overdraw_count = (int) overdraw_vertex_count; + int total_vertex_count = (int) vertex_count; if (overdraw) - total_vertex_count = (int) (overdraw_vertex_start + overdraw_vertex_count); + total_vertex_count = overdraw_start + overdraw_count; - const Matrix4 &t = gfx->getTransform(); - bool is2D = t.isAffine2DTransform(); + // love's automatic batching can only deal with < 65k vertices per draw. + // uint16_max - 3 is evenly divisible by 6 (needed for quads mode). + int maxvertices = LOVE_UINT16_MAX - 3; - Graphics::StreamDrawCommand cmd; - cmd.formats[0] = vertex::getSinglePositionFormat(is2D); - cmd.formats[1] = vertex::CommonFormat::RGBAub; - cmd.indexMode = triangle_mode; - cmd.vertexCount = total_vertex_count; + int advance = maxvertices; + if (triangle_mode == vertex::TriangleIndexMode::STRIP) + advance -= 2; - Graphics::StreamVertexData data = gfx->requestStreamDraw(cmd); + for (int vertex_start = 0; vertex_start < total_vertex_count; vertex_start += advance) + { + const Vector2 *verts = vertices + vertex_start; - if (is2D) - t.transformXY((Vector2 *) data.stream[0], vertices, total_vertex_count); - else - t.transformXY0((Vector3 *) data.stream[0], vertices, total_vertex_count); + Graphics::StreamDrawCommand cmd; + cmd.formats[0] = vertex::getSinglePositionFormat(is2D); + cmd.formats[1] = vertex::CommonFormat::RGBAub; + cmd.indexMode = triangle_mode; + cmd.vertexCount = std::min(maxvertices, total_vertex_count - vertex_start); - Color curcolor = toColor(gfx->getColor()); - Color *colordata = (Color *) data.stream[1]; + Graphics::StreamVertexData data = gfx->requestStreamDraw(cmd); - for (int i = 0; i < (int) vertex_count; i++) - colordata[i] = curcolor; + if (is2D) + t.transformXY((Vector2 *) data.stream[0], verts, cmd.vertexCount); + else + t.transformXY0((Vector3 *) data.stream[0], verts, cmd.vertexCount); - if (overdraw) - fill_color_array(curcolor, colordata + overdraw_vertex_start); + Color32 *colordata = (Color32 *) data.stream[1]; + + // Constant vertex color up to the overdraw vertices. + for (int i = 0; i < std::min(cmd.vertexCount, (int) vertex_count - vertex_start); i++) + colordata[i] = curcolor; + + int colorcount = 0; + if (overdraw) + colorcount = std::min(cmd.vertexCount, overdraw_count - (vertex_start - overdraw_start)); + + if (colorcount > 0) + { + Color32 *colors = colordata + std::max(0, (overdraw_start - vertex_start)); + fill_color_array(curcolor, colors, colorcount); + } + } } -void Polyline::fill_color_array(Color constant_color, Color *colors) +void Polyline::fill_color_array(Color32 constant_color, Color32 *colors, int count) { - for (size_t i = 0; i < overdraw_vertex_count; ++i) + for (int i = 0; i < count; ++i) { - Color c = constant_color; + Color32 c = constant_color; c.a *= (i+1) % 2; // avoids branching. equiv to if (i%2 == 1) c.a = 0; colors[i] = c; } } -void NoneJoinPolyline::fill_color_array(Color constant_color, Color *colors) +void NoneJoinPolyline::fill_color_array(Color32 constant_color, Color32 *colors, int count) { - for (size_t i = 0; i < overdraw_vertex_count; ++i) + for (int i = 0; i < count; ++i) { - Color c = constant_color; + Color32 c = constant_color; c.a *= (i & 3) < 2; // if (i % 4 == 2 || i % 4 == 3) c.a = 0 colors[i] = c; } diff -Nru love-11.1/src/modules/graphics/Polyline.h love-11.3/src/modules/graphics/Polyline.h --- love-11.1/src/modules/graphics/Polyline.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Polyline.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,7 @@ virtual void calc_overdraw_vertex_count(bool is_looping); virtual void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping); - virtual void fill_color_array(Color constant_color, Color *colors); + virtual void fill_color_array(Color32 constant_color, Color32 *colors, int count); /** Calculate line boundary points. * @@ -131,12 +131,12 @@ protected: - virtual void calc_overdraw_vertex_count(bool is_looping); - virtual void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping); - virtual void fill_color_array(Color constant_color, Color *colors); - virtual void renderEdge(std::vector &anchors, std::vector &normals, - Vector2 &s, float &len_s, Vector2 &ns, - const Vector2 &q, const Vector2 &r, float hw); + void calc_overdraw_vertex_count(bool is_looping) override; + void render_overdraw(const std::vector &normals, float pixel_size, bool is_looping) override; + void fill_color_array(Color32 constant_color, Color32 *colors, int count) override; + void renderEdge(std::vector &anchors, std::vector &normals, + Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q, + const Vector2 &r, float hw) override; }; // NoneJoinPolyline @@ -156,9 +156,9 @@ protected: - virtual void renderEdge(std::vector &anchors, std::vector &normals, - Vector2 &s, float &len_s, Vector2 &ns, - const Vector2 &q, const Vector2 &r, float hw); + void renderEdge(std::vector &anchors, std::vector &normals, + Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q, + const Vector2 &r, float hw) override; }; // MiterJoinPolyline @@ -178,9 +178,9 @@ protected: - virtual void renderEdge(std::vector &anchors, std::vector &normals, - Vector2 &s, float &len_s, Vector2 &ns, - const Vector2 &q, const Vector2 &r, float hw); + void renderEdge(std::vector &anchors, std::vector &normals, + Vector2 &s, float &len_s, Vector2 &ns, const Vector2 &q, + const Vector2 &r, float hw) override; }; // BevelJoinPolyline diff -Nru love-11.1/src/modules/graphics/Quad.cpp love-11.3/src/modules/graphics/Quad.cpp --- love-11.1/src/modules/graphics/Quad.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Quad.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Quad.h love-11.3/src/modules/graphics/Quad.h --- love-11.1/src/modules/graphics/Quad.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Quad.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Resource.h love-11.3/src/modules/graphics/Resource.h --- love-11.1/src/modules/graphics/Resource.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Resource.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Shader.cpp love-11.3/src/modules/graphics/Shader.cpp --- love-11.1/src/modules/graphics/Shader.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Shader.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Shader.h love-11.3/src/modules/graphics/Shader.h --- love-11.1/src/modules/graphics/Shader.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Shader.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/ShaderStage.cpp love-11.3/src/modules/graphics/ShaderStage.cpp --- love-11.1/src/modules/graphics/ShaderStage.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/ShaderStage.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -109,6 +109,15 @@ /* .MaxCullDistances = */ 8, /* .MaxCombinedClipAndCullDistances = */ 8, /* .MaxSamples = */ 32, + /* .maxMeshOutputVerticesNV = */ 256, + /* .maxMeshOutputPrimitivesNV = */ 512, + /* .maxMeshWorkGroupSizeX_NV = */ 32, + /* .maxMeshWorkGroupSizeY_NV = */ 1, + /* .maxMeshWorkGroupSizeZ_NV = */ 1, + /* .maxTaskWorkGroupSizeX_NV = */ 32, + /* .maxTaskWorkGroupSizeY_NV = */ 1, + /* .maxTaskWorkGroupSizeZ_NV = */ 1, + /* .maxMeshViewCountNV = */ 4, /* .limits = */ { /* .nonInductiveForLoops = */ 1, /* .whileLoops = */ 1, diff -Nru love-11.1/src/modules/graphics/ShaderStage.h love-11.3/src/modules/graphics/ShaderStage.h --- love-11.1/src/modules/graphics/ShaderStage.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/ShaderStage.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/SpriteBatch.cpp love-11.3/src/modules/graphics/SpriteBatch.cpp --- love-11.1/src/modules/graphics/SpriteBatch.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/SpriteBatch.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -93,7 +93,7 @@ const Vector2 *quadpositions = quad->getVertexPositions(); const Vector2 *quadtexcoords = quad->getVertexTexCoords(); - // Always keep the VBO mapped when adding data (it'll be unmapped on draw.) + // Always keep the buffer mapped when adding data (it'll be unmapped on draw.) size_t offset = (index == -1 ? next : index) * vertex_stride * 4; auto verts = (XYf_STf_RGBAub *) ((uint8 *) array_buf->map() + offset); @@ -139,7 +139,7 @@ const Vector2 *quadpositions = quad->getVertexPositions(); const Vector2 *quadtexcoords = quad->getVertexTexCoords(); - // Always keep the VBO mapped when adding data (it'll be unmapped on draw.) + // Always keep the buffer mapped when adding data (it'll be unmapped on draw.) size_t offset = (index == -1 ? next : index) * vertex_stride * 4; auto verts = (XYf_STPf_RGBAub *) ((uint8 *) array_buf->map() + offset); @@ -196,13 +196,13 @@ cclamped.b = std::min(std::max(c.b, 0.0f), 1.0f); cclamped.a = std::min(std::max(c.a, 0.0f), 1.0f); - this->color = toColor(cclamped); + this->color = toColor32(cclamped); } void SpriteBatch::setColor() { color_active = false; - color = Color(255, 255, 255, 255); + color = Color32(255, 255, 255, 255); } Colorf SpriteBatch::getColor(bool &active) const @@ -328,11 +328,11 @@ Shader::current->checkMainTexture(texture); } - // Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.) + // Make sure the buffer isn't mapped when we draw (sends data to GPU if needed.) array_buf->unmap(); Attributes attributes; - Buffers buffers; + BufferBindings buffers; { buffers.set(0, array_buf, 0); @@ -357,7 +357,7 @@ // If the attribute is one of the LOVE-defined ones, use the constant // attribute index for it, otherwise query the index from the shader. - VertexAttribID builtinattrib; + BuiltinVertexAttribute builtinattrib; if (vertex::getConstant(it.first.c_str(), builtinattrib)) attributeindex = (int) builtinattrib; else if (Shader::current) @@ -366,7 +366,7 @@ if (attributeindex >= 0) { // Make sure the buffer isn't mapped (sends data to GPU if needed.) - mesh->vbo->unmap(); + mesh->vertexBuffer->unmap(); const auto &formats = mesh->getVertexFormat(); const auto &format = formats[it.second.index]; @@ -374,10 +374,11 @@ uint16 offset = (uint16) mesh->getAttributeOffset(it.second.index); uint16 stride = (uint16) mesh->getVertexStride(); - attributes.set(attributeindex, format.type, format.components, offset, stride, activebuffers); + attributes.set(attributeindex, format.type, (uint8) format.components, offset, activebuffers); + attributes.setBufferLayout(activebuffers, stride); - // TODO: Ideally we want to reuse buffers with the same stride+step. - buffers.set(activebuffers, mesh->vbo, 0); + // TODO: We should reuse buffer bindings with the same buffer+stride+step. + buffers.set(activebuffers, mesh->vertexBuffer, 0); activebuffers++; } } diff -Nru love-11.1/src/modules/graphics/SpriteBatch.h love-11.3/src/modules/graphics/SpriteBatch.h --- love-11.1/src/modules/graphics/SpriteBatch.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/SpriteBatch.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -133,7 +133,7 @@ // Current color. This color, if present, will be applied to the next // added sprite. - Color color; + Color32 color; bool color_active; vertex::CommonFormat vertex_format; diff -Nru love-11.1/src/modules/graphics/StreamBuffer.cpp love-11.3/src/modules/graphics/StreamBuffer.cpp --- love-11.1/src/modules/graphics/StreamBuffer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/StreamBuffer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,7 @@ StreamBuffer::StreamBuffer(BufferType mode, size_t size) : bufferSize(size) + , frameGPUReadOffset(0) , mode(mode) { } diff -Nru love-11.1/src/modules/graphics/StreamBuffer.h love-11.3/src/modules/graphics/StreamBuffer.h --- love-11.1/src/modules/graphics/StreamBuffer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/StreamBuffer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -54,8 +54,8 @@ size_t getSize() const { return bufferSize; } BufferType getMode() const { return mode; } + size_t getUsableSize() const { return bufferSize - frameGPUReadOffset; } - virtual size_t getUsableSize() const = 0; virtual MapInfo map(size_t minsize) = 0; virtual size_t unmap(size_t usedsize) = 0; virtual void markUsed(size_t usedsize) = 0; @@ -67,6 +67,7 @@ StreamBuffer(BufferType mode, size_t size); size_t bufferSize; + size_t frameGPUReadOffset; BufferType mode; }; // StreamBuffer diff -Nru love-11.1/src/modules/graphics/Text.cpp love-11.3/src/modules/graphics/Text.cpp --- love-11.1/src/modules/graphics/Text.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Text.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,7 @@ Text::Text(Font *font, const std::vector &text) : font(font) , vertexAttributes(Font::vertexFormat, 0) - , vbo(nullptr) + , vertex_buffer(nullptr) , vert_offset(0) , texture_cache_id((uint32) -1) { @@ -42,40 +42,39 @@ Text::~Text() { - delete vbo; + delete vertex_buffer; } void Text::uploadVertices(const std::vector &vertices, size_t vertoffset) { size_t offset = vertoffset * sizeof(Font::GlyphVertex); size_t datasize = vertices.size() * sizeof(Font::GlyphVertex); - uint8 *vbodata = nullptr; // If we haven't created a VBO or the vertices are too big, make a new one. - if (datasize > 0 && (!vbo || (offset + datasize) > vbo->getSize())) + if (datasize > 0 && (!vertex_buffer || (offset + datasize) > vertex_buffer->getSize())) { // Make it bigger than necessary to reduce potential future allocations. size_t newsize = size_t((offset + datasize) * 1.5); - if (vbo != nullptr) - newsize = std::max(size_t(vbo->getSize() * 1.5), newsize); + if (vertex_buffer != nullptr) + newsize = std::max(size_t(vertex_buffer->getSize() * 1.5), newsize); auto gfx = Module::getInstance(Module::M_GRAPHICS); - Buffer *new_vbo = gfx->newBuffer(newsize, nullptr, BUFFER_VERTEX, vertex::USAGE_DYNAMIC, 0); + Buffer *new_buffer = gfx->newBuffer(newsize, nullptr, BUFFER_VERTEX, vertex::USAGE_DYNAMIC, 0); - if (vbo != nullptr) - vbo->copyTo(0, vbo->getSize(), new_vbo, 0); + if (vertex_buffer != nullptr) + vertex_buffer->copyTo(0, vertex_buffer->getSize(), new_buffer, 0); - delete vbo; - vbo = new_vbo; + delete vertex_buffer; + vertex_buffer = new_buffer; - vertexBuffers.set(0, vbo, 0); + vertexBuffers.set(0, vertex_buffer, 0); } - if (vbo != nullptr && datasize > 0) + if (vertex_buffer != nullptr && datasize > 0) { - vbodata = (uint8 *) vbo->map(); - memcpy(vbodata + offset, &vertices[0], datasize); + uint8 *bufferdata = (uint8 *) vertex_buffer->map(); + memcpy(bufferdata + offset, &vertices[0], datasize); // We unmap when we draw, to avoid unnecessary full map()/unmap() calls. } } @@ -112,21 +111,23 @@ else new_commands = font->generateVerticesFormatted(t.codepoints, constantcolor, t.wrap, t.align, vertices, &text_info); - if (vertices.empty()) - return; - - if (t.use_matrix) - t.matrix.transformXY(&vertices[0], &vertices[0], (int) vertices.size()); - size_t voffset = vert_offset; + // Must be before the early exit below. if (!t.append_vertices) { voffset = 0; + vert_offset = 0; draw_commands.clear(); text_data.clear(); } + if (vertices.empty()) + return; + + if (t.use_matrix) + t.matrix.transformXY(&vertices[0], &vertices[0], (int) vertices.size()); + uploadVertices(vertices, voffset); if (!new_commands.empty()) @@ -222,10 +223,10 @@ { if (index < 0) index = std::max((int) text_data.size() - 1, 0); - + if (index >= (int) text_data.size()) return 0; - + return text_data[index].text_info.width; } @@ -233,16 +234,16 @@ { if (index < 0) index = std::max((int) text_data.size() - 1, 0); - + if (index >= (int) text_data.size()) return 0; - + return text_data[index].text_info.height; } void Text::draw(Graphics *gfx, const Matrix4 &m) { - if (vbo == nullptr || draw_commands.empty()) + if (vertex_buffer == nullptr || draw_commands.empty()) return; gfx->flushStreamDraws(); @@ -261,7 +262,7 @@ for (const Font::DrawCommand &cmd : draw_commands) totalverts = std::max(cmd.startvertex + cmd.vertexcount, totalverts); - vbo->unmap(); // Make sure all pending data is flushed to the GPU. + vertex_buffer->unmap(); // Make sure all pending data is flushed to the GPU. Graphics::TempTransform transform(gfx, m); diff -Nru love-11.1/src/modules/graphics/Text.h love-11.3/src/modules/graphics/Text.h --- love-11.1/src/modules/graphics/Text.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Text.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** -* Copyright (c) 2006-2018 LOVE Development Team +* Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -86,9 +86,9 @@ StrongRef font; vertex::Attributes vertexAttributes; - vertex::Buffers vertexBuffers; + vertex::BufferBindings vertexBuffers; - Buffer *vbo; + Buffer *vertex_buffer; std::vector draw_commands; diff -Nru love-11.1/src/modules/graphics/Texture.cpp love-11.3/src/modules/graphics/Texture.cpp --- love-11.1/src/modules/graphics/Texture.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Texture.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -150,7 +150,7 @@ const Vector2 *texcoords = q->getVertexTexCoords(); vertex::STf_RGBAub *vertexdata = (vertex::STf_RGBAub *) data.stream[1]; - Color c = toColor(gfx->getColor()); + Color32 c = toColor32(gfx->getColor()); for (int i = 0; i < 4; i++) { @@ -178,7 +178,7 @@ if (layer < 0 || layer >= layers) throw love::Exception("Invalid layer: %d (Texture has %d layers)", layer + 1, layers); - Color c = toColor(gfx->getColor()); + Color32 c = toColor32(gfx->getColor()); const Matrix4 &tm = gfx->getTransform(); bool is2D = tm.isAffine2DTransform(); diff -Nru love-11.1/src/modules/graphics/Texture.h love-11.3/src/modules/graphics/Texture.h --- love-11.1/src/modules/graphics/Texture.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Texture.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/vertex.cpp love-11.3/src/modules/graphics/vertex.cpp --- love-11.1/src/modules/graphics/vertex.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/vertex.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -28,14 +28,14 @@ namespace vertex { -static_assert(sizeof(Color) == 4, "sizeof(Color) incorrect!"); -static_assert(sizeof(STf_RGBAub) == sizeof(float)*2 + sizeof(Color), "sizeof(STf_RGBAub) incorrect!"); -static_assert(sizeof(STPf_RGBAub) == sizeof(float)*3 + sizeof(Color), "sizeof(STPf_RGBAub) incorrect!"); +static_assert(sizeof(Color32) == 4, "sizeof(Color32) incorrect!"); +static_assert(sizeof(STf_RGBAub) == sizeof(float)*2 + sizeof(Color32), "sizeof(STf_RGBAub) incorrect!"); +static_assert(sizeof(STPf_RGBAub) == sizeof(float)*3 + sizeof(Color32), "sizeof(STPf_RGBAub) incorrect!"); static_assert(sizeof(XYf_STf) == sizeof(float)*2 + sizeof(float)*2, "sizeof(XYf_STf) incorrect!"); static_assert(sizeof(XYf_STPf) == sizeof(float)*2 + sizeof(float)*3, "sizeof(XYf_STPf) incorrect!"); -static_assert(sizeof(XYf_STf_RGBAub) == sizeof(float)*2 + sizeof(float)*2 + sizeof(Color), "sizeof(XYf_STf_RGBAub) incorrect!"); -static_assert(sizeof(XYf_STus_RGBAub) == sizeof(float)*2 + sizeof(uint16)*2 + sizeof(Color), "sizeof(XYf_STus_RGBAub) incorrect!"); -static_assert(sizeof(XYf_STPf_RGBAub) == sizeof(float)*2 + sizeof(float)*3 + sizeof(Color), "sizeof(XYf_STPf_RGBAub) incorrect!"); +static_assert(sizeof(XYf_STf_RGBAub) == sizeof(float)*2 + sizeof(float)*2 + sizeof(Color32), "sizeof(XYf_STf_RGBAub) incorrect!"); +static_assert(sizeof(XYf_STus_RGBAub) == sizeof(float)*2 + sizeof(uint16)*2 + sizeof(Color32), "sizeof(XYf_STus_RGBAub) incorrect!"); +static_assert(sizeof(XYf_STPf_RGBAub) == sizeof(float)*2 + sizeof(float)*3 + sizeof(Color32), "sizeof(XYf_STPf_RGBAub) incorrect!"); size_t getFormatStride(CommonFormat format) { @@ -64,6 +64,7 @@ case CommonFormat::XYf_STPf_RGBAub: return sizeof(XYf_STPf_RGBAub); } + return 0; } uint32 getFormatFlags(CommonFormat format) @@ -88,6 +89,7 @@ case CommonFormat::XYf_STPf_RGBAub: return ATTRIBFLAG_POS | ATTRIBFLAG_TEXCOORD | ATTRIBFLAG_COLOR; } + return 0; } int getFormatPositionComponents(CommonFormat format) @@ -109,6 +111,7 @@ case CommonFormat::XYZf: return 3; } + return 0; } size_t getIndexDataSize(IndexDataType type) @@ -157,6 +160,7 @@ case TriangleIndexMode::QUADS: return vertexCount * 6 / 4; } + return 0; } template @@ -224,56 +228,56 @@ void Attributes::setCommonFormat(CommonFormat format, uint8 bufferindex) { - uint16 stride = (uint16) getFormatStride(format); + setBufferLayout(bufferindex, (uint16) getFormatStride(format)); switch (format) { case CommonFormat::NONE: break; case CommonFormat::XYf: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); break; case CommonFormat::XYZf: - set(ATTRIB_POS, DATA_FLOAT, 3, 0, stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 3, 0, bufferindex); break; case CommonFormat::RGBAub: - set(ATTRIB_COLOR, DATA_UNORM8, 4, 0, stride, bufferindex); + set(ATTRIB_COLOR, DATA_UNORM8, 4, 0, bufferindex); break; case CommonFormat::STf_RGBAub: - set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, 0, stride, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 2), stride, bufferindex); + set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 2), bufferindex); break; case CommonFormat::STPf_RGBAub: - set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, 0, stride, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 3), stride, bufferindex); + set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, 0, bufferindex); + set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 3), bufferindex); break; case CommonFormat::XYf_STf: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, stride, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, uint16(sizeof(float) * 2), stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, uint16(sizeof(float) * 2), bufferindex); break; case CommonFormat::XYf_STPf: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, stride, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, uint16(sizeof(float) * 2), stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, uint16(sizeof(float) * 2), bufferindex); break; case CommonFormat::XYf_STf_RGBAub: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, stride, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, uint16(sizeof(float) * 2), stride, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 4), stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 4), bufferindex); break; case CommonFormat::XYf_STus_RGBAub: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, stride, bufferindex); - set(ATTRIB_TEXCOORD, DATA_UNORM16, 2, uint16(sizeof(float) * 2), stride, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 2 + sizeof(uint16) * 2), stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATA_UNORM16, 2, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 2 + sizeof(uint16) * 2), bufferindex); break; case CommonFormat::XYf_STPf_RGBAub: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, stride, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, uint16(sizeof(float) * 2), stride, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 5), stride, bufferindex); + set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 5), bufferindex); break; } } -static StringMap::Entry attribNameEntries[] = +static StringMap::Entry attribNameEntries[] = { { "VertexPosition", ATTRIB_POS }, { "VertexTexCoord", ATTRIB_TEXCOORD }, @@ -281,7 +285,7 @@ { "ConstantColor", ATTRIB_CONSTANTCOLOR }, }; -static StringMap attribNames(attribNameEntries, sizeof(attribNameEntries)); +static StringMap attribNames(attribNameEntries, sizeof(attribNameEntries)); static StringMap::Entry indexTypeEntries[] = { @@ -344,12 +348,12 @@ static StringMap windings(windingEntries, sizeof(windingEntries)); -bool getConstant(const char *in, VertexAttribID &out) +bool getConstant(const char *in, BuiltinVertexAttribute &out) { return attribNames.find(in, out); } -bool getConstant(VertexAttribID in, const char *&out) +bool getConstant(BuiltinVertexAttribute in, const char *&out) { return attribNames.find(in, out); } diff -Nru love-11.1/src/modules/graphics/vertex.h love-11.3/src/modules/graphics/vertex.h --- love-11.1/src/modules/graphics/vertex.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/vertex.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -36,9 +36,9 @@ class Resource; -// Vertex attribute indices used in shaders by LOVE. The values map to OpenGL +// Vertex attribute indices used in shaders by LOVE. The values map to GPU // generic vertex attribute indices. -enum VertexAttribID +enum BuiltinVertexAttribute { ATTRIB_POS = 0, ATTRIB_TEXCOORD, @@ -47,7 +47,7 @@ ATTRIB_MAX_ENUM }; -enum VertexAttribFlags +enum BuiltinVertexAttributeFlag { ATTRIBFLAG_POS = 1 << ATTRIB_POS, ATTRIBFLAG_TEXCOORD = 1 << ATTRIB_TEXCOORD, @@ -147,13 +147,13 @@ struct STf_RGBAub { float s, t; - Color color; + Color32 color; }; struct STPf_RGBAub { float s, t, p; - Color color; + Color32 color; }; struct XYf_STf @@ -172,28 +172,28 @@ { float x, y; float s, t; - Color color; + Color32 color; }; struct XYf_STus_RGBAub { float x, y; uint16 s, t; - Color color; + Color32 color; }; struct XYf_STPf_RGBAub { float x, y; float s, t, p; - Color color; + Color32 color; }; -struct Buffers +struct BufferBindings { - static const unsigned int MAX = 32; + static const uint32 MAX = 32; - uint32 usebits = 0; + uint32 useBits = 0; struct { @@ -201,33 +201,38 @@ size_t offset; } info[MAX]; - void set(unsigned int index, Resource *r, size_t offset) + void set(uint32 index, Resource *r, size_t offset) { - usebits |= (1u << index); + useBits |= (1u << index); info[index] = {r, offset}; } - void disable(unsigned int index) { usebits &= (1u << index); } - void clear() { usebits = 0; } + void disable(uint32 index) { useBits &= (1u << index); } + void clear() { useBits = 0; } }; struct AttributeInfo { - uint8 bufferindex; - DataType type : 8; - uint16 components; - uint16 offsetfromvertex; + uint8 bufferIndex; + DataType type : 4; + uint8 components : 4; + uint16 offsetFromVertex; +}; + +struct BufferLayout +{ uint16 stride; }; struct Attributes { - static const unsigned int MAX = 32; + static const uint32 MAX = 32; - uint32 enablebits = 0; - uint32 instancebits = 0; + uint32 enableBits = 0; // indexed by attribute + uint32 instanceBits = 0; // indexed by buffer AttributeInfo attribs[MAX]; + BufferLayout bufferLayouts[BufferBindings::MAX]; Attributes() {} Attributes(CommonFormat format, uint8 bufferindex) @@ -235,42 +240,46 @@ setCommonFormat(format, bufferindex); } - void set(unsigned int index, DataType type, uint16 components, uint16 offsetfromvertex, uint16 stride, uint8 bufferindex, AttributeStep step = STEP_PER_VERTEX) + void set(uint32 index, DataType type, uint8 components, uint16 offsetfromvertex, uint8 bufferindex) { - uint32 bit = (1u << index); + enableBits |= (1u << index); + + attribs[index].bufferIndex = bufferindex; + attribs[index].type = type; + attribs[index].components = components; + attribs[index].offsetFromVertex = offsetfromvertex; + } - enablebits |= bit; + void setBufferLayout(uint32 bufferindex, uint16 stride, AttributeStep step = STEP_PER_VERTEX) + { + uint32 bufferbit = (1u << bufferindex); if (step == STEP_PER_INSTANCE) - instancebits |= bit; + instanceBits |= bufferbit; else - instancebits &= ~bit; + instanceBits &= ~bufferbit; - attribs[index].bufferindex = bufferindex; - attribs[index].type = type; - attribs[index].components = components; - attribs[index].offsetfromvertex = offsetfromvertex; - attribs[index].stride = stride; + bufferLayouts[bufferindex].stride = stride; } - void disable(unsigned int index) + void disable(uint32 index) { - enablebits &= ~(1u << index); + enableBits &= ~(1u << index); } void clear() { - enablebits = 0; + enableBits = 0; } - bool isEnabled(unsigned int index) const + bool isEnabled(uint32 index) const { - return (enablebits & (1u << index)) != 0; + return (enableBits & (1u << index)) != 0; } - AttributeStep getStep(unsigned int index) const + AttributeStep getBufferStep(uint32 index) const { - return (instancebits & (1u << index)) != 0 ? STEP_PER_INSTANCE : STEP_PER_VERTEX; + return (instanceBits & (1u << index)) != 0 ? STEP_PER_INSTANCE : STEP_PER_VERTEX; } void setCommonFormat(CommonFormat format, uint8 bufferindex); @@ -297,8 +306,8 @@ void fillIndices(TriangleIndexMode mode, uint16 vertexStart, uint16 vertexCount, uint16 *indices); void fillIndices(TriangleIndexMode mode, uint32 vertexStart, uint32 vertexCount, uint32 *indices); -bool getConstant(const char *in, VertexAttribID &out); -bool getConstant(VertexAttribID in, const char *&out); +bool getConstant(const char *in, BuiltinVertexAttribute &out); +bool getConstant(BuiltinVertexAttribute in, const char *&out); bool getConstant(const char *in, IndexDataType &out); bool getConstant(IndexDataType in, const char *&out); diff -Nru love-11.1/src/modules/graphics/Video.cpp love-11.3/src/modules/graphics/Video.cpp --- love-11.1/src/modules/graphics/Video.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Video.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -42,7 +42,7 @@ stream->fillBackBuffer(); for (int i = 0; i < 4; i++) - vertices[i].color = Color(255, 255, 255, 255); + vertices[i].color = Color32(255, 255, 255, 255); // Vertices are ordered for use with triangle strips: // 0---2 @@ -96,6 +96,8 @@ Video::~Video() { + if (source) + source->stop(); } love::video::VideoStream *Video::getStream() @@ -128,7 +130,7 @@ vertex::STf_RGBAub *verts = (vertex::STf_RGBAub *) data.stream[1]; - Color c = toColor(gfx->getColor()); + Color32 c = toColor32(gfx->getColor()); for (int i = 0; i < 4; i++) { diff -Nru love-11.1/src/modules/graphics/Video.h love-11.3/src/modules/graphics/Video.h --- love-11.1/src/modules/graphics/Video.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Video.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Volatile.cpp love-11.3/src/modules/graphics/Volatile.cpp --- love-11.1/src/modules/graphics/Volatile.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Volatile.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/Volatile.h love-11.3/src/modules/graphics/Volatile.h --- love-11.1/src/modules/graphics/Volatile.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/Volatile.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Canvas.cpp love-11.3/src/modules/graphics/wrap_Canvas.cpp --- love-11.1/src/modules/graphics/wrap_Canvas.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Canvas.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Canvas.h love-11.3/src/modules/graphics/wrap_Canvas.h --- love-11.1/src/modules/graphics/wrap_Canvas.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Canvas.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Font.cpp love-11.3/src/modules/graphics/wrap_Font.cpp --- love-11.1/src/modules/graphics/wrap_Font.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Font.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Font.h love-11.3/src/modules/graphics/wrap_Font.h --- love-11.1/src/modules/graphics/wrap_Font.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Font.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Graphics.cpp love-11.3/src/modules/graphics/wrap_Graphics.cpp --- love-11.1/src/modules/graphics/wrap_Graphics.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Graphics.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -45,6 +45,11 @@ #include "wrap_Graphics.lua" ; +// This is in a separate file because VS2013 has a 16KB limit for raw strings.. +static const char graphics_shader_lua[] = +#include "wrap_GraphicsShader.lua" +; + namespace love { namespace graphics @@ -290,7 +295,7 @@ targets.colors.emplace_back(luax_checkcanvas(L, -1), 0); if (targets.colors.back().canvas->getTextureType() != TEXTURE_2D) - return luaL_error(L, "The table-of-tables variant of setCanvas must be used with non-2D Canvases."); + return luaL_error(L, "Non-2D canvases must use the table-of-tables variant of setCanvas."); } lua_pop(L, 1); @@ -1091,7 +1096,7 @@ for (int i = 0; i < lua_gettop(L); i++) idxs.push_back(i + 1); - luax_convobj(L, &idxs[0], (int) idxs.size(), "font", "newRasterizer"); + luax_convobj(L, idxs, "font", "newRasterizer"); } love::font::Rasterizer *rasterizer = luax_checktype(L, 1); @@ -1122,7 +1127,7 @@ for (int i = 0; i < lua_gettop(L); i++) idxs.push_back(i + 1); - luax_convobj(L, &idxs[0], (int) idxs.size(), "font", "newImageRasterizer"); + luax_convobj(L, idxs, "font", "newImageRasterizer"); } love::font::Rasterizer *rasterizer = luax_checktype(L, 1); @@ -2245,7 +2250,7 @@ if (!Texture::getConstant(textype, name)) continue; - lua_pushnumber(L, caps.textureTypes[i]); + luax_pushboolean(L, caps.textureTypes[i]); lua_setfield(L, -2, name); } @@ -3074,6 +3079,11 @@ lua_call(L, 0, 0); else lua_error(L); + + if (luaL_loadbuffer(L, (const char *)graphics_shader_lua, sizeof(graphics_shader_lua), "wrap_GraphicsShader.lua") == 0) + lua_call(L, 0, 0); + else + lua_error(L); return n; } diff -Nru love-11.1/src/modules/graphics/wrap_Graphics.h love-11.3/src/modules/graphics/wrap_Graphics.h --- love-11.1/src/modules/graphics/wrap_Graphics.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Graphics.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Graphics.lua love-11.3/src/modules/graphics/wrap_Graphics.lua --- love-11.1/src/modules/graphics/wrap_Graphics.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Graphics.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,468 +22,6 @@ 3. This notice may not be removed or altered from any source distribution. --]] -local table_concat = table.concat -local ipairs = ipairs - --- SHADERS - -local GLSL = {} - -GLSL.VERSION = { -- index using [target][gles] - glsl1 = {[false]="#version 120", [true]="#version 100"}, - glsl3 = {[false]="#version 330 core", [true]="#version 300 es"}, -} - -GLSL.SYNTAX = [[ -#if !defined(GL_ES) && __VERSION__ < 140 - #define lowp - #define mediump - #define highp -#endif -#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH) - #define LOVE_HIGHP_OR_MEDIUMP highp -#else - #define LOVE_HIGHP_OR_MEDIUMP mediump -#endif -#define number float -#define Image sampler2D -#define ArrayImage sampler2DArray -#define CubeImage samplerCube -#define VolumeImage sampler3D -#if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3) - #define DepthImage sampler2DShadow - #define DepthArrayImage sampler2DArrayShadow - #define DepthCubeImage samplerCubeShadow -#endif -#define extern uniform -#ifdef GL_EXT_texture_array -#extension GL_EXT_texture_array : enable -#endif -#ifdef GL_OES_texture_3D -#extension GL_OES_texture_3D : enable -#endif -#ifdef GL_OES_standard_derivatives -#extension GL_OES_standard_derivatives : enable -#endif -]] - --- Uniforms shared by the vertex and pixel shader stages. -GLSL.UNIFORMS = [[ -// According to the GLSL ES 1.0 spec, uniform precision must match between stages, -// but we can't guarantee that highp is always supported in fragment shaders... -// We *really* don't want to use mediump for these in vertex shaders though. -uniform LOVE_HIGHP_OR_MEDIUMP mat4 ViewSpaceFromLocal; -uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromView; -uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromLocal; -uniform LOVE_HIGHP_OR_MEDIUMP mat3 ViewNormalFromLocal; -uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize; - -// Compatibility -#define TransformMatrix ViewSpaceFromLocal -#define ProjectionMatrix ClipSpaceFromView -#define TransformProjectionMatrix ClipSpaceFromLocal -#define NormalMatrix ViewNormalFromLocal -]] - -GLSL.FUNCTIONS = [[ -#ifdef GL_ES - #if __VERSION__ >= 300 || defined(GL_EXT_texture_array) - precision lowp sampler2DArray; - #endif - #if __VERSION__ >= 300 || defined(GL_OES_texture_3D) - precision lowp sampler3D; - #endif - #if __VERSION__ >= 300 - precision lowp sampler2DShadow; - precision lowp samplerCubeShadow; - precision lowp sampler2DArrayShadow; - #endif -#endif - -#if __VERSION__ >= 130 && !defined(LOVE_GLSL1_ON_GLSL3) - #define Texel texture -#else - #if __VERSION__ >= 130 - #define texture2D Texel - #define texture3D Texel - #define textureCube Texel - #define texture2DArray Texel - #define love_texture2D texture - #define love_texture3D texture - #define love_textureCube texture - #define love_texture2DArray texture - #else - #define love_texture2D texture2D - #define love_texture3D texture3D - #define love_textureCube textureCube - #define love_texture2DArray texture2DArray - #endif - vec4 Texel(sampler2D s, vec2 c) { return love_texture2D(s, c); } - vec4 Texel(samplerCube s, vec3 c) { return love_textureCube(s, c); } - #if __VERSION__ > 100 || defined(GL_OES_texture_3D) - vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); } - #endif - #if __VERSION__ >= 130 || defined(GL_EXT_texture_array) - vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); } - #endif - #ifdef PIXEL - vec4 Texel(sampler2D s, vec2 c, float b) { return love_texture2D(s, c, b); } - vec4 Texel(samplerCube s, vec3 c, float b) { return love_textureCube(s, c, b); } - #if __VERSION__ > 100 || defined(GL_OES_texture_3D) - vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); } - #endif - #if __VERSION__ >= 130 || defined(GL_EXT_texture_array) - vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); } - #endif - #endif - #define texture love_texture -#endif - -float gammaToLinearPrecise(float c) { - return c <= 0.04045 ? c * 0.077399380804954 : pow((c + 0.055) * 0.9478672985782, 2.4); -} -vec3 gammaToLinearPrecise(vec3 c) { - bvec3 leq = lessThanEqual(c, vec3(0.04045)); - c.r = leq.r ? c.r * 0.077399380804954 : pow((c.r + 0.055) * 0.9478672985782, 2.4); - c.g = leq.g ? c.g * 0.077399380804954 : pow((c.g + 0.055) * 0.9478672985782, 2.4); - c.b = leq.b ? c.b * 0.077399380804954 : pow((c.b + 0.055) * 0.9478672985782, 2.4); - return c; -} -vec4 gammaToLinearPrecise(vec4 c) { return vec4(gammaToLinearPrecise(c.rgb), c.a); } -float linearToGammaPrecise(float c) { - return c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055; -} -vec3 linearToGammaPrecise(vec3 c) { - bvec3 lt = lessThanEqual(c, vec3(0.0031308)); - c.r = lt.r ? c.r * 12.92 : 1.055 * pow(c.r, 1.0 / 2.4) - 0.055; - c.g = lt.g ? c.g * 12.92 : 1.055 * pow(c.g, 1.0 / 2.4) - 0.055; - c.b = lt.b ? c.b * 12.92 : 1.055 * pow(c.b, 1.0 / 2.4) - 0.055; - return c; -} -vec4 linearToGammaPrecise(vec4 c) { return vec4(linearToGammaPrecise(c.rgb), c.a); } - -// http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1 - -mediump float gammaToLinearFast(mediump float c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); } -mediump vec3 gammaToLinearFast(mediump vec3 c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); } -mediump vec4 gammaToLinearFast(mediump vec4 c) { return vec4(gammaToLinearFast(c.rgb), c.a); } - -mediump float linearToGammaFast(mediump float c) { return max(1.055 * pow(max(c, 0.0), 0.41666666) - 0.055, 0.0); } -mediump vec3 linearToGammaFast(mediump vec3 c) { return max(1.055 * pow(max(c, vec3(0.0)), vec3(0.41666666)) - 0.055, vec3(0.0)); } -mediump vec4 linearToGammaFast(mediump vec4 c) { return vec4(linearToGammaFast(c.rgb), c.a); } - -#define gammaToLinear gammaToLinearFast -#define linearToGamma linearToGammaFast - -#ifdef LOVE_GAMMA_CORRECT - #define gammaCorrectColor gammaToLinear - #define unGammaCorrectColor linearToGamma - #define gammaCorrectColorPrecise gammaToLinearPrecise - #define unGammaCorrectColorPrecise linearToGammaPrecise - #define gammaCorrectColorFast gammaToLinearFast - #define unGammaCorrectColorFast linearToGammaFast -#else - #define gammaCorrectColor - #define unGammaCorrectColor - #define gammaCorrectColorPrecise - #define unGammaCorrectColorPrecise - #define gammaCorrectColorFast - #define unGammaCorrectColorFast -#endif]] - -GLSL.VERTEX = { - HEADER = [[ -#define love_Position gl_Position - -#if __VERSION__ >= 130 - #define attribute in - #define varying out - #ifndef LOVE_GLSL1_ON_GLSL3 - #define love_VertexID gl_VertexID - #define love_InstanceID gl_InstanceID - #endif -#endif - -#ifdef GL_ES - uniform mediump float love_PointSize; -#endif]], - - FUNCTIONS = [[ -void setPointSize() { -#ifdef GL_ES - gl_PointSize = love_PointSize; -#endif -}]], - - MAIN = [[ -attribute vec4 VertexPosition; -attribute vec4 VertexTexCoord; -attribute vec4 VertexColor; -attribute vec4 ConstantColor; - -varying vec4 VaryingTexCoord; -varying vec4 VaryingColor; - -vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition); - -void main() { - VaryingTexCoord = VertexTexCoord; - VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor; - setPointSize(); - love_Position = position(ClipSpaceFromLocal, VertexPosition); -}]], -} - -GLSL.PIXEL = { - HEADER = [[ -#ifdef GL_ES - precision mediump float; -#endif - -#define love_MaxCanvases gl_MaxDrawBuffers - -#if __VERSION__ >= 130 - #define varying in - layout(location = 0) out vec4 love_Canvases[love_MaxCanvases]; - #define love_PixelColor love_Canvases[0] -#else - #define love_Canvases gl_FragData - #define love_PixelColor gl_FragColor -#endif - -// See Shader::updateScreenParams in Shader.cpp. -#define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))]], - - FUNCTIONS = [[ -uniform sampler2D love_VideoYChannel; -uniform sampler2D love_VideoCbChannel; -uniform sampler2D love_VideoCrChannel; - -vec4 VideoTexel(vec2 texcoords) { - vec3 yuv; - yuv[0] = Texel(love_VideoYChannel, texcoords).r; - yuv[1] = Texel(love_VideoCbChannel, texcoords).r; - yuv[2] = Texel(love_VideoCrChannel, texcoords).r; - yuv += vec3(-0.0627451017, -0.501960814, -0.501960814); - - vec4 color; - color.r = dot(yuv, vec3(1.164, 0.000, 1.596)); - color.g = dot(yuv, vec3(1.164, -0.391, -0.813)); - color.b = dot(yuv, vec3(1.164, 2.018, 0.000)); - color.a = 1.0; - - return gammaCorrectColor(color); -}]], - - MAIN = [[ -uniform sampler2D MainTex; -varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord; -varying mediump vec4 VaryingColor; - -vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord); - -void main() { - love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord); -}]], - - MAIN_CUSTOM = [[ -varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord; -varying mediump vec4 VaryingColor; - -void effect(); - -void main() { - effect(); -}]], -} - -local function getLanguageTarget(code) - if not code then return nil end - return (code:match("^%s*#pragma language (%w+)")) or "glsl1" -end - -local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom) - stage = stage:upper() - local lines = { - GLSL.VERSION[lang][gles], - "#define " ..stage .. " " .. stage, - glsl1on3 and "#define LOVE_GLSL1_ON_GLSL3 1" or "", - gammacorrect and "#define LOVE_GAMMA_CORRECT 1" or "", - GLSL.SYNTAX, - GLSL[stage].HEADER, - GLSL.UNIFORMS, - GLSL.FUNCTIONS, - GLSL[stage].FUNCTIONS, - custom and GLSL[stage].MAIN_CUSTOM or GLSL[stage].MAIN, - ((lang == "glsl1" or glsl1on3) and not gles) and "#line 0" or "#line 1", - code, - } - return table_concat(lines, "\n") -end - -local function isVertexCode(code) - return code:match("vec4%s+position%s*%(") ~= nil -end - -local function isPixelCode(code) - if code:match("vec4%s+effect%s*%(") then - return true - elseif code:match("void%s+effect%s*%(") then - -- custom effect function - return true, true - else - return false - end -end - -function love.graphics._shaderCodeToGLSL(gles, arg1, arg2) - local vertexcode, pixelcode - local is_custompixel = false -- whether pixel code has "effects" function instead of "effect" - - if arg1 then - if isVertexCode(arg1) then - vertexcode = arg1 -- first arg contains vertex shader code - end - - local ispixel, isCustomPixel = isPixelCode(arg1) - if ispixel then - pixelcode = arg1 -- first arg contains pixel shader code - is_custompixel = isCustomPixel - end - end - - if arg2 then - if isVertexCode(arg2) then - vertexcode = arg2 -- second arg contains vertex shader code - end - - local ispixel, isCustomPixel = isPixelCode(arg2) - if ispixel then - pixelcode = arg2 -- second arg contains pixel shader code - is_custompixel = isCustomPixel - end - end - - local supportsGLSL3 = love.graphics.getSupported().glsl3 - local gammacorrect = love.graphics.isGammaCorrect() - - local targetlang = getLanguageTarget(pixelcode or vertexcode) - if getLanguageTarget(vertexcode or pixelcode) ~= targetlang then - error("vertex and pixel shader languages must match", 2) - end - - if targetlang == "glsl3" and not supportsGLSL3 then - error("GLSL 3 shaders are not supported on this system!", 2) - end - - if targetlang ~= nil and not GLSL.VERSION[targetlang] then - error("Invalid shader language: " .. targetlang, 2) - end - - local lang = targetlang or "glsl1" - local glsl1on3 = false - if lang == "glsl1" and supportsGLSL3 then - lang = "glsl3" - glsl1on3 = true - end - - if vertexcode then - vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect) - end - if pixelcode then - pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_custompixel) - end - - return vertexcode, pixelcode -end - -function love.graphics._transformGLSLErrorMessages(message) - local compiling = true - local shadertype = message:match("Cannot compile (%a+) shader code") - if not shadertype then - compiling = false - shadertype = message:match("Error validating (%a+) shader") - end - if not shadertype then return message end - local lines = {} - if compiling then - lines[#lines+1] = "Cannot compile "..shadertype.." shader code:" - else - lines[#lines+1] = "Error validating "..shadertype.." shader code:" - end - for l in message:gmatch("[^\n]+") do - -- nvidia compiler message: - -- 0() : error/warning [NUMBER]: - local linenumber, what, message = l:match("^0%((%d+)%)%s*:%s*(%w+)[^:]+:%s*(.+)$") - if not linenumber then - -- ati compiler message: - -- ERROR 0:: error/warning(#[NUMBER]) [ERRORNAME]: - linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$") - end - if not linenumber then - -- OSX compiler message (?): - -- ERROR: 0:: - what, linenumber, message = l:match("^(%w+): %d+:(%d+): (.+)$") - end - if not linenumber and l:match("^ERROR:") then - what = l - end - if linenumber and what and message then - lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message) - elseif what then - lines[#lines+1] = what - end - end - -- did not match any known error messages - if #lines == 1 then return message end - return table_concat(lines, "\n") -end - -local defaultcode = { - vertex = [[ -vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition) { - return clipSpaceFromLocal * localPosition; -}]], - pixel = [[ -vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) { - return Texel(tex, texcoord) * vcolor; -}]], - videopixel = [[ -void effect() { - love_PixelColor = VideoTexel(VaryingTexCoord.xy) * VaryingColor; -}]], - arraypixel = [[ -uniform ArrayImage MainTex; -void effect() { - love_PixelColor = Texel(MainTex, VaryingTexCoord.xyz) * VaryingColor; -}]], -} - -local defaults = {} -local defaults_gammacorrect = {} - -local langs = { - glsl1 = {target="glsl1", gles=false}, - essl1 = {target="glsl1", gles=true}, - glsl3 = {target="glsl3", gles=false}, - essl3 = {target="glsl3", gles=true}, -} - -for lang, info in pairs(langs) do - for _, gammacorrect in ipairs{false, true} do - local t = gammacorrect and defaults_gammacorrect or defaults - t[lang] = { - vertex = createShaderStageCode("VERTEX", defaultcode.vertex, info.target, info.gles, false, gammacorrect), - pixel = createShaderStageCode("PIXEL", defaultcode.pixel, info.target, info.gles, false, gammacorrect, false), - videopixel = createShaderStageCode("PIXEL", defaultcode.videopixel, info.target, info.gles, false, gammacorrect, true), - arraypixel = createShaderStageCode("PIXEL", defaultcode.arraypixel, info.target, info.gles, false, gammacorrect, true), - } - end -end - -love.graphics._setDefaultShaderCode(defaults, defaults_gammacorrect) - - function love.graphics.newVideo(file, settings) settings = settings == nil and {} or settings if type(settings) ~= "table" then error("bad argument #2 to newVideo (expected table)", 2) end diff -Nru love-11.1/src/modules/graphics/wrap_GraphicsShader.lua love-11.3/src/modules/graphics/wrap_GraphicsShader.lua --- love-11.1/src/modules/graphics/wrap_GraphicsShader.lua 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_GraphicsShader.lua 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,490 @@ +R"luastring"--( +-- DO NOT REMOVE THE ABOVE LINE. It is used to load this file as a C++ string. +-- There is a matching delimiter at the bottom of the file. + +--[[ +Copyright (c) 2006-2019 LOVE Development Team + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software +in a product, an acknowledgment in the product documentation would be +appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +--]] + +local table_concat = table.concat +local ipairs = ipairs + +local GLSL = {} + +GLSL.VERSION = { -- index using [target][gles] + glsl1 = {[false]="#version 120", [true]="#version 100"}, + glsl3 = {[false]="#version 330 core", [true]="#version 300 es"}, +} + +GLSL.SYNTAX = [[ +#if !defined(GL_ES) && __VERSION__ < 140 + #define lowp + #define mediump + #define highp +#endif +#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH) + #define LOVE_HIGHP_OR_MEDIUMP highp +#else + #define LOVE_HIGHP_OR_MEDIUMP mediump +#endif +#define number float +#define Image sampler2D +#define ArrayImage sampler2DArray +#define CubeImage samplerCube +#define VolumeImage sampler3D +#if __VERSION__ >= 300 && !defined(LOVE_GLSL1_ON_GLSL3) + #define DepthImage sampler2DShadow + #define DepthArrayImage sampler2DArrayShadow + #define DepthCubeImage samplerCubeShadow +#endif +#define extern uniform +#ifdef GL_EXT_texture_array +#extension GL_EXT_texture_array : enable +#endif +#ifdef GL_OES_texture_3D +#extension GL_OES_texture_3D : enable +#endif +#ifdef GL_OES_standard_derivatives +#extension GL_OES_standard_derivatives : enable +#endif +]] + +-- Uniforms shared by the vertex and pixel shader stages. +GLSL.UNIFORMS = [[ +// According to the GLSL ES 1.0 spec, uniform precision must match between stages, +// but we can't guarantee that highp is always supported in fragment shaders... +// We *really* don't want to use mediump for these in vertex shaders though. +uniform LOVE_HIGHP_OR_MEDIUMP mat4 ViewSpaceFromLocal; +uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromView; +uniform LOVE_HIGHP_OR_MEDIUMP mat4 ClipSpaceFromLocal; +uniform LOVE_HIGHP_OR_MEDIUMP mat3 ViewNormalFromLocal; +uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize; + +// Compatibility +#define TransformMatrix ViewSpaceFromLocal +#define ProjectionMatrix ClipSpaceFromView +#define TransformProjectionMatrix ClipSpaceFromLocal +#define NormalMatrix ViewNormalFromLocal +]] + +GLSL.FUNCTIONS = [[ +#ifdef GL_ES + #if __VERSION__ >= 300 || defined(GL_EXT_texture_array) + precision lowp sampler2DArray; + #endif + #if __VERSION__ >= 300 || defined(GL_OES_texture_3D) + precision lowp sampler3D; + #endif + #if __VERSION__ >= 300 + precision lowp sampler2DShadow; + precision lowp samplerCubeShadow; + precision lowp sampler2DArrayShadow; + #endif +#endif + +#if __VERSION__ >= 130 && !defined(LOVE_GLSL1_ON_GLSL3) + #define Texel texture +#else + #if __VERSION__ >= 130 + #define texture2D Texel + #define texture3D Texel + #define textureCube Texel + #define texture2DArray Texel + #define love_texture2D texture + #define love_texture3D texture + #define love_textureCube texture + #define love_texture2DArray texture + #else + #define love_texture2D texture2D + #define love_texture3D texture3D + #define love_textureCube textureCube + #define love_texture2DArray texture2DArray + #endif + vec4 Texel(sampler2D s, vec2 c) { return love_texture2D(s, c); } + vec4 Texel(samplerCube s, vec3 c) { return love_textureCube(s, c); } + #if __VERSION__ > 100 || defined(GL_OES_texture_3D) + vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); } + #endif + #if __VERSION__ >= 130 || defined(GL_EXT_texture_array) + vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); } + #endif + #ifdef PIXEL + vec4 Texel(sampler2D s, vec2 c, float b) { return love_texture2D(s, c, b); } + vec4 Texel(samplerCube s, vec3 c, float b) { return love_textureCube(s, c, b); } + #if __VERSION__ > 100 || defined(GL_OES_texture_3D) + vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); } + #endif + #if __VERSION__ >= 130 || defined(GL_EXT_texture_array) + vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); } + #endif + #endif + #define texture love_texture +#endif + +float gammaToLinearPrecise(float c) { + return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4); +} +vec3 gammaToLinearPrecise(vec3 c) { + bvec3 leq = lessThanEqual(c, vec3(0.04045)); + c.r = leq.r ? c.r / 12.92 : pow((c.r + 0.055) / 1.055, 2.4); + c.g = leq.g ? c.g / 12.92 : pow((c.g + 0.055) / 1.055, 2.4); + c.b = leq.b ? c.b / 12.92 : pow((c.b + 0.055) / 1.055, 2.4); + return c; +} +vec4 gammaToLinearPrecise(vec4 c) { return vec4(gammaToLinearPrecise(c.rgb), c.a); } +float linearToGammaPrecise(float c) { + return c < 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1.0 / 2.4) - 0.055; +} +vec3 linearToGammaPrecise(vec3 c) { + bvec3 lt = lessThanEqual(c, vec3(0.0031308)); + c.r = lt.r ? c.r * 12.92 : 1.055 * pow(c.r, 1.0 / 2.4) - 0.055; + c.g = lt.g ? c.g * 12.92 : 1.055 * pow(c.g, 1.0 / 2.4) - 0.055; + c.b = lt.b ? c.b * 12.92 : 1.055 * pow(c.b, 1.0 / 2.4) - 0.055; + return c; +} +vec4 linearToGammaPrecise(vec4 c) { return vec4(linearToGammaPrecise(c.rgb), c.a); } + +// http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1 + +mediump float gammaToLinearFast(mediump float c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); } +mediump vec3 gammaToLinearFast(mediump vec3 c) { return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); } +mediump vec4 gammaToLinearFast(mediump vec4 c) { return vec4(gammaToLinearFast(c.rgb), c.a); } + +mediump float linearToGammaFast(mediump float c) { return max(1.055 * pow(max(c, 0.0), 0.41666666) - 0.055, 0.0); } +mediump vec3 linearToGammaFast(mediump vec3 c) { return max(1.055 * pow(max(c, vec3(0.0)), vec3(0.41666666)) - 0.055, vec3(0.0)); } +mediump vec4 linearToGammaFast(mediump vec4 c) { return vec4(linearToGammaFast(c.rgb), c.a); } + +#define gammaToLinear gammaToLinearFast +#define linearToGamma linearToGammaFast + +#ifdef LOVE_GAMMA_CORRECT + #define gammaCorrectColor gammaToLinear + #define unGammaCorrectColor linearToGamma + #define gammaCorrectColorPrecise gammaToLinearPrecise + #define unGammaCorrectColorPrecise linearToGammaPrecise + #define gammaCorrectColorFast gammaToLinearFast + #define unGammaCorrectColorFast linearToGammaFast +#else + #define gammaCorrectColor + #define unGammaCorrectColor + #define gammaCorrectColorPrecise + #define unGammaCorrectColorPrecise + #define gammaCorrectColorFast + #define unGammaCorrectColorFast +#endif]] + +GLSL.VERTEX = { + HEADER = [[ +#define love_Position gl_Position + +#if __VERSION__ >= 130 + #define attribute in + #define varying out + #ifndef LOVE_GLSL1_ON_GLSL3 + #define love_VertexID gl_VertexID + #define love_InstanceID gl_InstanceID + #endif +#endif + +#ifdef GL_ES + uniform mediump float love_PointSize; +#endif]], + + FUNCTIONS = [[ +void setPointSize() { +#ifdef GL_ES + gl_PointSize = love_PointSize; +#endif +}]], + + MAIN = [[ +attribute vec4 VertexPosition; +attribute vec4 VertexTexCoord; +attribute vec4 VertexColor; +attribute vec4 ConstantColor; + +varying vec4 VaryingTexCoord; +varying vec4 VaryingColor; + +vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition); + +void main() { + VaryingTexCoord = VertexTexCoord; + VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor; + setPointSize(); + love_Position = position(ClipSpaceFromLocal, VertexPosition); +}]], +} + +GLSL.PIXEL = { + HEADER = [[ +#ifdef GL_ES + precision mediump float; +#endif + +#define love_MaxCanvases gl_MaxDrawBuffers + +#if __VERSION__ >= 130 + #define varying in + // Some drivers seem to make the pixel shader do more work when multiple + // pixel shader outputs are defined, even when only one is actually used. + // TODO: We should use reflection or something instead of this, to determine + // how many outputs are actually used in the shader code. + #ifdef LOVE_MULTI_CANVAS + layout(location = 0) out vec4 love_Canvases[love_MaxCanvases]; + #define love_PixelColor love_Canvases[0] + #else + layout(location = 0) out vec4 love_PixelColor; + #endif +#else + #ifdef LOVE_MULTI_CANVAS + #define love_Canvases gl_FragData + #endif + #define love_PixelColor gl_FragColor +#endif + +// See Shader::updateScreenParams in Shader.cpp. +#define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))]], + + FUNCTIONS = [[ +uniform sampler2D love_VideoYChannel; +uniform sampler2D love_VideoCbChannel; +uniform sampler2D love_VideoCrChannel; + +vec4 VideoTexel(vec2 texcoords) { + vec3 yuv; + yuv[0] = Texel(love_VideoYChannel, texcoords).r; + yuv[1] = Texel(love_VideoCbChannel, texcoords).r; + yuv[2] = Texel(love_VideoCrChannel, texcoords).r; + yuv += vec3(-0.0627451017, -0.501960814, -0.501960814); + + vec4 color; + color.r = dot(yuv, vec3(1.164, 0.000, 1.596)); + color.g = dot(yuv, vec3(1.164, -0.391, -0.813)); + color.b = dot(yuv, vec3(1.164, 2.018, 0.000)); + color.a = 1.0; + + return gammaCorrectColor(color); +}]], + + MAIN = [[ +uniform sampler2D MainTex; +varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord; +varying mediump vec4 VaryingColor; + +vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord); + +void main() { + love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord); +}]], + + MAIN_CUSTOM = [[ +varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord; +varying mediump vec4 VaryingColor; + +void effect(); + +void main() { + effect(); +}]], +} + +local function getLanguageTarget(code) + if not code then return nil end + return (code:match("^%s*#pragma language (%w+)")) or "glsl1" +end + +local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom, multicanvas) + stage = stage:upper() + local lines = { + GLSL.VERSION[lang][gles], + "#define " ..stage .. " " .. stage, + glsl1on3 and "#define LOVE_GLSL1_ON_GLSL3 1" or "", + gammacorrect and "#define LOVE_GAMMA_CORRECT 1" or "", + multicanvas and "#define LOVE_MULTI_CANVAS 1" or "", + GLSL.SYNTAX, + GLSL[stage].HEADER, + GLSL.UNIFORMS, + GLSL.FUNCTIONS, + GLSL[stage].FUNCTIONS, + custom and GLSL[stage].MAIN_CUSTOM or GLSL[stage].MAIN, + ((lang == "glsl1" or glsl1on3) and not gles) and "#line 0" or "#line 1", + code, + } + return table_concat(lines, "\n") +end + +local function isVertexCode(code) + return code:match("vec4%s+position%s*%(") ~= nil +end + +local function isPixelCode(code) + if code:match("vec4%s+effect%s*%(") then + return true + elseif code:match("void%s+effect%s*%(") then -- custom effect function + local multicanvas = code:match("love_Canvases") ~= nil + return true, true, multicanvas + else + return false + end +end + +function love.graphics._shaderCodeToGLSL(gles, arg1, arg2) + local vertexcode, pixelcode + local is_custompixel = false -- whether pixel code has "effects" function instead of "effect" + local is_multicanvas = false + + if arg1 then + if isVertexCode(arg1) then + vertexcode = arg1 -- first arg contains vertex shader code + end + + local ispixel, isCustomPixel, isMultiCanvas = isPixelCode(arg1) + if ispixel then + pixelcode = arg1 -- first arg contains pixel shader code + is_custompixel, is_multicanvas = isCustomPixel, isMultiCanvas + end + end + + if arg2 then + if isVertexCode(arg2) then + vertexcode = arg2 -- second arg contains vertex shader code + end + + local ispixel, isCustomPixel, isMultiCanvas = isPixelCode(arg2) + if ispixel then + pixelcode = arg2 -- second arg contains pixel shader code + is_custompixel, is_multicanvas = isCustomPixel, isMultiCanvas + end + end + + local supportsGLSL3 = love.graphics.getSupported().glsl3 + local gammacorrect = love.graphics.isGammaCorrect() + + local targetlang = getLanguageTarget(pixelcode or vertexcode) + if getLanguageTarget(vertexcode or pixelcode) ~= targetlang then + error("vertex and pixel shader languages must match", 2) + end + + if targetlang == "glsl3" and not supportsGLSL3 then + error("GLSL 3 shaders are not supported on this system!", 2) + end + + if targetlang ~= nil and not GLSL.VERSION[targetlang] then + error("Invalid shader language: " .. targetlang, 2) + end + + local lang = targetlang or "glsl1" + local glsl1on3 = false + if lang == "glsl1" and supportsGLSL3 then + lang = "glsl3" + glsl1on3 = true + end + + if vertexcode then + vertexcode = createShaderStageCode("VERTEX", vertexcode, lang, gles, glsl1on3, gammacorrect) + end + if pixelcode then + pixelcode = createShaderStageCode("PIXEL", pixelcode, lang, gles, glsl1on3, gammacorrect, is_custompixel, is_multicanvas) + end + + return vertexcode, pixelcode +end + +function love.graphics._transformGLSLErrorMessages(message) + local shadertype = message:match("Cannot compile (%a+) shader code") + local compiling = shadertype ~= nil + if not shadertype then + shadertype = message:match("Error validating (%a+) shader") + end + if not shadertype then return message end + local lines = {} + local prefix = compiling and "Cannot compile " or "Error validating " + lines[#lines+1] = prefix..shadertype.." shader code:" + for l in message:gmatch("[^\n]+") do + -- nvidia: 0() : error/warning [NUMBER]: + local linenumber, what, message = l:match("^0%((%d+)%)%s*:%s*(%w+)[^:]+:%s*(.+)$") + if not linenumber then + -- AMD: ERROR 0:: error/warning(#[NUMBER]) [ERRORNAME]: + linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$") + end + if not linenumber then + -- macOS (?): ERROR: 0:: + what, linenumber, message = l:match("^(%w+): %d+:(%d+): (.+)$") + end + if not linenumber and l:match("^ERROR:") then + what = l + end + if linenumber and what and message then + lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message) + elseif what then + lines[#lines+1] = what + end + end + -- did not match any known error messages + if #lines == 1 then return message end + return table_concat(lines, "\n") +end + +local defaultcode = { + vertex = [[ +vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition) { + return clipSpaceFromLocal * localPosition; +}]], + pixel = [[ +vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord) { + return Texel(tex, texcoord) * vcolor; +}]], + videopixel = [[ +void effect() { + love_PixelColor = VideoTexel(VaryingTexCoord.xy) * VaryingColor; +}]], + arraypixel = [[ +uniform ArrayImage MainTex; +void effect() { + love_PixelColor = Texel(MainTex, VaryingTexCoord.xyz) * VaryingColor; +}]], +} + +local defaults = {} +local defaults_gammacorrect = {} + +local langs = { + glsl1 = {target="glsl1", gles=false}, + essl1 = {target="glsl1", gles=true}, + glsl3 = {target="glsl3", gles=false}, + essl3 = {target="glsl3", gles=true}, +} + +for lang, info in pairs(langs) do + for _, gammacorrect in ipairs{false, true} do + local t = gammacorrect and defaults_gammacorrect or defaults + t[lang] = { + vertex = createShaderStageCode("VERTEX", defaultcode.vertex, info.target, info.gles, false, gammacorrect), + pixel = createShaderStageCode("PIXEL", defaultcode.pixel, info.target, info.gles, false, gammacorrect, false), + videopixel = createShaderStageCode("PIXEL", defaultcode.videopixel, info.target, info.gles, false, gammacorrect, true), + arraypixel = createShaderStageCode("PIXEL", defaultcode.arraypixel, info.target, info.gles, false, gammacorrect, true), + } + end +end + +love.graphics._setDefaultShaderCode(defaults, defaults_gammacorrect) + +-- DO NOT REMOVE THE NEXT LINE. It is used to load this file as a C++ string. +--)luastring"--" diff -Nru love-11.1/src/modules/graphics/wrap_Image.cpp love-11.3/src/modules/graphics/wrap_Image.cpp --- love-11.1/src/modules/graphics/wrap_Image.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Image.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Image.h love-11.3/src/modules/graphics/wrap_Image.h --- love-11.1/src/modules/graphics/wrap_Image.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Image.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Mesh.cpp love-11.3/src/modules/graphics/wrap_Mesh.cpp --- love-11.1/src/modules/graphics/wrap_Mesh.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Mesh.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -130,19 +130,33 @@ int w_Mesh_setVertices(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); - size_t vertoffset = (size_t) luaL_optnumber(L, 3, 1) - 1; - if (vertoffset >= t->getVertexCount()) - return luaL_error(L, "Invalid vertex start index (must be between 1 and %d)", (int) t->getVertexCount()); + int vertstart = (int) luaL_optnumber(L, 3, 1) - 1; + + int vertcount = -1; + if (!lua_isnoneornil(L, 4)) + { + vertcount = (int) luaL_checknumber(L, 4); + if (vertcount <= 0) + return luaL_error(L, "Vertex count must be greater than 0."); + } size_t stride = t->getVertexStride(); - size_t byteoffset = vertoffset * stride; + size_t byteoffset = vertstart * stride; + int totalverts = (int) t->getVertexCount(); + + if (vertstart >= totalverts) + return luaL_error(L, "Invalid vertex start index (must be between 1 and %d)", totalverts); if (luax_istype(L, 2, Data::type)) { Data *d = luax_checktype(L, 2); - size_t datasize = std::min(d->getSize(), (t->getVertexCount() - vertoffset) * stride); + vertcount = vertcount >= 0 ? vertcount : (totalverts - vertstart); + if (vertstart + vertcount > totalverts) + return luaL_error(L, "Too many vertices (expected at most %d, got %d)", totalverts - vertstart, vertcount); + + size_t datasize = std::min(d->getSize(), vertcount * stride); char *bytedata = (char *) t->mapVertexData() + byteoffset; memcpy(bytedata, d->getData(), datasize); @@ -152,10 +166,11 @@ } luaL_checktype(L, 2, LUA_TTABLE); - int nvertices = (int) luax_objlen(L, 2); + int tablelen = (int) luax_objlen(L, 2); - if (vertoffset + nvertices > t->getVertexCount()) - return luaL_error(L, "Too many vertices (expected at most %d, got %d)", (int) t->getVertexCount() - (int) vertoffset, (int) nvertices); + vertcount = vertcount >= 0 ? std::min(vertcount, tablelen) : tablelen; + if (vertstart + vertcount > totalverts) + return luaL_error(L, "Too many vertices (expected at most %d, got %d)", totalverts - vertstart, vertcount); const std::vector &vertexformat = t->getVertexFormat(); @@ -165,7 +180,7 @@ char *data = (char *) t->mapVertexData() + byteoffset; - for (int i = 0; i < nvertices; i++) + for (int i = 0; i < vertcount; i++) { // get vertices[vertindex] lua_rawgeti(L, 2, i + 1); @@ -181,14 +196,13 @@ { // Fetch the values from Lua and store them in data buffer. data = luax_writeAttributeData(L, idx, format.type, format.components, data); - idx += format.components; } lua_pop(L, ncomponents + 1); } - t->unmapVertexData(byteoffset, nvertices * stride); + t->unmapVertexData(byteoffset, vertcount * stride); return 0; } diff -Nru love-11.1/src/modules/graphics/wrap_Mesh.h love-11.3/src/modules/graphics/wrap_Mesh.h --- love-11.1/src/modules/graphics/wrap_Mesh.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Mesh.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_ParticleSystem.cpp love-11.3/src/modules/graphics/wrap_ParticleSystem.cpp --- love-11.1/src/modules/graphics/wrap_ParticleSystem.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_ParticleSystem.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_ParticleSystem.h love-11.3/src/modules/graphics/wrap_ParticleSystem.h --- love-11.1/src/modules/graphics/wrap_ParticleSystem.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_ParticleSystem.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Quad.cpp love-11.3/src/modules/graphics/wrap_Quad.cpp --- love-11.1/src/modules/graphics/wrap_Quad.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Quad.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Quad.h love-11.3/src/modules/graphics/wrap_Quad.h --- love-11.1/src/modules/graphics/wrap_Quad.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Quad.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Shader.cpp love-11.3/src/modules/graphics/wrap_Shader.cpp --- love-11.1/src/modules/graphics/wrap_Shader.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Shader.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Shader.h love-11.3/src/modules/graphics/wrap_Shader.h --- love-11.1/src/modules/graphics/wrap_Shader.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Shader.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_SpriteBatch.cpp love-11.3/src/modules/graphics/wrap_SpriteBatch.cpp --- love-11.1/src/modules/graphics/wrap_SpriteBatch.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_SpriteBatch.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_SpriteBatch.h love-11.3/src/modules/graphics/wrap_SpriteBatch.h --- love-11.1/src/modules/graphics/wrap_SpriteBatch.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_SpriteBatch.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Text.cpp love-11.3/src/modules/graphics/wrap_Text.cpp --- love-11.1/src/modules/graphics/wrap_Text.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Text.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Text.h love-11.3/src/modules/graphics/wrap_Text.h --- love-11.1/src/modules/graphics/wrap_Text.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Text.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Texture.cpp love-11.3/src/modules/graphics/wrap_Texture.cpp --- love-11.1/src/modules/graphics/wrap_Texture.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Texture.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Texture.h love-11.3/src/modules/graphics/wrap_Texture.h --- love-11.1/src/modules/graphics/wrap_Texture.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Texture.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Video.cpp love-11.3/src/modules/graphics/wrap_Video.cpp --- love-11.1/src/modules/graphics/wrap_Video.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Video.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Video.h love-11.3/src/modules/graphics/wrap_Video.h --- love-11.1/src/modules/graphics/wrap_Video.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Video.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/graphics/wrap_Video.lua love-11.3/src/modules/graphics/wrap_Video.lua --- love-11.1/src/modules/graphics/wrap_Video.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/graphics/wrap_Video.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/CompressedImageData.cpp love-11.3/src/modules/image/CompressedImageData.cpp --- love-11.1/src/modules/image/CompressedImageData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/CompressedImageData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/CompressedImageData.h love-11.3/src/modules/image/CompressedImageData.h --- love-11.1/src/modules/image/CompressedImageData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/CompressedImageData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/CompressedSlice.cpp love-11.3/src/modules/image/CompressedSlice.cpp --- love-11.1/src/modules/image/CompressedSlice.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/CompressedSlice.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -46,23 +46,19 @@ } CompressedSlice::CompressedSlice(PixelFormat format, int width, int height, CompressedMemory *memory, size_t offset, size_t size) - : memory(memory) + : ImageDataBase(format, width, height) + , memory(memory) , offset(offset) , dataSize(size) { - this->format = format; - this->width = width; - this->height = height; } CompressedSlice::CompressedSlice(const CompressedSlice &s) - : memory(s.memory) + : ImageDataBase(s.getFormat(), s.getWidth(), s.getHeight()) + , memory(s.memory) , offset(s.offset) , dataSize(s.dataSize) { - this->format = s.getFormat(); - this->width = s.getWidth(); - this->height = s.getHeight(); } CompressedSlice::~CompressedSlice() diff -Nru love-11.1/src/modules/image/CompressedSlice.h love-11.3/src/modules/image/CompressedSlice.h --- love-11.1/src/modules/image/CompressedSlice.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/CompressedSlice.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/FormatHandler.cpp love-11.3/src/modules/image/FormatHandler.cpp --- love-11.1/src/modules/image/FormatHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/FormatHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/FormatHandler.h love-11.3/src/modules/image/FormatHandler.h --- love-11.1/src/modules/image/FormatHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/FormatHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/Image.cpp love-11.3/src/modules/image/Image.cpp --- love-11.1/src/modules/image/Image.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/Image.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -43,7 +43,7 @@ { using namespace magpie; - halfInit(); // Makes sure half-float conversions can be used. + float16Init(); // Makes sure half-float conversions can be used. formatHandlers = { new PNGHandler, diff -Nru love-11.1/src/modules/image/ImageDataBase.cpp love-11.3/src/modules/image/ImageDataBase.cpp --- love-11.1/src/modules/image/ImageDataBase.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/ImageDataBase.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,10 +25,10 @@ namespace image { -ImageDataBase::ImageDataBase() - : format(PIXELFORMAT_UNKNOWN) - , width(0) - , height(0) +ImageDataBase::ImageDataBase(PixelFormat format, int width, int height) + : format(format) + , width(width) + , height(height) { } diff -Nru love-11.1/src/modules/image/ImageDataBase.h love-11.3/src/modules/image/ImageDataBase.h --- love-11.1/src/modules/image/ImageDataBase.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/ImageDataBase.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,6 @@ { public: - ImageDataBase(); virtual ~ImageDataBase() {} PixelFormat getFormat() const; @@ -45,6 +44,8 @@ protected: + ImageDataBase(PixelFormat format, int width, int height); + PixelFormat format; int width; int height; diff -Nru love-11.1/src/modules/image/ImageData.cpp love-11.3/src/modules/image/ImageData.cpp --- love-11.1/src/modules/image/ImageData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/ImageData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -22,6 +22,8 @@ #include "Image.h" #include "filesystem/Filesystem.h" +#include // min/max + using love::thread::Lock; namespace love @@ -32,19 +34,17 @@ love::Type ImageData::type("ImageData", &Data::type); ImageData::ImageData(Data *data) + : ImageDataBase(PIXELFORMAT_UNKNOWN, 0, 0) { decode(data); } ImageData::ImageData(int width, int height, PixelFormat format) + : ImageDataBase(format, width, height) { if (!validPixelFormat(format)) throw love::Exception("Unsupported pixel format for ImageData"); - this->width = width; - this->height = height; - this->format = format; - create(width, height, format); // Set to black/transparency. @@ -52,14 +52,11 @@ } ImageData::ImageData(int width, int height, PixelFormat format, void *data, bool own) + : ImageDataBase(format, width, height) { if (!validPixelFormat(format)) throw love::Exception("Unsupported pixel format for ImageData"); - this->width = width; - this->height = height; - this->format = format; - if (own) this->data = (unsigned char *) data; else @@ -67,11 +64,8 @@ } ImageData::ImageData(const ImageData &c) + : ImageDataBase(c.format, c.width, c.height) { - width = c.width; - height = c.height; - format = c.format; - create(width, height, format, c.getData()); } @@ -106,6 +100,9 @@ decodeHandler = nullptr; this->format = format; + + pixelSetFunction = getPixelSetFunction(format); + pixelGetFunction = getPixelGetFunction(format); } void ImageData::decode(Data *data) @@ -161,6 +158,9 @@ this->format = decodedimage.format; decodeHandler = decoder; + + pixelSetFunction = getPixelSetFunction(format); + pixelGetFunction = getPixelGetFunction(format); } love::filesystem::FileData *ImageData::encode(FormatHandler::EncodedFormat encodedFormat, const char *filename, bool writefile) const @@ -261,27 +261,393 @@ return x >= 0 && x < getWidth() && y >= 0 && y < getHeight(); } -void ImageData::setPixel(int x, int y, const Pixel &p) +static float clamp01(float x) +{ + return std::min(std::max(x, 0.0f), 1.0f); +} + +static void setPixelR8(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba8[0] = (uint8) (clamp01(c.r) * 255.0f + 0.5f); +} + +static void setPixelRG8(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba8[0] = (uint8) (clamp01(c.r) * 255.0f + 0.5f); + p->rgba8[1] = (uint8) (clamp01(c.g) * 255.0f + 0.5f); +} + +static void setPixelRGBA8(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba8[0] = (uint8) (clamp01(c.r) * 255.0f + 0.5f); + p->rgba8[1] = (uint8) (clamp01(c.g) * 255.0f + 0.5f); + p->rgba8[2] = (uint8) (clamp01(c.b) * 255.0f + 0.5f); + p->rgba8[3] = (uint8) (clamp01(c.a) * 255.0f + 0.5f); +} + +static void setPixelR16(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba16[0] = (uint16) (clamp01(c.r) * 65535.0f + 0.5f); +} + +static void setPixelRG16(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba16[0] = (uint16) (clamp01(c.r) * 65535.0f + 0.5f); + p->rgba16[1] = (uint16) (clamp01(c.g) * 65535.0f + 0.5f); +} + +static void setPixelRGBA16(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba16[0] = (uint16) (clamp01(c.r) * 65535.0f + 0.5f); + p->rgba16[1] = (uint16) (clamp01(c.b) * 65535.0f + 0.5f); + p->rgba16[2] = (uint16) (clamp01(c.g) * 65535.0f + 0.5f); + p->rgba16[3] = (uint16) (clamp01(c.a) * 65535.0f + 0.5f); +} + +static void setPixelR16F(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba16f[0] = float32to16(c.r); +} + +static void setPixelRG16F(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba16f[0] = float32to16(c.r); + p->rgba16f[1] = float32to16(c.g); +} + +static void setPixelRGBA16F(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba16f[0] = float32to16(c.r); + p->rgba16f[1] = float32to16(c.g); + p->rgba16f[2] = float32to16(c.b); + p->rgba16f[3] = float32to16(c.a); +} + +static void setPixelR32F(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba32f[0] = c.r; +} + +static void setPixelRG32F(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba32f[0] = c.r; + p->rgba32f[1] = c.g; +} + +static void setPixelRGBA32F(const Colorf &c, ImageData::Pixel *p) +{ + p->rgba32f[0] = c.r; + p->rgba32f[1] = c.g; + p->rgba32f[2] = c.b; + p->rgba32f[3] = c.a; +} + +static void setPixelRGBA4(const Colorf &c, ImageData::Pixel *p) +{ + // LSB->MSB: [a, b, g, r] + uint16 r = (uint16) (clamp01(c.r) * 0xF + 0.5); + uint16 g = (uint16) (clamp01(c.g) * 0xF + 0.5); + uint16 b = (uint16) (clamp01(c.b) * 0xF + 0.5); + uint16 a = (uint16) (clamp01(c.a) * 0xF + 0.5); + p->packed16 = (r << 12) | (g << 8) | (b << 4) | (a << 0); +} + +static void setPixelRGB5A1(const Colorf &c, ImageData::Pixel *p) +{ + // LSB->MSB: [a, b, g, r] + uint16 r = (uint16) (clamp01(c.r) * 0x1F + 0.5); + uint16 g = (uint16) (clamp01(c.g) * 0x1F + 0.5); + uint16 b = (uint16) (clamp01(c.b) * 0x1F + 0.5); + uint16 a = (uint16) (clamp01(c.a) * 0x1 + 0.5); + p->packed16 = (r << 11) | (g << 6) | (b << 1) | (a << 0); +} + +static void setPixelRGB565(const Colorf &c, ImageData::Pixel *p) +{ + // LSB->MSB: [b, g, r] + uint16 r = (uint16) (clamp01(c.r) * 0x1F + 0.5); + uint16 g = (uint16) (clamp01(c.g) * 0x3F + 0.5); + uint16 b = (uint16) (clamp01(c.b) * 0x1F + 0.5); + p->packed16 = (r << 11) | (g << 5) | (b << 0); +} + +static void setPixelRGB10A2(const Colorf &c, ImageData::Pixel *p) +{ + // LSB->MSB: [r, g, b, a] + uint32 r = (uint32) (clamp01(c.r) * 0x3FF + 0.5); + uint32 g = (uint32) (clamp01(c.g) * 0x3FF + 0.5); + uint32 b = (uint32) (clamp01(c.b) * 0x3FF + 0.5); + uint32 a = (uint32) (clamp01(c.a) * 0x3 + 0.5); + p->packed32 = (r << 0) | (g << 10) | (b << 20) | (a << 30); +} + +static void setPixelRG11B10F(const Colorf &c, ImageData::Pixel *p) +{ + // LSB->MSB: [r, g, b] + float11 r = float32to11(c.r); + float11 g = float32to11(c.g); + float10 b = float32to10(c.b); + p->packed32 = (r << 0) | (g << 11) | (b << 22); +} + +static void getPixelR8(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba8[0] / 255.0f; + c.g = 0.0f; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRG8(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba8[0] / 255.0f; + c.g = p->rgba8[1] / 255.0f; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRGBA8(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba8[0] / 255.0f; + c.g = p->rgba8[1] / 255.0f; + c.b = p->rgba8[2] / 255.0f; + c.a = p->rgba8[3] / 255.0f; +} + +static void getPixelR16(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba16[0] / 65535.0f; + c.g = 0.0f; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRG16(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba16[0] / 65535.0f; + c.g = p->rgba16[1] / 65535.0f; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRGBA16(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba16[0] / 65535.0f; + c.g = p->rgba16[1] / 65535.0f; + c.b = p->rgba16[2] / 65535.0f; + c.a = p->rgba16[3] / 65535.0f; +} + +static void getPixelR16F(const ImageData::Pixel *p, Colorf &c) +{ + c.r = float16to32(p->rgba16f[0]); + c.g = 0.0f; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRG16F(const ImageData::Pixel *p, Colorf &c) +{ + c.r = float16to32(p->rgba16f[0]); + c.g = float16to32(p->rgba16f[1]); + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRGBA16F(const ImageData::Pixel *p, Colorf &c) +{ + c.r = float16to32(p->rgba16f[0]); + c.g = float16to32(p->rgba16f[1]); + c.b = float16to32(p->rgba16f[2]); + c.a = float16to32(p->rgba16f[3]); +} + +static void getPixelR32F(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba32f[0]; + c.g = 0.0f; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRG32F(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba32f[0]; + c.g = p->rgba32f[1]; + c.b = 0.0f; + c.a = 1.0f; +} + +static void getPixelRGBA32F(const ImageData::Pixel *p, Colorf &c) +{ + c.r = p->rgba32f[0]; + c.g = p->rgba32f[1]; + c.b = p->rgba32f[2]; + c.a = p->rgba32f[3]; +} + +static void getPixelRGBA4(const ImageData::Pixel *p, Colorf &c) +{ + // LSB->MSB: [a, b, g, r] + c.r = ((p->packed16 >> 12) & 0xF) / (float)0xF; + c.g = ((p->packed16 >> 8) & 0xF) / (float)0xF; + c.b = ((p->packed16 >> 4) & 0xF) / (float)0xF; + c.a = ((p->packed16 >> 0) & 0xF) / (float)0xF; +} + +static void getPixelRGB5A1(const ImageData::Pixel *p, Colorf &c) +{ + // LSB->MSB: [a, b, g, r] + c.r = ((p->packed16 >> 11) & 0x1F) / (float)0x1F; + c.g = ((p->packed16 >> 6) & 0x1F) / (float)0x1F; + c.b = ((p->packed16 >> 1) & 0x1F) / (float)0x1F; + c.a = ((p->packed16 >> 0) & 0x1) / (float)0x1; +} + +static void getPixelRGB565(const ImageData::Pixel *p, Colorf &c) +{ + // LSB->MSB: [b, g, r] + c.r = ((p->packed16 >> 11) & 0x1F) / (float)0x1F; + c.g = ((p->packed16 >> 5) & 0x3F) / (float)0x3F; + c.b = ((p->packed16 >> 0) & 0x1F) / (float)0x1F; + c.a = 1.0f; +} + +static void getPixelRGB10A2(const ImageData::Pixel *p, Colorf &c) +{ + // LSB->MSB: [r, g, b, a] + c.r = ((p->packed32 >> 0) & 0x3FF) / (float)0x3FF; + c.g = ((p->packed32 >> 10) & 0x3FF) / (float)0x3FF; + c.b = ((p->packed32 >> 20) & 0x3FF) / (float)0x3FF; + c.a = ((p->packed32 >> 30) & 0x3) / (float)0x3; +} + +static void getPixelRG11B10F(const ImageData::Pixel *p, Colorf &c) +{ + // LSB->MSB: [r, g, b] + c.r = float11to32((float11) ((p->packed32 >> 0) & 0x7FF)); + c.g = float11to32((float11) ((p->packed32 >> 11) & 0x7FF)); + c.b = float10to32((float10) ((p->packed32 >> 22) & 0x3FF)); + c.a = 1.0f; +} + +void ImageData::setPixel(int x, int y, const Colorf &c) { if (!inside(x, y)) throw love::Exception("Attempt to set out-of-range pixel!"); size_t pixelsize = getPixelSize(); - unsigned char *pixeldata = data + ((y * width + x) * pixelsize); + Pixel *p = (Pixel *) (data + ((y * width + x) * pixelsize)); + + if (pixelSetFunction == nullptr) + throw love::Exception("Unhandled pixel format %d in ImageData::setPixel", format); Lock lock(mutex); - memcpy(pixeldata, &p, pixelsize); + + pixelSetFunction(c, p); } -void ImageData::getPixel(int x, int y, Pixel &p) const +void ImageData::getPixel(int x, int y, Colorf &c) const { if (!inside(x, y)) throw love::Exception("Attempt to get out-of-range pixel!"); size_t pixelsize = getPixelSize(); + const Pixel *p = (const Pixel *) (data + ((y * width + x) * pixelsize)); + + if (pixelGetFunction == nullptr) + throw love::Exception("Unhandled pixel format %d in ImageData::setPixel", format); Lock lock(mutex); - memcpy(&p, data + ((y * width + x) * pixelsize), pixelsize); + + pixelGetFunction(p, c); +} + +Colorf ImageData::getPixel(int x, int y) const +{ + Colorf c; + getPixel(x, y, c); + return c; +} + +union Row +{ + uint8 *u8; + uint16 *u16; + float16 *f16; + float *f32; +}; + +static void pasteRGBA8toRGBA16(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.u16[i] = (uint16) src.u8[i] << 8u; +} + +static void pasteRGBA8toRGBA16F(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.f16[i] = float32to16(src.u8[i] / 255.0f); +} + +static void pasteRGBA8toRGBA32F(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.f32[i] = src.u8[i] / 255.0f; +} + +static void pasteRGBA16toRGBA8(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.u8[i] = src.u16[i] >> 8u; +} + +static void pasteRGBA16toRGBA16F(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.f16[i] = float32to16(src.u16[i] / 65535.0f); +} + +static void pasteRGBA16toRGBA32F(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.f32[i] = src.u16[i] / 65535.0f; +} + +static void pasteRGBA16FtoRGBA8(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.u8[i] = (uint8) (clamp01(float16to32(src.f16[i])) * 255.0f + 0.5f); +} + +static void pasteRGBA16FtoRGBA16(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.u16[i] = (uint16) (clamp01(float16to32(src.f16[i])) * 65535.0f + 0.5f); +} + +static void pasteRGBA16FtoRGBA32F(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.f32[i] = float16to32(src.f16[i]); +} + +static void pasteRGBA32FtoRGBA8(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.u8[i] = (uint8) (clamp01(src.f32[i]) * 255.0f + 0.5f); +} + +static void pasteRGBA32FtoRGBA16(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.u16[i] = (uint16) (clamp01(src.f32[i]) * 65535.0f + 0.5f); +} + +static void pasteRGBA32FtoRGBA16F(Row src, Row dst, int w) +{ + for (int i = 0; i < w * 4; i++) + dst.f16[i] = float32to16(src.f32[i]); } void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, int sh) @@ -346,6 +712,9 @@ uint8 *s = (uint8 *) src->getData(); uint8 *d = (uint8 *) getData(); + auto getfunction = src->pixelGetFunction; + auto setfunction = pixelSetFunction; + // If the dimensions match up, copy the entire memory stream in one go if (srcformat == dstformat && (sw == dstW && dstW == srcW && sh == dstH && dstH == srcH)) { @@ -391,83 +760,21 @@ pasteRGBA32FtoRGBA16F(rowsrc, rowdst, sw); else - throw love::Exception("Unsupported pixel format combination in ImageData:paste!"); + { + // Slow path: convert src -> Colorf -> dst. + Colorf c; + for (int x = 0; x < sw; x++) + { + auto srcp = (const Pixel *) (rowsrc.u8 + x * srcpixelsize); + auto dstp = (Pixel *) (rowdst.u8 + x * dstpixelsize); + getfunction(srcp, c); + setfunction(c, dstp); + } + } } } } -void ImageData::pasteRGBA8toRGBA16(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.u16[i] = (uint16) src.u8[i] << 8u; -} - -void ImageData::pasteRGBA8toRGBA16F(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.f16[i] = floatToHalf(src.u8[i] / 255.0f); -} - -void ImageData::pasteRGBA8toRGBA32F(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.f32[i] = src.u8[i] / 255.0f; -} - -void ImageData::pasteRGBA16toRGBA8(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.u8[i] = src.u16[i] >> 8u; -} - -void ImageData::pasteRGBA16toRGBA16F(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.f16[i] = floatToHalf(src.u16[i] / 65535.0f); -} - -void ImageData::pasteRGBA16toRGBA32F(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.f32[i] = src.u16[i] / 65535.0f; -} - -void ImageData::pasteRGBA16FtoRGBA8(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.u8[i] = (uint8) (halfToFloat(src.f16[i]) * 255.0f); -} - -void ImageData::pasteRGBA16FtoRGBA16(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.u16[i] = (uint16) (halfToFloat(src.f16[i]) * 65535.0f); -} - -void ImageData::pasteRGBA16FtoRGBA32F(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.f32[i] = halfToFloat(src.f16[i]); -} - -void ImageData::pasteRGBA32FtoRGBA8(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.u8[i] = (uint8) (src.f32[i] * 255.0f); -} - -void ImageData::pasteRGBA32FtoRGBA16(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.u16[i] = (uint16) (src.f32[i] * 65535.0f); -} - -void ImageData::pasteRGBA32FtoRGBA16F(Row src, Row dst, int w) -{ - for (int i = 0; i < w * 4; i++) - dst.f16[i] = (uint16) floatToHalf(src.f32[i]); -} - love::thread::Mutex *ImageData::getMutex() const { return mutex; @@ -482,16 +789,95 @@ { switch (format) { + case PIXELFORMAT_R8: + case PIXELFORMAT_RG8: case PIXELFORMAT_RGBA8: + case PIXELFORMAT_R16: + case PIXELFORMAT_RG16: case PIXELFORMAT_RGBA16: + case PIXELFORMAT_R16F: + case PIXELFORMAT_RG16F: case PIXELFORMAT_RGBA16F: + case PIXELFORMAT_R32F: + case PIXELFORMAT_RG32F: case PIXELFORMAT_RGBA32F: + case PIXELFORMAT_RGBA4: + case PIXELFORMAT_RGB5A1: + case PIXELFORMAT_RGB565: + case PIXELFORMAT_RGB10A2: + case PIXELFORMAT_RG11B10F: return true; default: return false; } } +bool ImageData::canPaste(PixelFormat src, PixelFormat dst) +{ + if (src == dst) + return true; + + if (!(src == PIXELFORMAT_RGBA8 || src == PIXELFORMAT_RGBA16 + || src == PIXELFORMAT_RGBA16F || src == PIXELFORMAT_RGBA32F)) + return false; + + if (!(dst == PIXELFORMAT_RGBA8 || dst == PIXELFORMAT_RGBA16 + || dst == PIXELFORMAT_RGBA16F || dst == PIXELFORMAT_RGBA32F)) + return false; + + return true; +} + +ImageData::PixelSetFunction ImageData::getPixelSetFunction(PixelFormat format) +{ + switch (format) + { + case PIXELFORMAT_R8: return setPixelR8; + case PIXELFORMAT_RG8: return setPixelRG8; + case PIXELFORMAT_RGBA8: return setPixelRGBA8; + case PIXELFORMAT_R16: return setPixelR16; + case PIXELFORMAT_RG16: return setPixelRG16; + case PIXELFORMAT_RGBA16: return setPixelRGBA16; + case PIXELFORMAT_R16F: return setPixelR16F; + case PIXELFORMAT_RG16F: return setPixelRG16F; + case PIXELFORMAT_RGBA16F: return setPixelRGBA16F; + case PIXELFORMAT_R32F: return setPixelR32F; + case PIXELFORMAT_RG32F: return setPixelRG32F; + case PIXELFORMAT_RGBA32F: return setPixelRGBA32F; + case PIXELFORMAT_RGBA4: return setPixelRGBA4; + case PIXELFORMAT_RGB5A1: return setPixelRGB5A1; + case PIXELFORMAT_RGB565: return setPixelRGB565; + case PIXELFORMAT_RGB10A2: return setPixelRGB10A2; + case PIXELFORMAT_RG11B10F: return setPixelRG11B10F; + default: return nullptr; + } +} + +ImageData::PixelGetFunction ImageData::getPixelGetFunction(PixelFormat format) +{ + switch (format) + { + case PIXELFORMAT_R8: return getPixelR8; + case PIXELFORMAT_RG8: return getPixelRG8; + case PIXELFORMAT_RGBA8: return getPixelRGBA8; + case PIXELFORMAT_R16: return getPixelR16; + case PIXELFORMAT_RG16: return getPixelRG16; + case PIXELFORMAT_RGBA16: return getPixelRGBA16; + case PIXELFORMAT_R16F: return getPixelR16F; + case PIXELFORMAT_RG16F: return getPixelRG16F; + case PIXELFORMAT_RGBA16F: return getPixelRGBA16F; + case PIXELFORMAT_R32F: return getPixelR32F; + case PIXELFORMAT_RG32F: return getPixelRG32F; + case PIXELFORMAT_RGBA32F: return getPixelRGBA32F; + case PIXELFORMAT_RGBA4: return getPixelRGBA4; + case PIXELFORMAT_RGB5A1: return getPixelRGB5A1; + case PIXELFORMAT_RGB565: return getPixelRGB565; + case PIXELFORMAT_RGB10A2: return getPixelRGB10A2; + case PIXELFORMAT_RG11B10F: return getPixelRG11B10F; + default: return nullptr; + } +} + bool ImageData::getConstant(const char *in, FormatHandler::EncodedFormat &out) { return encodedFormats.find(in, out); diff -Nru love-11.1/src/modules/image/ImageData.h love-11.3/src/modules/image/ImageData.h --- love-11.1/src/modules/image/ImageData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/ImageData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,8 @@ #include "common/StringMap.h" #include "common/int.h" #include "common/pixelformat.h" -#include "common/halffloat.h" +#include "common/floattypes.h" +#include "common/Color.h" #include "filesystem/FileData.h" #include "thread/threads.h" #include "ImageDataBase.h" @@ -38,14 +39,6 @@ namespace image { -union Pixel -{ - uint8 rgba8[4]; - uint16 rgba16[4]; - half rgba16f[4]; - float rgba32f[4]; -}; - /** * Represents raw pixel data. **/ @@ -53,6 +46,19 @@ { public: + union Pixel + { + uint8 rgba8[4]; + uint16 rgba16[4]; + float16 rgba16f[4]; + float rgba32f[4]; + uint16 packed16; + uint32 packed32; + }; + + typedef void (*PixelSetFunction)(const Colorf &c, Pixel *p); + typedef void (*PixelGetFunction)(const Pixel *p, Colorf &c); + static love::Type type; ImageData(Data *data); @@ -86,7 +92,7 @@ * @param y The location along the y-axis. * @param p The color to use for the given location. **/ - void setPixel(int x, int y, const Pixel &p); + void setPixel(int x, int y, const Colorf &p); /** * Gets the pixel at location (x,y). @@ -94,7 +100,8 @@ * @param y The location along the y-axis. * @return The color for the given location. **/ - void getPixel(int x, int y, Pixel &p) const; + void getPixel(int x, int y, Colorf &c) const; + Colorf getPixel(int x, int y) const; /** * Encodes raw pixel data into a given format. @@ -113,7 +120,14 @@ size_t getPixelSize() const; + PixelSetFunction getPixelSetFunction() const { return pixelSetFunction; } + PixelGetFunction getPixelGetFunction() const { return pixelGetFunction; } + static bool validPixelFormat(PixelFormat format); + static bool canPaste(PixelFormat src, PixelFormat dst); + + static PixelSetFunction getPixelSetFunction(PixelFormat format); + static PixelGetFunction getPixelGetFunction(PixelFormat format); static bool getConstant(const char *in, FormatHandler::EncodedFormat &out); static bool getConstant(FormatHandler::EncodedFormat in, const char *&out); @@ -121,14 +135,6 @@ private: - union Row - { - uint8 *u8; - uint16 *u16; - half *f16; - float *f32; - }; - // Create imagedata. Initialize with data if not null. void create(int width, int height, PixelFormat format, void *data = nullptr); @@ -144,21 +150,8 @@ // this so we can properly delete memory allocated by the decoder. StrongRef decodeHandler; - static void pasteRGBA8toRGBA16(Row src, Row dst, int w); - static void pasteRGBA8toRGBA16F(Row src, Row dst, int w); - static void pasteRGBA8toRGBA32F(Row src, Row dst, int w); - - static void pasteRGBA16toRGBA8(Row src, Row dst, int w); - static void pasteRGBA16toRGBA16F(Row src, Row dst, int w); - static void pasteRGBA16toRGBA32F(Row src, Row dst, int w); - - static void pasteRGBA16FtoRGBA8(Row src, Row dst, int w); - static void pasteRGBA16FtoRGBA16(Row src, Row dst, int w); - static void pasteRGBA16FtoRGBA32F(Row src, Row dst, int w); - - static void pasteRGBA32FtoRGBA8(Row src, Row dst, int w); - static void pasteRGBA32FtoRGBA16(Row src, Row dst, int w); - static void pasteRGBA32FtoRGBA16F(Row src, Row dst, int w); + PixelSetFunction pixelSetFunction; + PixelGetFunction pixelGetFunction; static StringMap::Entry encodedFormatEntries[]; static StringMap encodedFormats; diff -Nru love-11.1/src/modules/image/Image.h love-11.3/src/modules/image/Image.h --- love-11.1/src/modules/image/Image.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/Image.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/ASTCHandler.cpp love-11.3/src/modules/image/magpie/ASTCHandler.cpp --- love-11.1/src/modules/image/magpie/ASTCHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/ASTCHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/ASTCHandler.h love-11.3/src/modules/image/magpie/ASTCHandler.h --- love-11.1/src/modules/image/magpie/ASTCHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/ASTCHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/ddsHandler.cpp love-11.3/src/modules/image/magpie/ddsHandler.cpp --- love-11.1/src/modules/image/magpie/ddsHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/ddsHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -20,6 +20,10 @@ #include "ddsHandler.h" #include "common/Exception.h" +#include "image/ImageData.h" + +// dds parser +#include "ddsparse/ddsparse.h" namespace love { @@ -28,6 +32,198 @@ namespace magpie { +static PixelFormat convertFormat(dds::dxinfo::DXGIFormat dxformat, bool &sRGB, bool &bgra) +{ + using namespace dds::dxinfo; + + sRGB = false; + bgra = false; + + switch (dxformat) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return PIXELFORMAT_RGBA32F; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return PIXELFORMAT_RGBA16F; + + case DXGI_FORMAT_R16G16B16A16_UNORM: + return PIXELFORMAT_RGBA16; + + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + return PIXELFORMAT_RG32F; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + return PIXELFORMAT_RGB10A2; + + case DXGI_FORMAT_R11G11B10_FLOAT: + return PIXELFORMAT_RG11B10F; + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + sRGB = (dxformat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + return PIXELFORMAT_RGBA8; + + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + return PIXELFORMAT_RG16F; + + case DXGI_FORMAT_R16G16_UNORM: + return PIXELFORMAT_RG16; + + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_R32_FLOAT: + return PIXELFORMAT_R32F; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + return PIXELFORMAT_RG8; + + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + return PIXELFORMAT_R16F; + + case DXGI_FORMAT_R16_UNORM: + return PIXELFORMAT_R16; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_A8_UNORM: + return PIXELFORMAT_R8; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + sRGB = (dxformat == DXGI_FORMAT_BC1_UNORM_SRGB); + return PIXELFORMAT_DXT1; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + sRGB = (dxformat == DXGI_FORMAT_BC2_UNORM_SRGB); + return PIXELFORMAT_DXT3; + + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + sRGB = (dxformat == DXGI_FORMAT_BC3_UNORM_SRGB); + return PIXELFORMAT_DXT5; + + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + return PIXELFORMAT_BC4; + + case DXGI_FORMAT_BC4_SNORM: + return PIXELFORMAT_BC4s; + + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + return PIXELFORMAT_BC5; + + case DXGI_FORMAT_BC5_SNORM: + return PIXELFORMAT_BC5s; + + case DXGI_FORMAT_B5G6R5_UNORM: + return PIXELFORMAT_RGB565; + + case DXGI_FORMAT_B5G5R5A1_UNORM: + return PIXELFORMAT_RGB5A1; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + sRGB = (dxformat == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); + bgra = true; + return PIXELFORMAT_RGBA8; + + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + return PIXELFORMAT_BC6H; + + case DXGI_FORMAT_BC6H_SF16: + return PIXELFORMAT_BC6Hs; + + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + sRGB = (dxformat == DXGI_FORMAT_BC7_UNORM_SRGB); + return PIXELFORMAT_BC7; + + default: + return PIXELFORMAT_UNKNOWN; + } +} + +bool DDSHandler::canDecode(Data *data) +{ + using namespace dds::dxinfo; + + DXGIFormat dxformat = dds::getDDSPixelFormat(data->getData(), data->getSize()); + bool isSRGB = false; + bool bgra = false; + PixelFormat format = convertFormat(dxformat, isSRGB, bgra); + + return ImageData::validPixelFormat(format); +} + +FormatHandler::DecodedImage DDSHandler::decode(Data *data) +{ + DecodedImage img; + + dds::Parser parser(data->getData(), data->getSize()); + + bool isSRGB = false; + bool bgra = false; + img.format = convertFormat(parser.getFormat(), isSRGB, bgra); + + if (!ImageData::validPixelFormat(img.format)) + throw love::Exception("Could not parse DDS pixel data: Unsupported format."); + + if (parser.getMipmapCount() == 0) + throw love::Exception("Could not parse DDS pixel data: No readable texture data."); + + // We only support the top mip level through this codepath. + const dds::Image *ddsimg = parser.getImageData(0); + + try + { + img.data = new uint8[ddsimg->dataSize]; + } + catch (std::exception &) + { + throw love::Exception("Out of memory."); + } + + memcpy(img.data, ddsimg->data, ddsimg->dataSize); + + img.size = ddsimg->dataSize; + img.width = ddsimg->width; + img.height = ddsimg->height; + + // Swap red and blue channels for incoming BGRA data. + if (bgra) + { + for (int y = 0; y < img.height; y++) + { + for (int x = 0; x < img.width; x++) + { + size_t offset = (y * img.width + x) * 4; + uint8 b = img.data[offset + 0]; + uint8 r = img.data[offset + 2]; + img.data[offset + 0] = r; + img.data[offset + 2] = b; + } + } + } + + return img; +} + bool DDSHandler::canParseCompressed(Data *data) { return dds::isCompressedDDS(data->getData(), data->getSize()); @@ -35,11 +231,12 @@ StrongRef DDSHandler::parseCompressed(Data *filedata, std::vector> &images, PixelFormat &format, bool &sRGB) { - if (!dds::isDDS(filedata->getData(), filedata->getSize())) + if (!dds::isCompressedDDS(filedata->getData(), filedata->getSize())) throw love::Exception("Could not decode compressed data (not a DDS file?)"); PixelFormat texformat = PIXELFORMAT_UNKNOWN; bool isSRGB = false; + bool bgra = false; StrongRef memory; size_t dataSize = 0; @@ -49,7 +246,7 @@ // Attempt to parse the dds file. dds::Parser parser(filedata->getData(), filedata->getSize()); - texformat = convertFormat(parser.getFormat(), isSRGB); + texformat = convertFormat(parser.getFormat(), isSRGB, bgra); if (texformat == PIXELFORMAT_UNKNOWN) throw love::Exception("Could not parse compressed data: Unsupported format."); @@ -88,40 +285,6 @@ return memory; } -PixelFormat DDSHandler::convertFormat(dds::Format ddsformat, bool &sRGB) -{ - sRGB = false; - - switch (ddsformat) - { - case dds::FORMAT_DXT1: - return PIXELFORMAT_DXT1; - case dds::FORMAT_DXT3: - return PIXELFORMAT_DXT3; - case dds::FORMAT_DXT5: - return PIXELFORMAT_DXT5; - case dds::FORMAT_BC4: - return PIXELFORMAT_BC4; - case dds::FORMAT_BC4s: - return PIXELFORMAT_BC4s; - case dds::FORMAT_BC5: - return PIXELFORMAT_BC5; - case dds::FORMAT_BC5s: - return PIXELFORMAT_BC5s; - case dds::FORMAT_BC6H: - return PIXELFORMAT_BC6H; - case dds::FORMAT_BC6Hs: - return PIXELFORMAT_BC6Hs; - case dds::FORMAT_BC7: - return PIXELFORMAT_BC7; - case dds::FORMAT_BC7srgb: - sRGB = true; - return PIXELFORMAT_BC7; - default: - return PIXELFORMAT_UNKNOWN; - } -} - } // magpie } // image } // love diff -Nru love-11.1/src/modules/image/magpie/ddsHandler.h love-11.3/src/modules/image/magpie/ddsHandler.h --- love-11.1/src/modules/image/magpie/ddsHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/ddsHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,6 @@ // LOVE #include "image/FormatHandler.h" -// dds parser -#include "ddsparse/ddsparse.h" - // STL #include @@ -46,16 +43,13 @@ virtual ~DDSHandler() {} // Implements FormatHandler. + bool canDecode(Data *data) override; + DecodedImage decode(Data *data) override; bool canParseCompressed(Data *data) override; - StrongRef parseCompressed(Data *filedata, std::vector> &images, PixelFormat &format, bool &sRGB) override; -private: - - static PixelFormat convertFormat(dds::Format ddsformat, bool &sRGB); - }; // DDSHandler } // magpie diff -Nru love-11.1/src/modules/image/magpie/EXRHandler.cpp love-11.3/src/modules/image/magpie/EXRHandler.cpp --- love-11.1/src/modules/image/magpie/EXRHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/EXRHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ // LOVE #include "EXRHandler.h" -#include "common/halffloat.h" +#include "common/floattypes.h" #include "common/Exception.h" // zlib (for tinyexr) @@ -118,18 +118,26 @@ EXRImage exrImage; InitEXRImage(&exrImage); - EXRVersion exrVersion; - if (ParseEXRVersionFromMemory(&exrVersion, mem, memsize) != TINYEXR_SUCCESS) - throw love::Exception("Could not parse EXR image header."); + try + { + EXRVersion exrVersion; + if (ParseEXRVersionFromMemory(&exrVersion, mem, memsize) != TINYEXR_SUCCESS) + throw love::Exception("Could not parse EXR image header."); - if (exrVersion.multipart || exrVersion.non_image || exrVersion.tiled) - throw love::Exception("Multi-part, tiled, and non-image EXR files are not supported."); + if (exrVersion.multipart || exrVersion.non_image || exrVersion.tiled) + throw love::Exception("Multi-part, tiled, and non-image EXR files are not supported."); - if (ParseEXRHeaderFromMemory(&exrHeader, &exrVersion, mem, memsize, &err) != TINYEXR_SUCCESS) - throw love::Exception("Could not parse EXR image header: %s", err); + if (ParseEXRHeaderFromMemory(&exrHeader, &exrVersion, mem, memsize, &err) != TINYEXR_SUCCESS) + throw love::Exception("Could not parse EXR image header: %s", err); - if (LoadEXRImageFromMemory(&exrImage, &exrHeader, mem, memsize, &err) != TINYEXR_SUCCESS) - throw love::Exception("Could not decode EXR image: %s", err); + if (LoadEXRImageFromMemory(&exrImage, &exrHeader, mem, memsize, &err) != TINYEXR_SUCCESS) + throw love::Exception("Could not decode EXR image: %s", err); + } + catch (love::Exception &) + { + FreeEXRErrorMessage(err); + throw; + } int pixelType = exrHeader.pixel_types[0]; @@ -149,12 +157,12 @@ { img.format = PIXELFORMAT_RGBA16F; - half *rgba[4] = {nullptr}; + float16 *rgba[4] = {nullptr}; getEXRChannels(exrHeader, exrImage, rgba); try { - img.data = (unsigned char *) loadEXRChannels(img.width, img.height, rgba, floatToHalf(1.0f)); + img.data = (unsigned char *) loadEXRChannels(img.width, img.height, rgba, float32to16(1.0f)); } catch (love::Exception &) { diff -Nru love-11.1/src/modules/image/magpie/EXRHandler.h love-11.3/src/modules/image/magpie/EXRHandler.h --- love-11.1/src/modules/image/magpie/EXRHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/EXRHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/KTXHandler.cpp love-11.3/src/modules/image/magpie/KTXHandler.cpp --- love-11.1/src/modules/image/magpie/KTXHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/KTXHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/KTXHandler.h love-11.3/src/modules/image/magpie/KTXHandler.h --- love-11.1/src/modules/image/magpie/KTXHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/KTXHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/PKMHandler.cpp love-11.3/src/modules/image/magpie/PKMHandler.cpp --- love-11.1/src/modules/image/magpie/PKMHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/PKMHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/PKMHandler.h love-11.3/src/modules/image/magpie/PKMHandler.h --- love-11.1/src/modules/image/magpie/PKMHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/PKMHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/PNGHandler.cpp love-11.3/src/modules/image/magpie/PNGHandler.cpp --- love-11.1/src/modules/image/magpie/PNGHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/PNGHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/PNGHandler.h love-11.3/src/modules/image/magpie/PNGHandler.h --- love-11.1/src/modules/image/magpie/PNGHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/PNGHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/PVRHandler.cpp love-11.3/src/modules/image/magpie/PVRHandler.cpp --- love-11.1/src/modules/image/magpie/PVRHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/PVRHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/PVRHandler.h love-11.3/src/modules/image/magpie/PVRHandler.h --- love-11.1/src/modules/image/magpie/PVRHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/PVRHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/magpie/STBHandler.cpp love-11.3/src/modules/image/magpie/STBHandler.cpp --- love-11.1/src/modules/image/magpie/STBHandler.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/STBHandler.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -50,7 +50,7 @@ namespace magpie { -static_assert(sizeof(Color) == 4, "sizeof(Color) must equal 4 bytes!"); +static_assert(sizeof(Color32) == 4, "sizeof(Color32) must equal 4 bytes!"); bool STBHandler::canDecode(Data *data) { @@ -147,7 +147,7 @@ memcpy(encimg.data + headerlen, img.data, img.width * img.height * bpp); // convert the pixels from RGBA to BGRA. - Color *encodedpixels = (Color *) (encimg.data + headerlen); + Color32 *encodedpixels = (Color32 *) (encimg.data + headerlen); for (int y = 0; y < img.height; y++) { for (int x = 0; x < img.width; x++) diff -Nru love-11.1/src/modules/image/magpie/STBHandler.h love-11.3/src/modules/image/magpie/STBHandler.h --- love-11.1/src/modules/image/magpie/STBHandler.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/magpie/STBHandler.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/wrap_CompressedImageData.cpp love-11.3/src/modules/image/wrap_CompressedImageData.cpp --- love-11.1/src/modules/image/wrap_CompressedImageData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_CompressedImageData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -116,7 +116,9 @@ extern "C" int luaopen_compressedimagedata(lua_State *L) { - return luax_register_type(L, &CompressedImageData::type, data::w_Data_functions, w_CompressedImageData_functions, nullptr); + int ret = luax_register_type(L, &CompressedImageData::type, data::w_Data_functions, w_CompressedImageData_functions, nullptr); + love::data::luax_rundatawrapper(L, CompressedImageData::type); + return ret; } } // image diff -Nru love-11.1/src/modules/image/wrap_CompressedImageData.h love-11.3/src/modules/image/wrap_CompressedImageData.h --- love-11.1/src/modules/image/wrap_CompressedImageData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_CompressedImageData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/wrap_Image.cpp love-11.3/src/modules/image/wrap_Image.cpp --- love-11.1/src/modules/image/wrap_Image.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_Image.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/wrap_ImageData.cpp love-11.3/src/modules/image/wrap_ImageData.cpp --- love-11.1/src/modules/image/wrap_ImageData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_ImageData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -88,84 +88,20 @@ return 2; } -static void luax_checkpixel_rgba8(lua_State *L, int startidx, Pixel &p) -{ - for (int i = 0; i < 3; i++) - p.rgba8[i] = (uint8) (luax_checknumberclamped01(L, startidx + i) * 255.0); - - p.rgba8[3] = (uint8) (luax_optnumberclamped01(L, startidx + 3, 1.0) * 255.0); -} - -static void luax_checkpixel_rgba16(lua_State *L, int startidx, Pixel &p) -{ - for (int i = 0; i < 3; i++) - p.rgba16[i] = (uint16) (luax_checknumberclamped01(L, startidx + i) * 65535.0); - - p.rgba16[3] = (uint16) (luax_optnumberclamped01(L, startidx + 3, 1.0) * 65535.0); -} - -static void luax_checkpixel_rgba16f(lua_State *L, int startidx, Pixel &p) -{ - for (int i = 0; i < 3; i++) - p.rgba16f[i] = floatToHalf((float) luaL_checknumber(L, startidx + i)); - - p.rgba16f[3] = floatToHalf((float) luaL_optnumber(L, startidx + 3, 1.0)); -} - -static void luax_checkpixel_rgba32f(lua_State *L, int startidx, Pixel &p) -{ - for (int i = 0; i < 3; i++) - p.rgba32f[i] = (float) luaL_checknumber(L, startidx + i); - - p.rgba32f[3] = (float) luaL_optnumber(L, startidx + 3, 1.0); -} - -static int luax_pushpixel_rgba8(lua_State *L, const Pixel &p) -{ - for (int i = 0; i < 4; i++) - lua_pushnumber(L, (lua_Number) p.rgba8[i] / 255.0); - return 4; -} - -static int luax_pushpixel_rgba16(lua_State *L, const Pixel &p) -{ - for (int i = 0; i < 4; i++) - lua_pushnumber(L, (lua_Number) p.rgba16[i] / 65535.0); - return 4; -} - -static int luax_pushpixel_rgba16f(lua_State *L, const Pixel &p) -{ - for (int i = 0; i < 4; i++) - lua_pushnumber(L, (lua_Number) halfToFloat(p.rgba16f[i])); - return 4; -} - -static int luax_pushpixel_rgba32f(lua_State *L, const Pixel &p) -{ - for (int i = 0; i < 4; i++) - lua_pushnumber(L, (lua_Number) p.rgba32f[i]); - return 4; -} - -typedef void(*checkpixel)(lua_State *L, int startidx, Pixel &p); -typedef int(*pushpixel)(lua_State *L, const Pixel &p); - -static checkpixel checkFormats[PIXELFORMAT_MAX_ENUM] = {}; -static pushpixel pushFormats[PIXELFORMAT_MAX_ENUM] = {}; - int w_ImageData_getPixel(lua_State *L) { ImageData *t = luax_checkimagedata(L, 1); int x = (int) luaL_checkinteger(L, 2); int y = (int) luaL_checkinteger(L, 3); - PixelFormat format = t->getFormat(); - - Pixel p; - luax_catchexcept(L, [&](){ t->getPixel(x, y, p); }); + Colorf c; + luax_catchexcept(L, [&](){ t->getPixel(x, y, c); }); - return pushFormats[format](L, p); + lua_pushnumber(L, c.r); + lua_pushnumber(L, c.g); + lua_pushnumber(L, c.b); + lua_pushnumber(L, c.a); + return 4; } int w_ImageData_setPixel(lua_State *L) @@ -174,23 +110,37 @@ int x = (int) luaL_checkinteger(L, 2); int y = (int) luaL_checkinteger(L, 3); - PixelFormat format = t->getFormat(); + int components = getPixelFormatColorComponents(t->getFormat()); - Pixel p; + Colorf c; if (lua_istable(L, 4)) { - for (int i = 1; i <= 4; i++) - lua_rawgeti(L, 4, i); + for (int i = 1; i <= components; i++) + lua_rawgeti(L, components, i); - checkFormats[format](L, -4, p); + c.r = (float) luaL_checknumber(L, -components); + if (components > 1) + c.g = (float) luaL_checknumber(L, (-components) + 1); + if (components > 2) + c.b = (float) luaL_checknumber(L, (-components) + 2); + if (components > 3) + c.a = (float) luaL_optnumber(L, (-components) + 3, 1.0); - lua_pop(L, 4); + lua_pop(L, components); } else - checkFormats[format](L, 4, p); + { + c.r = (float) luaL_checknumber(L, 4); + if (components > 1) + c.g = (float) luaL_checknumber(L, 5); + if (components > 2) + c.b = (float) luaL_checknumber(L, 6); + if (components > 3) + c.a = (float) luaL_optnumber(L, 7, 1.0); + } - luax_catchexcept(L, [&](){ t->setPixel(x, y, p); }); + luax_catchexcept(L, [&](){ t->setPixel(x, y, c); }); return 0; } @@ -213,9 +163,10 @@ int iw = t->getWidth(); PixelFormat format = t->getFormat(); + int components = getPixelFormatColorComponents(format); - auto checkpixel = checkFormats[format]; - auto pushpixel = pushFormats[format]; + auto pixelsetfunction = t->getPixelSetFunction(); + auto pixelgetfunction = t->getPixelGetFunction(); uint8 *data = (uint8 *) t->getData(); size_t pixelsize = t->getPixelSize(); @@ -224,17 +175,33 @@ { for (int x = sx; x < sx+w; x++) { - Pixel *pixeldata = (Pixel *) (data + (y * iw + x) * pixelsize); + auto pixeldata = (ImageData::Pixel *) (data + (y * iw + x) * pixelsize); + + Colorf c; + pixelgetfunction(pixeldata, c); lua_pushvalue(L, 2); // ImageData + lua_pushnumber(L, x); lua_pushnumber(L, y); - pushpixel(L, *pixeldata); + lua_pushnumber(L, c.r); + lua_pushnumber(L, c.g); + lua_pushnumber(L, c.b); + lua_pushnumber(L, c.a); lua_call(L, 6, 4); - checkpixel(L, -4, *pixeldata); + c.r = (float) luaL_checknumber(L, -4); + if (components > 1) + c.g = (float) luaL_checknumber(L, -3); + if (components > 2) + c.b = (float) luaL_checknumber(L, -2); + if (components > 3) + c.a = (float) luaL_optnumber(L, -1, 1.0); + + pixelsetfunction(c, pixeldata); + lua_pop(L, 4); // Pop return values. } } @@ -309,8 +276,14 @@ void (*lockMutex)(Proxy *p); void (*unlockMutex)(Proxy *p); - float (*halfToFloat)(half h); - half (*floatToHalf)(float f); + float (*float16to32)(float16 f); + float16 (*float32to16)(float f); + + float (*float11to32)(float11 f); + float11 (*float32to11)(float f); + + float (*float10to32)(float10 f); + float10 (*float32to10)(float f); }; static FFI_ImageData ffifuncs = @@ -329,8 +302,12 @@ i->getMutex()->unlock(); }, - halfToFloat, - floatToHalf, + float16to32, + float32to16, + float11to32, + float32to11, + float10to32, + float32to10, }; static const luaL_Reg w_ImageData_functions[] = @@ -354,32 +331,10 @@ extern "C" int luaopen_imagedata(lua_State *L) { - checkFormats[PIXELFORMAT_RGBA8] = luax_checkpixel_rgba8; - checkFormats[PIXELFORMAT_RGBA16] = luax_checkpixel_rgba16; - checkFormats[PIXELFORMAT_RGBA16F] = luax_checkpixel_rgba16f; - checkFormats[PIXELFORMAT_RGBA32F] = luax_checkpixel_rgba32f; - - pushFormats[PIXELFORMAT_RGBA8] = luax_pushpixel_rgba8; - pushFormats[PIXELFORMAT_RGBA16] = luax_pushpixel_rgba16; - pushFormats[PIXELFORMAT_RGBA16F] = luax_pushpixel_rgba16f; - pushFormats[PIXELFORMAT_RGBA32F] = luax_pushpixel_rgba32f; - int ret = luax_register_type(L, &ImageData::type, data::w_Data_functions, w_ImageData_functions, nullptr); - luax_gettypemetatable(L, ImageData::type); - - // Load and execute ImageData.lua, sending the metatable and the ffi - // functions struct pointer as arguments. - if (lua_istable(L, -1)) - { - luaL_loadbuffer(L, imagedata_lua, sizeof(imagedata_lua), "ImageData.lua"); - lua_pushvalue(L, -2); - lua_pushlightuserdata(L, &ffifuncs); - lua_call(L, 2, 0); - } - - // Pop the metatable. - lua_pop(L, 1); + love::data::luax_rundatawrapper(L, ImageData::type); + luax_runwrapper(L, imagedata_lua, sizeof(imagedata_lua), "ImageData.lua", ImageData::type, &ffifuncs); return ret; } diff -Nru love-11.1/src/modules/image/wrap_ImageData.h love-11.3/src/modules/image/wrap_ImageData.h --- love-11.1/src/modules/image/wrap_ImageData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_ImageData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/image/wrap_ImageData.lua love-11.3/src/modules/image/wrap_ImageData.lua --- love-11.1/src/modules/image/wrap_ImageData.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_ImageData.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,20 +22,20 @@ 3. This notice may not be removed or altered from any source distribution. --]] -local ImageData_mt, ffifuncspointer = ... +local ImageData_mt, ffifuncspointer_str = ... local ImageData = ImageData_mt.__index local tonumber, assert, error = tonumber, assert, error local type, pcall = type, pcall -local floor = math.floor +local floor = math.floor local min, max = math.min, math.max local function inside(x, y, w, h) return x >= 0 and x < w and y >= 0 and y < h -end - -local function clamp01(x) - return min(max(x, 0), 1) +end + +local function clamp01(x) + return min(max(x, 0), 1) end -- Implement thread-safe ImageData:mapPixel regardless of whether the FFI is @@ -73,84 +73,173 @@ local status, ffi = pcall(require, "ffi") if not status then return end +local bitstatus, bit = pcall(require, "bit") +if not bitstatus then return end + pcall(ffi.cdef, [[ typedef struct Proxy Proxy; -typedef uint16_t half; +typedef uint16_t float16; +typedef uint16_t float11; +typedef uint16_t float10; typedef struct FFI_ImageData { void (*lockMutex)(Proxy *p); void (*unlockMutex)(Proxy *p); - float (*halfToFloat)(half h); - half (*floatToHalf)(float f); -} FFI_ImageData; + float (*float16to32)(float16 f); + float16 (*float32to16)(float f); -typedef struct ImageData_Pixel_RGBA8 -{ - uint8_t r, g, b, a; -} ImageData_Pixel_RGBA8; + float (*float11to32)(float11 f); + float11 (*float32to11)(float f); -typedef struct ImageData_Pixel_RGBA16 -{ - uint16_t r, g, b, a; -} ImageData_Pixel_RGBA16; - -typedef struct ImageData_Pixel_RGBA16F -{ - half r, g, b, a; -} ImageData_Pixel_RGBA16F; + float (*float10to32)(float10 f); + float10 (*float32to10)(float f); +} FFI_ImageData; -typedef struct ImageData_Pixel_RGBA32F -{ - float r, g, b, a; -} ImageData_Pixel_RGBA32F; +struct ImageData_Pixel_R8 { uint8_t r; }; +struct ImageData_Pixel_RG8 { uint8_t r, g; }; +struct ImageData_Pixel_RGBA8 { uint8_t r, g, b, a; }; + +struct ImageData_Pixel_R16 { uint16_t r; }; +struct ImageData_Pixel_RG16 { uint16_t r, g; }; +struct ImageData_Pixel_RGBA16 { uint16_t r, g, b, a; }; + +struct ImageData_Pixel_R16F { float16 r; }; +struct ImageData_Pixel_RG16F { float16 r, g; }; +struct ImageData_Pixel_RGBA16F { float16 r, g, b, a; }; + +struct ImageData_Pixel_R32F { float r; }; +struct ImageData_Pixel_RG32F { float r, g; }; +struct ImageData_Pixel_RGBA32F { float r, g, b, a; }; + +struct ImageData_Pixel_RGBA4 { uint16_t rgba; }; +struct ImageData_Pixel_RGB5A1 { uint16_t rgba; }; +struct ImageData_Pixel_RGB565 { uint16_t rgb; }; +struct ImageData_Pixel_RGB10A2 { uint32_t rgba; }; +struct ImageData_Pixel_RG11B10F { uint32_t rgb; }; ]]) -local ffifuncs = ffi.cast("FFI_ImageData *", ffifuncspointer) +local ffifuncs = ffi.cast("FFI_ImageData **", ffifuncspointer_str)[0] local conversions = { + r8 = { + pointer = ffi.typeof("struct ImageData_Pixel_R8 *"), + tolua = function(self) + return tonumber(self.r) / 255, 0, 0, 1 + end, + fromlua = function(self, r) + self.r = (clamp01(r) * 255) + 0.5 + end, + }, + rg8 = { + pointer = ffi.typeof("struct ImageData_Pixel_RG8 *"), + tolua = function(self) + return tonumber(self.r) / 255, tonumber(self.g) / 255, 0, 1 + end, + fromlua = function(self, r, g) + self.r = (clamp01(r) * 255) + 0.5 + self.g = (clamp01(g) * 255) + 0.5 + end, + }, rgba8 = { - pointer = ffi.typeof("ImageData_Pixel_RGBA8 *"), + pointer = ffi.typeof("struct ImageData_Pixel_RGBA8 *"), tolua = function(self) return tonumber(self.r) / 255, tonumber(self.g) / 255, tonumber(self.b) / 255, tonumber(self.a) / 255 end, fromlua = function(self, r, g, b, a) - self.r = clamp01(r) * 255 - self.g = clamp01(g) * 255 - self.b = clamp01(b) * 255 - self.a = a == nil and 255 or clamp01(a) * 255 + self.r = (clamp01(r) * 255) + 0.5 + self.g = (clamp01(g) * 255) + 0.5 + self.b = (clamp01(b) * 255) + 0.5 + self.a = a == nil and 255 or (clamp01(a) * 255) + 0.5 + end, + }, + r16 = { + pointer = ffi.typeof("struct ImageData_Pixel_R16 *"), + tolua = function(self) + return tonumber(self.r) / 65535, 0, 0, 1 + end, + fromlua = function(self, r) + self.r = (clamp01(r) * 65535) + 0.5 + end, + }, + rg16 = { + pointer = ffi.typeof("struct ImageData_Pixel_RG16 *"), + tolua = function(self) + return tonumber(self.r) / 65535, tonumber(self.g) / 65535, 0, 1 + end, + fromlua = function(self, r, g) + self.r = (clamp01(r) * 65535) + 0.5 + self.g = (clamp01(g) * 65535) + 0.5 end, }, rgba16 = { - pointer = ffi.typeof("ImageData_Pixel_RGBA16 *"), + pointer = ffi.typeof("struct ImageData_Pixel_RGBA16 *"), tolua = function(self) return tonumber(self.r) / 65535, tonumber(self.g) / 65535, tonumber(self.b) / 65535, tonumber(self.a) / 65535 end, fromlua = function(self, r, g, b, a) - self.r = clamp01(r) * 65535 - self.g = clamp01(g) * 65535 - self.b = clamp01(b) * 65535 - self.a = a == nil and 65535 or clamp01(a) * 65535 + self.r = (clamp01(r) * 65535) + 0.5 + self.g = (clamp01(g) * 65535) + 0.5 + self.b = (clamp01(b) * 65535) + 0.5 + self.a = a == nil and 65535 or (clamp01(a) * 65535) + 0.5 + end, + }, + r16f = { + pointer = ffi.typeof("struct ImageData_Pixel_R16F *"), + tolua = function(self) + return tonumber(ffifuncs.float16to32(self.r)), 0, 0, 1 + end, + fromlua = function(self, r) + self.r = ffifuncs.float32to16(r) + end, + }, + rg16f = { + pointer = ffi.typeof("struct ImageData_Pixel_RG16F *"), + tolua = function(self) + return tonumber(ffifuncs.float16to32(self.r)), tonumber(ffifuncs.float16to32(self.g)), 0, 1 + end, + fromlua = function(self, r, g, b, a) + self.r = ffifuncs.float32to16(r) + self.g = ffifuncs.float32to16(g) end, }, rgba16f = { - pointer = ffi.typeof("ImageData_Pixel_RGBA16F *"), + pointer = ffi.typeof("struct ImageData_Pixel_RGBA16F *"), + tolua = function(self) + return tonumber(ffifuncs.float16to32(self.r)), + tonumber(ffifuncs.float16to32(self.g)), + tonumber(ffifuncs.float16to32(self.b)), + tonumber(ffifuncs.float16to32(self.a)) + end, + fromlua = function(self, r, g, b, a) + self.r = ffifuncs.float32to16(r) + self.g = ffifuncs.float32to16(g) + self.b = ffifuncs.float32to16(b) + self.a = ffifuncs.float32to16(a == nil and 1.0 or a) + end, + }, + r32f = { + pointer = ffi.typeof("struct ImageData_Pixel_R32F *"), + tolua = function(self) + return tonumber(self.r), 0, 0, 1 + end, + fromlua = function(self, r, g, b, a) + self.r = r + end, + }, + rg32f = { + pointer = ffi.typeof("struct ImageData_Pixel_RG32F *"), tolua = function(self) - return tonumber(ffifuncs.halfToFloat(self.r)), - tonumber(ffifuncs.halfToFloat(self.g)), - tonumber(ffifuncs.halfToFloat(self.b)), - tonumber(ffifuncs.halfToFloat(self.a)) + return tonumber(self.r), tonumber(self.g), 0, 1 end, fromlua = function(self, r, g, b, a) - self.r = ffifuncs.floatToHalf(r) - self.g = ffifuncs.floatToHalf(g) - self.b = ffifuncs.floatToHalf(b) - self.a = ffifuncs.floatToHalf(a == nil and 1.0 or a) + self.r = r + self.g = g end, }, rgba32f = { - pointer = ffi.typeof("ImageData_Pixel_RGBA32F *"), + pointer = ffi.typeof("struct ImageData_Pixel_RGBA32F *"), tolua = function(self) return tonumber(self.r), tonumber(self.g), tonumber(self.b), tonumber(self.a) end, @@ -161,6 +250,102 @@ self.a = a == nil and 1.0 or a end, }, + rgba4 = { + -- LSB->MSB: [a, b, g, r] + pointer = ffi.typeof("struct ImageData_Pixel_RGBA4 *"), + tolua = function(self) + local rgba = self.rgba + local a = tonumber(bit.band(rgba, 0xF)) / 0xF + local b = tonumber(bit.band(bit.rshift(rgba, 4), 0xF)) / 0xF + local g = tonumber(bit.band(bit.rshift(rgba, 8), 0xF)) / 0xF + local r = tonumber(bit.rshift(rgba, 12)) / 0xF + return r, g, b, a + end, + fromlua = function(self, r, g, b, a) + -- bit functions round internally. + r = clamp01(r) * 0xF + g = clamp01(g) * 0xF + b = clamp01(b) * 0xF + a = a == nil and 0xF or clamp01(a) * 0xF + self.rgba = bit.bor(bit.lshift(r, 12), bit.lshift(g, 8), bit.lshift(b, 4), a) + end, + }, + rgb5a1 = { + -- LSB->MSB: [a, b, g, r] + pointer = ffi.typeof("struct ImageData_Pixel_RGB5A1 *"), + tolua = function(self) + local rgba = self.rgba + local r = tonumber(bit.band(bit.rshift(rgba, 11), 0x1F)) / 0x1F + local g = tonumber(bit.band(bit.rshift(rgba, 6), 0x1F)) / 0x1F + local b = tonumber(bit.band(bit.rshift(rgba, 1), 0x1F)) / 0x1F + local a = tonumber(bit.band(rgba, 0x1)) + return r, g, b, a + end, + fromlua = function(self, r, g, b, a) + -- bit functions round internally. + r = clamp01(r) * 0x1F + g = clamp01(g) * 0x1F + b = clamp01(b) * 0x1F + a = a == nil and 1 or clamp01(a) + self.rgba = bit.bor(bit.lshift(r, 11), bit.lshift(g, 6), bit.lshift(b, 1), a) + end, + }, + rgb565 = { + -- LSB->MSB: [b, g, r] + pointer = ffi.typeof("struct ImageData_Pixel_RGB565 *"), + tolua = function(self) + local rgb = self.rgb + local r = bit.band(bit.rshift(rgb, 11), 0x1F) / 0x1F + local g = bit.band(bit.rshift(rgb, 5), 0x3F) / 0x3F + local b = bit.band(rgb, 0x1F) / 0x1F + return r, g, b, 1 + end, + fromlua = function(self, r, g, b) + -- bit functions round internally. + r = clamp01(r) * 0x1F + g = clamp01(g) * 0x3F + b = clamp01(b) * 0x1F + self.rgb = bit.bor(bit.lshift(r, 11), bit.lshift(g, 5), b) + end, + }, + rgb10a2 = { + -- LSB->MSB: [r, g, b, a] + pointer = ffi.typeof("struct ImageData_Pixel_RGB10A2 *"), + tolua = function(self) + local rgba = self.rgba + local r = tonumber(bit.band(rgba, 0x3FF)) / 0x3FF + local g = tonumber(bit.band(bit.rshift(rgba, 10), 0x3FF)) / 0x3FF + local b = tonumber(bit.band(bit.rshift(rgba, 20), 0x3FF)) / 0x3FF + local a = tonumber(bit.rshift(rgba, 30)) / 0x3 + return r, g, b, a + end, + fromlua = function(self, r, g, b, a) + -- bit functions round internally. + r = clamp01(r) * 0x3FF + g = clamp01(g) * 0x3FF + b = clamp01(b) * 0x3FF + a = a == nil and 0x3 or clamp01(a) * 0x3 + self.rgba = bit.bor(r, bit.lshift(g, 10), bit.lshift(b, 20), bit.lshift(a, 30)) + end, + }, + rg11b10f = { + -- LSB->MSB: [r, g, b] + pointer = ffi.typeof("struct ImageData_Pixel_RG11B10F *"), + tolua = function(self) + local rgb = self.rgb + local r = tonumber(ffifuncs.float11to32(bit.band(rgb, 0x7FF))) + local g = tonumber(ffifuncs.float11to32(bit.band(bit.rshift(rgb, 11), 0x7FF))) + local b = tonumber(ffifuncs.float10to32(bit.band(bit.rshift(rgb, 22), 0x3FF))) + return r, g, b, 1 + end, + fromlua = function(self, r, g, b, a) + self.rgb = bit.bor( + ffifuncs.float32to11(r), + bit.lshift(ffifuncs.float32to11(g), 11), + bit.lshift(ffifuncs.float32to10(b), 22) + ) + end, + }, } local _getWidth = ImageData.getWidth diff -Nru love-11.1/src/modules/image/wrap_Image.h love-11.3/src/modules/image/wrap_Image.h --- love-11.1/src/modules/image/wrap_Image.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/image/wrap_Image.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/joystick/Joystick.cpp love-11.3/src/modules/joystick/Joystick.cpp --- love-11.1/src/modules/joystick/Joystick.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/Joystick.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/joystick/Joystick.h love-11.3/src/modules/joystick/Joystick.h --- love-11.1/src/modules/joystick/Joystick.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/Joystick.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -153,6 +153,7 @@ virtual bool isGamepadDown(const std::vector &blist) const = 0; virtual JoystickInput getGamepadMapping(const GamepadInput &input) const = 0; + virtual std::string getGamepadMappingString() const = 0; virtual void *getHandle() const = 0; @@ -160,6 +161,8 @@ virtual int getInstanceID() const = 0; virtual int getID() const = 0; + virtual void getDeviceInfo(int &vendorID, int &productID, int &productVersion) const = 0; + virtual bool isVibrationSupported() = 0; virtual bool setVibration(float left, float right, float duration = -1.0f) = 0; virtual bool setVibration() = 0; diff -Nru love-11.1/src/modules/joystick/JoystickModule.h love-11.3/src/modules/joystick/JoystickModule.h --- love-11.1/src/modules/joystick/JoystickModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/JoystickModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -37,7 +37,7 @@ virtual ~JoystickModule() {} // Implements Module. - virtual ModuleType getModuleType() const { return M_JOYSTICK; } + ModuleType getModuleType() const override { return M_JOYSTICK; } /** * Adds a connected Joystick device and opens it for use. @@ -96,6 +96,11 @@ **/ virtual std::string saveGamepadMappings() = 0; + /** + * Gets the gamepad mapping string for the given GUID. + **/ + virtual std::string getGamepadMappingString(const std::string &guid) const = 0; + }; // JoystickModule } // joystick diff -Nru love-11.1/src/modules/joystick/sdl/Joystick.cpp love-11.3/src/modules/joystick/sdl/Joystick.cpp --- love-11.1/src/modules/joystick/sdl/Joystick.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/sdl/Joystick.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -301,6 +301,33 @@ return jinput; } +std::string Joystick::getGamepadMappingString() const +{ + char *sdlmapping = nullptr; + + if (controller != nullptr) + sdlmapping = SDL_GameControllerMapping(controller); + + if (sdlmapping == nullptr) + { + SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(pguid.c_str()); + sdlmapping = SDL_GameControllerMappingForGUID(sdlguid); + } + + if (sdlmapping == nullptr) + return ""; + + std::string mappingstr(sdlmapping); + SDL_free(sdlmapping); + + // Matches SDL_GameControllerAddMappingsFromRW. + if (mappingstr.find_last_of(',') != mappingstr.length() - 1) + mappingstr += ","; + mappingstr += "platform:" + std::string(SDL_GetPlatform()); + + return mappingstr; +} + void *Joystick::getHandle() const { return joyhandle; @@ -322,6 +349,24 @@ return id; } +void Joystick::getDeviceInfo(int &vendorID, int &productID, int &productVersion) const +{ +#if SDL_VERSION_ATLEAST(2, 0, 6) + if (joyhandle != nullptr) + { + vendorID = SDL_JoystickGetVendor(joyhandle); + productID = SDL_JoystickGetProduct(joyhandle); + productVersion = SDL_JoystickGetProductVersion(joyhandle); + } + else +#endif + { + vendorID = 0; + productID = 0; + productVersion = 0; + } +} + bool Joystick::checkCreateHaptic() { if (!isConnected()) diff -Nru love-11.1/src/modules/joystick/sdl/Joystick.h love-11.3/src/modules/joystick/sdl/Joystick.h --- love-11.1/src/modules/joystick/sdl/Joystick.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/sdl/Joystick.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -68,6 +68,7 @@ bool isGamepadDown(const std::vector &blist) const override; JoystickInput getGamepadMapping(const GamepadInput &input) const override; + std::string getGamepadMappingString() const override; void *getHandle() const override; @@ -75,6 +76,8 @@ int getInstanceID() const override; int getID() const override; + void getDeviceInfo(int &vendorID, int &productID, int &productVersion) const override; + bool isVibrationSupported() override; bool setVibration(float left, float right, float duration = -1.0f) override; bool setVibration() override; @@ -110,13 +113,15 @@ { float left = 0.0f; float right = 0.0f; - SDL_HapticEffect effect = {}; + SDL_HapticEffect effect; Uint16 data[4]; int id = -1; Uint32 endtime = SDL_HAPTIC_INFINITY; + // Old versions of VS2013 have trouble with initializing these in-line. Vibration() - : data() // VS2013 can't initialize the array above... + : effect() + , data() {} } vibration; diff -Nru love-11.1/src/modules/joystick/sdl/JoystickModule.cpp love-11.3/src/modules/joystick/sdl/JoystickModule.cpp --- love-11.1/src/modules/joystick/sdl/JoystickModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/sdl/JoystickModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -356,7 +356,7 @@ for (auto stick : activeSticks) { - if (stick->isGamepad() || guid.compare(stick->getGUID()) != 0) + if (guid.compare(stick->getGUID()) != 0) continue; // Big hack time: open the index as a game controller and compare @@ -365,12 +365,15 @@ if (controller == nullptr) continue; + // GameController objects are reference-counted in SDL, so we don't want to + // have a joystick open when trying to re-initialize it SDL_Joystick *sdlstick = SDL_GameControllerGetJoystick(controller); - if (sdlstick == (SDL_Joystick *) stick->getHandle()) - stick->openGamepad(d_index); - - // GameController objects are reference-counted in SDL. + bool open_gamepad = (sdlstick == (SDL_Joystick *) stick->getHandle()); SDL_GameControllerClose(controller); + + // open as gamepad if necessary + if (open_gamepad) + stick->openGamepad(d_index); } } } @@ -448,6 +451,25 @@ throw love::Exception("Invalid gamepad mappings."); } +std::string JoystickModule::getGamepadMappingString(const std::string &guid) const +{ + SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(guid.c_str()); + + char *sdlmapping = SDL_GameControllerMappingForGUID(sdlguid); + if (sdlmapping == nullptr) + return ""; + + std::string mapping(sdlmapping); + SDL_free(sdlmapping); + + // Matches SDL_GameControllerAddMappingsFromRW. + if (mapping.find_last_of(',') != mapping.length() - 1) + mapping += ","; + mapping += "platform:" + std::string(SDL_GetPlatform()); + + return mapping; +} + std::string JoystickModule::saveGamepadMappings() { std::string mappings; diff -Nru love-11.1/src/modules/joystick/sdl/JoystickModule.h love-11.3/src/modules/joystick/sdl/JoystickModule.h --- love-11.1/src/modules/joystick/sdl/JoystickModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/sdl/JoystickModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -45,19 +45,21 @@ virtual ~JoystickModule(); // Implements Module. - const char *getName() const; + const char *getName() const override; // Implements JoystickModule. - love::joystick::Joystick *addJoystick(int deviceindex); - void removeJoystick(love::joystick::Joystick *joystick); - love::joystick::Joystick *getJoystickFromID(int instanceid); - love::joystick::Joystick *getJoystick(int joyindex); - int getIndex(const love::joystick::Joystick *joystick); - int getJoystickCount() const; - - bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput); - void loadGamepadMappings(const std::string &mappings); - std::string saveGamepadMappings(); + love::joystick::Joystick *addJoystick(int deviceindex) override; + void removeJoystick(love::joystick::Joystick *joystick) override; + love::joystick::Joystick *getJoystickFromID(int instanceid) override; + love::joystick::Joystick *getJoystick(int joyindex) override; + int getIndex(const love::joystick::Joystick *joystick) override; + int getJoystickCount() const override; + + bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput) override; + void loadGamepadMappings(const std::string &mappings) override; + + std::string getGamepadMappingString(const std::string &guid) const override; + std::string saveGamepadMappings() override; private: diff -Nru love-11.1/src/modules/joystick/wrap_Joystick.cpp love-11.3/src/modules/joystick/wrap_Joystick.cpp --- love-11.1/src/modules/joystick/wrap_Joystick.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/wrap_Joystick.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -71,6 +71,20 @@ return 1; } +int w_Joystick_getDeviceInfo(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + + int vendorID = 0, productID = 0, productVersion = 0; + j->getDeviceInfo(vendorID, productID, productVersion); + + lua_pushnumber(L, vendorID); + lua_pushnumber(L, productID); + lua_pushnumber(L, productVersion); + + return 3; +} + int w_Joystick_getAxisCount(lua_State *L) { Joystick *j = luax_checkjoystick(L, 1); @@ -278,6 +292,17 @@ return 1; } +int w_Joystick_getGamepadMappingString(lua_State *L) +{ + Joystick *j = luax_checkjoystick(L, 1); + std::string mapping = j->getGamepadMappingString(); + if (mapping.empty()) + lua_pushnil(L); + else + luax_pushstring(L, mapping); + return 1; +} + int w_Joystick_isVibrationSupported(lua_State *L) { Joystick *j = luax_checkjoystick(L, 1); @@ -324,6 +349,7 @@ { "getName", w_Joystick_getName }, { "getID", w_Joystick_getID }, { "getGUID", w_Joystick_getGUID }, + { "getDeviceInfo", w_Joystick_getDeviceInfo }, { "getAxisCount", w_Joystick_getAxisCount }, { "getButtonCount", w_Joystick_getButtonCount }, { "getHatCount", w_Joystick_getHatCount }, @@ -336,6 +362,7 @@ { "getGamepadAxis", w_Joystick_getGamepadAxis }, { "isGamepadDown", w_Joystick_isGamepadDown }, { "getGamepadMapping", w_Joystick_getGamepadMapping }, + { "getGamepadMappingString", w_Joystick_getGamepadMappingString }, { "isVibrationSupported", w_Joystick_isVibrationSupported }, { "setVibration", w_Joystick_setVibration }, diff -Nru love-11.1/src/modules/joystick/wrap_Joystick.h love-11.3/src/modules/joystick/wrap_Joystick.h --- love-11.1/src/modules/joystick/wrap_Joystick.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/wrap_Joystick.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/joystick/wrap_JoystickModule.cpp love-11.3/src/modules/joystick/wrap_JoystickModule.cpp --- love-11.1/src/modules/joystick/wrap_JoystickModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/wrap_JoystickModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -160,6 +160,17 @@ return 1; } +int w_getGamepadMappingString(lua_State *L) +{ + const char *guid = luaL_checkstring(L, 1); + std::string mapping = instance()->getGamepadMappingString(guid); + if (mapping.empty()) + lua_pushnil(L); + else + luax_pushstring(L, mapping); + return 1; +} + // List of functions to wrap. static const luaL_Reg functions[] = { @@ -168,6 +179,7 @@ { "setGamepadMapping", w_setGamepadMapping }, { "loadGamepadMappings", w_loadGamepadMappings }, { "saveGamepadMappings", w_saveGamepadMappings }, + { "getGamepadMappingString", w_getGamepadMappingString }, { 0, 0 } }; diff -Nru love-11.1/src/modules/joystick/wrap_JoystickModule.h love-11.3/src/modules/joystick/wrap_JoystickModule.h --- love-11.1/src/modules/joystick/wrap_JoystickModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/joystick/wrap_JoystickModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/keyboard/Keyboard.cpp love-11.3/src/modules/keyboard/Keyboard.cpp --- love-11.1/src/modules/keyboard/Keyboard.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/keyboard/Keyboard.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/keyboard/Keyboard.h love-11.3/src/modules/keyboard/Keyboard.h --- love-11.1/src/modules/keyboard/Keyboard.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/keyboard/Keyboard.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/keyboard/sdl/Keyboard.cpp love-11.3/src/modules/keyboard/sdl/Keyboard.cpp --- love-11.1/src/modules/keyboard/sdl/Keyboard.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/keyboard/sdl/Keyboard.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/keyboard/sdl/Keyboard.h love-11.3/src/modules/keyboard/sdl/Keyboard.h --- love-11.1/src/modules/keyboard/sdl/Keyboard.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/keyboard/sdl/Keyboard.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/keyboard/wrap_Keyboard.cpp love-11.3/src/modules/keyboard/wrap_Keyboard.cpp --- love-11.1/src/modules/keyboard/wrap_Keyboard.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/keyboard/wrap_Keyboard.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/keyboard/wrap_Keyboard.h love-11.3/src/modules/keyboard/wrap_Keyboard.h --- love-11.1/src/modules/keyboard/wrap_Keyboard.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/keyboard/wrap_Keyboard.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/love/love.cpp love-11.3/src/modules/love/love.cpp --- love-11.1/src/modules/love/love.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/love/love.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -69,6 +69,11 @@ # include "graphics/Graphics.h" #endif +// For love::audio::Audio::setMixWithSystem. +#ifdef LOVE_ENABLE_AUDIO +# include "audio/Audio.h" +#endif + // Scripts #include "scripts/nogame.lua.h" #include "scripts/boot.lua.h" @@ -269,12 +274,18 @@ std::string version; if (lua_type(L, 1) == LUA_TSTRING) + { version = luaL_checkstring(L, 1); + + // Convert major.minor to major.minor.revision. + if (std::count(version.begin(), version.end(), '.') < 2) + version.append(".0"); + } else { int major = (int) luaL_checkinteger(L, 1); int minor = (int) luaL_checkinteger(L, 2); - int rev = (int) luaL_checkinteger(L, 3); + int rev = (int) luaL_optinteger(L, 3, 0); // Convert the numbers to a string, since VERSION_COMPATIBILITY is an // array of version strings. @@ -286,7 +297,13 @@ for (int i = 0; love::VERSION_COMPATIBILITY[i] != nullptr; i++) { - if (version.compare(love::VERSION_COMPATIBILITY[i]) != 0) + std::string v(love::VERSION_COMPATIBILITY[i]); + + // Convert major.minor to major.minor.revision. + if (std::count(v.begin(), v.end(), '.') < 2) + v.append(".0"); + + if (version.compare(v) != 0) continue; lua_pushboolean(L, true); @@ -305,6 +322,27 @@ return 0; } +static int w__setAudioMixWithSystem(lua_State *L) +{ + bool success = false; + +#ifdef LOVE_ENABLE_AUDIO + bool mix = love::luax_checkboolean(L, 1); + success = love::audio::Audio::setMixWithSystem(mix); +#endif + + love::luax_pushboolean(L, success); + return 1; +} + +static int w__requestRecordingPermission(lua_State *L) +{ +#ifdef LOVE_ENABLE_AUDIO + love::audio::setRequestRecordingPermission((bool) lua_toboolean(L, 1)); +#endif + return 0; +} + static int w_love_setDeprecationOutput(lua_State *L) { bool enable = love::luax_checkboolean(L, 1); @@ -362,6 +400,13 @@ lua_pushcfunction(L, w__setGammaCorrect); lua_setfield(L, -2, "_setGammaCorrect"); + // Exposed here because we need to be able to call it before the audio + // module is initialized. + lua_pushcfunction(L, w__setAudioMixWithSystem); + lua_setfield(L, -2, "_setAudioMixWithSystem"); + lua_pushcfunction(L, w__requestRecordingPermission); + lua_setfield(L, -2, "_requestRecordingPermission"); + lua_newtable(L); for (int i = 0; love::VERSION_COMPATIBILITY[i] != nullptr; i++) diff -Nru love-11.1/src/modules/love/love.h love-11.3/src/modules/love/love.h --- love-11.1/src/modules/love/love.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/love/love.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/BezierCurve.cpp love-11.3/src/modules/math/BezierCurve.cpp --- love-11.1/src/modules/math/BezierCurve.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/BezierCurve.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/BezierCurve.h love-11.3/src/modules/math/BezierCurve.h --- love-11.1/src/modules/math/BezierCurve.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/BezierCurve.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/MathModule.cpp love-11.3/src/modules/math/MathModule.cpp --- love-11.1/src/modules/math/MathModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/MathModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -199,14 +199,9 @@ return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; } -Math Math::instance; - Math::Math() : rng() { - // prevent the runtime from free()-ing this - retain(); - RandomGenerator::Seed seed; seed.b64 = (uint64) time(nullptr); rng.setSeed(seed); diff -Nru love-11.1/src/modules/math/MathModule.h love-11.3/src/modules/math/MathModule.h --- love-11.1/src/modules/math/MathModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/MathModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -91,12 +91,9 @@ class Math : public Module { -private: - - RandomGenerator rng; - public: + Math(); virtual ~Math(); RandomGenerator *getRandomGenerator() @@ -128,11 +125,9 @@ return "love.math"; } - static Math instance; - private: - Math(); + RandomGenerator rng; }; // Math diff -Nru love-11.1/src/modules/math/RandomGenerator.cpp love-11.3/src/modules/math/RandomGenerator.cpp --- love-11.1/src/modules/math/RandomGenerator.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/RandomGenerator.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -104,6 +104,8 @@ } while (newseed.b64 == 0); rng_state = newseed; + + last_randomnormal = std::numeric_limits::infinity(); } RandomGenerator::Seed RandomGenerator::getSeed() const @@ -129,6 +131,8 @@ throw love::Exception("Invalid random state: %s", statestr.c_str()); rng_state = state; + + last_randomnormal = std::numeric_limits::infinity(); } std::string RandomGenerator::getState() const diff -Nru love-11.1/src/modules/math/RandomGenerator.h love-11.3/src/modules/math/RandomGenerator.h --- love-11.1/src/modules/math/RandomGenerator.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/RandomGenerator.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/Transform.cpp love-11.3/src/modules/math/Transform.cpp --- love-11.1/src/modules/math/Transform.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/Transform.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/Transform.h love-11.3/src/modules/math/Transform.h --- love-11.1/src/modules/math/Transform.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/Transform.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/wrap_BezierCurve.cpp love-11.3/src/modules/math/wrap_BezierCurve.cpp --- love-11.1/src/modules/math/wrap_BezierCurve.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_BezierCurve.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/wrap_BezierCurve.h love-11.3/src/modules/math/wrap_BezierCurve.h --- love-11.1/src/modules/math/wrap_BezierCurve.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_BezierCurve.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/wrap_Math.cpp love-11.3/src/modules/math/wrap_Math.cpp --- love-11.1/src/modules/math/wrap_Math.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_Math.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -44,9 +44,11 @@ namespace math { +#define instance() (Module::getInstance(Module::M_MATH)) + int w__getRandomGenerator(lua_State *L) { - RandomGenerator *t = Math::instance.getRandomGenerator(); + RandomGenerator *t = instance()->getRandomGenerator(); luax_pushtype(L, t); return 1; } @@ -57,7 +59,7 @@ if (lua_gettop(L) > 0) s = luax_checkrandomseed(L, 1); - RandomGenerator *t = Math::instance.newRandomGenerator(); + RandomGenerator *t = instance()->newRandomGenerator(); if (lua_gettop(L) > 0) { @@ -116,7 +118,7 @@ } } - BezierCurve *curve = Math::instance.newBezierCurve(points); + BezierCurve *curve = instance()->newBezierCurve(points); luax_pushtype(L, curve); curve->release(); return 1; @@ -127,7 +129,7 @@ Transform *t = nullptr; if (lua_isnoneornil(L, 1)) - t = Math::instance.newTransform(); + t = instance()->newTransform(); else { float x = (float) luaL_checknumber(L, 1); @@ -139,7 +141,7 @@ float oy = (float) luaL_optnumber(L, 7, 0.0); float kx = (float) luaL_optnumber(L, 8, 0.0); float ky = (float) luaL_optnumber(L, 9, 0.0); - t = Math::instance.newTransform(x, y, a, sx, sy, ox, oy, kx, ky); + t = instance()->newTransform(x, y, a, sx, sy, ox, oy, kx, ky); } luax_pushtype(L, t); @@ -478,10 +480,16 @@ extern "C" int luaopen_love_math(lua_State *L) { - Math::instance.retain(); + Math *instance = instance(); + if (instance == nullptr) + { + luax_catchexcept(L, [&](){ instance = new Math(); }); + } + else + instance->retain(); WrappedModule w; - w.module = &Math::instance; + w.module = instance; w.name = "math"; w.type = &Module::type; w.functions = functions; @@ -492,7 +500,7 @@ // Execute wrap_Math.lua, sending the math table and ffifuncs pointer as args. luaL_loadbuffer(L, math_lua, sizeof(math_lua), "wrap_Math.lua"); lua_pushvalue(L, -2); - lua_pushlightuserdata(L, &ffifuncs); + luax_pushpointerasstring(L, &ffifuncs); lua_call(L, 2, 0); return n; diff -Nru love-11.1/src/modules/math/wrap_Math.h love-11.3/src/modules/math/wrap_Math.h --- love-11.1/src/modules/math/wrap_Math.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_Math.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/wrap_Math.lua love-11.3/src/modules/math/wrap_Math.lua --- love-11.1/src/modules/math/wrap_Math.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_Math.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ 3. This notice may not be removed or altered from any source distribution. --]] -local love_math, ffifuncspointer = ... +local love_math, ffifuncspointer_str = ... local type, tonumber, error = type, tonumber, error local floor = math.floor @@ -58,6 +58,28 @@ return rng:getState() end +function love_math.colorToBytes(r, g, b, a) + if type(r) == "table" then + r, g, b, a = r[1], r[2], r[3], r[4] + end + r = floor(clamp01(r) * 255 + 0.5) + g = floor(clamp01(g) * 255 + 0.5) + b = floor(clamp01(b) * 255 + 0.5) + a = a ~= nil and floor(clamp01(a) * 255 + 0.5) or nil + return r, g, b, a +end + +function love_math.colorFromBytes(r, g, b, a) + if type(r) == "table" then + r, g, b, a = r[1], r[2], r[3], r[4] + end + r = clamp01(floor(r + 0.5) / 255) + g = clamp01(floor(g + 0.5) / 255) + b = clamp01(floor(b + 0.5) / 255) + a = a ~= nil and clamp01(floor(a + 0.5) / 255) or nil + return r, g, b, a +end + if type(jit) ~= "table" or not jit.status() then -- LuaJIT's FFI is *much* slower than LOVE's regular methods when the JIT -- compiler is disabled. @@ -81,7 +103,7 @@ } FFI_Math; ]]) -local ffifuncs = ffi.cast("FFI_Math *", ffifuncspointer) +local ffifuncs = ffi.cast("FFI_Math **", ffifuncspointer_str)[0] -- Overwrite some regular love.math functions with FFI implementations. diff -Nru love-11.1/src/modules/math/wrap_RandomGenerator.cpp love-11.3/src/modules/math/wrap_RandomGenerator.cpp --- love-11.1/src/modules/math/wrap_RandomGenerator.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_RandomGenerator.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -126,22 +126,14 @@ { [](Proxy *p) -> double // random() { - // FIXME: We need better type-checking... - if (p == nullptr || p->object == nullptr || p->type == nullptr || !p->type->isa(RandomGenerator::type)) - return 0.0; - - RandomGenerator *rng = (RandomGenerator *) p->object; - return rng->random(); + auto rng = luax_ffi_checktype(p); + return rng != nullptr ? rng->random() : 0.0; }, [](Proxy *p, double stdddev, double mean) -> double // randomNormal { - // FIXME: We need better type-checking... - if (p == nullptr || p->object == nullptr || p->type == nullptr || !p->type->isa(RandomGenerator::type)) - return 0.0; - - RandomGenerator *rng = (RandomGenerator *) p->object; - return rng->randomNormal(stdddev) + mean; + auto rng = luax_ffi_checktype(p); + return rng != nullptr ? (rng->randomNormal(stdddev) + mean) : 0.0; } }; @@ -160,20 +152,7 @@ { int n = luax_register_type(L, &RandomGenerator::type, w_RandomGenerator_functions, nullptr); - luax_gettypemetatable(L, RandomGenerator::type); - - // Load and execute wrap_RandomGenerator.lua, sending the metatable and the - // ffi functions struct pointer as arguments. - if (lua_istable(L, -1)) - { - luaL_loadbuffer(L, randomgenerator_lua, sizeof(randomgenerator_lua), "wrap_RandomGenerator.lua"); - lua_pushvalue(L, -2); - lua_pushlightuserdata(L, &ffifuncs); - lua_call(L, 2, 0); - } - - // Pop the metatable. - lua_pop(L, 1); + luax_runwrapper(L, randomgenerator_lua, sizeof(randomgenerator_lua), "RandomGenerator.lua", RandomGenerator::type, &ffifuncs); return n; } diff -Nru love-11.1/src/modules/math/wrap_RandomGenerator.h love-11.3/src/modules/math/wrap_RandomGenerator.h --- love-11.1/src/modules/math/wrap_RandomGenerator.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_RandomGenerator.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/wrap_RandomGenerator.lua love-11.3/src/modules/math/wrap_RandomGenerator.lua --- love-11.1/src/modules/math/wrap_RandomGenerator.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_RandomGenerator.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ 3. This notice may not be removed or altered from any source distribution. --]] -local RandomGenerator_mt, ffifuncspointer = ... +local RandomGenerator_mt, ffifuncspointer_str = ... local RandomGenerator = RandomGenerator_mt.__index local type, tonumber, error = type, tonumber, error @@ -67,7 +67,7 @@ } FFI_RandomGenerator; ]]) -local ffifuncs = ffi.cast("FFI_RandomGenerator *", ffifuncspointer) +local ffifuncs = ffi.cast("FFI_RandomGenerator **", ffifuncspointer_str)[0] -- Overwrite some regular love.math functions with FFI implementations. diff -Nru love-11.1/src/modules/math/wrap_Transform.cpp love-11.3/src/modules/math/wrap_Transform.cpp --- love-11.1/src/modules/math/wrap_Transform.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_Transform.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/math/wrap_Transform.h love-11.3/src/modules/math/wrap_Transform.h --- love-11.1/src/modules/math/wrap_Transform.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/math/wrap_Transform.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/Cursor.cpp love-11.3/src/modules/mouse/Cursor.cpp --- love-11.1/src/modules/mouse/Cursor.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/Cursor.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/Cursor.h love-11.3/src/modules/mouse/Cursor.h --- love-11.1/src/modules/mouse/Cursor.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/Cursor.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/Mouse.h love-11.3/src/modules/mouse/Mouse.h --- love-11.1/src/modules/mouse/Mouse.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/Mouse.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/sdl/Cursor.cpp love-11.3/src/modules/mouse/sdl/Cursor.cpp --- love-11.1/src/modules/mouse/sdl/Cursor.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/sdl/Cursor.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/sdl/Cursor.h love-11.3/src/modules/mouse/sdl/Cursor.h --- love-11.1/src/modules/mouse/sdl/Cursor.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/sdl/Cursor.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/sdl/Mouse.cpp love-11.3/src/modules/mouse/sdl/Mouse.cpp --- love-11.1/src/modules/mouse/sdl/Mouse.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/sdl/Mouse.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -57,6 +57,9 @@ Mouse::Mouse() : curCursor(nullptr) { + // SDL may need the video subsystem in order to clean up the cursor when + // quitting. Subsystems are reference-counted. + SDL_InitSubSystem(SDL_INIT_VIDEO); } Mouse::~Mouse() @@ -66,6 +69,8 @@ for (auto &c : systemCursors) c.second->release(); + + SDL_QuitSubSystem(SDL_INIT_VIDEO); } love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, int hoty) diff -Nru love-11.1/src/modules/mouse/sdl/Mouse.h love-11.3/src/modules/mouse/sdl/Mouse.h --- love-11.1/src/modules/mouse/sdl/Mouse.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/sdl/Mouse.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/wrap_Cursor.cpp love-11.3/src/modules/mouse/wrap_Cursor.cpp --- love-11.1/src/modules/mouse/wrap_Cursor.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/wrap_Cursor.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/wrap_Cursor.h love-11.3/src/modules/mouse/wrap_Cursor.h --- love-11.1/src/modules/mouse/wrap_Cursor.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/wrap_Cursor.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/wrap_Mouse.cpp love-11.3/src/modules/mouse/wrap_Mouse.cpp --- love-11.1/src/modules/mouse/wrap_Mouse.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/wrap_Mouse.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/mouse/wrap_Mouse.h love-11.3/src/modules/mouse/wrap_Mouse.h --- love-11.1/src/modules/mouse/wrap_Mouse.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/mouse/wrap_Mouse.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/Body.cpp love-11.3/src/modules/physics/Body.cpp --- love-11.1/src/modules/physics/Body.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/Body.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/Body.h love-11.3/src/modules/physics/Body.h --- love-11.1/src/modules/physics/Body.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/Body.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Body.cpp love-11.3/src/modules/physics/box2d/Body.cpp --- love-11.1/src/modules/physics/box2d/Body.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Body.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,6 @@ #include "Body.h" #include "common/math.h" -#include "common/Memoizer.h" #include "Shape.h" #include "Fixture.h" @@ -51,18 +50,7 @@ // Box2D body holds a reference to the love Body. this->retain(); this->setType(type); - Memoizer::add(body, this); -} - -Body::Body(b2Body *b) - : body(b) - , udata(nullptr) -{ - udata = (bodyudata *) b->GetUserData(); - world = (World *) Memoizer::find(b->GetWorld()); - // Box2D body holds a reference to the love Body. - this->retain(); - Memoizer::add(body, this); + world->registerObject(body, this); } Body::~Body() @@ -452,7 +440,7 @@ { if (!f) break; - Fixture *fixture = (Fixture *)Memoizer::find(f); + Fixture *fixture = (Fixture *)world->findObject(f); if (!fixture) throw love::Exception("A fixture has escaped Memoizer!"); luax_pushtype(L, fixture); @@ -474,7 +462,7 @@ if (!je) break; - Joint *joint = (Joint *) Memoizer::find(je->joint); + Joint *joint = (Joint *) world->findObject(je->joint); if (!joint) throw love::Exception("A joint has escaped Memoizer!"); @@ -497,9 +485,9 @@ if (!ce) break; - Contact *contact = (Contact *) Memoizer::find(ce->contact); + Contact *contact = (Contact *) world->findObject(ce->contact); if (!contact) - contact = new Contact(ce->contact); + contact = new Contact(world, ce->contact); else contact->retain(); @@ -512,21 +500,6 @@ return 1; } -b2Vec2 Body::getVector(lua_State *L) -{ - love::luax_assert_argc(L, 2, 2); - b2Vec2 v((float)lua_tonumber(L, 1), (float)lua_tonumber(L, 2)); - lua_pop(L, 2); - return v; -} - -int Body::pushVector(lua_State *L, const b2Vec2 &v) -{ - lua_pushnumber(L, v.x); - lua_pushnumber(L, v.y); - return 2; -} - void Body::destroy() { if (world->world->IsLocked()) @@ -538,7 +511,7 @@ } world->world->DestroyBody(body); - Memoizer::remove(body); + world->unregisterObject(body); body = NULL; // Remove userdata reference to avoid it sticking around after GC diff -Nru love-11.1/src/modules/physics/box2d/Body.h love-11.3/src/modules/physics/box2d/Body.h --- love-11.1/src/modules/physics/box2d/Body.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Body.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -77,11 +77,6 @@ **/ Body(World *world, b2Vec2 p, Type type); - /** - * Create a Body from an extant b2Body. - **/ - Body(b2Body *b); - virtual ~Body(); /** @@ -426,17 +421,6 @@ private: - /** - * Gets a 2d vector from the arguments on the stack. - **/ - b2Vec2 getVector(lua_State *L); - - /** - * Pushed the x- and y-components of a vector on - * the stack. - **/ - int pushVector(lua_State *L, const b2Vec2 &v); - // FIXME: This should be a weak reference, rather than being completely // unowned? World *world; diff -Nru love-11.1/src/modules/physics/box2d/ChainShape.cpp love-11.3/src/modules/physics/box2d/ChainShape.cpp --- love-11.1/src/modules/physics/box2d/ChainShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/ChainShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - namespace love { namespace physics diff -Nru love-11.1/src/modules/physics/box2d/ChainShape.h love-11.3/src/modules/physics/box2d/ChainShape.h --- love-11.1/src/modules/physics/box2d/ChainShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/ChainShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/CircleShape.cpp love-11.3/src/modules/physics/box2d/CircleShape.cpp --- love-11.1/src/modules/physics/box2d/CircleShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/CircleShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - namespace love { namespace physics diff -Nru love-11.1/src/modules/physics/box2d/CircleShape.h love-11.3/src/modules/physics/box2d/CircleShape.h --- love-11.1/src/modules/physics/box2d/CircleShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/CircleShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Contact.cpp love-11.3/src/modules/physics/box2d/Contact.cpp --- love-11.1/src/modules/physics/box2d/Contact.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Contact.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -22,8 +22,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - namespace love { namespace physics @@ -33,10 +31,11 @@ love::Type Contact::type("Contact", &Object::type); -Contact::Contact(b2Contact *contact) +Contact::Contact(World *world, b2Contact *contact) : contact(contact) + , world(world) { - Memoizer::add(contact, this); + world->registerObject(contact, this); } Contact::~Contact() @@ -48,14 +47,14 @@ { if (contact != NULL) { - Memoizer::remove(contact); + world->unregisterObject(contact); contact = NULL; } } bool Contact::isValid() { - return contact != NULL ? true : false; + return contact != NULL; } int Contact::getPositions(lua_State *L) @@ -146,8 +145,8 @@ void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB) { - fixtureA = (Fixture *) Memoizer::find(contact->GetFixtureA()); - fixtureB = (Fixture *) Memoizer::find(contact->GetFixtureB()); + fixtureA = (Fixture *) world->findObject(contact->GetFixtureA()); + fixtureB = (Fixture *) world->findObject(contact->GetFixtureB()); if (!fixtureA || !fixtureB) throw love::Exception("A fixture has escaped Memoizer!"); diff -Nru love-11.1/src/modules/physics/box2d/Contact.h love-11.3/src/modules/physics/box2d/Contact.h --- love-11.1/src/modules/physics/box2d/Contact.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Contact.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -57,7 +57,7 @@ * data pointed to. * @param contact Pointer to the Box2D contact. **/ - Contact(b2Contact *contact); + Contact(World *world, b2Contact *contact); virtual ~Contact(); @@ -159,6 +159,8 @@ // The Box2D contact. b2Contact *contact; + + World *world; }; } // box2d diff -Nru love-11.1/src/modules/physics/box2d/DistanceJoint.cpp love-11.3/src/modules/physics/box2d/DistanceJoint.cpp --- love-11.1/src/modules/physics/box2d/DistanceJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/DistanceJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/DistanceJoint.h love-11.3/src/modules/physics/box2d/DistanceJoint.h --- love-11.1/src/modules/physics/box2d/DistanceJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/DistanceJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/EdgeShape.cpp love-11.3/src/modules/physics/box2d/EdgeShape.cpp --- love-11.1/src/modules/physics/box2d/EdgeShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/EdgeShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - namespace love { namespace physics diff -Nru love-11.1/src/modules/physics/box2d/EdgeShape.h love-11.3/src/modules/physics/box2d/EdgeShape.h --- love-11.1/src/modules/physics/box2d/EdgeShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/EdgeShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Fixture.cpp love-11.3/src/modules/physics/box2d/Fixture.cpp --- love-11.1/src/modules/physics/box2d/Fixture.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Fixture.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - // STD #include @@ -51,18 +49,7 @@ def.density = density; fixture = body->body->CreateFixture(&def); this->retain(); - Memoizer::add(fixture, this); -} - -Fixture::Fixture(b2Fixture *f) - : fixture(f) -{ - udata = (fixtureudata *)f->GetUserData(); - body = (Body *)Memoizer::find(f->GetBody()); - if (!body) - body = new Body(f->GetBody()); - this->retain(); - Memoizer::add(fixture, this); + body->world->registerObject(fixture, this); } Fixture::~Fixture() @@ -361,7 +348,7 @@ if (!implicit && fixture != nullptr) body->body->DestroyFixture(fixture); - Memoizer::remove(fixture); + body->world->unregisterObject(fixture); fixture = nullptr; // Remove userdata reference to avoid it sticking around after GC diff -Nru love-11.1/src/modules/physics/box2d/Fixture.h love-11.3/src/modules/physics/box2d/Fixture.h --- love-11.1/src/modules/physics/box2d/Fixture.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Fixture.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -38,6 +38,8 @@ namespace box2d { +class World; + /** * This struct is stored in a void pointer * in the Box2D Fixture class. For now, all we @@ -68,11 +70,6 @@ **/ Fixture(Body *body, Shape *shape, float density); - /** - * Creates a Fixture. - **/ - Fixture(b2Fixture *f); - virtual ~Fixture(); /** diff -Nru love-11.1/src/modules/physics/box2d/FrictionJoint.cpp love-11.3/src/modules/physics/box2d/FrictionJoint.cpp --- love-11.1/src/modules/physics/box2d/FrictionJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/FrictionJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/FrictionJoint.h love-11.3/src/modules/physics/box2d/FrictionJoint.h --- love-11.1/src/modules/physics/box2d/FrictionJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/FrictionJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/GearJoint.cpp love-11.3/src/modules/physics/box2d/GearJoint.cpp --- love-11.1/src/modules/physics/box2d/GearJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/GearJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,6 @@ // Module #include "Body.h" #include "World.h" -#include "common/Memoizer.h" namespace love { @@ -69,7 +68,7 @@ if (b2joint == nullptr) return nullptr; - Joint *j = (Joint *) Memoizer::find(b2joint); + Joint *j = (Joint *) world->findObject(b2joint); if (j == nullptr) throw love::Exception("A joint has escaped Memoizer!"); @@ -82,7 +81,7 @@ if (b2joint == nullptr) return nullptr; - Joint *j = (Joint *) Memoizer::find(b2joint); + Joint *j = (Joint *) world->findObject(b2joint); if (j == nullptr) throw love::Exception("A joint has escaped Memoizer!"); diff -Nru love-11.1/src/modules/physics/box2d/GearJoint.h love-11.3/src/modules/physics/box2d/GearJoint.h --- love-11.1/src/modules/physics/box2d/GearJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/GearJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Joint.cpp love-11.3/src/modules/physics/box2d/Joint.cpp --- love-11.1/src/modules/physics/box2d/Joint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Joint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,6 @@ // STD #include -// LOVE -#include "common/Memoizer.h" - // Module #include "Body.h" #include "World.h" @@ -107,7 +104,7 @@ if (b2body == nullptr) return nullptr; - Body *body = (Body *) Memoizer::find(b2body); + Body *body = (Body *) world->findObject(b2body); if (body == nullptr) throw love::Exception("A body has escaped Memoizer!"); @@ -120,7 +117,7 @@ if (b2body == nullptr) return nullptr; - Body *body = (Body *) Memoizer::find(b2body); + Body *body = (Body *) world->findObject(b2body); if (body == nullptr) throw love::Exception("A body has escaped Memoizer!"); @@ -129,7 +126,7 @@ bool Joint::isValid() const { - return joint != 0; + return joint != nullptr; } int Joint::getAnchors(lua_State *L) @@ -159,7 +156,7 @@ { def->userData = udata; joint = world->world->CreateJoint(def); - Memoizer::add(joint, this); + world->registerObject(joint, this); // Box2D joint has a reference to this love Joint. this->retain(); return joint; @@ -175,9 +172,9 @@ return; } - if (!implicit && joint != 0) + if (!implicit && joint != nullptr) world->world->DestroyJoint(joint); - Memoizer::remove(joint); + world->unregisterObject(joint); joint = NULL; // Remove userdata reference to avoid it sticking around after GC diff -Nru love-11.1/src/modules/physics/box2d/Joint.h love-11.3/src/modules/physics/box2d/Joint.h --- love-11.1/src/modules/physics/box2d/Joint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Joint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -153,7 +153,7 @@ // The Box2D joint object. b2Joint *joint; -}; +}; // Joint } // box2d } // physics diff -Nru love-11.1/src/modules/physics/box2d/MotorJoint.cpp love-11.3/src/modules/physics/box2d/MotorJoint.cpp --- love-11.1/src/modules/physics/box2d/MotorJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/MotorJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/MotorJoint.h love-11.3/src/modules/physics/box2d/MotorJoint.h --- love-11.1/src/modules/physics/box2d/MotorJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/MotorJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/MouseJoint.cpp love-11.3/src/modules/physics/box2d/MouseJoint.cpp --- love-11.1/src/modules/physics/box2d/MouseJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/MouseJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/MouseJoint.h love-11.3/src/modules/physics/box2d/MouseJoint.h --- love-11.1/src/modules/physics/box2d/MouseJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/MouseJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Physics.cpp love-11.3/src/modules/physics/box2d/Physics.cpp --- love-11.1/src/modules/physics/box2d/Physics.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Physics.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Physics.h love-11.3/src/modules/physics/box2d/Physics.h --- love-11.1/src/modules/physics/box2d/Physics.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Physics.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/PolygonShape.cpp love-11.3/src/modules/physics/box2d/PolygonShape.cpp --- love-11.1/src/modules/physics/box2d/PolygonShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/PolygonShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - namespace love { namespace physics diff -Nru love-11.1/src/modules/physics/box2d/PolygonShape.h love-11.3/src/modules/physics/box2d/PolygonShape.h --- love-11.1/src/modules/physics/box2d/PolygonShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/PolygonShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/PrismaticJoint.cpp love-11.3/src/modules/physics/box2d/PrismaticJoint.cpp --- love-11.1/src/modules/physics/box2d/PrismaticJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/PrismaticJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/PrismaticJoint.h love-11.3/src/modules/physics/box2d/PrismaticJoint.h --- love-11.1/src/modules/physics/box2d/PrismaticJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/PrismaticJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/PulleyJoint.cpp love-11.3/src/modules/physics/box2d/PulleyJoint.cpp --- love-11.1/src/modules/physics/box2d/PulleyJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/PulleyJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/PulleyJoint.h love-11.3/src/modules/physics/box2d/PulleyJoint.h --- love-11.1/src/modules/physics/box2d/PulleyJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/PulleyJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/RevoluteJoint.cpp love-11.3/src/modules/physics/box2d/RevoluteJoint.cpp --- love-11.1/src/modules/physics/box2d/RevoluteJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/RevoluteJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/RevoluteJoint.h love-11.3/src/modules/physics/box2d/RevoluteJoint.h --- love-11.1/src/modules/physics/box2d/RevoluteJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/RevoluteJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/RopeJoint.cpp love-11.3/src/modules/physics/box2d/RopeJoint.cpp --- love-11.1/src/modules/physics/box2d/RopeJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/RopeJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/RopeJoint.h love-11.3/src/modules/physics/box2d/RopeJoint.h --- love-11.1/src/modules/physics/box2d/RopeJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/RopeJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/Shape.cpp love-11.3/src/modules/physics/box2d/Shape.cpp --- love-11.1/src/modules/physics/box2d/Shape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Shape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,6 @@ #include "World.h" #include "Physics.h" -#include "common/Memoizer.h" - // STD #include @@ -47,17 +45,12 @@ : shape(shape) , own(own) { - if (own) - Memoizer::add(shape, this); } Shape::~Shape() { if (shape && own) - { - Memoizer::remove(shape); delete shape; - } shape = nullptr; } diff -Nru love-11.1/src/modules/physics/box2d/Shape.h love-11.3/src/modules/physics/box2d/Shape.h --- love-11.1/src/modules/physics/box2d/Shape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/Shape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/WeldJoint.cpp love-11.3/src/modules/physics/box2d/WeldJoint.cpp --- love-11.1/src/modules/physics/box2d/WeldJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/WeldJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/WeldJoint.h love-11.3/src/modules/physics/box2d/WeldJoint.h --- love-11.1/src/modules/physics/box2d/WeldJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/WeldJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/WheelJoint.cpp love-11.3/src/modules/physics/box2d/WheelJoint.cpp --- love-11.1/src/modules/physics/box2d/WheelJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/WheelJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/WheelJoint.h love-11.3/src/modules/physics/box2d/WheelJoint.h --- love-11.1/src/modules/physics/box2d/WheelJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/WheelJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/World.cpp love-11.3/src/modules/physics/box2d/World.cpp --- love-11.1/src/modules/physics/box2d/World.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/World.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,11 @@ #include "Shape.h" #include "Contact.h" #include "Physics.h" -#include "common/Memoizer.h" #include "common/Reference.h" +// Needed for World::getJoints. It should be moved to wrapper code... +#include "wrap_Joint.h" + namespace love { namespace physics @@ -36,9 +38,10 @@ love::Type World::type("World", &Object::type); -World::ContactCallback::ContactCallback() +World::ContactCallback::ContactCallback(World *world) : ref(nullptr) , L(nullptr) + , world(world) { } @@ -57,7 +60,7 @@ // Push first fixture. { - Fixture *a = (Fixture *)Memoizer::find(contact->GetFixtureA()); + Fixture *a = (Fixture *)world->findObject(contact->GetFixtureA()); if (a != nullptr) luax_pushtype(L, a); else @@ -66,16 +69,16 @@ // Push second fixture. { - Fixture *b = (Fixture *)Memoizer::find(contact->GetFixtureB()); + Fixture *b = (Fixture *)world->findObject(contact->GetFixtureB()); if (b != nullptr) luax_pushtype(L, b); else throw love::Exception("A fixture has escaped Memoizer!"); } - Contact *cobj = (Contact *)Memoizer::find(contact); + Contact *cobj = (Contact *)world->findObject(contact); if (!cobj) - cobj = new Contact(contact); + cobj = new Contact(world, contact); else cobj->retain(); @@ -138,8 +141,9 @@ return true; } -World::QueryCallback::QueryCallback(lua_State *L, int idx) - : L(L) +World::QueryCallback::QueryCallback(World *world, lua_State *L, int idx) + : world(world) + , L(L) , funcidx(idx) { luaL_checktype(L, funcidx, LUA_TFUNCTION); @@ -154,7 +158,7 @@ if (L != nullptr) { lua_pushvalue(L, funcidx); - Fixture *f = (Fixture *)Memoizer::find(fixture); + Fixture *f = (Fixture *)world->findObject(fixture); if (!f) throw love::Exception("A fixture has escaped Memoizer!"); luax_pushtype(L, f); @@ -167,8 +171,9 @@ return true; } -World::RayCastCallback::RayCastCallback(lua_State *L, int idx) - : L(L) +World::RayCastCallback::RayCastCallback(World *world, lua_State *L, int idx) + : world(world) + , L(L) , funcidx(idx) { luaL_checktype(L, funcidx, LUA_TFUNCTION); @@ -183,7 +188,7 @@ if (L != nullptr) { lua_pushvalue(L, funcidx); - Fixture *f = (Fixture *)Memoizer::find(fixture); + Fixture *f = (Fixture *)world->findObject(fixture); if (!f) throw love::Exception("A fixture has escaped Memoizer!"); luax_pushtype(L, f); @@ -206,14 +211,14 @@ void World::SayGoodbye(b2Fixture *fixture) { - Fixture *f = (Fixture *)Memoizer::find(fixture); + Fixture *f = (Fixture *)findObject(fixture); // Hint implicit destruction with true. if (f) f->destroy(true); } void World::SayGoodbye(b2Joint *joint) { - Joint *j = (Joint *)Memoizer::find(joint); + Joint *j = (Joint *)findObject(joint); // Hint implicit destruction with true. if (j) j->destroyJoint(true); } @@ -221,6 +226,10 @@ World::World() : world(nullptr) , destructWorld(false) + , begin(this) + , end(this) + , presolve(this) + , postsolve(this) { world = new b2World(b2Vec2(0,0)); world->SetAllowSleeping(true); @@ -229,12 +238,16 @@ world->SetDestructionListener(this); b2BodyDef def; groundBody = world->CreateBody(&def); - Memoizer::add(world, this); + registerObject(world, this); } World::World(b2Vec2 gravity, bool sleep) : world(nullptr) , destructWorld(false) + , begin(this) + , end(this) + , presolve(this) + , postsolve(this) { world = new b2World(Physics::scaleDown(gravity)); world->SetAllowSleeping(sleep); @@ -243,7 +256,7 @@ world->SetDestructionListener(this); b2BodyDef def; groundBody = world->CreateBody(&def); - Memoizer::add(world, this); + registerObject(world, this); } World::~World() @@ -297,8 +310,8 @@ end.process(contact); // Letting the Contact know that the b2Contact will be destroyed any second. - Contact *c = (Contact *)Memoizer::find(contact); - if (c != NULL) + Contact *c = (Contact *)findObject(contact); + if (c != nullptr) c->invalidate(); } @@ -316,8 +329,8 @@ bool World::ShouldCollide(b2Fixture *fixtureA, b2Fixture *fixtureB) { // Fixtures should be memoized, if we created them - Fixture *a = (Fixture *)Memoizer::find(fixtureA); - Fixture *b = (Fixture *)Memoizer::find(fixtureB); + Fixture *a = (Fixture *)findObject(fixtureA); + Fixture *b = (Fixture *)findObject(fixtureB); if (!a || !b) throw love::Exception("A fixture has escaped Memoizer!"); return filter.process(a, b); @@ -472,7 +485,7 @@ break; if (b == groundBody) continue; - Body *body = (Body *)Memoizer::find(b); + Body *body = (Body *)findObject(b); if (!body) throw love::Exception("A body has escaped Memoizer!"); luax_pushtype(L, body); @@ -491,9 +504,9 @@ do { if (!j) break; - Joint *joint = (Joint *)Memoizer::find(j); + Joint *joint = (Joint *)findObject(j); if (!joint) throw love::Exception("A joint has escaped Memoizer!"); - luax_pushtype(L, joint); + luax_pushjoint(L, joint); lua_rawseti(L, -2, i); i++; } @@ -501,7 +514,7 @@ return 1; } -int World::getContacts(lua_State *L) const +int World::getContacts(lua_State *L) { lua_newtable(L); b2Contact *c = world->GetContactList(); @@ -509,9 +522,9 @@ do { if (!c) break; - Contact *contact = (Contact *)Memoizer::find(c); + Contact *contact = (Contact *)findObject(c); if (!contact) - contact = new Contact(c); + contact = new Contact(this, c); else contact->retain(); luax_pushtype(L, contact); @@ -538,7 +551,7 @@ box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly)); box.upperBound = Physics::scaleDown(b2Vec2(ux, uy)); luaL_checktype(L, 5, LUA_TFUNCTION); - QueryCallback query(L, 5); + QueryCallback query(this, L, 5); world->QueryAABB(&query, box); return 0; } @@ -552,7 +565,7 @@ b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1)); b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2)); luaL_checktype(L, 5, LUA_TFUNCTION); - RayCastCallback raycast(L, 5); + RayCastCallback raycast(this, L, 5); world->RayCast(&raycast, v1, v2); return 0; } @@ -586,19 +599,38 @@ b = b->GetNext(); if (t == groundBody) continue; - Body *body = (Body *)Memoizer::find(t); + Body *body = (Body *)findObject(t); if (!body) throw love::Exception("A body has escaped Memoizer!"); body->destroy(); } world->DestroyBody(groundBody); - Memoizer::remove(world); + unregisterObject(world); delete world; world = nullptr; } +void World::registerObject(void *b2object, love::Object *object) +{ + box2dObjectMap[b2object] = object; +} + +void World::unregisterObject(void *b2object) +{ + box2dObjectMap.erase(b2object); +} + +love::Object *World::findObject(void *b2object) const +{ + auto it = box2dObjectMap.find(b2object); + if (it != box2dObjectMap.end()) + return it->second; + else + return nullptr; +} + } // box2d } // physics } // love diff -Nru love-11.1/src/modules/physics/box2d/World.h love-11.3/src/modules/physics/box2d/World.h --- love-11.1/src/modules/physics/box2d/World.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/World.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,7 @@ // STD #include +#include // Box2D #include @@ -73,7 +74,8 @@ public: Reference *ref; lua_State *L; - ContactCallback(); + World *world; + ContactCallback(World *world); ~ContactCallback(); void process(b2Contact *contact, const b2ContactImpulse *impulse = NULL); }; @@ -91,10 +93,11 @@ class QueryCallback : public b2QueryCallback { public: - QueryCallback(lua_State *L, int idx); + QueryCallback(World *world, lua_State *L, int idx); ~QueryCallback(); virtual bool ReportFixture(b2Fixture *fixture); private: + World *world; lua_State *L; int funcidx; }; @@ -102,10 +105,11 @@ class RayCastCallback : public b2RayCastCallback { public: - RayCastCallback(lua_State *L, int idx); + RayCastCallback(World *world, lua_State *L, int idx); ~RayCastCallback(); virtual float32 ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction); private: + World *world; lua_State *L; int funcidx; }; @@ -257,7 +261,7 @@ * Get an array of all the Contacts in the World. * @return An array of Contacts. **/ - int getContacts(lua_State *L) const; + int getContacts(lua_State *L); /** * Gets the ground body. @@ -280,6 +284,10 @@ **/ void destroy(); + void registerObject(void *b2object, love::Object *object); + void unregisterObject(void *b2object); + love::Object *findObject(void *b2object) const; + private: // Pointer to the Box2D world. @@ -297,7 +305,10 @@ // Contact callbacks. ContactCallback begin, end, presolve, postsolve; ContactFilter filter; -}; + + std::unordered_map box2dObjectMap; + +}; // World } // box2d } // physics diff -Nru love-11.1/src/modules/physics/box2d/wrap_Body.cpp love-11.3/src/modules/physics/box2d/wrap_Body.cpp --- love-11.1/src/modules/physics/box2d/wrap_Body.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Body.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -69,6 +69,19 @@ return 2; } +int w_Body_getTransform(lua_State *L) +{ + Body *t = luax_checkbody(L, 1); + + float x_o, y_o; + t->getPosition(x_o, y_o); + lua_pushnumber(L, x_o); + lua_pushnumber(L, y_o); + lua_pushnumber(L, t->getAngle()); + + return 3; +} + int w_Body_getLinearVelocity(lua_State *L) { Body *t = luax_checkbody(L, 1); @@ -253,6 +266,19 @@ return 0; } +int w_Body_setTransform(lua_State *L) +{ + Body *t = luax_checkbody(L, 1); + float x = (float)luaL_checknumber(L, 2); + float y = (float)luaL_checknumber(L, 3); + float angle = (float)luaL_checknumber(L, 4); + luax_catchexcept(L, [&](){ + t->setPosition(x, y); + t->setAngle(angle); + }); + return 0; +} + int w_Body_setLinearVelocity(lua_State *L) { Body *t = luax_checkbody(L, 1); @@ -617,6 +643,8 @@ { "getY", w_Body_getY }, { "getAngle", w_Body_getAngle }, { "getPosition", w_Body_getPosition }, + { "getTransform", w_Body_getTransform }, + { "setTransform", w_Body_setTransform }, { "getLinearVelocity", w_Body_getLinearVelocity }, { "getWorldCenter", w_Body_getWorldCenter }, { "getLocalCenter", w_Body_getLocalCenter }, diff -Nru love-11.1/src/modules/physics/box2d/wrap_Body.h love-11.3/src/modules/physics/box2d/wrap_Body.h --- love-11.1/src/modules/physics/box2d/wrap_Body.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Body.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_ChainShape.cpp love-11.3/src/modules/physics/box2d/wrap_ChainShape.cpp --- love-11.1/src/modules/physics/box2d/wrap_ChainShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_ChainShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_ChainShape.h love-11.3/src/modules/physics/box2d/wrap_ChainShape.h --- love-11.1/src/modules/physics/box2d/wrap_ChainShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_ChainShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_CircleShape.cpp love-11.3/src/modules/physics/box2d/wrap_CircleShape.cpp --- love-11.1/src/modules/physics/box2d/wrap_CircleShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_CircleShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_CircleShape.h love-11.3/src/modules/physics/box2d/wrap_CircleShape.h --- love-11.1/src/modules/physics/box2d/wrap_CircleShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_CircleShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Contact.cpp love-11.3/src/modules/physics/box2d/wrap_Contact.cpp --- love-11.1/src/modules/physics/box2d/wrap_Contact.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Contact.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Contact.h love-11.3/src/modules/physics/box2d/wrap_Contact.h --- love-11.1/src/modules/physics/box2d/wrap_Contact.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Contact.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_DistanceJoint.cpp love-11.3/src/modules/physics/box2d/wrap_DistanceJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_DistanceJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_DistanceJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_DistanceJoint.h love-11.3/src/modules/physics/box2d/wrap_DistanceJoint.h --- love-11.1/src/modules/physics/box2d/wrap_DistanceJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_DistanceJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_EdgeShape.cpp love-11.3/src/modules/physics/box2d/wrap_EdgeShape.cpp --- love-11.1/src/modules/physics/box2d/wrap_EdgeShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_EdgeShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_EdgeShape.h love-11.3/src/modules/physics/box2d/wrap_EdgeShape.h --- love-11.1/src/modules/physics/box2d/wrap_EdgeShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_EdgeShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Fixture.cpp love-11.3/src/modules/physics/box2d/wrap_Fixture.cpp --- love-11.1/src/modules/physics/box2d/wrap_Fixture.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Fixture.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Fixture.h love-11.3/src/modules/physics/box2d/wrap_Fixture.h --- love-11.1/src/modules/physics/box2d/wrap_Fixture.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Fixture.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_FrictionJoint.cpp love-11.3/src/modules/physics/box2d/wrap_FrictionJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_FrictionJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_FrictionJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_FrictionJoint.h love-11.3/src/modules/physics/box2d/wrap_FrictionJoint.h --- love-11.1/src/modules/physics/box2d/wrap_FrictionJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_FrictionJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_GearJoint.cpp love-11.3/src/modules/physics/box2d/wrap_GearJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_GearJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_GearJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_GearJoint.h love-11.3/src/modules/physics/box2d/wrap_GearJoint.h --- love-11.1/src/modules/physics/box2d/wrap_GearJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_GearJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Joint.cpp love-11.3/src/modules/physics/box2d/wrap_Joint.cpp --- love-11.1/src/modules/physics/box2d/wrap_Joint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Joint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Joint.h love-11.3/src/modules/physics/box2d/wrap_Joint.h --- love-11.1/src/modules/physics/box2d/wrap_Joint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Joint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_MotorJoint.cpp love-11.3/src/modules/physics/box2d/wrap_MotorJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_MotorJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_MotorJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_MotorJoint.h love-11.3/src/modules/physics/box2d/wrap_MotorJoint.h --- love-11.1/src/modules/physics/box2d/wrap_MotorJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_MotorJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_MouseJoint.cpp love-11.3/src/modules/physics/box2d/wrap_MouseJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_MouseJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_MouseJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_MouseJoint.h love-11.3/src/modules/physics/box2d/wrap_MouseJoint.h --- love-11.1/src/modules/physics/box2d/wrap_MouseJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_MouseJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Physics.cpp love-11.3/src/modules/physics/box2d/wrap_Physics.cpp --- love-11.1/src/modules/physics/box2d/wrap_Physics.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Physics.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Physics.h love-11.3/src/modules/physics/box2d/wrap_Physics.h --- love-11.1/src/modules/physics/box2d/wrap_Physics.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Physics.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_PolygonShape.cpp love-11.3/src/modules/physics/box2d/wrap_PolygonShape.cpp --- love-11.1/src/modules/physics/box2d/wrap_PolygonShape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_PolygonShape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_PolygonShape.h love-11.3/src/modules/physics/box2d/wrap_PolygonShape.h --- love-11.1/src/modules/physics/box2d/wrap_PolygonShape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_PolygonShape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_PrismaticJoint.cpp love-11.3/src/modules/physics/box2d/wrap_PrismaticJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_PrismaticJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_PrismaticJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_PrismaticJoint.h love-11.3/src/modules/physics/box2d/wrap_PrismaticJoint.h --- love-11.1/src/modules/physics/box2d/wrap_PrismaticJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_PrismaticJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_PulleyJoint.cpp love-11.3/src/modules/physics/box2d/wrap_PulleyJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_PulleyJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_PulleyJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_PulleyJoint.h love-11.3/src/modules/physics/box2d/wrap_PulleyJoint.h --- love-11.1/src/modules/physics/box2d/wrap_PulleyJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_PulleyJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_RevoluteJoint.cpp love-11.3/src/modules/physics/box2d/wrap_RevoluteJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_RevoluteJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_RevoluteJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_RevoluteJoint.h love-11.3/src/modules/physics/box2d/wrap_RevoluteJoint.h --- love-11.1/src/modules/physics/box2d/wrap_RevoluteJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_RevoluteJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_RopeJoint.cpp love-11.3/src/modules/physics/box2d/wrap_RopeJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_RopeJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_RopeJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_RopeJoint.h love-11.3/src/modules/physics/box2d/wrap_RopeJoint.h --- love-11.1/src/modules/physics/box2d/wrap_RopeJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_RopeJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Shape.cpp love-11.3/src/modules/physics/box2d/wrap_Shape.cpp --- love-11.1/src/modules/physics/box2d/wrap_Shape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Shape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_Shape.h love-11.3/src/modules/physics/box2d/wrap_Shape.h --- love-11.1/src/modules/physics/box2d/wrap_Shape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_Shape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_WeldJoint.cpp love-11.3/src/modules/physics/box2d/wrap_WeldJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_WeldJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_WeldJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_WeldJoint.h love-11.3/src/modules/physics/box2d/wrap_WeldJoint.h --- love-11.1/src/modules/physics/box2d/wrap_WeldJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_WeldJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_WheelJoint.cpp love-11.3/src/modules/physics/box2d/wrap_WheelJoint.cpp --- love-11.1/src/modules/physics/box2d/wrap_WheelJoint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_WheelJoint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_WheelJoint.h love-11.3/src/modules/physics/box2d/wrap_WheelJoint.h --- love-11.1/src/modules/physics/box2d/wrap_WheelJoint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_WheelJoint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_World.cpp love-11.3/src/modules/physics/box2d/wrap_World.cpp --- love-11.1/src/modules/physics/box2d/wrap_World.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_World.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/box2d/wrap_World.h love-11.3/src/modules/physics/box2d/wrap_World.h --- love-11.1/src/modules/physics/box2d/wrap_World.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/box2d/wrap_World.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/Joint.cpp love-11.3/src/modules/physics/Joint.cpp --- love-11.1/src/modules/physics/Joint.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/Joint.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/Joint.h love-11.3/src/modules/physics/Joint.h --- love-11.1/src/modules/physics/Joint.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/Joint.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/Shape.cpp love-11.3/src/modules/physics/Shape.cpp --- love-11.1/src/modules/physics/Shape.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/Shape.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/physics/Shape.h love-11.3/src/modules/physics/Shape.h --- love-11.1/src/modules/physics/Shape.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/physics/Shape.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/Decoder.cpp love-11.3/src/modules/sound/Decoder.cpp --- love-11.1/src/modules/sound/Decoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/Decoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -29,9 +29,8 @@ love::Type Decoder::type("Decoder", &Object::type); -Decoder::Decoder(Data *data, const std::string &ext, int bufferSize) +Decoder::Decoder(Data *data, int bufferSize) : data(data) - , ext(ext) , bufferSize(bufferSize) , sampleRate(DEFAULT_SAMPLE_RATE) , buffer(0) diff -Nru love-11.1/src/modules/sound/Decoder.h love-11.3/src/modules/sound/Decoder.h --- love-11.1/src/modules/sound/Decoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/Decoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -41,7 +41,7 @@ static love::Type type; - Decoder(Data *data, const std::string &ext, int bufferSize); + Decoder(Data *data, int bufferSize); virtual ~Decoder(); /** @@ -98,7 +98,7 @@ * @param s The position in the stream in seconds. * @return True if success, false on fail/unsupported. **/ - virtual bool seek(float s) = 0; + virtual bool seek(double s) = 0; /** * Rewinds the stream to the start. @@ -149,9 +149,6 @@ // reads in the future. StrongRef data; - // File extension. - std::string ext; - // When the decoder decodes data incrementally, it writes // this many bytes at a time (at most). int bufferSize; diff -Nru love-11.1/src/modules/sound/lullaby/CoreAudioDecoder.cpp love-11.3/src/modules/sound/lullaby/CoreAudioDecoder.cpp --- love-11.1/src/modules/sound/lullaby/CoreAudioDecoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/CoreAudioDecoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -63,8 +63,8 @@ } } // anonymous namespace -CoreAudioDecoder::CoreAudioDecoder(Data *data, const std::string &ext, int bufferSize) - : Decoder(data, ext, bufferSize) +CoreAudioDecoder::CoreAudioDecoder(Data *data, int bufferSize) + : Decoder(data, bufferSize) , audioFile(nullptr) , extAudioFile(nullptr) , inputInfo() @@ -195,7 +195,7 @@ love::sound::Decoder *CoreAudioDecoder::clone() { - return new CoreAudioDecoder(data.get(), ext, bufferSize); + return new CoreAudioDecoder(data.get(), bufferSize); } int CoreAudioDecoder::decode() @@ -227,7 +227,7 @@ return size; } -bool CoreAudioDecoder::seek(float s) +bool CoreAudioDecoder::seek(double s) { OSStatus err = ExtAudioFileSeek(extAudioFile, (SInt64) (s * inputInfo.mSampleRate)); diff -Nru love-11.1/src/modules/sound/lullaby/CoreAudioDecoder.h love-11.3/src/modules/sound/lullaby/CoreAudioDecoder.h --- love-11.1/src/modules/sound/lullaby/CoreAudioDecoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/CoreAudioDecoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -47,14 +47,14 @@ { public: - CoreAudioDecoder(Data *data, const std::string &ext, int bufferSize); + CoreAudioDecoder(Data *data, int bufferSize); virtual ~CoreAudioDecoder(); static bool accepts(const std::string &ext); love::sound::Decoder *clone(); int decode(); - bool seek(float s); + bool seek(double s); bool rewind(); bool isSeekable(); int getChannelCount() const; diff -Nru love-11.1/src/modules/sound/lullaby/FLACDecoder.cpp love-11.3/src/modules/sound/lullaby/FLACDecoder.cpp --- love-11.1/src/modules/sound/lullaby/FLACDecoder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/FLACDecoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2006-2019 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#define DR_FLAC_IMPLEMENTATION +#include "FLACDecoder.h" + +#include +#include "common/Exception.h" + +namespace love +{ +namespace sound +{ +namespace lullaby +{ + +FLACDecoder::FLACDecoder(Data *data, int nbufferSize) +: Decoder(data, nbufferSize) +{ + flac = drflac_open_memory(data->getData(), data->getSize()); + if (flac == nullptr) + throw love::Exception("Could not load FLAC file"); +} + +FLACDecoder::~FLACDecoder() +{ + drflac_close(flac); +} + +bool FLACDecoder::accepts(const std::string &ext) +{ + // dr_flac supports FLAC encapsulated in Ogg, but unfortunately + // LOVE detects .ogg extension as Vorbis. It would be a good idea + // to always probe in the future (see #1487 and commit ccf9e63). + // Please remove once it's no longer the case. + static const std::string supported[] = + { + "flac", "ogg" + }; + + for (int i = 0; !(supported[i].empty()); i++) + { + if (supported[i].compare(ext) == 0) + return true; + } + + return false; +} + +love::sound::Decoder *FLACDecoder::clone() +{ + return new FLACDecoder(data.get(), bufferSize); +} + +int FLACDecoder::decode() +{ + // `bufferSize` is in bytes, so divide by 2. + drflac_uint64 read = drflac_read_pcm_frames_s16(flac, bufferSize / 2 / flac->channels, (drflac_int16 *) buffer); + read *= 2 * flac->channels; + + if ((int) read < bufferSize) + eof = true; + + return (int) read; +} + +bool FLACDecoder::seek(double s) +{ + drflac_uint64 seekPosition = (drflac_uint64) (s * flac->sampleRate); + + drflac_bool32 result = drflac_seek_to_pcm_frame(flac, seekPosition); + if (result) + eof = false; + + return result; +} + +bool FLACDecoder::rewind() +{ + return seek(0); +} + +bool FLACDecoder::isSeekable() +{ + return true; +} + +int FLACDecoder::getChannelCount() const +{ + return flac->channels; +} + +int FLACDecoder::getBitDepth() const +{ + return 16; +} + +int FLACDecoder::getSampleRate() const +{ + return flac->sampleRate; +} + +double FLACDecoder::getDuration() +{ + return ((double) flac->totalPCMFrameCount) / ((double) flac->sampleRate); +} + +} // lullaby +} // sound +} // love + diff -Nru love-11.1/src/modules/sound/lullaby/FLACDecoder.h love-11.3/src/modules/sound/lullaby/FLACDecoder.h --- love-11.1/src/modules/sound/lullaby/FLACDecoder.h 1970-01-01 00:00:00.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/FLACDecoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2006-2019 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#ifndef LOVE_SOUND_LULLABY_FLAC_DECODER_H +#define LOVE_SOUND_LULLABY_FLAC_DECODER_H + +// LOVE +#include "common/Data.h" +#include "sound/Decoder.h" + +#include "dr_flac/dr_flac.h" +#include + +namespace love +{ +namespace sound +{ +namespace lullaby +{ + +class FLACDecoder : public Decoder +{ +public: + FLACDecoder(Data *data, int bufferSize); + ~FLACDecoder(); + + static bool accepts(const std::string &ext); + love::sound::Decoder *clone(); + int decode(); + bool seek(double s); + bool rewind(); + bool isSeekable(); + int getChannelCount() const; + int getBitDepth() const; + int getSampleRate() const; + double getDuration(); + +private: + drflac *flac; +}; // Decoder + +} // lullaby +} // sound +} // love + +#endif // LOVE_SOUND_LULLABY_FLAC_DECODER_H diff -Nru love-11.1/src/modules/sound/lullaby/GmeDecoder.cpp love-11.3/src/modules/sound/lullaby/GmeDecoder.cpp --- love-11.1/src/modules/sound/lullaby/GmeDecoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/GmeDecoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -32,8 +32,8 @@ namespace lullaby { -GmeDecoder::GmeDecoder(Data *data, const std::string &ext, int bufferSize) - : Decoder(data, ext, bufferSize) +GmeDecoder::GmeDecoder(Data *data, int bufferSize) + : Decoder(data, bufferSize) , emu(0) , num_tracks(0) , cur_track(0) @@ -86,7 +86,7 @@ love::sound::Decoder *GmeDecoder::clone() { - return new GmeDecoder(data.get(), ext, bufferSize); + return new GmeDecoder(data.get(), bufferSize); } int GmeDecoder::decode() @@ -109,9 +109,9 @@ return bufferSize; } -bool GmeDecoder::seek(float s) +bool GmeDecoder::seek(double s) { - return gme_seek(emu, static_cast(s * 1000.f)) != 0; + return gme_seek(emu, static_cast(s * 1000.0)) != 0; } bool GmeDecoder::rewind() diff -Nru love-11.1/src/modules/sound/lullaby/GmeDecoder.h love-11.3/src/modules/sound/lullaby/GmeDecoder.h --- love-11.1/src/modules/sound/lullaby/GmeDecoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/GmeDecoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -44,14 +44,14 @@ { public: - GmeDecoder(Data *data, const std::string &ext, int bufferSize); + GmeDecoder(Data *data, int bufferSize); virtual ~GmeDecoder(); static bool accepts(const std::string &ext); love::sound::Decoder *clone(); int decode(); - bool seek(float s); + bool seek(double s); bool rewind(); bool isSeekable(); int getChannelCount() const; diff -Nru love-11.1/src/modules/sound/lullaby/ModPlugDecoder.cpp love-11.3/src/modules/sound/lullaby/ModPlugDecoder.cpp --- love-11.1/src/modules/sound/lullaby/ModPlugDecoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/ModPlugDecoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -31,8 +31,8 @@ namespace lullaby { -ModPlugDecoder::ModPlugDecoder(Data *data, const std::string &ext, int bufferSize) - : Decoder(data, ext, bufferSize) +ModPlugDecoder::ModPlugDecoder(Data *data, int bufferSize) + : Decoder(data, bufferSize) , plug(0) , duration(-2.0) { @@ -98,7 +98,7 @@ love::sound::Decoder *ModPlugDecoder::clone() { - return new ModPlugDecoder(data.get(), ext, bufferSize); + return new ModPlugDecoder(data.get(), bufferSize); } int ModPlugDecoder::decode() @@ -111,9 +111,9 @@ return r; } -bool ModPlugDecoder::seek(float s) +bool ModPlugDecoder::seek(double s) { - ModPlug_Seek(plug, (int)(s*1000.0f)); + ModPlug_Seek(plug, (int)(s*1000.0)); return true; } diff -Nru love-11.1/src/modules/sound/lullaby/ModPlugDecoder.h love-11.3/src/modules/sound/lullaby/ModPlugDecoder.h --- love-11.1/src/modules/sound/lullaby/ModPlugDecoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/ModPlugDecoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -47,14 +47,14 @@ { public: - ModPlugDecoder(Data *data, const std::string &ext, int bufferSize); + ModPlugDecoder(Data *data, int bufferSize); virtual ~ModPlugDecoder(); static bool accepts(const std::string &ext); love::sound::Decoder *clone(); int decode(); - bool seek(float s); + bool seek(double s); bool rewind(); bool isSeekable(); int getChannelCount() const; diff -Nru love-11.1/src/modules/sound/lullaby/Mpg123Decoder.cpp love-11.3/src/modules/sound/lullaby/Mpg123Decoder.cpp --- love-11.1/src/modules/sound/lullaby/Mpg123Decoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/Mpg123Decoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -107,8 +107,8 @@ bool Mpg123Decoder::inited = false; -Mpg123Decoder::Mpg123Decoder(Data *data, const std::string &ext, int bufferSize) - : Decoder(data, ext, bufferSize) +Mpg123Decoder::Mpg123Decoder(Data *data, int bufferSize) + : Decoder(data, bufferSize) , decoder_file(data) , handle(0) , channels(MPG123_STEREO) @@ -158,6 +158,12 @@ mpg123_format(handle, rate, channels, MPG123_ENC_SIGNED_16); sampleRate = (int) rate; + + // Force a read, so we can determine if it's actually an mp3 + struct mpg123_frameinfo info; + ret = mpg123_info(handle, &info); + if (ret != MPG123_OK) + throw love::Exception("Could not read mp3 data."); } catch (love::Exception &) { @@ -196,7 +202,7 @@ love::sound::Decoder *Mpg123Decoder::clone() { - return new Mpg123Decoder(data.get(), ext, bufferSize); + return new Mpg123Decoder(data.get(), bufferSize); } int Mpg123Decoder::decode() @@ -226,7 +232,7 @@ return size; } -bool Mpg123Decoder::seek(float s) +bool Mpg123Decoder::seek(double s) { off_t offset = (off_t) (s * (double) sampleRate); diff -Nru love-11.1/src/modules/sound/lullaby/Mpg123Decoder.h love-11.3/src/modules/sound/lullaby/Mpg123Decoder.h --- love-11.1/src/modules/sound/lullaby/Mpg123Decoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/Mpg123Decoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -58,7 +58,7 @@ { public: - Mpg123Decoder(Data *data, const std::string &ext, int bufferSize); + Mpg123Decoder(Data *data, int bufferSize); virtual ~Mpg123Decoder(); static bool accepts(const std::string &ext); @@ -66,7 +66,7 @@ love::sound::Decoder *clone(); int decode(); - bool seek(float s); + bool seek(double s); bool rewind(); bool isSeekable(); int getChannelCount() const; diff -Nru love-11.1/src/modules/sound/lullaby/Sound.cpp love-11.3/src/modules/sound/lullaby/Sound.cpp --- love-11.1/src/modules/sound/lullaby/Sound.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/Sound.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -21,6 +21,7 @@ #include "common/config.h" #include +#include #include "Sound.h" @@ -28,7 +29,7 @@ #include "VorbisDecoder.h" #include "GmeDecoder.h" #include "WaveDecoder.h" -//#include "FLACDecoder.h" +#include "FLACDecoder.h" #ifndef LOVE_NOMPG123 # include "Mpg123Decoder.h" @@ -38,6 +39,27 @@ # include "CoreAudioDecoder.h" #endif +struct DecoderImpl +{ + love::sound::Decoder *(*create)(love::filesystem::FileData *data, int bufferSize); + bool (*accepts)(const std::string& ext); +}; + +template +DecoderImpl DecoderImplFor() +{ + DecoderImpl decoderImpl; + decoderImpl.create = [](love::filesystem::FileData *data, int bufferSize) -> love::sound::Decoder* + { + return new DecoderType(data, bufferSize); + }; + decoderImpl.accepts = [](const std::string& ext) -> bool + { + return DecoderType::accepts(ext); + }; + return decoderImpl; +} + namespace love { namespace sound @@ -66,37 +88,53 @@ std::string ext = data->getExtension(); std::transform(ext.begin(), ext.end(), ext.begin(), tolower); - sound::Decoder *decoder = nullptr; - - // Find a suitable decoder here, and return it. - if (false) - /* nothing */; + std::vector possibleDecoders = { #ifndef LOVE_NO_MODPLUG - else if (ModPlugDecoder::accepts(ext)) - decoder = new ModPlugDecoder(data, ext, bufferSize); + DecoderImplFor(), #endif // LOVE_NO_MODPLUG #ifndef LOVE_NOMPG123 - else if (Mpg123Decoder::accepts(ext)) - decoder = new Mpg123Decoder(data, ext, bufferSize); + DecoderImplFor(), #endif // LOVE_NOMPG123 - else if (VorbisDecoder::accepts(ext)) - decoder = new VorbisDecoder(data, ext, bufferSize); + DecoderImplFor(), #ifdef LOVE_SUPPORT_GME - else if (GmeDecoder::accepts(ext)) - decoder = new GmeDecoder(data, ext, bufferSize); + DecoderImplFor(), #endif // LOVE_SUPPORT_GME #ifdef LOVE_SUPPORT_COREAUDIO - else if (CoreAudioDecoder::accepts(ext)) - decoder = new CoreAudioDecoder(data, ext, bufferSize); + DecoderImplFor(), #endif - else if (WaveDecoder::accepts(ext)) - decoder = new WaveDecoder(data, ext, bufferSize); - /*else if (FLACDecoder::accepts(ext)) - decoder = new FLACDecoder(data, ext, bufferSize);*/ + DecoderImplFor(), + DecoderImplFor(), + // DecoderImplFor(), + }; + + // First find a matching decoder based on extension + for (DecoderImpl &possibleDecoder : possibleDecoders) + { + if (possibleDecoder.accepts(ext)) + return possibleDecoder.create(data, bufferSize); + } + + // If that fails, start probing instead + std::stringstream decodingErrors; + decodingErrors << "Failed to determine file type:\n"; + for (DecoderImpl &possibleDecoder : possibleDecoders) + { + try + { + sound::Decoder *decoder = possibleDecoder.create(data, bufferSize); + return decoder; + } + catch (love::Exception &e) + { + decodingErrors << e.what() << '\n'; + } + } - // else if (OtherDecoder::accept(ext)) + // Probing failed too, bail with the accumulated errors + throw love::Exception(decodingErrors.str().c_str()); - return decoder; + // Unreachable, but here to prevent (possible) warnings + return nullptr; } } // lullaby diff -Nru love-11.1/src/modules/sound/lullaby/Sound.h love-11.3/src/modules/sound/lullaby/Sound.h --- love-11.1/src/modules/sound/lullaby/Sound.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/Sound.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/lullaby/VorbisDecoder.cpp love-11.3/src/modules/sound/lullaby/VorbisDecoder.cpp --- love-11.1/src/modules/sound/lullaby/VorbisDecoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/VorbisDecoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -128,8 +128,8 @@ * END CALLBACK FUNCTIONS **/ -VorbisDecoder::VorbisDecoder(Data *data, const std::string &ext, int bufferSize) - : Decoder(data, ext, bufferSize) +VorbisDecoder::VorbisDecoder(Data *data, int bufferSize) + : Decoder(data, bufferSize) , duration(-2.0) { // Initialize callbacks @@ -182,7 +182,7 @@ love::sound::Decoder *VorbisDecoder::clone() { - return new VorbisDecoder(data.get(), ext, bufferSize); + return new VorbisDecoder(data.get(), bufferSize); } int VorbisDecoder::decode() @@ -209,7 +209,7 @@ return size; } -bool VorbisDecoder::seek(float s) +bool VorbisDecoder::seek(double s) { int result = 0; diff -Nru love-11.1/src/modules/sound/lullaby/VorbisDecoder.h love-11.3/src/modules/sound/lullaby/VorbisDecoder.h --- love-11.1/src/modules/sound/lullaby/VorbisDecoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/VorbisDecoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -50,14 +50,14 @@ { public: - VorbisDecoder(Data *data, const std::string &ext, int bufferSize); + VorbisDecoder(Data *data, int bufferSize); virtual ~VorbisDecoder(); static bool accepts(const std::string &ext); love::sound::Decoder *clone(); int decode(); - bool seek(float s); + bool seek(double s); bool rewind(); bool isSeekable(); int getChannelCount() const; diff -Nru love-11.1/src/modules/sound/lullaby/WaveDecoder.cpp love-11.3/src/modules/sound/lullaby/WaveDecoder.cpp --- love-11.1/src/modules/sound/lullaby/WaveDecoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/WaveDecoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -60,8 +60,8 @@ wuff_callback WaveDecoderCallbacks = {read_callback, seek_callback, tell_callback}; -WaveDecoder::WaveDecoder(Data *data, const std::string &ext, int bufferSize) - : Decoder(data, ext, bufferSize) +WaveDecoder::WaveDecoder(Data *data, int bufferSize) + : Decoder(data, bufferSize) { dataFile.data = (char *) data->getData(); dataFile.size = data->getSize(); @@ -117,7 +117,7 @@ love::sound::Decoder *WaveDecoder::clone() { - return new WaveDecoder(data.get(), ext, bufferSize); + return new WaveDecoder(data.get(), bufferSize); } int WaveDecoder::decode() @@ -143,7 +143,7 @@ return (int) size; } -bool WaveDecoder::seek(float s) +bool WaveDecoder::seek(double s) { int wuff_status = wuff_seek(handle, (wuff_uint64) (s * info.sample_rate)); diff -Nru love-11.1/src/modules/sound/lullaby/WaveDecoder.h love-11.3/src/modules/sound/lullaby/WaveDecoder.h --- love-11.1/src/modules/sound/lullaby/WaveDecoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/lullaby/WaveDecoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -46,14 +46,14 @@ { public: - WaveDecoder(Data *data, const std::string &ext, int bufferSize); + WaveDecoder(Data *data, int bufferSize); virtual ~WaveDecoder(); static bool accepts(const std::string &ext); love::sound::Decoder *clone(); int decode(); - bool seek(float s); + bool seek(double s); bool rewind(); bool isSeekable(); int getChannelCount() const; diff -Nru love-11.1/src/modules/sound/Sound.cpp love-11.3/src/modules/sound/Sound.cpp --- love-11.1/src/modules/sound/Sound.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/Sound.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/SoundData.cpp love-11.3/src/modules/sound/SoundData.cpp --- love-11.1/src/modules/sound/SoundData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/SoundData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/SoundData.h love-11.3/src/modules/sound/SoundData.h --- love-11.1/src/modules/sound/SoundData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/SoundData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/Sound.h love-11.3/src/modules/sound/Sound.h --- love-11.1/src/modules/sound/Sound.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/Sound.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/wrap_Decoder.cpp love-11.3/src/modules/sound/wrap_Decoder.cpp --- love-11.1/src/modules/sound/wrap_Decoder.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_Decoder.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -34,6 +34,16 @@ return luax_checktype(L, idx); } +int w_Decoder_clone(lua_State *L) +{ + Decoder *t = luax_checkdecoder(L, 1); + Decoder *c = nullptr; + luax_catchexcept(L, [&]() { c = t->clone(); }); + luax_pushtype(L, c); + c->release(); + return 1; +} + int w_Decoder_getChannelCount(lua_State *L) { Decoder *t = luax_checkdecoder(L, 1); @@ -86,7 +96,7 @@ int w_Decoder_seek(lua_State *L) { Decoder *t = luax_checkdecoder(L, 1); - float offset = luaL_checknumber(L, 2); + double offset = luaL_checknumber(L, 2); if (offset < 0) return luaL_argerror(L, 2, "can't seek to a negative position"); else if (offset == 0) @@ -104,6 +114,7 @@ static const luaL_Reg w_Decoder_functions[] = { + { "clone", w_Decoder_clone }, { "getChannelCount", w_Decoder_getChannelCount }, { "getBitDepth", w_Decoder_getBitDepth }, { "getSampleRate", w_Decoder_getSampleRate }, diff -Nru love-11.1/src/modules/sound/wrap_Decoder.h love-11.3/src/modules/sound/wrap_Decoder.h --- love-11.1/src/modules/sound/wrap_Decoder.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_Decoder.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/wrap_Sound.cpp love-11.3/src/modules/sound/wrap_Sound.cpp --- love-11.1/src/modules/sound/wrap_Sound.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_Sound.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/wrap_SoundData.cpp love-11.3/src/modules/sound/wrap_SoundData.cpp --- love-11.1/src/modules/sound/wrap_SoundData.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_SoundData.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -148,18 +148,8 @@ { int ret = luax_register_type(L, &SoundData::type, data::w_Data_functions, w_SoundData_functions, nullptr); - luax_gettypemetatable(L, SoundData::type); - - // Load and execute SoundData.lua, sending the metatable as an argument. - if (lua_istable(L, -1)) - { - luaL_loadbuffer(L, sounddata_lua, sizeof(sounddata_lua), "SoundData.lua"); - lua_pushvalue(L, -2); - lua_call(L, 1, 0); - } - - // Pop the metatable. - lua_pop(L, 1); + love::data::luax_rundatawrapper(L, SoundData::type); + luax_runwrapper(L, sounddata_lua, sizeof(sounddata_lua), "SoundData.lua", SoundData::type, nullptr); return ret; } diff -Nru love-11.1/src/modules/sound/wrap_SoundData.h love-11.3/src/modules/sound/wrap_SoundData.h --- love-11.1/src/modules/sound/wrap_SoundData.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_SoundData.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/wrap_SoundData.lua love-11.3/src/modules/sound/wrap_SoundData.lua --- love-11.1/src/modules/sound/wrap_SoundData.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_SoundData.lua 2019-10-27 13:44:49.000000000 +0000 @@ -3,7 +3,7 @@ -- There is a matching delimiter at the bottom of the file. --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/sound/wrap_Sound.h love-11.3/src/modules/sound/wrap_Sound.h --- love-11.1/src/modules/sound/wrap_Sound.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/sound/wrap_Sound.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/system/sdl/System.cpp love-11.3/src/modules/system/sdl/System.cpp --- love-11.1/src/modules/system/sdl/System.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/system/sdl/System.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/system/sdl/System.h love-11.3/src/modules/system/sdl/System.h --- love-11.1/src/modules/system/sdl/System.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/system/sdl/System.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/system/System.cpp love-11.3/src/modules/system/System.cpp --- love-11.1/src/modules/system/System.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/system/System.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/system/System.h love-11.3/src/modules/system/System.h --- love-11.1/src/modules/system/System.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/system/System.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/system/wrap_System.cpp love-11.3/src/modules/system/wrap_System.cpp --- love-11.1/src/modules/system/wrap_System.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/system/wrap_System.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/system/wrap_System.h love-11.3/src/modules/system/wrap_System.h --- love-11.1/src/modules/system/wrap_System.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/system/wrap_System.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/Channel.cpp love-11.3/src/modules/thread/Channel.cpp --- love-11.1/src/modules/thread/Channel.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/Channel.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -19,8 +19,6 @@ **/ #include "Channel.h" -#include -#include #include @@ -30,60 +28,21 @@ { love::Type Channel::type("Channel", &Object::type); -static std::map namedChannels; -static Mutex *namedChannelMutex; - -Channel *Channel::getChannel(const std::string &name) -{ - if (!namedChannelMutex) - namedChannelMutex = newMutex(); - - Lock lock(namedChannelMutex); - - auto it = namedChannels.find(name); - if (it != namedChannels.end()) - { - it->second->retain(); - return it->second; - } - - namedChannels[name] = new Channel(name); - return namedChannels[name]; -} Channel::Channel() - : named(false) - , sent(0) - , received(0) -{ -} - -Channel::Channel(const std::string &name) - : named(true) - , name(name) - , sent(0) + : sent(0) , received(0) { } Channel::~Channel() { - if (named) - { - Lock l(namedChannelMutex); - namedChannels.erase(name); - } } uint64 Channel::push(const Variant &var) { Lock l(mutex); - // Keep a reference to ourselves - // if we're non-empty and named. - if (named && queue.empty()) - retain(); - queue.push(var); cond->broadcast(); @@ -134,11 +93,6 @@ received++; cond->broadcast(); - // Release our reference to ourselves - // if we're empty and named. - if (named && queue.empty()) - release(); - return true; } @@ -208,11 +162,6 @@ // Finish all the supply waits received = sent; cond->broadcast(); - - // Once again, release our own - // reference if we're named. - if (named) - release(); } void Channel::lockMutex() diff -Nru love-11.1/src/modules/thread/Channel.h love-11.3/src/modules/thread/Channel.h --- love-11.1/src/modules/thread/Channel.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/Channel.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,6 @@ // STL #include -#include // LOVE #include "common/Variant.h" @@ -47,8 +46,6 @@ Channel(); ~Channel(); - static Channel *getChannel(const std::string &name); - uint64 push(const Variant &var); bool supply(const Variant &var); // blocking push bool supply(const Variant &var, double timeout); @@ -62,15 +59,12 @@ private: - Channel(const std::string &name); void lockMutex(); void unlockMutex(); MutexRef mutex; ConditionalRef cond; std::queue queue; - bool named; - std::string name; uint64 sent; uint64 received; diff -Nru love-11.1/src/modules/thread/LuaThread.cpp love-11.3/src/modules/thread/LuaThread.cpp --- love-11.1/src/modules/thread/LuaThread.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/LuaThread.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/LuaThread.h love-11.3/src/modules/thread/LuaThread.h --- love-11.1/src/modules/thread/LuaThread.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/LuaThread.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/sdl/Thread.cpp love-11.3/src/modules/thread/sdl/Thread.cpp --- love-11.1/src/modules/thread/sdl/Thread.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/sdl/Thread.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/sdl/Thread.h love-11.3/src/modules/thread/sdl/Thread.h --- love-11.1/src/modules/thread/sdl/Thread.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/sdl/Thread.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/sdl/threads.cpp love-11.3/src/modules/thread/sdl/threads.cpp --- love-11.1/src/modules/thread/sdl/threads.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/sdl/threads.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/sdl/threads.h love-11.3/src/modules/thread/sdl/threads.h --- love-11.1/src/modules/thread/sdl/threads.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/sdl/threads.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/Thread.h love-11.3/src/modules/thread/Thread.h --- love-11.1/src/modules/thread/Thread.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/Thread.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/ThreadModule.cpp love-11.3/src/modules/thread/ThreadModule.cpp --- love-11.1/src/modules/thread/ThreadModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/ThreadModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -37,7 +37,15 @@ Channel *ThreadModule::getChannel(const std::string &name) { - return Channel::getChannel(name); + Lock lock(namedChannelMutex); + + auto it = namedChannels.find(name); + if (it != namedChannels.end()) + return it->second; + + Channel *c = new Channel(); + namedChannels[name].set(c, Acquire::NORETAIN); + return c; } const char *ThreadModule::getName() const diff -Nru love-11.1/src/modules/thread/ThreadModule.h love-11.3/src/modules/thread/ThreadModule.h --- love-11.1/src/modules/thread/ThreadModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/ThreadModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -23,6 +23,7 @@ // STL #include +#include // LOVE #include "common/Data.h" @@ -51,6 +52,11 @@ virtual const char *getName() const; virtual ModuleType getModuleType() const { return M_THREAD; } +private: + + std::map> namedChannels; + MutexRef namedChannelMutex; + }; // ThreadModule } // thread diff -Nru love-11.1/src/modules/thread/threads.cpp love-11.3/src/modules/thread/threads.cpp --- love-11.1/src/modules/thread/threads.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/threads.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/threads.h love-11.3/src/modules/thread/threads.h --- love-11.1/src/modules/thread/threads.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/threads.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/wrap_Channel.h love-11.3/src/modules/thread/wrap_Channel.h --- love-11.1/src/modules/thread/wrap_Channel.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/wrap_Channel.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/wrap_LuaThread.h love-11.3/src/modules/thread/wrap_LuaThread.h --- love-11.1/src/modules/thread/wrap_LuaThread.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/wrap_LuaThread.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/thread/wrap_ThreadModule.cpp love-11.3/src/modules/thread/wrap_ThreadModule.cpp --- love-11.1/src/modules/thread/wrap_ThreadModule.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/wrap_ThreadModule.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -94,7 +94,6 @@ std::string name = luax_checkstring(L, 1); Channel *c = instance()->getChannel(name); luax_pushtype(L, c); - c->release(); return 1; } diff -Nru love-11.1/src/modules/thread/wrap_ThreadModule.h love-11.3/src/modules/thread/wrap_ThreadModule.h --- love-11.1/src/modules/thread/wrap_ThreadModule.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/thread/wrap_ThreadModule.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/timer/Timer.cpp love-11.3/src/modules/timer/Timer.cpp --- love-11.1/src/modules/timer/Timer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/timer/Timer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -90,7 +90,7 @@ void Timer::sleep(double seconds) const { - if (seconds > 0) + if (seconds >= 0) love::sleep((unsigned int)(seconds*1000)); } diff -Nru love-11.1/src/modules/timer/Timer.h love-11.3/src/modules/timer/Timer.h --- love-11.1/src/modules/timer/Timer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/timer/Timer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/timer/wrap_Timer.cpp love-11.3/src/modules/timer/wrap_Timer.cpp --- love-11.1/src/modules/timer/wrap_Timer.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/timer/wrap_Timer.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/timer/wrap_Timer.h love-11.3/src/modules/timer/wrap_Timer.h --- love-11.1/src/modules/timer/wrap_Timer.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/timer/wrap_Timer.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/touch/sdl/Touch.cpp love-11.3/src/modules/touch/sdl/Touch.cpp --- love-11.1/src/modules/touch/sdl/Touch.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/touch/sdl/Touch.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/touch/sdl/Touch.h love-11.3/src/modules/touch/sdl/Touch.h --- love-11.1/src/modules/touch/sdl/Touch.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/touch/sdl/Touch.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/touch/Touch.h love-11.3/src/modules/touch/Touch.h --- love-11.1/src/modules/touch/Touch.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/touch/Touch.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/touch/wrap_Touch.cpp love-11.3/src/modules/touch/wrap_Touch.cpp --- love-11.1/src/modules/touch/wrap_Touch.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/touch/wrap_Touch.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/touch/wrap_Touch.h love-11.3/src/modules/touch/wrap_Touch.h --- love-11.1/src/modules/touch/wrap_Touch.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/touch/wrap_Touch.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/theora/TheoraVideoStream.cpp love-11.3/src/modules/video/theora/TheoraVideoStream.cpp --- love-11.1/src/modules/video/theora/TheoraVideoStream.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/theora/TheoraVideoStream.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -213,19 +213,24 @@ if (position < lastFrame) seekDecoder(position); + th_ycbcr_buffer bufferinfo; + bool hasFrame = false; + // Until we are at the end of the stream, or we are displaying the right frame - unsigned int lagCounter = 0; + unsigned int framesBehind = 0; + bool failedSeek = false; while (!demuxer.isEos() && position >= nextFrame) { // If we can't catch up, seek - if (lagCounter++ > 5) + if (framesBehind++ > 5 && !failedSeek) { seekDecoder(position); - lagCounter = 0; + framesBehind = 0; + failedSeek = true; } - th_ycbcr_buffer bufferinfo; th_decode_ycbcr_out(decoder, bufferinfo); + hasFrame = true; ogg_int64_t granulePosition; do @@ -235,7 +240,11 @@ } while (th_decode_packetin(decoder, &packet, &granulePosition) != 0); lastFrame = nextFrame; nextFrame = th_granule_time(decoder, granulePosition); + } + // Only swap once, even if we read many frames to get here + if (hasFrame) + { // Don't swap whilst we're writing to the backbuffer { love::thread::Lock l(bufferMutex); @@ -284,6 +293,9 @@ if (demuxer.isEos()) return false; + if (!frameSync->isPlaying()) + return false; + love::thread::Lock l(bufferMutex); if (!frameReady) return false; diff -Nru love-11.1/src/modules/video/theora/TheoraVideoStream.h love-11.3/src/modules/video/theora/TheoraVideoStream.h --- love-11.1/src/modules/video/theora/TheoraVideoStream.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/theora/TheoraVideoStream.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/theora/Video.cpp love-11.3/src/modules/video/theora/Video.cpp --- love-11.1/src/modules/video/theora/Video.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/theora/Video.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/theora/Video.h love-11.3/src/modules/video/theora/Video.h --- love-11.1/src/modules/video/theora/Video.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/theora/Video.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/Video.h love-11.3/src/modules/video/Video.h --- love-11.1/src/modules/video/Video.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/Video.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/VideoStream.cpp love-11.3/src/modules/video/VideoStream.cpp --- love-11.1/src/modules/video/VideoStream.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/VideoStream.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/VideoStream.h love-11.3/src/modules/video/VideoStream.h --- love-11.1/src/modules/video/VideoStream.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/VideoStream.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/wrap_Video.cpp love-11.3/src/modules/video/wrap_Video.cpp --- love-11.1/src/modules/video/wrap_Video.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/wrap_Video.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -47,6 +47,7 @@ luax_pushtype(L, stream); stream->release(); + file->release(); return 1; } diff -Nru love-11.1/src/modules/video/wrap_Video.h love-11.3/src/modules/video/wrap_Video.h --- love-11.1/src/modules/video/wrap_Video.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/wrap_Video.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/wrap_VideoStream.cpp love-11.3/src/modules/video/wrap_VideoStream.cpp --- love-11.1/src/modules/video/wrap_VideoStream.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/wrap_VideoStream.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/video/wrap_VideoStream.h love-11.3/src/modules/video/wrap_VideoStream.h --- love-11.1/src/modules/video/wrap_VideoStream.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/video/wrap_VideoStream.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/modules/window/sdl/Window.cpp love-11.3/src/modules/window/sdl/Window.cpp --- love-11.1/src/modules/window/sdl/Window.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/window/sdl/Window.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,10 @@ #include "common/android.h" #endif +#ifdef LOVE_IOS +#include "common/ios.h" +#endif + // C++ #include #include @@ -512,12 +516,7 @@ SDL_RaiseWindow(window); - SDL_GL_SetSwapInterval(f.vsync); - - // Check if adaptive vsync was requested but not supported, and fall back - // to regular vsync if so. - if (f.vsync == -1 && SDL_GL_GetSwapInterval() != -1) - SDL_GL_SetSwapInterval(1); + setVSync(f.vsync); updateSettings(f, false); @@ -594,6 +593,7 @@ getPosition(settings.x, settings.y, settings.display); settings.highdpi = (wflags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; + settings.usedpiscale = newsettings.usedpiscale; // Only minimize on focus loss if the window is in exclusive-fullscreen mode if (settings.fullscreen && settings.fstype == FULLSCREEN_EXCLUSIVE) @@ -608,7 +608,7 @@ SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples); settings.msaa = (buffers > 0 ? samples : 0); - settings.vsync = SDL_GL_GetSwapInterval(); + settings.vsync = getVSync(); settings.stencil = newsettings.stencil; settings.depth = newsettings.depth; @@ -743,6 +743,26 @@ return name; } +Window::DisplayOrientation Window::getDisplayOrientation(int displayindex) const +{ + // TODO: We can expose this everywhere, we just need to watch out for the + // SDL binary being older than the headers on Linux. +#if SDL_VERSION_ATLEAST(2, 0, 9) && (defined(LOVE_ANDROID) || !defined(LOVE_LINUX)) + switch (SDL_GetDisplayOrientation(displayindex)) + { + case SDL_ORIENTATION_UNKNOWN: return ORIENTATION_UNKNOWN; + case SDL_ORIENTATION_LANDSCAPE: return ORIENTATION_LANDSCAPE; + case SDL_ORIENTATION_LANDSCAPE_FLIPPED: return ORIENTATION_LANDSCAPE_FLIPPED; + case SDL_ORIENTATION_PORTRAIT: return ORIENTATION_PORTRAIT; + case SDL_ORIENTATION_PORTRAIT_FLIPPED: return ORIENTATION_PORTRAIT_FLIPPED; + } +#else + LOVE_UNUSED(displayindex); +#endif + + return ORIENTATION_UNKNOWN; +} + std::vector Window::getFullscreenSizes(int displayindex) const { std::vector sizes; @@ -824,6 +844,33 @@ } } +Rect Window::getSafeArea() const +{ +#if defined(LOVE_IOS) + if (window != nullptr) + return love::ios::getSafeArea(window); +#elif defined(LOVE_ANDROID) + if (window != nullptr) + { + int top, left, bottom, right; + + if (love::android::getSafeArea(top, left, bottom, right)) + { + // DisplayCutout API returns safe area in pixels + // and is affected by display orientation. + double safeLeft, safeTop, safeWidth, safeHeight; + fromPixels(left, top, safeLeft, safeTop); + fromPixels(pixelWidth - left - right, pixelHeight - top - bottom, safeWidth, safeHeight); + return {(int) safeLeft, (int) safeTop, (int) safeWidth, (int) safeHeight}; + } + } +#endif + + double dw, dh; + fromPixels(pixelWidth, pixelHeight, dw, dh); + return {0, 0, (int) dw, (int) dh}; +} + bool Window::isOpen() const { return open; @@ -895,6 +942,24 @@ return icon.get(); } +void Window::setVSync(int vsync) +{ + if (context == nullptr) + return; + + SDL_GL_SetSwapInterval(vsync); + + // Check if adaptive vsync was requested but not supported, and fall back + // to regular vsync if so. + if (vsync == -1 && SDL_GL_GetSwapInterval() != -1) + SDL_GL_SetSwapInterval(1); +} + +int Window::getVSync() const +{ + return context != nullptr ? SDL_GL_GetSwapInterval() : 0; +} + void Window::setDisplaySleepEnabled(bool enable) { if (enable) @@ -1051,6 +1116,11 @@ double Window::getDPIScale() const { + return settings.usedpiscale ? getNativeDPIScale() : 1.0; +} + +double Window::getNativeDPIScale() const +{ #ifdef LOVE_ANDROID return love::android::getScreenScale(); #else diff -Nru love-11.1/src/modules/window/sdl/Window.h love-11.3/src/modules/window/sdl/Window.h --- love-11.1/src/modules/window/sdl/Window.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/window/sdl/Window.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -57,6 +57,8 @@ const char *getDisplayName(int displayindex) const override; + DisplayOrientation getDisplayOrientation(int displayindex) const override; + std::vector getFullscreenSizes(int displayindex) const override; void getDesktopDimensions(int displayindex, int &width, int &height) const override; @@ -64,6 +66,8 @@ void setPosition(int x, int y, int displayindex) override; void getPosition(int &x, int &y, int &displayindex) override; + Rect getSafeArea() const override; + bool isOpen() const override; void setWindowTitle(const std::string &title) override; @@ -72,6 +76,9 @@ bool setIcon(love::image::ImageData *imgd) override; love::image::ImageData *getIcon() override; + void setVSync(int vsync) override; + int getVSync() const override; + void setDisplaySleepEnabled(bool enable) override; bool isDisplaySleepEnabled() const override; @@ -104,6 +111,7 @@ void DPIToWindowCoords(double *x, double *y) const override; double getDPIScale() const override; + double getNativeDPIScale() const override; double toPixels(double x) const override; void toPixels(double wx, double wy, double &px, double &py) const override; diff -Nru love-11.1/src/modules/window/Window.cpp love-11.3/src/modules/window/Window.cpp --- love-11.1/src/modules/window/Window.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/window/Window.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -74,6 +74,21 @@ return messageBoxTypes.getNames(); } +bool Window::getConstant(const char *in, DisplayOrientation &out) +{ + return orientations.find(in, out); +} + +bool Window::getConstant(DisplayOrientation in, const char *&out) +{ + return orientations.find(in, out); +} + +std::vector Window::getConstants(DisplayOrientation) +{ + return orientations.getNames(); +} + StringMap::Entry Window::settingEntries[] = { {"fullscreen", SETTING_FULLSCREEN}, @@ -89,6 +104,7 @@ {"centered", SETTING_CENTERED}, {"display", SETTING_DISPLAY}, {"highdpi", SETTING_HIGHDPI}, + {"usedpiscale", SETTING_USE_DPISCALE}, {"refreshrate", SETTING_REFRESHRATE}, {"x", SETTING_X}, {"y", SETTING_Y}, @@ -113,5 +129,16 @@ StringMap Window::messageBoxTypes(Window::messageBoxTypeEntries, sizeof(Window::messageBoxTypeEntries)); +StringMap::Entry Window::orientationEntries[] = +{ + {"unknown", ORIENTATION_UNKNOWN}, + {"landscape", ORIENTATION_LANDSCAPE}, + {"landscapeflipped", ORIENTATION_LANDSCAPE_FLIPPED}, + {"portrait", ORIENTATION_PORTRAIT}, + {"portraitflipped", ORIENTATION_PORTRAIT_FLIPPED}, +}; + +StringMap Window::orientations(Window::orientationEntries, sizeof(Window::orientationEntries)); + } // window } // love diff -Nru love-11.1/src/modules/window/Window.h love-11.3/src/modules/window/Window.h --- love-11.1/src/modules/window/Window.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/window/Window.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,8 @@ // LOVE #include "common/Module.h" #include "common/StringMap.h" +#include "common/math.h" +#include "common/Optional.h" #include "image/ImageData.h" // C++ @@ -65,6 +67,7 @@ SETTING_CENTERED, SETTING_DISPLAY, SETTING_HIGHDPI, + SETTING_USE_DPISCALE, SETTING_REFRESHRATE, SETTING_X, SETTING_Y, @@ -86,6 +89,16 @@ MESSAGEBOX_MAX_ENUM }; + enum DisplayOrientation + { + ORIENTATION_UNKNOWN, + ORIENTATION_LANDSCAPE, + ORIENTATION_LANDSCAPE_FLIPPED, + ORIENTATION_PORTRAIT, + ORIENTATION_PORTRAIT_FLIPPED, + ORIENTATION_MAX_ENUM + }; + struct WindowSize { int width; @@ -132,6 +145,8 @@ virtual const char *getDisplayName(int displayindex) const = 0; + virtual DisplayOrientation getDisplayOrientation(int displayindex) const = 0; + virtual std::vector getFullscreenSizes(int displayindex) const = 0; virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0; @@ -139,6 +154,8 @@ virtual void setPosition(int x, int y, int displayindex) = 0; virtual void getPosition(int &x, int &y, int &displayindex) = 0; + virtual Rect getSafeArea() const = 0; + virtual bool isOpen() const = 0; virtual void setWindowTitle(const std::string &title) = 0; @@ -147,6 +164,9 @@ virtual bool setIcon(love::image::ImageData *imgd) = 0; virtual love::image::ImageData *getIcon() = 0; + virtual void setVSync(int vsync) = 0; + virtual int getVSync() const = 0; + virtual void setDisplaySleepEnabled(bool enable) = 0; virtual bool isDisplaySleepEnabled() const = 0; @@ -182,6 +202,7 @@ virtual void DPIToWindowCoords(double *x, double *y) const = 0; virtual double getDPIScale() const = 0; + virtual double getNativeDPIScale() const = 0; virtual double toPixels(double x) const = 0; virtual void toPixels(double wx, double wy, double &px, double &py) const = 0; @@ -206,6 +227,10 @@ static bool getConstant(MessageBoxType in, const char *&out); static std::vector getConstants(MessageBoxType); + static bool getConstant(const char *in, DisplayOrientation &out); + static bool getConstant(DisplayOrientation in, const char *&out); + static std::vector getConstants(DisplayOrientation); + private: static StringMap::Entry settingEntries[]; @@ -217,6 +242,9 @@ static StringMap::Entry messageBoxTypeEntries[]; static StringMap messageBoxTypes; + static StringMap::Entry orientationEntries[]; + static StringMap orientations; + }; // Window struct WindowSettings @@ -234,6 +262,7 @@ bool centered = true; int display = 0; bool highdpi = false; + bool usedpiscale = true; double refreshrate = 0.0; bool useposition = false; int x = 0; diff -Nru love-11.1/src/modules/window/wrap_Window.cpp love-11.3/src/modules/window/wrap_Window.cpp --- love-11.1/src/modules/window/wrap_Window.cpp 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/window/wrap_Window.cpp 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -76,6 +76,7 @@ settings.centered = luax_boolflag(L, idx, settingName(Window::SETTING_CENTERED), settings.centered); settings.display = luax_intflag(L, idx, settingName(Window::SETTING_DISPLAY), settings.display+1) - 1; settings.highdpi = luax_boolflag(L, idx, settingName(Window::SETTING_HIGHDPI), settings.highdpi); + settings.usedpiscale = luax_boolflag(L, idx, settingName(Window::SETTING_USE_DPISCALE), settings.usedpiscale); lua_getfield(L, idx, settingName(Window::SETTING_VSYNC)); if (lua_isnumber(L, -1)) @@ -203,6 +204,9 @@ luax_pushboolean(L, settings.highdpi); lua_setfield(L, -2, settingName(Window::SETTING_HIGHDPI)); + luax_pushboolean(L, settings.usedpiscale); + lua_setfield(L, -2, settingName(Window::SETTING_USE_DPISCALE)); + lua_pushnumber(L, settings.refreshrate); lua_setfield(L, -2, settingName(Window::SETTING_REFRESHRATE)); @@ -215,6 +219,25 @@ return 3; } +int w_getDisplayOrientation(lua_State *L) +{ + int displayindex = 0; + if (!lua_isnoneornil(L, 1)) + displayindex = (int) luaL_checkinteger(L, 1) - 1; + else + { + int x, y; + instance()->getPosition(x, y, displayindex); + } + + const char *orientationstr = nullptr; + if (!Window::getConstant(instance()->getDisplayOrientation(displayindex), orientationstr)) + return luaL_error(L, "Unknown display orientation type."); + + lua_pushstring(L, orientationstr); + return 1; +} + int w_getFullscreenModes(lua_State *L) { int displayindex = 0; @@ -346,6 +369,16 @@ return 3; } +int w_getSafeArea(lua_State *L) +{ + Rect area = instance()->getSafeArea(); + lua_pushnumber(L, area.x); + lua_pushnumber(L, area.y); + lua_pushnumber(L, area.w); + lua_pushnumber(L, area.h); + return 4; +} + int w_setIcon(lua_State *L) { image::ImageData *i = luax_checktype(L, 1); @@ -362,6 +395,23 @@ return 1; } +int w_setVSync(lua_State *L) +{ + int vsync = 0; + if (lua_type(L, 1) == LUA_TBOOLEAN) + vsync = lua_toboolean(L, 1); + else + vsync = (int)luaL_checkinteger(L, 1); + instance()->setVSync(vsync); + return 0; +} + +int w_getVSync(lua_State *L) +{ + lua_pushinteger(L, instance()->getVSync()); + return 1; +} + int w_setDisplaySleepEnabled(lua_State *L) { instance()->setDisplaySleepEnabled(luax_checkboolean(L, 1)); @@ -411,6 +461,12 @@ return 1; } +int w_getNativeDPIScale(lua_State *L) +{ + lua_pushnumber(L, instance()->getNativeDPIScale()); + return 1; +} + int w_toPixels(lua_State *L) { double wx = luaL_checknumber(L, 1); @@ -562,6 +618,7 @@ { "setMode", w_setMode }, { "updateMode", w_updateMode }, { "getMode", w_getMode }, + { "getDisplayOrientation", w_getDisplayOrientation }, { "getFullscreenModes", w_getFullscreenModes }, { "setFullscreen", w_setFullscreen }, { "getFullscreen", w_getFullscreen }, @@ -570,8 +627,11 @@ { "getDesktopDimensions", w_getDesktopDimensions }, { "setPosition", w_setPosition }, { "getPosition", w_getPosition }, + { "getSafeArea", w_getSafeArea }, { "setIcon", w_setIcon }, { "getIcon", w_getIcon }, + { "setVSync", w_setVSync }, + { "getVSync", w_getVSync }, { "setDisplaySleepEnabled", w_setDisplaySleepEnabled }, { "isDisplaySleepEnabled", w_isDisplaySleepEnabled }, { "setTitle", w_setTitle }, @@ -580,6 +640,7 @@ { "hasMouseFocus", w_hasMouseFocus }, { "isVisible", w_isVisible }, { "getDPIScale", w_getDPIScale }, + { "getNativeDPIScale", w_getNativeDPIScale }, { "toPixels", w_toPixels }, { "fromPixels", w_fromPixels }, { "minimize", w_minimize }, diff -Nru love-11.1/src/modules/window/wrap_Window.h love-11.3/src/modules/window/wrap_Window.h --- love-11.1/src/modules/window/wrap_Window.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/modules/window/wrap_Window.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/scripts/auto.lua love-11.3/src/scripts/auto.lua --- love-11.1/src/scripts/auto.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/scripts/auto.lua 2019-10-27 13:44:49.000000000 +0000 @@ -7,7 +7,7 @@ local max_width = 18 local pattern = [[ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -43,7 +43,7 @@ -- - input file name -function auto(name) +local function auto(name) --the input file name local src = name .. ".lua" --and the output one @@ -84,13 +84,15 @@ counter = -1 --append the output to what we had, plus a newline character (0x0a is newline) out_data = ("%s%s0x0a,"):format(out_data, line:gsub("\r", ""):gsub(".", tohex)) + else + out_data = out_data .. "\n\t0x0a," end end --close our input src_file:close() --open, write and close the output - out_file = io.open(dst, "wb") + local out_file = io.open(dst, "wb") --see pattern above out_file:write(pattern:format(src, cpp_name, out_data, src)) out_file:close() diff -Nru love-11.1/src/scripts/boot.lua love-11.3/src/scripts/boot.lua --- love-11.1/src/scripts/boot.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/scripts/boot.lua 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -272,6 +272,9 @@ collectgarbage() collectgarbage() end, + displayrotated = function (display, orient) + if love.displayrotated then return love.displayrotated(display, orient) end + end, }, { __index = function(self, name) error("Unknown event: " .. name) @@ -398,6 +401,7 @@ resizable = false, centered = true, highdpi = false, + usedpiscale = true, }, modules = { data = true, @@ -421,6 +425,7 @@ }, audio = { mixwithsystem = true, -- Only relevant for Android / iOS. + mic = false, -- Only relevant for Android. }, console = false, -- Only relevant for windows. identity = false, @@ -465,6 +470,16 @@ love._setGammaCorrect(c.gammacorrect) end + if love._setAudioMixWithSystem then + if c.audio and c.audio.mixwithsystem ~= nil then + love._setAudioMixWithSystem(c.audio.mixwithsystem) + end + end + + if love._requestRecordingPermission then + love._requestRecordingPermission(c.audio and c.audio.mic) + end + -- Gets desired modules. for k,v in ipairs{ "data", @@ -532,6 +547,7 @@ centered = c.window.centered, display = c.window.display, highdpi = c.window.highdpi, + usedpiscale = c.window.usedpiscale, x = c.window.x, y = c.window.y, }), "Could not set window mode") @@ -542,10 +558,6 @@ end end - if love.audio then - love.audio.setMixWithSystem(c.audio.mixwithsystem) - end - -- Our first timestep, because window creation can take some time if love.timer then love.timer.step() diff -Nru love-11.1/src/scripts/boot.lua.h love-11.3/src/scripts/boot.lua.h --- love-11.1/src/scripts/boot.lua.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/scripts/boot.lua.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,8 +27,9 @@ 0x2d, 0x2d, 0x5b, 0x5b, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, - 0x2d, 0x32, 0x30, 0x31, 0x38, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x2d, 0x32, 0x30, 0x31, 0x39, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x0a, + 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x27, 0x61, 0x73, 0x2d, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, @@ -40,6 +41,7 @@ 0x61, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x0a, + 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x66, @@ -51,6 +53,7 @@ 0x66, 0x72, 0x65, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x0a, + 0x0a, 0x31, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x69, 0x73, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, @@ -79,13 +82,16 @@ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x2d, 0x2d, 0x5d, 0x5d, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x4d, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x22, 0x29, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x74, 0x75, 0x70, 0x3a, 0x0a, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x5c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x2f, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, @@ -93,6 +99,7 @@ 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x5c, 0x22, 0x2c, 0x20, 0x22, 0x2f, 0x22, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x4d, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a, @@ -106,14 +113,17 @@ 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 0x28, 0x70, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x6d, 0x70, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x28, 0x70, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x74, 0x68, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x20, 0x22, 0x2f, 0x22, 0x2e, 0x0a, @@ -121,6 +131,7 @@ 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x74, 0x68, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x20, 0x69, 0x66, 0x20, 0x69, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x0a, @@ -130,19 +141,24 @@ 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x28, 0x70, 0x29, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 0x28, 0x70, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x28, 0x70, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x77, 0x64, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x28, 0x29, 0x0a, @@ -150,11 +166,13 @@ 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x28, 0x63, 0x77, 0x64, 0x29, 0x0a, 0x09, 0x63, 0x77, 0x64, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x28, 0x63, 0x77, 0x64, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x3d, 0x20, 0x63, 0x77, 0x64, 0x20, 0x2e, 0x2e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x28, 0x70, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x2f, 0x2e, 0x2c, 0x20, 0x69, 0x66, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x0a, @@ -162,24 +180,30 @@ 0x28, 0x22, 0x28, 0x2e, 0x2d, 0x29, 0x2f, 0x25, 0x2e, 0x24, 0x22, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x28, 0x70, 0x29, 0x0a, 0x09, 0x70, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x28, 0x70, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x70, 0x0a, + 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x61, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x61, 0x20, 0x3d, 0x20, 0x70, 0x3a, 0x66, 0x69, 0x6e, 0x64, 0x28, 0x22, 0x2f, 0x22, 0x2c, 0x20, 0x61, 0x2b, 0x31, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x61, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x3d, 0x20, 0x70, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x61, 0x2b, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x46, 0x69, 0x6e, 0x64, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, @@ -200,6 +224,7 @@ 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x5b, 0x6d, 0x5d, 0x2c, 0x20, 0x6d, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x30, @@ -207,11 +232,14 @@ 0x09, 0x66, 0x75, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x7b, 0x61, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x7d, 0x2c, 0x0a, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x31, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, + 0x0a, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6d, 0x2c, 0x20, 0x69, 0x29, 0x0a, 0x09, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6d, 0x2e, 0x61, 0x20, 0x3e, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6d, 0x2e, 0x61, 0x72, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6a, 0x3d, 0x69, 0x2c, 0x69, 0x2b, 0x6d, 0x2e, 0x61, 0x2d, 0x31, 0x20, @@ -222,12 +250,16 @@ 0x61, 0x72, 0x67, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x6a, 0x5d, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x2e, 0x61, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x67, 0x63, 0x20, 0x3d, 0x20, 0x23, 0x61, 0x72, 0x67, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x31, 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x69, 0x20, 0x3c, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x63, 0x20, 0x64, 0x6f, 0x0a, @@ -236,6 +268,7 @@ 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x5b, 0x69, 0x5d, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x5e, 0x25, 0x2d, 0x25, 0x2d, 0x28, 0x2e, 0x2a, 0x29, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6d, 0x5d, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, @@ -265,6 +298,7 @@ 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x69, 0x20, 0x3d, 0x20, 0x69, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -274,6 +308,7 @@ 0x30, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x20, @@ -285,9 +320,11 @@ 0x70, 0x61, 0x72, 0x73, 0x65, 0x47, 0x61, 0x6d, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x61, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x77, 0x28, 0x61, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x23, @@ -299,10 +336,13 @@ 0x09, 0x09, 0x09, 0x6f, 0x20, 0x3d, 0x20, 0x6f, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x20, 0x3d, 0x20, 0x73, @@ -514,6 +554,15 @@ 0x09, 0x09, 0x09, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x67, 0x61, 0x72, 0x62, 0x61, 0x67, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, + 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x29, 0x0a, + 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x72, 0x6f, 0x74, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x6f, 0x72, 0x69, 0x65, 0x6e, + 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x7d, 0x2c, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, @@ -521,7 +570,9 @@ 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x7d, 0x29, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x72, 0x69, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x73, 0x29, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x25, @@ -532,22 +583,27 @@ 0x62, 0x28, 0x32, 0x29, 0x2c, 0x20, 0x31, 0x36, 0x29, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x62, 0x6f, 0x6f, 0x74, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x6c, 0x79, 0x20, 0x6e, 0x65, 0x65, 0x64, 0x65, 0x64, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x72, 0x67, 0x30, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x77, 0x28, 0x61, 0x72, 0x67, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x61, 0x72, 0x67, 0x30, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x28, 0x29, 0x0a, @@ -559,10 +615,12 @@ 0x6c, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x30, 0x2e, 0x0a, 0x09, 0x09, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x30, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x66, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x22, 0x66, 0x75, 0x73, 0x65, 0x64, 0x22, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x3f, 0x0a, @@ -570,6 +628,7 @@ 0x65, 0x20, 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 0x20, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x74, 0x27, 0x73, 0x20, 0x61, 0x20, 0x66, 0x75, 0x73, 0x65, 0x64, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x20, 0x2d, 0x2d, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x0a, @@ -578,25 +637,31 @@ 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x50, 0x61, 0x72, 0x73, 0x65, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x20, 0x6b, 0x6e, 0x6f, 0x77, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x77, 0x65, 0x27, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x75, 0x73, 0x65, 0x64, 0x2e, 0x73, 0x65, 0x74, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x46, 0x75, 0x73, 0x65, 0x64, 0x28, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x28, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x69, 0x73, 0x46, 0x75, 0x73, 0x65, 0x64, 0x28, 0x29, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x22, 0x22, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, @@ -605,12 +670,14 @@ 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x20, 0x3d, 0x20, 0x6f, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x5b, 0x31, 0x5d, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x31, 0x2c, 0x20, 0x37, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x2f, 0x2f, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x20, 0x3d, 0x20, 0x75, 0x72, 0x69, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x38, 0x29, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x28, 0x6e, 0x6f, 0x75, 0x72, 0x69, 0x29, 0x0a, @@ -618,11 +685,13 @@ 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x55, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x2e, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, @@ -637,6 +706,7 @@ 0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x28, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x54, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6c, 0x75, 0x61, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, @@ -653,6 +723,7 @@ 0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x28, 0x72, 0x65, 0x61, 0x6c, 0x64, 0x69, 0x72, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5e, 0x28, 0x5b, 0x25, 0x2e, 0x5d, 0x2b, 0x29, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x20, 0x2d, 0x2d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x70, 0x20, 0x6c, 0x65, 0x61, @@ -668,6 +739,7 @@ 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x23, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3e, 0x20, 0x30, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x22, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x6c, 0x75, 0x61, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, @@ -679,6 +751,7 @@ 0x09, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x65, 0x29, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x28, 0x22, 0x6d, 0x61, 0x69, @@ -688,6 +761,7 @@ 0x09, 0x09, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6e, 0x6f, 0x67, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x72, @@ -696,8 +770,10 @@ 0x09, 0x09, 0x6e, 0x6f, 0x67, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x0a, @@ -734,6 +810,8 @@ 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x75, 0x73, 0x65, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a, @@ -763,6 +841,9 @@ 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20, 0x2f, 0x20, 0x69, 0x4f, 0x53, 0x2e, 0x0a, + 0x09, 0x09, 0x09, 0x6d, 0x69, 0x63, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x2d, 0x2d, + 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, @@ -782,6 +863,7 @@ 0x09, 0x09, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a, 0x09, 0x7d, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x31, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x73, 0x6f, @@ -795,6 +877,7 @@ 0x09, 0x09, 0x6f, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2c, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x69, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x20, 0x69, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x70, 0x64, @@ -810,6 +893,7 @@ 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x2c, 0x20, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x59, 0x65, 0x73, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x6c, 0x75, 0x61, 0x20, 0x6d, 0x69, 0x67, 0x68, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x72, 0x65, 0x20, 0x61, 0x72, 0x65, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, @@ -831,6 +915,7 @@ 0x73, 0x61, 0x67, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x32, 0x2e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, @@ -840,6 +925,7 @@ 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x48, 0x61, 0x63, 0x6b, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x63, 0x63, 0x65, 0x6c, 0x65, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2d, 0x61, 0x73, 0x2d, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6f, 0x6e, 0x20, 0x41, 0x6e, @@ -852,12 +938,34 @@ 0x2e, 0x61, 0x63, 0x63, 0x65, 0x6c, 0x65, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x47, 0x61, 0x6d, 0x6d, 0x61, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x47, 0x61, 0x6d, 0x6d, 0x61, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x28, 0x63, 0x2e, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f, + 0x4d, 0x69, 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, + 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x77, 0x69, 0x74, 0x68, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, + 0x69, 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x28, 0x63, 0x2e, 0x61, 0x75, 0x64, + 0x69, 0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x77, 0x69, 0x74, 0x68, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x29, 0x0a, + 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x63, + 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, + 0x2e, 0x6d, 0x69, 0x63, 0x29, 0x0a, + 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, @@ -887,11 +995,13 @@ 0x20, 0x2e, 0x2e, 0x20, 0x76, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x0a, 0x09, 0x63, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, @@ -922,7 +1032,9 @@ 0x20, 0x28, 0x25, 0x73, 0x29, 0x2e, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x63, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x68, @@ -932,10 +1044,12 @@ 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x6f, 0x6b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x63, 0x6f, 0x6e, 0x66, 0x65, 0x72, 0x72, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x74, 0x75, 0x70, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x68, 0x65, 0x72, 0x65, 0x2e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, @@ -973,6 +1087,9 @@ 0x64, 0x6f, 0x77, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x2c, 0x0a, + 0x09, 0x09, 0x09, 0x75, 0x73, 0x65, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, + 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x78, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x78, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x79, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, @@ -993,12 +1110,7 @@ 0x77, 0x2e, 0x69, 0x63, 0x6f, 0x6e, 0x29, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, - 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65, - 0x6e, 0x0a, - 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x69, - 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x28, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, - 0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x77, 0x69, 0x74, 0x68, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x29, 0x0a, - 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x4f, 0x75, 0x72, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x70, 0x2c, 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x74, 0x61, @@ -1008,6 +1120,7 @@ 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, @@ -1026,6 +1139,7 @@ 0x09, 0x09, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, @@ -1046,6 +1160,7 @@ 0x20, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, @@ -1056,12 +1171,14 @@ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x28, 0x29, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x47, 0x61, 0x6d, 0x65, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x61, 0x72, 0x67, 0x29, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x65, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x77, 0x61, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x27, 0x73, 0x20, 0x64, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, @@ -1070,7 +1187,9 @@ 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x4d, 0x61, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, @@ -1096,12 +1215,14 @@ 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x28, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c, 0x65, 0x2c, 0x66, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x64, 0x74, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x27, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x70, 0x61, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x64, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x61, 0x6c, 0x6c, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x72, 0x61, 0x77, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, @@ -1109,6 +1230,7 @@ 0x29, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x2d, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x70, 0x61, 0x73, 0x73, 0x20, 0x30, 0x20, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -1118,27 +1240,35 @@ 0x6c, 0x65, 0x61, 0x72, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x29, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x28, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2c, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2c, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x74, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x29, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x28, 0x22, 0x2e, 0x2e, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x74, 0x29, 0x2e, 0x2e, 0x22, 0x29, 0x5c, 0x6e, 0x5c, 0x6e, 0x22, 0x2e, 0x2e, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x30, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x75, 0x74, 0x66, 0x38, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x75, 0x74, 0x66, 0x38, 0x22, 0x29, 0x0a, + 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x6d, 0x73, 0x67, 0x2c, 0x20, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x29, 0x0a, @@ -1149,18 +1279,22 @@ 0x28, 0x22, 0x5c, 0x6e, 0x5b, 0x5e, 0x5c, 0x6e, 0x5d, 0x2b, 0x24, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x29, 0x29, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x0a, 0x09, 0x6d, 0x73, 0x67, 0x20, 0x3d, 0x20, 0x74, 0x6f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x0a, + 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x6d, 0x73, 0x67, 0x2c, 0x20, 0x32, 0x29, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69, @@ -1174,6 +1308,7 @@ 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x52, 0x65, 0x73, 0x65, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -1204,17 +1339,22 @@ 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x65, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4e, 0x65, 0x77, 0x46, 0x6f, 0x6e, 0x74, 0x28, 0x31, 0x34, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x6d, 0x73, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6d, 0x73, 0x67, 0x3a, 0x67, @@ -1226,11 +1366,14 @@ 0x09, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x6d, 0x73, 0x67, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x6d, 0x73, 0x67, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x22, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x6d, 0x73, 0x67, 0x29, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x23, 0x73, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x6d, 0x73, 0x67, 0x20, 0x7e, 0x3d, 0x20, 0x23, 0x6d, 0x73, 0x67, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, @@ -1238,8 +1381,10 @@ 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x22, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x72, 0x61, 0x63, 0x65, 0x3a, 0x67, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x28, 0x2e, 0x2d, 0x29, 0x5c, 0x6e, 0x22, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x3a, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, @@ -1251,13 +1396,16 @@ 0x72, 0x2c, 0x20, 0x6c, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x65, 0x72, 0x72, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x70, 0x20, 0x3d, 0x20, 0x70, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5c, 0x74, 0x22, 0x2c, 0x20, 0x22, 0x22, 0x29, 0x0a, 0x09, 0x70, 0x20, 0x3d, 0x20, 0x70, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x25, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x5c, 0x22, 0x28, 0x2e, 0x2d, 0x29, 0x5c, 0x22, 0x25, 0x5d, 0x22, 0x2c, 0x20, 0x22, 0x25, 0x31, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x37, 0x30, 0x0a, @@ -1271,6 +1419,7 @@ 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x70, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x6f, @@ -1284,6 +1433,7 @@ 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x21, 0x22, 0x0a, 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x70, 0x20, 0x3d, 0x20, 0x70, 0x20, 0x2e, 0x2e, 0x20, 0x22, 0x5c, 0x6e, 0x5c, 0x6e, 0x50, 0x72, @@ -1291,9 +1441,11 @@ 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, 0x0a, @@ -1343,14 +1495,18 @@ 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x28, 0x30, 0x2e, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, @@ -1361,10 +1517,12 @@ 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x66, 0x65, 0x72, 0x45, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x3d, 0x20, @@ -1378,6 +1536,7 @@ 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x62, 0x6f, 0x6f, 0x74, 0x20, @@ -1389,6 +1548,7 @@ 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x75, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x73, 0x2c, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x20, 0x76, 0x61, @@ -1401,6 +1561,7 @@ 0x72, 0x68, 0x61, 0x6e, 0x64, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x4e, 0x4f, 0x54, 0x45, 0x3a, 0x20, 0x57, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x2c, 0x20, 0x61, 0x73, 0x20, 0x77, 0x65, 0x27, 0x64, 0x0a, @@ -1416,7 +1577,9 @@ 0x09, 0x09, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x69, 0x74, 0x0a, + 0x0a, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x78, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x20, 0x64, 0x65, 0x66, @@ -1426,6 +1589,7 @@ 0x09, 0x09, 0x63, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x2e, 0x79, 0x69, 0x65, 0x6c, 0x64, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x0a, 0x65, 0x6e, 0x64, 0x0a, }; // [boot.lua] diff -Nru love-11.1/src/scripts/nogame.lua love-11.3/src/scripts/nogame.lua --- love-11.1/src/scripts/nogame.lua 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/scripts/nogame.lua 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ --[[ -Copyright (c) 2006-2018 LOVE Development Team +Copyright (c) 2006-2019 LOVE Development Team This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff -Nru love-11.1/src/scripts/nogame.lua.h love-11.3/src/scripts/nogame.lua.h --- love-11.1/src/scripts/nogame.lua.h 2018-04-15 18:31:45.000000000 +0000 +++ love-11.3/src/scripts/nogame.lua.h 2019-10-27 13:44:49.000000000 +0000 @@ -1,5 +1,5 @@ /** - * Copyright (c) 2006-2018 LOVE Development Team + * Copyright (c) 2006-2019 LOVE Development Team * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages @@ -27,8 +27,9 @@ 0x2d, 0x2d, 0x5b, 0x5b, 0x0a, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, - 0x2d, 0x32, 0x30, 0x31, 0x38, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x2d, 0x32, 0x30, 0x31, 0x39, 0x20, 0x4c, 0x4f, 0x56, 0x45, 0x20, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x0a, + 0x0a, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x27, 0x61, 0x73, 0x2d, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, @@ -40,6 +41,7 @@ 0x61, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x0a, + 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x66, @@ -51,6 +53,7 @@ 0x66, 0x72, 0x65, 0x65, 0x6c, 0x79, 0x2c, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x72, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x0a, + 0x0a, 0x31, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x69, 0x73, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, @@ -79,15 +82,20 @@ 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x0a, 0x2d, 0x2d, 0x5d, 0x5d, 0x0a, + 0x0a, 0x2d, 0x2d, 0x20, 0x4d, 0x61, 0x6b, 0x65, 0x20, 0x73, 0x75, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2e, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x28, 0x22, 0x6c, 0x6f, 0x76, 0x65, 0x22, 0x29, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6e, 0x6f, 0x67, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x52, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x09, 0x52, 0x2e, 0x62, 0x67, 0x20, 0x3d, 0x20, 0x7b, 0x5b, 0x31, 0x5d, 0x3d, 0x7b, 0x7d, 0x2c, 0x20, 0x5b, 0x32, 0x5d, 0x3d, 0x7b, 0x7d, 0x7d, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x31, 0x2e, 0x70, 0x6e, 0x67, 0x0a, 0x09, 0x52, 0x2e, 0x62, 0x67, 0x5b, 0x31, 0x5d, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x31, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x65, 0x63, @@ -1618,8 +1626,10 @@ 0x53, 0x51, 0x46, 0x2b, 0x78, 0x2f, 0x52, 0x6d, 0x6b, 0x72, 0x57, 0x62, 0x48, 0x42, 0x37, 0x4c, 0x51, 0x41, 0x41, 0x41, 0x41, 0x42, 0x4a, 0x52, 0x55, 0x35, 0x45, 0x72, 0x6b, 0x4a, 0x67, 0x67, 0x67, 0x3d, 0x3d, 0x5c, 0x0a, 0x09, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x52, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x5b, 0x31, 0x5d, 0x3d, 0x7b, 0x7d, 0x2c, 0x20, 0x5b, 0x32, 0x5d, 0x3d, 0x7b, 0x7d, 0x7d, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x61, 0x2e, 0x70, 0x6e, 0x67, 0x0a, 0x09, 0x52, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5b, 0x31, 0x5d, 0x2e, 0x61, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, @@ -3294,8 +3304,10 @@ 0x48, 0x62, 0x37, 0x5a, 0x63, 0x6b, 0x71, 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x53, 0x55, 0x56, 0x4f, 0x52, 0x4b, 0x35, 0x43, 0x59, 0x49, 0x49, 0x3d, 0x5c, 0x0a, 0x09, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x52, 0x2e, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x5b, 0x31, 0x5d, 0x3d, 0x7b, 0x7d, 0x2c, 0x20, 0x5b, 0x32, 0x5d, 0x3d, 0x7b, 0x7d, 0x7d, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x70, 0x6e, 0x67, 0x0a, 0x09, 0x52, 0x2e, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x5b, 0x31, 0x5d, 0x2e, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x70, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, @@ -11064,6 +11076,7 @@ 0x7a, 0x73, 0x35, 0x75, 0x6a, 0x53, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x6c, 0x46, 0x54, 0x6b, 0x53, 0x75, 0x51, 0x6d, 0x43, 0x43, 0x5c, 0x0a, 0x09, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x33, 0x30, 0x6c, 0x6f, 0x67, 0x2e, 0x6c, 0x75, 0x61, 0x20, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x73, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, @@ -11262,8 +11275,10 @@ 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x33, 0x30, 0x6c, 0x6f, 0x67, 0x2e, 0x6c, 0x75, 0x61, 0x20, 0x65, 0x6e, 0x64, 0x73, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x33, 0x30, 0x6c, 0x6f, 0x67, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x67, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x20, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x0a, @@ -11272,6 +11287,7 @@ 0x73, 0x69, 0x63, 0x73, 0x20, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x53, 0x54, 0x45, 0x50, 0x20, 0x3d, 0x20, 0x31, 0x2f, 0x32, 0x30, 0x20, 0x2d, 0x2d, 0x20, 0x32, 0x30, 0x48, 0x7a, 0x20, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x44, 0x65, 0x62, 0x75, 0x67, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x44, 0x45, 0x42, 0x55, 0x47, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, @@ -11281,6 +11297,7 @@ 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x41, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x78, 0x2c, 0x79, 0x2c, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x0a, @@ -11289,6 +11306,7 @@ 0x68, 0x6f, 0x73, 0x65, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x22, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x30, 0x20, 0x3d, 0x20, 0x30, 0x0a, @@ -11298,6 +11316,7 @@ 0x65, 0x74, 0x59, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x31, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x30, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, @@ -11307,6 +11326,7 @@ 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x31, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x30, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x6f, 0x64, 0x79, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x74, 0x2e, 0x0a, @@ -11320,6 +11340,7 @@ 0x31, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x31, 0x0a, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x31, 0x20, 0x3d, 0x20, 0x74, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x67, 0x65, 0x74, 0x58, 0x28, 0x29, 0x0a, @@ -11328,15 +11349,18 @@ 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x31, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x31, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x74, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x30, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x30, 0x29, 0x20, 0x2f, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x31, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x30, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x30, 0x20, 0x2b, 0x20, 0x70, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x31, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x78, 0x30, 0x29, 0x0a, @@ -11346,8 +11370,10 @@ 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x30, 0x20, 0x2b, 0x20, 0x70, 0x20, 0x2a, 0x20, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x31, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x72, 0x30, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x72, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x69, 0x67, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x77, 0x68, 0x65, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x79, 0x65, 0x73, 0x0a, @@ -11356,6 +11382,7 @@ 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x22, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x68, 0x69, 0x74, @@ -11363,12 +11390,14 @@ 0x65, 0x20, 0x65, 0x79, 0x65, 0x73, 0x2e, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x0a, + 0x0a, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x57, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x68, 0x69, 0x74, 0x73, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2c, 0x20, 0x77, 0x65, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x79, 0x65, 0x73, 0x2e, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x35, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, @@ -11378,6 +11407,7 @@ 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x20, 0x2d, 0x20, 0x64, 0x74, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, @@ -11387,14 +11417,17 @@ 0x20, 0x30, 0x2e, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x69, 0x73, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x20, 0x3e, 0x20, 0x30, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x20, 0x28, 0x54, 0x4d, 0x29, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x22, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x3a, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, @@ -11432,10 +11465,12 @@ 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x3a, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x73, 0x61, 0x76, 0x65, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x20, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x20, 0x25, 0x20, 0x35, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, @@ -11444,18 +11479,22 @@ 0x33, 0x30, 0x2c, 0x20, 0x35, 0x30, 0x29, 0x2c, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x28, 0x67, 0x5f, 0x74, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x6d, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x69, 0x73, @@ -11463,11 +11502,13 @@ 0x09, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x69, 0x6d, 0x67, 0x5f, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x69, 0x6d, 0x67, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x72, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x69, 0x6d, 0x67, 0x3a, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x2c, 0x20, 0x69, 0x6d, 0x67, 0x3a, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x44, 0x45, 0x42, 0x55, 0x47, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, 0x2e, 0x38, 0x2c, 0x20, 0x30, 0x2e, 0x33, 0x2c, 0x20, @@ -11477,6 +11518,7 @@ 0x66, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x67, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x68, 0x61, 0x70, 0x65, 0x3a, 0x67, 0x65, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x29, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x78, 0x2c, 0x20, 0x61, 0x79, 0x20, 0x3d, 0x20, @@ -11487,6 +11529,7 @@ 0x61, 0x79, 0x2c, 0x20, 0x33, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x0a, @@ -11497,6 +11540,7 @@ 0x3a, 0x67, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x34, 0x2c, 0x20, 0x39, 0x30, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x22, 0x23, 0x20, 0x6e, 0x6f, 0x67, @@ -11507,11 +11551,13 @@ 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x22, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x3a, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x2c, 0x20, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x29, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x44, 0x52, 0x41, 0x57, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x31, 0x31, 0x2c, 0x20, 0x69, @@ -11532,29 +11578,37 @@ 0x2c, 0x20, 0x69, 0x6d, 0x67, 0x20, 0x3d, 0x20, 0x69, 0x6d, 0x67, 0x5f, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x20, 0x7d, 0x0a, 0x09, 0x09, 0x7d, 0x0a, + 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x23, 0x73, 0x74, 0x72, 0x20, 0x64, 0x6f, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x65, 0x76, 0x20, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x69, 0x20, 0x3e, 0x3d, 0x32, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x70, 0x72, 0x65, 0x76, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x5b, 0x69, 0x20, 0x2d, 0x20, 0x31, 0x5d, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x3a, 0x62, 0x79, 0x74, 0x65, 0x28, 0x69, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x78, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x79, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x3d, 0x20, 0x44, 0x52, 0x41, 0x57, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x28, 0x62, 0x79, 0x74, 0x65, 0x29, 0x5d, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x72, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x76, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x65, 0x76, 0x2e, 0x79, 0x20, 0x2b, 0x20, 0x70, 0x72, 0x65, 0x76, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x2b, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x42, 0x6f, 0x64, 0x79, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x78, 0x2c, 0x20, 0x6c, 0x69, 0x6e, @@ -11574,6 +11628,7 @@ 0x29, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x28, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x61, 0x6c, 0x73, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x44, 0x75, @@ -11583,6 +11638,7 @@ 0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x67, 0x6f, 0x65, 0x73, 0x20, 0x68, 0x61, 0x79, 0x77, 0x69, 0x72, 0x65, 0x20, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x20, 0x73, 0x70, 0x65, 0x65, 0x64, 0x73, 0x2e, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x70, 0x72, 0x65, 0x76, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, @@ -11604,10 +11660,13 @@ 0x64, 0x79, 0x2c, 0x20, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x78, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x79, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x3a, 0x73, 0x74, 0x65, 0x70, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x69, @@ -11618,12 +11677,15 @@ 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x72, 0x6f, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, + 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, @@ -11634,6 +11696,7 @@ 0x09, 0x09, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x72, 0x6f, 0x70, 0x65, 0x2c, 0x20, 0x79, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x64, 0x74, 0x68, 0x28, 0x33, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, @@ -11641,6 +11704,7 @@ 0x37, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x72, 0x6f, 0x70, 0x65, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, @@ -11662,6 +11726,7 @@ 0x78, 0x2c, 0x20, 0x6f, 0x79, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x44, 0x45, 0x42, 0x55, 0x47, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x29, @@ -11678,6 +11743,7 @@ 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x44, 0x72, 0x61, 0x77, 0x73, 0x20, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, 0x2c, 0x20, 0x62, 0x75, @@ -11687,6 +11753,7 @@ 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x22, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x78, 0x2c, 0x79, 0x3a, 0x20, 0x54, 0x6f, 0x70, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x63, 0x6f, 0x72, 0x6e, 0x65, 0x72, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x2e, 0x0a, @@ -11712,9 +11779,11 @@ 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x31, 0x2c, 0x20, 0x34, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x61, 0x62, 0x73, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, @@ -11745,12 +11814,15 @@ 0x20, 0x34, 0x5d, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x2d, 0x30, 0x2e, 0x30, 0x35, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x28, 0x22, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x22, 0x29, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x3a, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x0a, + 0x0a, 0x09, 0x09, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x48, 0x65, 0x69, 0x67, @@ -11766,6 +11838,7 @@ 0x69, 0x6d, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x31, 0x29, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x2c, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x69, @@ -11774,6 +11847,7 @@ 0x09, 0x09, 0x09, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x2e, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x77, @@ -11796,11 +11870,13 @@ 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x29, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x20, 0x3d, 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x67, 0x5f, 0x6f, 0x62, 0x6a, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x0a, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, @@ -11809,6 +11885,7 @@ 0x33, 0x2f, 0x32, 0x35, 0x35, 0x29, 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x28, 0x36, 0x34, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x67, 0x65, 0x74, 0x44, 0x50, 0x49, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x29, 0x20, 0x3e, 0x20, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x32, @@ -11816,6 +11893,7 @@ 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x7d, 0x0a, + 0x0a, 0x09, 0x09, 0x52, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x20, 0x3d, 0x20, 0x52, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5b, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x5d, 0x2e, 0x6e, 0x5f, 0x70, 0x6e, 0x67, 0x0a, @@ -11855,6 +11933,7 @@ 0x09, 0x09, 0x52, 0x2e, 0x62, 0x67, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x34, 0x20, 0x3d, 0x20, 0x52, 0x2e, 0x62, 0x67, 0x5b, 0x64, 0x70, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x5d, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x34, 0x5f, 0x70, 0x6e, 0x67, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x52, 0x2e, 0x64, 0x75, 0x63, 0x6b, 0x6c, @@ -11865,6 +11944,7 @@ 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x52, 0x2e, 0x64, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6e, 0x2e, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x6e, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x52, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x29, 0x0a, @@ -11887,6 +11967,7 @@ 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x52, 0x2e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x31, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x52, 0x2e, 0x62, 0x67, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x31, 0x2c, 0x20, 0x73, @@ -11903,17 +11984,21 @@ 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x28, 0x52, 0x2e, 0x62, 0x67, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x34, 0x2c, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x31, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x32, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x33, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x6d, 0x67, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x34, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x0a, + 0x0a, 0x09, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x67, 0x5f, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x5f, 0x74, 0x20, 0x2b, 0x20, 0x64, 0x74, 0x0a, + 0x0a, 0x09, 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x67, 0x5f, 0x74, 0x20, 0x3e, 0x20, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x53, 0x54, @@ -11927,20 +12012,24 @@ 0x09, 0x09, 0x09, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x67, 0x5f, 0x6f, 0x62, 0x6a, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x67, 0x5f, 0x6f, 0x62, 0x6a, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x28, 0x64, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, + 0x0a, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x69, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73, 0x28, 0x67, 0x5f, 0x6f, 0x62, 0x6a, 0x73, 0x29, 0x20, 0x64, 0x6f, 0x0a, 0x09, 0x09, 0x09, 0x67, 0x5f, 0x6f, 0x62, 0x6a, 0x73, 0x5b, 0x69, 0x5d, 0x3a, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x44, 0x45, 0x42, 0x55, 0x47, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, @@ -11964,9 +12053,11 @@ 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, 0x35, 0x30, 0x2c, 0x20, 0x31, 0x31, 0x30, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x09, 0x67, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x67, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2b, 0x20, 0x31, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x69, 0x73, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2c, 0x20, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x73, 0x29, 0x0a, @@ -11986,6 +12077,7 @@ 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, 0x6b, 0x65, 0x79, 0x29, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x65, 0x73, 0x63, 0x61, 0x70, @@ -11994,10 +12086,12 @@ 0x28, 0x29, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x0a, 0x09, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x28, 0x29, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x28, 0x74, 0x29, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x4c, 0x5c, 0x31, 0x39, 0x35, @@ -12017,6 +12111,7 @@ 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x74, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x70, 0x69, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, + 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x69, 0x4f, 0x53, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x09, 0x09, 0x09, 0x74, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, @@ -12024,6 +12119,7 @@ 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a, + 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6e, 0x6f, 0x67, 0x61, 0x6d, 0x65, 0x0a, }; // [nogame.lua] } // love