From 690dee3533334d504b4b776723ac83e405c36dfb Mon Sep 17 00:00:00 2001 From: orbea Date: Mon, 2 Mar 2020 07:42:00 -0800 Subject: [PATCH] Externals: Update glslang. This updates glslang to commit 4fc7a33910fb8e40b970d160e1b38ab3f67fe0f3 which is the current version listed in the known_good.json file for the version 1.2.131.2 of the Vulkan-ValidationLayers repo. --- Externals/glslang/CMakeLists.txt.dist | 122 +- Externals/glslang/External/CMakeLists.txt | 3 +- Externals/glslang/LICENSE.txt | 108 + .../glslang/OGLCompilersDLL/CMakeLists.txt | 3 +- Externals/glslang/README.md | 89 +- Externals/glslang/SPIRV/CMakeLists.txt | 61 +- Externals/glslang/SPIRV/GLSL.ext.EXT.h | 4 +- Externals/glslang/SPIRV/GLSL.ext.KHR.h | 6 + Externals/glslang/SPIRV/GLSL.ext.NV.h | 28 +- Externals/glslang/SPIRV/GLSL.std.450.h | 0 Externals/glslang/SPIRV/GlslangToSpv.cpp | 3135 +++-- Externals/glslang/SPIRV/GlslangToSpv.h | 12 +- Externals/glslang/SPIRV/InReadableOrder.cpp | 44 +- Externals/glslang/SPIRV/Logger.cpp | 4 + Externals/glslang/SPIRV/Logger.h | 9 + Externals/glslang/SPIRV/SPVRemapper.cpp | 18 +- Externals/glslang/SPIRV/SPVRemapper.h | 4 +- Externals/glslang/SPIRV/SpvBuilder.cpp | 553 +- Externals/glslang/SPIRV/SpvBuilder.h | 188 +- Externals/glslang/SPIRV/SpvPostProcess.cpp | 450 + Externals/glslang/SPIRV/SpvTools.cpp | 216 + Externals/glslang/SPIRV/SpvTools.h | 82 + Externals/glslang/SPIRV/bitutils.h | 2 +- Externals/glslang/SPIRV/disassemble.cpp | 95 +- Externals/glslang/SPIRV/disassemble.h | 3 +- Externals/glslang/SPIRV/doc.cpp | 338 +- Externals/glslang/SPIRV/doc.h | 2 +- Externals/glslang/SPIRV/spirv.hpp | 890 +- Externals/glslang/SPIRV/spvIR.h | 100 +- Externals/glslang/StandAlone/CMakeLists.txt | 39 +- .../glslang/StandAlone/ResourceLimits.cpp | 38 +- Externals/glslang/StandAlone/ResourceLimits.h | 2 +- Externals/glslang/StandAlone/StandAlone.cpp | 527 +- Externals/glslang/StandAlone/spirv-remap.cpp | 2 +- Externals/glslang/build_overrides/glslang.gni | 37 + Externals/glslang/glslang/CMakeLists.txt | 26 +- Externals/glslang/glslang/Include/BaseTypes.h | 131 +- Externals/glslang/glslang/Include/Common.h | 24 +- .../glslang/glslang/Include/ConstantUnion.h | 228 +- Externals/glslang/glslang/Include/PoolAlloc.h | 1 - .../glslang/glslang/Include/ResourceLimits.h | 9 + Externals/glslang/glslang/Include/Types.h | 824 +- Externals/glslang/glslang/Include/arrays.h | 8 +- .../glslang/glslang/Include/intermediate.h | 202 +- Externals/glslang/glslang/Include/revision.h | 2 +- .../glslang/MachineIndependent/Constant.cpp | 451 +- .../glslang/MachineIndependent/Initialize.cpp | 4604 +++---- .../glslang/MachineIndependent/Initialize.h | 2 + .../MachineIndependent/Intermediate.cpp | 1162 +- .../MachineIndependent/ParseContextBase.cpp | 37 +- .../MachineIndependent/ParseHelper.cpp | 2646 +++- .../glslang/MachineIndependent/ParseHelper.h | 40 +- .../glslang/MachineIndependent/Scan.cpp | 647 +- .../glslang/glslang/MachineIndependent/Scan.h | 12 +- .../glslang/MachineIndependent/ScanContext.h | 7 +- .../glslang/MachineIndependent/ShaderLang.cpp | 269 +- .../MachineIndependent/SymbolTable.cpp | 137 +- .../glslang/MachineIndependent/SymbolTable.h | 126 +- .../glslang/MachineIndependent/Versions.cpp | 533 +- .../glslang/MachineIndependent/Versions.h | 74 +- .../glslang/MachineIndependent/attribute.cpp | 117 +- .../glslang/MachineIndependent/attribute.h | 49 +- .../glslang/MachineIndependent/gl_types.h | 4 - .../glslang/MachineIndependent/glslang.m4 | 3827 ++++++ .../glslang/MachineIndependent/glslang.y | 1449 +- .../MachineIndependent/glslang_tab.cpp | 10888 ++++++++-------- .../MachineIndependent/glslang_tab.cpp.h | 809 +- .../glslang/MachineIndependent/intermOut.cpp | 108 +- .../glslang/MachineIndependent/iomapper.cpp | 1353 +- .../glslang/MachineIndependent/iomapper.h | 244 +- .../glslang/MachineIndependent/limits.cpp | 2 + .../MachineIndependent/linkValidate.cpp | 655 +- .../MachineIndependent/localintermediate.h | 690 +- .../MachineIndependent/parseVersions.h | 129 +- .../glslang/MachineIndependent/pch.cpp | 35 + .../glslang/glslang/MachineIndependent/pch.h | 49 + .../MachineIndependent/preprocessor/Pp.cpp | 191 +- .../preprocessor/PpContext.cpp | 1 + .../preprocessor/PpContext.h | 118 +- .../preprocessor/PpScanner.cpp | 209 +- .../preprocessor/PpTokens.cpp | 187 +- .../propagateNoContraction.cpp | 6 +- .../glslang/MachineIndependent/reflection.cpp | 535 +- .../glslang/MachineIndependent/reflection.h | 142 +- .../glslang/OSDependent/Unix/CMakeLists.txt | 20 +- .../glslang/OSDependent/Unix/ossource.cpp | 5 +- .../glslang/OSDependent/Web/CMakeLists.txt | 24 + .../glslang/OSDependent/Web/glslang.after.js | 26 + .../glslang/OSDependent/Web/glslang.js.cpp | 269 + .../glslang/OSDependent/Web/glslang.pre.js | 45 + .../OSDependent/Windows/CMakeLists.txt | 3 +- Externals/glslang/glslang/Public/ShaderLang.h | 347 +- Externals/glslang/glslang/updateGrammar | 15 +- Externals/glslang/gtests/AST.FromFile.cpp | 57 +- Externals/glslang/gtests/CMakeLists.txt | 20 +- Externals/glslang/gtests/Config.FromFile.cpp | 3 +- Externals/glslang/gtests/HexFloat.cpp | 38 +- Externals/glslang/gtests/Hlsl.FromFile.cpp | 77 +- Externals/glslang/gtests/Link.FromFile.Vk.cpp | 12 +- Externals/glslang/gtests/Link.FromFile.cpp | 3 +- Externals/glslang/gtests/Pp.FromFile.cpp | 1 + Externals/glslang/gtests/Spv.FromFile.cpp | 222 +- Externals/glslang/gtests/TestFixture.cpp | 16 + Externals/glslang/gtests/TestFixture.h | 134 +- Externals/glslang/gtests/pch.cpp | 35 + Externals/glslang/gtests/pch.h | 39 + Externals/glslang/hlsl/CMakeLists.txt | 10 +- Externals/glslang/hlsl/hlslAttributes.cpp | 43 + Externals/glslang/hlsl/hlslGrammar.cpp | 89 +- Externals/glslang/hlsl/hlslGrammar.h | 6 +- Externals/glslang/hlsl/hlslOpMap.cpp | 0 Externals/glslang/hlsl/hlslOpMap.h | 0 Externals/glslang/hlsl/hlslParseHelper.cpp | 260 +- Externals/glslang/hlsl/hlslParseHelper.h | 5 +- Externals/glslang/hlsl/hlslParseables.cpp | 16 +- Externals/glslang/hlsl/hlslParseables.h | 0 Externals/glslang/hlsl/hlslScanContext.cpp | 0 Externals/glslang/hlsl/hlslScanContext.h | 0 Externals/glslang/hlsl/hlslTokenStream.cpp | 0 Externals/glslang/hlsl/hlslTokenStream.h | 0 Externals/glslang/hlsl/hlslTokens.h | 0 Externals/glslang/hlsl/pch.cpp | 35 + Externals/glslang/hlsl/pch.h | 54 + Externals/glslang/known_good.json | 4 +- Externals/glslang/known_good_khr.json | 2 +- Externals/glslang/update_glslang_sources.py | 6 +- 126 files changed, 29560 insertions(+), 13594 deletions(-) create mode 100644 Externals/glslang/LICENSE.txt mode change 100755 => 100644 Externals/glslang/SPIRV/CMakeLists.txt mode change 100755 => 100644 Externals/glslang/SPIRV/GLSL.std.450.h mode change 100755 => 100644 Externals/glslang/SPIRV/GlslangToSpv.cpp mode change 100755 => 100644 Externals/glslang/SPIRV/SPVRemapper.cpp mode change 100755 => 100644 Externals/glslang/SPIRV/SPVRemapper.h mode change 100755 => 100644 Externals/glslang/SPIRV/SpvBuilder.h create mode 100644 Externals/glslang/SPIRV/SpvPostProcess.cpp create mode 100644 Externals/glslang/SPIRV/SpvTools.cpp create mode 100644 Externals/glslang/SPIRV/SpvTools.h mode change 100755 => 100644 Externals/glslang/SPIRV/disassemble.cpp mode change 100755 => 100644 Externals/glslang/SPIRV/disassemble.h mode change 100755 => 100644 Externals/glslang/SPIRV/doc.cpp mode change 100755 => 100644 Externals/glslang/SPIRV/spvIR.h mode change 100755 => 100644 Externals/glslang/StandAlone/CMakeLists.txt create mode 100644 Externals/glslang/build_overrides/glslang.gni mode change 100755 => 100644 Externals/glslang/glslang/CMakeLists.txt mode change 100755 => 100644 Externals/glslang/glslang/Include/intermediate.h mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/Initialize.cpp mode change 100644 => 100755 Externals/glslang/glslang/MachineIndependent/Intermediate.cpp mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/Versions.cpp mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/Versions.h create mode 100644 Externals/glslang/glslang/MachineIndependent/glslang.m4 mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/intermOut.cpp mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/localintermediate.h mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/parseVersions.h create mode 100644 Externals/glslang/glslang/MachineIndependent/pch.cpp create mode 100644 Externals/glslang/glslang/MachineIndependent/pch.h mode change 100644 => 100755 Externals/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp mode change 100755 => 100644 Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h create mode 100644 Externals/glslang/glslang/OSDependent/Web/CMakeLists.txt create mode 100644 Externals/glslang/glslang/OSDependent/Web/glslang.after.js create mode 100644 Externals/glslang/glslang/OSDependent/Web/glslang.js.cpp create mode 100644 Externals/glslang/glslang/OSDependent/Web/glslang.pre.js mode change 100644 => 100755 Externals/glslang/glslang/Public/ShaderLang.h mode change 100755 => 100644 Externals/glslang/gtests/AST.FromFile.cpp mode change 100644 => 100755 Externals/glslang/gtests/Hlsl.FromFile.cpp mode change 100755 => 100644 Externals/glslang/gtests/Spv.FromFile.cpp mode change 100644 => 100755 Externals/glslang/gtests/TestFixture.h create mode 100644 Externals/glslang/gtests/pch.cpp create mode 100644 Externals/glslang/gtests/pch.h mode change 100755 => 100644 Externals/glslang/hlsl/CMakeLists.txt mode change 100755 => 100644 Externals/glslang/hlsl/hlslGrammar.cpp mode change 100755 => 100644 Externals/glslang/hlsl/hlslGrammar.h mode change 100755 => 100644 Externals/glslang/hlsl/hlslOpMap.cpp mode change 100755 => 100644 Externals/glslang/hlsl/hlslOpMap.h mode change 100755 => 100644 Externals/glslang/hlsl/hlslParseHelper.h mode change 100755 => 100644 Externals/glslang/hlsl/hlslParseables.cpp mode change 100755 => 100644 Externals/glslang/hlsl/hlslParseables.h mode change 100755 => 100644 Externals/glslang/hlsl/hlslScanContext.cpp mode change 100755 => 100644 Externals/glslang/hlsl/hlslScanContext.h mode change 100755 => 100644 Externals/glslang/hlsl/hlslTokenStream.cpp mode change 100755 => 100644 Externals/glslang/hlsl/hlslTokenStream.h mode change 100755 => 100644 Externals/glslang/hlsl/hlslTokens.h create mode 100644 Externals/glslang/hlsl/pch.cpp create mode 100644 Externals/glslang/hlsl/pch.h diff --git a/Externals/glslang/CMakeLists.txt.dist b/Externals/glslang/CMakeLists.txt.dist index 9a869c2c00..d6fc8d42aa 100644 --- a/Externals/glslang/CMakeLists.txt.dist +++ b/Externals/glslang/CMakeLists.txt.dist @@ -6,10 +6,17 @@ if (POLICY CMP0048) endif() set_property(GLOBAL PROPERTY USE_FOLDERS ON) +# Enable compile commands database +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) +# Needed for CMAKE_DEPENDENT_OPTION macro +include(CMakeDependentOption) + option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF) +option(BUILD_EXTERNAL "Build external dependencies in /External" ON) set(LIB_TYPE STATIC) @@ -21,36 +28,62 @@ option(SKIP_GLSLANG_INSTALL "Skip installation" ${SKIP_GLSLANG_INSTALL}) if(NOT ${SKIP_GLSLANG_INSTALL}) set(ENABLE_GLSLANG_INSTALL ON) endif() +option(ENABLE_SPVREMAPPER "Enables building of SPVRemapper" ON) -option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON) option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON) -option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON) +option(ENABLE_GLSLANG_WEB "Reduces glslang to minimum needed for web use" OFF) +option(ENABLE_GLSLANG_WEB_DEVEL "For ENABLE_GLSLANG_WEB builds, enables compilation error messages" OFF) +option(ENABLE_EMSCRIPTEN_SINGLE_FILE "If using Emscripten, enables SINGLE_FILE build" OFF) +option(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE "If using Emscripten, builds to run on Node instead of Web" OFF) -option(ENABLE_HLSL "Enables HLSL input support" ON) +CMAKE_DEPENDENT_OPTION(ENABLE_HLSL "Enables HLSL input support" ON "NOT ENABLE_GLSLANG_WEB" OFF) option(ENABLE_OPT "Enables spirv-opt capability if present" ON) +option(ENABLE_PCH "Enables Precompiled header" ON) +option(ENABLE_CTEST "Enables testing" ON) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND WIN32) set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "..." FORCE) endif() +option(USE_CCACHE "Use ccache" OFF) +if(USE_CCACHE) + find_program(CCACHE_FOUND ccache) + if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + endif(CCACHE_FOUND) +endif() + +# Precompiled header macro. Parameters are source file list and filename for pch cpp file. +macro(glslang_pch SRCS PCHCPP) + if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio" AND ENABLE_PCH) + set(PCH_NAME "$(IntDir)\\pch.pch") + # make source files use/depend on PCH_NAME + set_source_files_properties(${${SRCS}} PROPERTIES COMPILE_FLAGS "/Yupch.h /FIpch.h /Fp${PCH_NAME} /Zm300" OBJECT_DEPENDS "${PCH_NAME}") + # make PCHCPP file compile and generate PCH_NAME + set_source_files_properties(${PCHCPP} PROPERTIES COMPILE_FLAGS "/Ycpch.h /Fp${PCH_NAME} /Zm300" OBJECT_OUTPUTS "${PCH_NAME}") + list(APPEND ${SRCS} "${PCHCPP}") + endif() +endmacro(glslang_pch) + project(glslang) -# make testing optional -include(CTest) -if(ENABLE_AMD_EXTENSIONS) - add_definitions(-DAMD_EXTENSIONS) -endif(ENABLE_AMD_EXTENSIONS) - -if(ENABLE_NV_EXTENSIONS) - add_definitions(-DNV_EXTENSIONS) -endif(ENABLE_NV_EXTENSIONS) +if(ENABLE_CTEST) + include(CTest) +endif() if(ENABLE_HLSL) add_definitions(-DENABLE_HLSL) endif(ENABLE_HLSL) +if(ENABLE_GLSLANG_WEB) + add_definitions(-DGLSLANG_WEB) + if(ENABLE_GLSLANG_WEB_DEVEL) + add_definitions(-DGLSLANG_WEB_DEVEL) + endif(ENABLE_GLSLANG_WEB_DEVEL) +endif(ENABLE_GLSLANG_WEB) + if(WIN32) set(CMAKE_DEBUG_POSTFIX "d") if(MSVC) @@ -67,12 +100,40 @@ if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") add_compile_options(-Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions) add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over. + add_compile_options(-fno-rtti) elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") add_compile_options(-Wall -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable) add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over. + add_compile_options(-fno-rtti) +elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") + add_compile_options(/GR-) # Disable RTTI endif() +if(EMSCRIPTEN) + add_compile_options(-Os -fno-exceptions) + add_compile_options("SHELL: -s WASM=1") + add_compile_options("SHELL: -s WASM_OBJECT_FILES=0") + add_link_options(-Os) + add_link_options("SHELL: -s FILESYSTEM=0") + add_link_options("SHELL: --llvm-lto 1") + add_link_options("SHELL: --closure 1") + add_link_options("SHELL: -s ALLOW_MEMORY_GROWTH=1") + + if(ENABLE_EMSCRIPTEN_SINGLE_FILE) + add_link_options("SHELL: -s SINGLE_FILE=1") + endif(ENABLE_EMSCRIPTEN_SINGLE_FILE) +else() + if(ENABLE_GLSLANG_WEB) + if(MSVC) + add_compile_options(/Os /GR-) + else() + add_compile_options(-Os -fno-exceptions) + add_link_options(-Os) + endif() + endif(ENABLE_GLSLANG_WEB) +endif(EMSCRIPTEN) + # Request C++11 if(${CMAKE_VERSION} VERSION_LESS 3.1) # CMake versions before 3.1 do not understand CMAKE_CXX_STANDARD @@ -93,8 +154,14 @@ function(glslang_set_link_args TARGET) endif() endfunction(glslang_set_link_args) -# We depend on these for later projects, so they should come first. -add_subdirectory(External) +# CMake needs to find the right version of python, right from the beginning, +# otherwise, it will find the wrong version and fail later +if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External) + find_package(PythonInterp 3 REQUIRED) + + # We depend on these for later projects, so they should come first. + add_subdirectory(External) +endif() if(NOT TARGET SPIRV-Tools-opt) set(ENABLE_OPT OFF) @@ -119,4 +186,29 @@ add_subdirectory(SPIRV) if(ENABLE_HLSL) add_subdirectory(hlsl) endif(ENABLE_HLSL) -add_subdirectory(gtests) +if(ENABLE_CTEST) + add_subdirectory(gtests) +endif() + +if(BUILD_TESTING) + # glslang-testsuite runs a bash script on Windows. + # Make sure to use '-o igncr' flag to ignore carriage returns (\r). + set(IGNORE_CR_FLAG "") + if(WIN32) + set(IGNORE_CR_FLAG -o igncr) + endif() + + if (CMAKE_CONFIGURATION_TYPES) + set(RESULTS_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/localResults) + set(VALIDATOR_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/$/glslangValidator) + set(REMAP_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/$/spirv-remap) + else(CMAKE_CONFIGURATION_TYPES) + set(RESULTS_PATH ${CMAKE_CURRENT_BINARY_DIR}/localResults) + set(VALIDATOR_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/glslangValidator) + set(REMAP_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/spirv-remap) + endif(CMAKE_CONFIGURATION_TYPES) + + add_test(NAME glslang-testsuite + COMMAND bash ${IGNORE_CR_FLAG} runtests ${RESULTS_PATH} ${VALIDATOR_PATH} ${REMAP_PATH} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Test/) +endif(BUILD_TESTING) diff --git a/Externals/glslang/External/CMakeLists.txt b/Externals/glslang/External/CMakeLists.txt index 4d9690134a..6ff4f47acd 100644 --- a/Externals/glslang/External/CMakeLists.txt +++ b/Externals/glslang/External/CMakeLists.txt @@ -10,7 +10,8 @@ if(BUILD_TESTING) if(WIN32) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) endif(WIN32) - add_subdirectory(googletest) + # EXCLUDE_FROM_ALL keeps the install target from installing GTEST files. + add_subdirectory(googletest EXCLUDE_FROM_ALL) set(GTEST_TARGETS gtest gtest_main diff --git a/Externals/glslang/LICENSE.txt b/Externals/glslang/LICENSE.txt new file mode 100644 index 0000000000..a10c0944f8 --- /dev/null +++ b/Externals/glslang/LICENSE.txt @@ -0,0 +1,108 @@ +Here, glslang proper means core GLSL parsing, HLSL parsing, and SPIR-V code +generation. Glslang proper requires use of two licenses, one that covers +non-preprocessing and an additional one that covers preprocessing. + +Bison was removed long ago. You can build glslang from the source grammar, +using tools of your choice, without using bison or any bison files. + +Other parts, outside of glslang proper, include: + +- gl_types.h, only needed for OpenGL-like reflection, and can be left out of + a parse and codegen project. See it for its license. + +- update_glslang_sources.py, which is not part of the project proper and does + not need to be used. + +- the SPIR-V "remapper", which is optional, but has the same license as + glslang proper + +- Google tests and SPIR-V tools, and anything in the external subdirectory + are external and optional; see them for their respective licenses. + +-------------------------------------------------------------------------------- + +The core of glslang-proper, minus the preprocessor is licenced as follows: + +// +// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) +// +// 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. +// + +-------------------------------------------------------------------------------- + +The preprocessor has the core license stated above, plus an additional licence: + +/****************************************************************************\ +Copyright (c) 2002, NVIDIA Corporation. + +NVIDIA Corporation("NVIDIA") supplies this software to you in +consideration of your agreement to the following terms, and your use, +installation, modification or redistribution of this NVIDIA software +constitutes acceptance of these terms. If you do not agree with these +terms, please do not use, install, modify or redistribute this NVIDIA +software. + +In consideration of your agreement to abide by the following terms, and +subject to these terms, NVIDIA grants you a personal, non-exclusive +license, under NVIDIA's copyrights in this original NVIDIA software (the +"NVIDIA Software"), to use, reproduce, modify and redistribute the +NVIDIA Software, with or without modifications, in source and/or binary +forms; provided that if you redistribute the NVIDIA Software, you must +retain the copyright notice of NVIDIA, this notice and the following +text and disclaimers in all such redistributions of the NVIDIA Software. +Neither the name, trademarks, service marks nor logos of NVIDIA +Corporation may be used to endorse or promote products derived from the +NVIDIA Software without specific prior written permission from NVIDIA. +Except as expressly stated in this notice, no other rights or licenses +express or implied, are granted by NVIDIA herein, including but not +limited to any patent rights that may be infringed by your derivative +works or by other works in which the NVIDIA Software may be +incorporated. No hardware is licensed hereunder. + +THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, +INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER +PRODUCTS. + +IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, +INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY +OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE +NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, +TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF +NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +\****************************************************************************/ diff --git a/Externals/glslang/OGLCompilersDLL/CMakeLists.txt b/Externals/glslang/OGLCompilersDLL/CMakeLists.txt index 5bb3f0ee69..e0096743b3 100644 --- a/Externals/glslang/OGLCompilersDLL/CMakeLists.txt +++ b/Externals/glslang/OGLCompilersDLL/CMakeLists.txt @@ -9,6 +9,7 @@ if(WIN32) endif(WIN32) if(ENABLE_GLSLANG_INSTALL) - install(TARGETS OGLCompiler + install(TARGETS OGLCompiler EXPORT OGLCompilerTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT OGLCompilerTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/README.md b/Externals/glslang/README.md index 402b4d6005..67801e4790 100644 --- a/Externals/glslang/README.md +++ b/Externals/glslang/README.md @@ -28,6 +28,15 @@ comment in `glslang/MachineIndependent/Versions.cpp`. Tasks waiting to be done are documented as GitHub issues. +Deprecations +------------ + +1. GLSLang, when installed through CMake, will install a `SPIRV` folder into +`${CMAKE_INSTALL_INCLUDEDIR}`. This `SPIRV` folder is being moved to +`glslang/SPIRV`. During the transition the `SPIRV` folder will be installed into +both locations. The old install of `SPIRV/` will be removed as a CMake install +target no sooner then May 1, 2020. See issue #1964. + Execution of Standalone Wrapper ------------------------------- @@ -61,7 +70,7 @@ branch. (For MSVS: 2015 is recommended, 2013 is fully supported/tested, and 2010 support is attempted, but not tested.) * [CMake][cmake]: for generating compilation targets. * make: _Linux_, ninja is an alternative, if configured. -* [Python 2.7][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools.) +* [Python 3.x][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools and the 'External' subdirectory does not exist.) * [bison][bison]: _optional_, but needed when changing the grammar (glslang.y). * [googletest][googletest]: _optional_, but should use if making any changes to glslang. @@ -84,9 +93,18 @@ cd git clone https://github.com/google/googletest.git External/googletest ``` +If you want to use googletest with Visual Studio 2013, you also need to check out an older version: + +```bash +# to use googletest with Visual Studio 2013 +cd External/googletest +git checkout 440527a61e1c91188195f7de212c63c77e8f0a45 +cd ../.. +``` + If you wish to assure that SPIR-V generated from HLSL is legal for Vulkan, -or wish to invoke -Os to reduce SPIR-V size from HLSL or GLSL, install -spirv-tools with this: +wish to invoke -Os to reduce SPIR-V size from HLSL or GLSL, or wish to run the +integrated test suite, install spirv-tools with this: ```bash ./update_glslang_sources.py @@ -105,8 +123,8 @@ cd $BUILD_DIR For building on Linux: ```bash -cmake -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \ - -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR +# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo" ``` For building on Windows: @@ -118,6 +136,9 @@ cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install" The CMake GUI also works for Windows (version 3.4.1 tested). +Also, consider using `git config --global core.fileMode false` (or with `--local`) on Windows +to prevent the addition of execution permission on files. + #### 4) Build and Install ```bash @@ -125,8 +146,8 @@ The CMake GUI also works for Windows (version 3.4.1 tested). make -j4 install # for Windows: -cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \ - --target install +cmake --build . --config Release --target install +# "Release" (for --config) could also be "Debug", "MinSizeRel", or "RelWithDebInfo" ``` If using MSVC, after running CMake to configure, use the @@ -143,13 +164,40 @@ changes are quite infrequent. For windows you can get binaries from The command to rebuild is: ```bash +m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y bison --defines=MachineIndependent/glslang_tab.cpp.h -t MachineIndependent/glslang.y -o MachineIndependent/glslang_tab.cpp ``` -The above command is also available in the bash script at -`glslang/updateGrammar`. +The above commands are also available in the bash script in `updateGrammar`, +when executed from the glslang subdirectory of the glslang repository. +With no arguments it builds the full grammar, and with a "web" argument, +the web grammar subset (see more about the web subset in the next section). + +### Building to WASM for the Web and Node + +Use the steps in [Build Steps](#build-steps), with the following notes/exceptions: +* For building the web subset of core glslang: + + execute `updateGrammar web` from the glslang subdirectory + (or if using your own scripts, `m4` needs a `-DGLSLANG_WEB` argument) + + set `-DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF` + + turn on `-DENABLE_GLSLANG_WEB=ON` + + optionally, for GLSL compilation error messages, turn on `-DENABLE_GLSLANG_WEB_DEVEL=ON` +* `emsdk` needs to be present in your executable search path, *PATH* for + Bash-like enivironments + + [Instructions located + here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install) +* Wrap cmake call: `emcmake cmake` +* To get a fully minimized build, make sure to use `brotli` to compress the .js + and .wasm files + +Example: + +```sh +emcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_WEB=ON \ + -DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF .. +``` Testing ------- @@ -188,6 +236,11 @@ Running `runtests` script-backed tests: cd $SOURCE_DIR/Test && ./runtests ``` +If some tests fail with validation errors, there may be a mismatch between the +version of `spirv-val` on the system and the version of glslang. In this +case, it is necessary to run `update_glslang_sources.py`. See "Check-Out +External Projects" above for more details. + ### Contributing tests Test results should always be included with a pull request that modifies @@ -232,7 +285,8 @@ The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles. ### C++ Class Interface (new, preferred) This interface is in roughly the last 1/3 of `ShaderLang.h`. It is in the -glslang namespace and contains the following. +glslang namespace and contains the following, here with suggested calls +for generating SPIR-V: ```cxx const char* GetEsslVersionString(); @@ -255,10 +309,19 @@ class TProgram Reflection queries ``` -See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more -details. +For just validating (not generating code), subsitute these calls: -### C Functional Interface (orignal) +```cxx + setEnvInput(EShSourceHlsl or EShSourceGlsl, stage, EShClientNone, 0); + setEnvClient(EShClientNone, 0); + setEnvTarget(EShTargetNone, 0); +``` + +See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more +details. There is a block comment giving more detail above the calls for +`setEnvInput, setEnvClient, and setEnvTarget`. + +### C Functional Interface (original) This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to as the `Sh*()` interface, as all the entry points start `Sh`. diff --git a/Externals/glslang/SPIRV/CMakeLists.txt b/Externals/glslang/SPIRV/CMakeLists.txt old mode 100755 new mode 100644 index 1e5513c735..439b9918a4 --- a/Externals/glslang/SPIRV/CMakeLists.txt +++ b/Externals/glslang/SPIRV/CMakeLists.txt @@ -3,7 +3,9 @@ set(SOURCES InReadableOrder.cpp Logger.cpp SpvBuilder.cpp + SpvPostProcess.cpp doc.cpp + SpvTools.cpp disassemble.cpp) set(SPVREMAP_SOURCES @@ -22,36 +24,33 @@ set(HEADERS SpvBuilder.h spvIR.h doc.h - disassemble.h) + SpvTools.h + disassemble.h + GLSL.ext.AMD.h + GLSL.ext.NV.h) set(SPVREMAP_HEADERS SPVRemapper.h doc.h) -if(ENABLE_AMD_EXTENSIONS) - list(APPEND - HEADERS - GLSL.ext.AMD.h) -endif(ENABLE_AMD_EXTENSIONS) - -if(ENABLE_NV_EXTENSIONS) - list(APPEND - HEADERS - GLSL.ext.NV.h) -endif(ENABLE_NV_EXTENSIONS) - add_library(SPIRV ${LIB_TYPE} ${SOURCES} ${HEADERS}) set_property(TARGET SPIRV PROPERTY FOLDER glslang) set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON) -target_include_directories(SPIRV PUBLIC ..) +target_include_directories(SPIRV PUBLIC + $ + $) -add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS}) -set_property(TARGET SPVRemapper PROPERTY FOLDER glslang) -set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON) +if (ENABLE_SPVREMAPPER) + add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS}) + set_property(TARGET SPVRemapper PROPERTY FOLDER glslang) + set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON) +endif() if(WIN32 AND BUILD_SHARED_LIBS) set_target_properties(SPIRV PROPERTIES PREFIX "") - set_target_properties(SPVRemapper PROPERTIES PREFIX "") + if (ENABLE_SPVREMAPPER) + set_target_properties(SPVRemapper PROPERTIES PREFIX "") + endif() endif() if(ENABLE_OPT) @@ -60,6 +59,9 @@ if(ENABLE_OPT) PRIVATE ${spirv-tools_SOURCE_DIR}/source ) target_link_libraries(SPIRV glslang SPIRV-Tools-opt) + target_include_directories(SPIRV PUBLIC + $ + $) else() target_link_libraries(SPIRV glslang) endif(ENABLE_OPT) @@ -71,13 +73,30 @@ endif(WIN32) if(ENABLE_GLSLANG_INSTALL) if(BUILD_SHARED_LIBS) - install(TARGETS SPIRV SPVRemapper + if (ENABLE_SPVREMAPPER) + install(TARGETS SPVRemapper EXPORT SPVRemapperTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() + install(TARGETS SPIRV EXPORT SPIRVTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) else() - install(TARGETS SPIRV SPVRemapper + if (ENABLE_SPVREMAPPER) + install(TARGETS SPVRemapper EXPORT SPVRemapperTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + endif() + install(TARGETS SPIRV EXPORT SPIRVTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() + if (ENABLE_SPVREMAPPER) + install(EXPORT SPVRemapperTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) + endif() + + install(EXPORT SPIRVTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) + install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SPIRV/) + install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/SPIRV/) endif(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/SPIRV/GLSL.ext.EXT.h b/Externals/glslang/SPIRV/GLSL.ext.EXT.h index c4a243080c..40164b6187 100644 --- a/Externals/glslang/SPIRV/GLSL.ext.EXT.h +++ b/Externals/glslang/SPIRV/GLSL.ext.EXT.h @@ -28,10 +28,12 @@ #define GLSLextEXT_H static const int GLSLextEXTVersion = 100; -static const int GLSLextEXTRevision = 1; +static const int GLSLextEXTRevision = 2; static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export"; static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer"; static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered"; +static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density"; +static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation"; #endif // #ifndef GLSLextEXT_H diff --git a/Externals/glslang/SPIRV/GLSL.ext.KHR.h b/Externals/glslang/SPIRV/GLSL.ext.KHR.h index d8ea9b67d6..e58e836a8d 100644 --- a/Externals/glslang/SPIRV/GLSL.ext.KHR.h +++ b/Externals/glslang/SPIRV/GLSL.ext.KHR.h @@ -36,7 +36,13 @@ static const char* const E_SPV_KHR_device_group = "SPV_KHR_devic static const char* const E_SPV_KHR_multiview = "SPV_KHR_multiview"; static const char* const E_SPV_KHR_shader_draw_parameters = "SPV_KHR_shader_draw_parameters"; static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit_storage"; +static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage"; static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class"; static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage"; +static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model"; +static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer"; +static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer"; +static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock"; +static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock"; #endif // #ifndef GLSLextKHR_H diff --git a/Externals/glslang/SPIRV/GLSL.ext.NV.h b/Externals/glslang/SPIRV/GLSL.ext.NV.h index 148d4b457f..50146da104 100644 --- a/Externals/glslang/SPIRV/GLSL.ext.NV.h +++ b/Externals/glslang/SPIRV/GLSL.ext.NV.h @@ -33,7 +33,7 @@ enum Op; enum Capability; static const int GLSLextNVVersion = 100; -static const int GLSLextNVRevision = 5; +static const int GLSLextNVRevision = 11; //SPV_NV_sample_mask_override_coverage const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage"; @@ -54,4 +54,28 @@ const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_p //SPV_NV_shader_subgroup_partitioned const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned"; -#endif // #ifndef GLSLextNV_H \ No newline at end of file +//SPV_NV_fragment_shader_barycentric +const char* const E_SPV_NV_fragment_shader_barycentric = "SPV_NV_fragment_shader_barycentric"; + +//SPV_NV_compute_shader_derivatives +const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_derivatives"; + +//SPV_NV_shader_image_footprint +const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint"; + +//SPV_NV_mesh_shader +const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader"; + +//SPV_NV_raytracing +const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing"; + +//SPV_NV_shading_rate +const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate"; + +//SPV_NV_cooperative_matrix +const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix"; + +//SPV_NV_shader_sm_builtins +const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins"; + +#endif // #ifndef GLSLextNV_H diff --git a/Externals/glslang/SPIRV/GLSL.std.450.h b/Externals/glslang/SPIRV/GLSL.std.450.h old mode 100755 new mode 100644 diff --git a/Externals/glslang/SPIRV/GlslangToSpv.cpp b/Externals/glslang/SPIRV/GlslangToSpv.cpp old mode 100755 new mode 100644 index aa8ed0bbc0..0c8a87e3ce --- a/Externals/glslang/SPIRV/GlslangToSpv.cpp +++ b/Externals/glslang/SPIRV/GlslangToSpv.cpp @@ -1,6 +1,6 @@ // // Copyright (C) 2014-2016 LunarG, Inc. -// Copyright (C) 2015-2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. // Copyright (C) 2017 ARM Limited. // // All rights reserved. @@ -46,23 +46,10 @@ namespace spv { #include "GLSL.std.450.h" #include "GLSL.ext.KHR.h" #include "GLSL.ext.EXT.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif } -#if ENABLE_OPT - #include "spirv-tools/optimizer.hpp" - #include "message.h" -#endif - -#if ENABLE_OPT -using namespace spvtools; -#endif - // Glslang includes #include "../glslang/MachineIndependent/localintermediate.h" #include "../glslang/MachineIndependent/SymbolTable.h" @@ -100,9 +87,29 @@ private: }; struct OpDecorations { + public: + OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) : + precision(precision) +#ifndef GLSLANG_WEB + , + noContraction(noContraction), + nonUniform(nonUniform) +#endif + { } + spv::Decoration precision; - spv::Decoration noContraction; - spv::Decoration nonUniform; + +#ifdef GLSLANG_WEB + void addNoContraction(spv::Builder&, spv::Id) const { } + void addNonUniform(spv::Builder&, spv::Id) const { } +#else + void addNoContraction(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, noContraction); } + void addNonUniform(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, nonUniform); } + protected: + spv::Decoration noContraction; + spv::Decoration nonUniform; +#endif + }; } // namespace @@ -138,21 +145,25 @@ protected: spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier); spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier); spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier); + spv::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type); + spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); + spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); + spv::Scope TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration); spv::ImageFormat TranslateImageFormat(const glslang::TType& type); spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const; spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const; - spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, unsigned int& dependencyLength) const; + spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector& operands) const; spv::StorageClass TranslateStorageClass(const glslang::TType&); void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType); - spv::Id createSpvVariable(const glslang::TIntermSymbol*); + spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType); spv::Id getSampledType(const glslang::TSampler&); spv::Id getInvertedSwizzleType(const glslang::TIntermTyped&); spv::Id createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped&, spv::Id parentResult); void convertSwizzle(const glslang::TIntermAggregate&, std::vector& swizzle); - spv::Id convertGlslangToSpvType(const glslang::TType& type); + spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&, - bool lastBufferBlockMember); + bool lastBufferBlockMember, bool forwardReferenceOnly = false); bool filterMember(const glslang::TType& member); spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking, const glslang::TQualifier&); @@ -176,7 +187,7 @@ protected: void makeGlobalInitializers(const glslang::TIntermSequence&); void visitFunctions(const glslang::TIntermSequence&); void handleFunctionEntry(const glslang::TIntermAggregate* node); - void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments); + void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); void translateArguments(glslang::TIntermUnary& node, std::vector& arguments); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); @@ -185,33 +196,30 @@ protected: glslang::TBasicType typeProxy, bool reduceComparison = true); spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right); spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand, - glslang::TBasicType typeProxy); + glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy); - spv::Id createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize); + spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); - spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); + spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector& operands); spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId); spv::Id getSymbolId(const glslang::TIntermSymbol* node); + void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier); spv::Id createSpvConstant(const glslang::TIntermTyped&); spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); bool isTrivialLeaf(const glslang::TIntermTyped* node); bool isTrivial(const glslang::TIntermTyped* node); spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right); -#ifdef AMD_EXTENSIONS spv::Id getExtBuiltins(const char* name); -#endif - void addPre13Extension(const char* ext) - { - if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3) - builder.addExtension(ext); - } + std::pair getForcedType(spv::BuiltIn, const glslang::TType&); + spv::Id translateForcedType(spv::Id object); + spv::Id createCompositeConstruct(spv::Id typeId, std::vector constituents); glslang::SpvOptions& options; spv::Function* shaderEntry; @@ -228,6 +236,7 @@ protected: bool linkageOnly; // true when visiting the set of objects in the AST present only for establishing interface, whether or not they were statically used std::set iOSet; // all input/output variables from either static use or declaration of interface const glslang::TIntermediate* glslangIntermediate; + bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp spv::Id stdBuiltins; std::unordered_map extBuiltinMap; @@ -236,9 +245,17 @@ protected: std::unordered_map functionMap; std::unordered_map structMap[glslang::ElpCount][glslang::ElmCount]; // for mapping glslang block indices to spv indices (e.g., due to hidden members): - std::unordered_map > memberRemapper; + std::unordered_map> memberRemapper; + // for mapping glslang symbol struct to symbol Id + std::unordered_map glslangTypeToIdMap; std::stack breakForLoop; // false means break for switch std::unordered_map counterOriginator; + // Map pointee types for EbtReference to their forward pointers + std::map forwardPointers; + // Type forcing, for when SPIR-V wants a different type than the AST, + // requiring local translation to and from SPIR-V type on every access. + // Maps AST-required-type-id> + std::unordered_map forceType; }; // @@ -248,6 +265,10 @@ protected: // Translate glslang profile to SPIR-V source language. spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile) { +#ifdef GLSLANG_WEB + return spv::SourceLanguageESSL; +#endif + switch (source) { case glslang::EShSourceGlsl: switch (profile) { @@ -272,11 +293,21 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) { switch (stage) { case EShLangVertex: return spv::ExecutionModelVertex; + case EShLangFragment: return spv::ExecutionModelFragment; + case EShLangCompute: return spv::ExecutionModelGLCompute; +#ifndef GLSLANG_WEB case EShLangTessControl: return spv::ExecutionModelTessellationControl; case EShLangTessEvaluation: return spv::ExecutionModelTessellationEvaluation; case EShLangGeometry: return spv::ExecutionModelGeometry; - case EShLangFragment: return spv::ExecutionModelFragment; - case EShLangCompute: return spv::ExecutionModelGLCompute; + case EShLangRayGenNV: return spv::ExecutionModelRayGenerationNV; + case EShLangIntersectNV: return spv::ExecutionModelIntersectionNV; + case EShLangAnyHitNV: return spv::ExecutionModelAnyHitNV; + case EShLangClosestHitNV: return spv::ExecutionModelClosestHitNV; + case EShLangMissNV: return spv::ExecutionModelMissNV; + case EShLangCallableNV: return spv::ExecutionModelCallableNV; + case EShLangTaskNV: return spv::ExecutionModelTaskNV; + case EShLangMeshNV: return spv::ExecutionModelMeshNV; +#endif default: assert(0); return spv::ExecutionModelFragment; @@ -326,6 +357,13 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; case glslang::EvqVaryingIn: return spv::DecorationBlock; case glslang::EvqVaryingOut: return spv::DecorationBlock; +#ifndef GLSLANG_WEB + case glslang::EvqPayloadNV: return spv::DecorationBlock; + case glslang::EvqPayloadInNV: return spv::DecorationBlock; + case glslang::EvqHitAttrNV: return spv::DecorationBlock; + case glslang::EvqCallableDataNV: return spv::DecorationBlock; + case glslang::EvqCallableDataInNV: return spv::DecorationBlock; +#endif default: assert(0); break; @@ -336,17 +374,21 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto } // Translate glslang type to SPIR-V memory decorations. -void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory) +void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory, bool useVulkanMemoryModel) { - if (qualifier.coherent) - memory.push_back(spv::DecorationCoherent); - if (qualifier.volatil) - memory.push_back(spv::DecorationVolatile); - if (qualifier.restrict) + if (!useVulkanMemoryModel) { + if (qualifier.isCoherent()) + memory.push_back(spv::DecorationCoherent); + if (qualifier.isVolatile()) { + memory.push_back(spv::DecorationVolatile); + memory.push_back(spv::DecorationCoherent); + } + } + if (qualifier.isRestrict()) memory.push_back(spv::DecorationRestrict); - if (qualifier.readonly) + if (qualifier.isReadOnly()) memory.push_back(spv::DecorationNonWritable); - if (qualifier.writeonly) + if (qualifier.isWriteOnly()) memory.push_back(spv::DecorationNonReadable); } @@ -380,8 +422,24 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T } case glslang::EvqVaryingIn: case glslang::EvqVaryingOut: - assert(type.getQualifier().layoutPacking == glslang::ElpNone); + if (type.getQualifier().isTaskMemory()) { + switch (type.getQualifier().layoutPacking) { + case glslang::ElpShared: return spv::DecorationGLSLShared; + case glslang::ElpPacked: return spv::DecorationGLSLPacked; + default: break; + } + } else { + assert(type.getQualifier().layoutPacking == glslang::ElpNone); + } return spv::DecorationMax; +#ifndef GLSLANG_WEB + case glslang::EvqPayloadNV: + case glslang::EvqPayloadInNV: + case glslang::EvqHitAttrNV: + case glslang::EvqCallableDataNV: + case glslang::EvqCallableDataInNV: + return spv::DecorationMax; +#endif default: assert(0); return spv::DecorationMax; @@ -398,16 +456,14 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g if (qualifier.smooth) // Smooth decoration doesn't exist in SPIR-V 1.0 return spv::DecorationMax; - else if (qualifier.nopersp) + else if (qualifier.isNonPerspective()) return spv::DecorationNoPerspective; else if (qualifier.flat) return spv::DecorationFlat; -#ifdef AMD_EXTENSIONS - else if (qualifier.explicitInterp) { + else if (qualifier.isExplicitInterpolation()) { builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::DecorationExplicitInterpAMD; } -#endif else return spv::DecorationMax; } @@ -417,15 +473,18 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g // should be applied. spv::Decoration TGlslangToSpvTraverser::TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier) { - if (qualifier.patch) - return spv::DecorationPatch; - else if (qualifier.centroid) + if (qualifier.centroid) return spv::DecorationCentroid; +#ifndef GLSLANG_WEB + else if (qualifier.patch) + return spv::DecorationPatch; else if (qualifier.sample) { builder.addCapability(spv::CapabilitySampleRateShading); return spv::DecorationSample; - } else - return spv::DecorationMax; + } +#endif + + return spv::DecorationMax; } // If glslang type is invariant, return SPIR-V invariant decoration. @@ -440,23 +499,142 @@ spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifie // If glslang type is noContraction, return SPIR-V NoContraction decoration. spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier) { - if (qualifier.noContraction) +#ifndef GLSLANG_WEB + if (qualifier.isNoContraction()) return spv::DecorationNoContraction; else +#endif return spv::DecorationMax; } // If glslang type is nonUniform, return SPIR-V NonUniform decoration. spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier) { +#ifndef GLSLANG_WEB if (qualifier.isNonUniform()) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityShaderNonUniformEXT); return spv::DecorationNonUniformEXT; } else +#endif return spv::DecorationMax; } +spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( + const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +{ + spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone; + +#ifndef GLSLANG_WEB + if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) + return mask; + + if (coherentFlags.volatil || + coherentFlags.coherent || + coherentFlags.devicecoherent || + coherentFlags.queuefamilycoherent || + coherentFlags.workgroupcoherent || + coherentFlags.subgroupcoherent) { + mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask | + spv::MemoryAccessMakePointerVisibleKHRMask; + } + if (coherentFlags.nonprivate) { + mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask; + } + if (coherentFlags.volatil) { + mask = mask | spv::MemoryAccessVolatileMask; + } + if (mask != spv::MemoryAccessMaskNone) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } +#endif + + return mask; +} + +spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( + const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +{ + spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; + +#ifndef GLSLANG_WEB + if (!glslangIntermediate->usingVulkanMemoryModel()) + return mask; + + if (coherentFlags.volatil || + coherentFlags.coherent || + coherentFlags.devicecoherent || + coherentFlags.queuefamilycoherent || + coherentFlags.workgroupcoherent || + coherentFlags.subgroupcoherent) { + mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask | + spv::ImageOperandsMakeTexelVisibleKHRMask; + } + if (coherentFlags.nonprivate) { + mask = mask | spv::ImageOperandsNonPrivateTexelKHRMask; + } + if (coherentFlags.volatil) { + mask = mask | spv::ImageOperandsVolatileTexelKHRMask; + } + if (mask != spv::ImageOperandsMaskNone) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } +#endif + + return mask; +} + +spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type) +{ + spv::Builder::AccessChain::CoherentFlags flags = {}; +#ifndef GLSLANG_WEB + flags.coherent = type.getQualifier().coherent; + flags.devicecoherent = type.getQualifier().devicecoherent; + flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent; + // shared variables are implicitly workgroupcoherent in GLSL. + flags.workgroupcoherent = type.getQualifier().workgroupcoherent || + type.getQualifier().storage == glslang::EvqShared; + flags.subgroupcoherent = type.getQualifier().subgroupcoherent; + flags.volatil = type.getQualifier().volatil; + // *coherent variables are implicitly nonprivate in GLSL + flags.nonprivate = type.getQualifier().nonprivate || + flags.subgroupcoherent || + flags.workgroupcoherent || + flags.queuefamilycoherent || + flags.devicecoherent || + flags.coherent || + flags.volatil; + flags.isImage = type.getBasicType() == glslang::EbtSampler; +#endif + return flags; +} + +spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( + const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +{ + spv::Scope scope = spv::ScopeMax; + +#ifndef GLSLANG_WEB + if (coherentFlags.volatil || coherentFlags.coherent) { + // coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model + scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; + } else if (coherentFlags.devicecoherent) { + scope = spv::ScopeDevice; + } else if (coherentFlags.queuefamilycoherent) { + scope = spv::ScopeQueueFamilyKHR; + } else if (coherentFlags.workgroupcoherent) { + scope = spv::ScopeWorkgroup; + } else if (coherentFlags.subgroupcoherent) { + scope = spv::ScopeSubgroup; + } + if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) { + builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); + } +#endif + + return scope; +} + // Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate // associated capabilities when required. For some built-in variables, a capability // is generated only when using the variable in an executable instruction, but not when @@ -466,6 +644,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI { switch (builtIn) { case glslang::EbvPointSize: +#ifndef GLSLANG_WEB // Defer adding the capability until the built-in is actually used. if (! memberDeclaration) { switch (glslangIntermediate->getStage()) { @@ -480,8 +659,28 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI break; } } +#endif return spv::BuiltInPointSize; + case glslang::EbvPosition: return spv::BuiltInPosition; + case glslang::EbvVertexId: return spv::BuiltInVertexId; + case glslang::EbvInstanceId: return spv::BuiltInInstanceId; + case glslang::EbvVertexIndex: return spv::BuiltInVertexIndex; + case glslang::EbvInstanceIndex: return spv::BuiltInInstanceIndex; + + case glslang::EbvFragCoord: return spv::BuiltInFragCoord; + case glslang::EbvPointCoord: return spv::BuiltInPointCoord; + case glslang::EbvFace: return spv::BuiltInFrontFacing; + case glslang::EbvFragDepth: return spv::BuiltInFragDepth; + + case glslang::EbvNumWorkGroups: return spv::BuiltInNumWorkgroups; + case glslang::EbvWorkGroupSize: return spv::BuiltInWorkgroupSize; + case glslang::EbvWorkGroupId: return spv::BuiltInWorkgroupId; + case glslang::EbvLocalInvocationId: return spv::BuiltInLocalInvocationId; + case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex; + case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId; + +#ifndef GLSLANG_WEB // These *Distance capabilities logically belong here, but if the member is declared and // then never used, consumers of SPIR-V prefer the capability not be declared. // They are now generated when used, rather than here when declared. @@ -504,7 +703,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessEvaluation) { - builder.addExtension(spv::E_SPV_EXT_shader_viewport_index_layer); + builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5); builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT); } return spv::BuiltInViewportIndex; @@ -521,34 +720,31 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInSampleMask; case glslang::EbvLayer: + if (glslangIntermediate->getStage() == EShLangMeshNV) { + return spv::BuiltInLayer; + } builder.addCapability(spv::CapabilityGeometry); if (glslangIntermediate->getStage() == EShLangVertex || glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessEvaluation) { - builder.addExtension(spv::E_SPV_EXT_shader_viewport_index_layer); + builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5); builder.addCapability(spv::CapabilityShaderViewportIndexLayerEXT); } return spv::BuiltInLayer; - case glslang::EbvPosition: return spv::BuiltInPosition; - case glslang::EbvVertexId: return spv::BuiltInVertexId; - case glslang::EbvInstanceId: return spv::BuiltInInstanceId; - case glslang::EbvVertexIndex: return spv::BuiltInVertexIndex; - case glslang::EbvInstanceIndex: return spv::BuiltInInstanceIndex; - case glslang::EbvBaseVertex: - addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters); + builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3); builder.addCapability(spv::CapabilityDrawParameters); return spv::BuiltInBaseVertex; case glslang::EbvBaseInstance: - addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters); + builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3); builder.addCapability(spv::CapabilityDrawParameters); return spv::BuiltInBaseInstance; case glslang::EbvDrawId: - addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters); + builder.addIncorporatedExtension(spv::E_SPV_KHR_shader_draw_parameters, spv::Spv_1_3); builder.addCapability(spv::CapabilityDrawParameters); return spv::BuiltInDrawIndex; @@ -567,17 +763,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvTessLevelOuter: return spv::BuiltInTessLevelOuter; case glslang::EbvTessCoord: return spv::BuiltInTessCoord; case glslang::EbvPatchVertices: return spv::BuiltInPatchVertices; - case glslang::EbvFragCoord: return spv::BuiltInFragCoord; - case glslang::EbvPointCoord: return spv::BuiltInPointCoord; - case glslang::EbvFace: return spv::BuiltInFrontFacing; - case glslang::EbvFragDepth: return spv::BuiltInFragDepth; case glslang::EbvHelperInvocation: return spv::BuiltInHelperInvocation; - case glslang::EbvNumWorkGroups: return spv::BuiltInNumWorkgroups; - case glslang::EbvWorkGroupSize: return spv::BuiltInWorkgroupSize; - case glslang::EbvWorkGroupId: return spv::BuiltInWorkgroupId; - case glslang::EbvLocalInvocationId: return spv::BuiltInLocalInvocationId; - case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex; - case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId; case glslang::EbvSubGroupSize: builder.addExtension(spv::E_SPV_KHR_shader_ballot); @@ -592,27 +778,27 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvSubGroupEqMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupEqMaskKHR; + return spv::BuiltInSubgroupEqMask; case glslang::EbvSubGroupGeMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupGeMaskKHR; + return spv::BuiltInSubgroupGeMask; case glslang::EbvSubGroupGtMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupGtMaskKHR; + return spv::BuiltInSubgroupGtMask; case glslang::EbvSubGroupLeMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupLeMaskKHR; + return spv::BuiltInSubgroupLeMask; case glslang::EbvSubGroupLtMask: builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - return spv::BuiltInSubgroupLtMaskKHR; + return spv::BuiltInSubgroupLtMask; case glslang::EbvNumSubgroups: builder.addCapability(spv::CapabilityGroupNonUniform); @@ -654,7 +840,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityGroupNonUniform); builder.addCapability(spv::CapabilityGroupNonUniformBallot); return spv::BuiltInSubgroupLtMask; -#ifdef AMD_EXTENSIONS + case glslang::EbvBaryCoordNoPersp: builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::BuiltInBaryCoordNoPerspAMD; @@ -682,19 +868,27 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvBaryCoordPullModel: builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::BuiltInBaryCoordPullModelAMD; -#endif case glslang::EbvDeviceIndex: - addPre13Extension(spv::E_SPV_KHR_device_group); + builder.addIncorporatedExtension(spv::E_SPV_KHR_device_group, spv::Spv_1_3); builder.addCapability(spv::CapabilityDeviceGroup); return spv::BuiltInDeviceIndex; case glslang::EbvViewIndex: - addPre13Extension(spv::E_SPV_KHR_multiview); + builder.addIncorporatedExtension(spv::E_SPV_KHR_multiview, spv::Spv_1_3); builder.addCapability(spv::CapabilityMultiView); return spv::BuiltInViewIndex; -#ifdef NV_EXTENSIONS + case glslang::EbvFragSizeEXT: + builder.addExtension(spv::E_SPV_EXT_fragment_invocation_density); + builder.addCapability(spv::CapabilityFragmentDensityEXT); + return spv::BuiltInFragSizeEXT; + + case glslang::EbvFragInvocationCountEXT: + builder.addExtension(spv::E_SPV_EXT_fragment_invocation_density); + builder.addCapability(spv::CapabilityFragmentDensityEXT); + return spv::BuiltInFragInvocationCountEXT; + case glslang::EbvViewportMaskNV: if (!memberDeclaration) { builder.addExtension(spv::E_SPV_NV_viewport_array2); @@ -729,7 +923,92 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addExtension(spv::E_SPV_EXT_fragment_fully_covered); builder.addCapability(spv::CapabilityFragmentFullyCoveredEXT); return spv::BuiltInFullyCoveredEXT; -#endif + case glslang::EbvFragmentSizeNV: + builder.addExtension(spv::E_SPV_NV_shading_rate); + builder.addCapability(spv::CapabilityShadingRateNV); + return spv::BuiltInFragmentSizeNV; + case glslang::EbvInvocationsPerPixelNV: + builder.addExtension(spv::E_SPV_NV_shading_rate); + builder.addCapability(spv::CapabilityShadingRateNV); + return spv::BuiltInInvocationsPerPixelNV; + + // ray tracing + case glslang::EbvLaunchIdNV: + return spv::BuiltInLaunchIdNV; + case glslang::EbvLaunchSizeNV: + return spv::BuiltInLaunchSizeNV; + case glslang::EbvWorldRayOriginNV: + return spv::BuiltInWorldRayOriginNV; + case glslang::EbvWorldRayDirectionNV: + return spv::BuiltInWorldRayDirectionNV; + case glslang::EbvObjectRayOriginNV: + return spv::BuiltInObjectRayOriginNV; + case glslang::EbvObjectRayDirectionNV: + return spv::BuiltInObjectRayDirectionNV; + case glslang::EbvRayTminNV: + return spv::BuiltInRayTminNV; + case glslang::EbvRayTmaxNV: + return spv::BuiltInRayTmaxNV; + case glslang::EbvInstanceCustomIndexNV: + return spv::BuiltInInstanceCustomIndexNV; + case glslang::EbvHitTNV: + return spv::BuiltInHitTNV; + case glslang::EbvHitKindNV: + return spv::BuiltInHitKindNV; + case glslang::EbvObjectToWorldNV: + return spv::BuiltInObjectToWorldNV; + case glslang::EbvWorldToObjectNV: + return spv::BuiltInWorldToObjectNV; + case glslang::EbvIncomingRayFlagsNV: + return spv::BuiltInIncomingRayFlagsNV; + + // barycentrics + case glslang::EbvBaryCoordNV: + builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); + builder.addCapability(spv::CapabilityFragmentBarycentricNV); + return spv::BuiltInBaryCoordNV; + case glslang::EbvBaryCoordNoPerspNV: + builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); + builder.addCapability(spv::CapabilityFragmentBarycentricNV); + return spv::BuiltInBaryCoordNoPerspNV; + + // mesh shaders + case glslang::EbvTaskCountNV: + return spv::BuiltInTaskCountNV; + case glslang::EbvPrimitiveCountNV: + return spv::BuiltInPrimitiveCountNV; + case glslang::EbvPrimitiveIndicesNV: + return spv::BuiltInPrimitiveIndicesNV; + case glslang::EbvClipDistancePerViewNV: + return spv::BuiltInClipDistancePerViewNV; + case glslang::EbvCullDistancePerViewNV: + return spv::BuiltInCullDistancePerViewNV; + case glslang::EbvLayerPerViewNV: + return spv::BuiltInLayerPerViewNV; + case glslang::EbvMeshViewCountNV: + return spv::BuiltInMeshViewCountNV; + case glslang::EbvMeshViewIndicesNV: + return spv::BuiltInMeshViewIndicesNV; + + // sm builtins + case glslang::EbvWarpsPerSM: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInWarpsPerSMNV; + case glslang::EbvSMCount: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInSMCountNV; + case glslang::EbvWarpID: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInWarpIDNV; + case glslang::EbvSMID: + builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); + builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); + return spv::BuiltInSMIDNV; +#endif + default: return spv::BuiltInMax; } @@ -740,8 +1019,12 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy { assert(type.getBasicType() == glslang::EbtSampler); +#ifdef GLSLANG_WEB + return spv::ImageFormatUnknown; +#endif + // Check for capabilities - switch (type.getQualifier().layoutFormat) { + switch (type.getQualifier().getFormat()) { case glslang::ElfRg32f: case glslang::ElfRg16f: case glslang::ElfR11fG11fB10f: @@ -778,7 +1061,7 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy } // do the translation - switch (type.getQualifier().layoutFormat) { + switch (type.getQualifier().getFormat()) { case glslang::ElfNone: return spv::ImageFormatUnknown; case glslang::ElfRgba32f: return spv::ImageFormatRgba32f; case glslang::ElfRgba16f: return spv::ImageFormatRgba16f; @@ -843,7 +1126,7 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const g // return a non-0 dependency if the dependency argument must be set spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode, - unsigned int& dependencyLength) const + std::vector& operands) const { spv::LoopControlMask control = spv::LoopControlMaskNone; @@ -855,7 +1138,29 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang: control = control | spv::LoopControlDependencyInfiniteMask; else if (loopNode.getLoopDependency() > 0) { control = control | spv::LoopControlDependencyLengthMask; - dependencyLength = loopNode.getLoopDependency(); + operands.push_back((unsigned int)loopNode.getLoopDependency()); + } + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + if (loopNode.getMinIterations() > 0) { + control = control | spv::LoopControlMinIterationsMask; + operands.push_back(loopNode.getMinIterations()); + } + if (loopNode.getMaxIterations() < glslang::TIntermLoop::iterationsInfinite) { + control = control | spv::LoopControlMaxIterationsMask; + operands.push_back(loopNode.getMaxIterations()); + } + if (loopNode.getIterationMultiple() > 1) { + control = control | spv::LoopControlIterationMultipleMask; + operands.push_back(loopNode.getIterationMultiple()); + } + if (loopNode.getPeelCount() > 0) { + control = control | spv::LoopControlPeelCountMask; + operands.push_back(loopNode.getPeelCount()); + } + if (loopNode.getPartialCount() > 0) { + control = control | spv::LoopControlPartialCountMask; + operands.push_back(loopNode.getPartialCount()); + } } return control; @@ -870,20 +1175,25 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T return spv::StorageClassOutput; if (glslangIntermediate->getSource() != glslang::EShSourceHlsl || - type.getQualifier().storage == glslang::EvqUniform) { - if (type.getBasicType() == glslang::EbtAtomicUint) + type.getQualifier().storage == glslang::EvqUniform) { + if (type.isAtomic()) return spv::StorageClassAtomicCounter; if (type.containsOpaque()) return spv::StorageClassUniformConstant; } + if (type.getQualifier().isUniformOrBuffer() && + type.getQualifier().isShaderRecordNV()) { + return spv::StorageClassShaderRecordBufferNV; + } + if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) { - addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class); + builder.addIncorporatedExtension(spv::E_SPV_KHR_storage_buffer_storage_class, spv::Spv_1_3); return spv::StorageClassStorageBuffer; } if (type.getQualifier().isUniformOrBuffer()) { - if (type.getQualifier().layoutPushConstant) + if (type.getQualifier().isPushConstant()) return spv::StorageClassPushConstant; if (type.getBasicType() == glslang::EbtBlock) return spv::StorageClassUniform; @@ -891,10 +1201,17 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T } switch (type.getQualifier().storage) { - case glslang::EvqShared: return spv::StorageClassWorkgroup; case glslang::EvqGlobal: return spv::StorageClassPrivate; case glslang::EvqConstReadOnly: return spv::StorageClassFunction; case glslang::EvqTemporary: return spv::StorageClassFunction; + case glslang::EvqShared: return spv::StorageClassWorkgroup; +#ifndef GLSLANG_WEB + case glslang::EvqPayloadNV: return spv::StorageClassRayPayloadNV; + case glslang::EvqPayloadInNV: return spv::StorageClassIncomingRayPayloadNV; + case glslang::EvqHitAttrNV: return spv::StorageClassHitAttributeNV; + case glslang::EvqCallableDataNV: return spv::StorageClassCallableDataNV; + case glslang::EvqCallableDataInNV: return spv::StorageClassIncomingCallableDataNV; +#endif default: assert(0); break; @@ -907,14 +1224,16 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType) { +#ifndef GLSLANG_WEB if (indexType.getQualifier().isNonUniform()) { // deal with an asserted non-uniform index + // SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration if (baseType.getBasicType() == glslang::EbtSampler) { if (baseType.getQualifier().hasAttachment()) builder.addCapability(spv::CapabilityInputAttachmentArrayNonUniformIndexingEXT); - else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) + else if (baseType.isImage() && baseType.getSampler().isBuffer()) builder.addCapability(spv::CapabilityStorageTexelBufferArrayNonUniformIndexingEXT); - else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) + else if (baseType.isTexture() && baseType.getSampler().isBuffer()) builder.addCapability(spv::CapabilityUniformTexelBufferArrayNonUniformIndexingEXT); else if (baseType.isImage()) builder.addCapability(spv::CapabilityStorageImageArrayNonUniformIndexingEXT); @@ -929,14 +1248,19 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp } else { // assume a dynamically uniform index if (baseType.getBasicType() == glslang::EbtSampler) { - if (baseType.getQualifier().hasAttachment()) + if (baseType.getQualifier().hasAttachment()) { + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT); - else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) + } else if (baseType.isImage() && baseType.getSampler().isBuffer()) { + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityStorageTexelBufferArrayDynamicIndexingEXT); - else if (baseType.isTexture() && baseType.getSampler().dim == glslang::EsdBuffer) + } else if (baseType.isTexture() && baseType.getSampler().isBuffer()) { + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityUniformTexelBufferArrayDynamicIndexingEXT); + } } } +#endif } // Return whether or not the given type is something that should be tied to a @@ -945,7 +1269,9 @@ bool IsDescriptorResource(const glslang::TType& type) { // uniform and buffer blocks are included, unless it is a push_constant if (type.getBasicType() == glslang::EbtBlock) - return type.getQualifier().isUniformOrBuffer() && ! type.getQualifier().layoutPushConstant; + return type.getQualifier().isUniformOrBuffer() && + ! type.getQualifier().isShaderRecordNV() && + ! type.getQualifier().isPushConstant(); // non block... // basically samplerXXX/subpass/sampler/texture are all included @@ -965,22 +1291,37 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa if (parent.invariant) child.invariant = true; - if (parent.nopersp) - child.nopersp = true; -#ifdef AMD_EXTENSIONS - if (parent.explicitInterp) - child.explicitInterp = true; -#endif if (parent.flat) child.flat = true; if (parent.centroid) child.centroid = true; +#ifndef GLSLANG_WEB + if (parent.nopersp) + child.nopersp = true; + if (parent.explicitInterp) + child.explicitInterp = true; + if (parent.perPrimitiveNV) + child.perPrimitiveNV = true; + if (parent.perViewNV) + child.perViewNV = true; + if (parent.perTaskNV) + child.perTaskNV = true; if (parent.patch) child.patch = true; if (parent.sample) child.sample = true; if (parent.coherent) child.coherent = true; + if (parent.devicecoherent) + child.devicecoherent = true; + if (parent.queuefamilycoherent) + child.queuefamilycoherent = true; + if (parent.workgroupcoherent) + child.workgroupcoherent = true; + if (parent.subgroupcoherent) + child.subgroupcoherent = true; + if (parent.nonprivate) + child.nonprivate = true; if (parent.volatil) child.volatil = true; if (parent.restrict) @@ -989,6 +1330,7 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa child.readonly = true; if (parent.writeonly) child.writeonly = true; +#endif } bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifier& qualifier) @@ -1016,7 +1358,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl sequenceDepth(0), logger(buildLogger), builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger), inEntryPoint(false), entryPointTerminated(false), linkageOnly(false), - glslangIntermediate(glslangIntermediate) + glslangIntermediate(glslangIntermediate), + nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()) { spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage()); @@ -1034,20 +1377,43 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl std::string text; const std::vector& processes = glslangIntermediate->getProcesses(); for (int p = 0; p < (int)processes.size(); ++p) { - if (glslangIntermediate->getSpv().spv < 0x00010100) { + if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_1) { text.append("// OpModuleProcessed "); text.append(processes[p]); text.append("\n"); } else builder.addModuleProcessed(processes[p]); } - if (glslangIntermediate->getSpv().spv < 0x00010100 && (int)processes.size() > 0) + if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_1 && (int)processes.size() > 0) text.append("#line 1\n"); text.append(glslangIntermediate->getSourceText()); builder.setSourceText(text); + // Pass name and text for all included files + const std::map& include_txt = glslangIntermediate->getIncludeText(); + for (auto iItr = include_txt.begin(); iItr != include_txt.end(); ++iItr) + builder.addInclude(iItr->first, iItr->second); } stdBuiltins = builder.import("GLSL.std.450"); - builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450); + + spv::AddressingModel addressingModel = spv::AddressingModelLogical; + spv::MemoryModel memoryModel = spv::MemoryModelGLSL450; + + if (glslangIntermediate->usingPhysicalStorageBuffer()) { + addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT; + builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5); + builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT); + }; + if (glslangIntermediate->usingVulkanMemoryModel()) { + memoryModel = spv::MemoryModelVulkanKHR; + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + builder.addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5); + } + builder.setMemoryModel(addressingModel, memoryModel); + + if (glslangIntermediate->usingVariablePointers()) { + builder.addCapability(spv::CapabilityVariablePointers); + } + shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str()); entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str()); @@ -1069,6 +1435,84 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addCapability(spv::CapabilityShader); break; + case EShLangFragment: + builder.addCapability(spv::CapabilityShader); + if (glslangIntermediate->getPixelCenterInteger()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger); + + if (glslangIntermediate->getOriginUpperLeft()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft); + else + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginLowerLeft); + + if (glslangIntermediate->getEarlyFragmentTests()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests); + + if (glslangIntermediate->getPostDepthCoverage()) { + builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage); + builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage); + builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); + } + + if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); + +#ifndef GLSLANG_WEB + switch(glslangIntermediate->getDepth()) { + case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; + case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; + default: mode = spv::ExecutionModeMax; break; + } + if (mode != spv::ExecutionModeMax) + builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); + switch (glslangIntermediate->getInterlockOrdering()) { + case glslang::EioPixelInterlockOrdered: mode = spv::ExecutionModePixelInterlockOrderedEXT; + break; + case glslang::EioPixelInterlockUnordered: mode = spv::ExecutionModePixelInterlockUnorderedEXT; + break; + case glslang::EioSampleInterlockOrdered: mode = spv::ExecutionModeSampleInterlockOrderedEXT; + break; + case glslang::EioSampleInterlockUnordered: mode = spv::ExecutionModeSampleInterlockUnorderedEXT; + break; + case glslang::EioShadingRateInterlockOrdered: mode = spv::ExecutionModeShadingRateInterlockOrderedEXT; + break; + case glslang::EioShadingRateInterlockUnordered: mode = spv::ExecutionModeShadingRateInterlockUnorderedEXT; + break; + default: mode = spv::ExecutionModeMax; + break; + } + if (mode != spv::ExecutionModeMax) { + builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); + if (mode == spv::ExecutionModeShadingRateInterlockOrderedEXT || + mode == spv::ExecutionModeShadingRateInterlockUnorderedEXT) { + builder.addCapability(spv::CapabilityFragmentShaderShadingRateInterlockEXT); + } else if (mode == spv::ExecutionModePixelInterlockOrderedEXT || + mode == spv::ExecutionModePixelInterlockUnorderedEXT) { + builder.addCapability(spv::CapabilityFragmentShaderPixelInterlockEXT); + } else { + builder.addCapability(spv::CapabilityFragmentShaderSampleInterlockEXT); + } + builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); + } +#endif + break; + + case EShLangCompute: + builder.addCapability(spv::CapabilityShader); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), + glslangIntermediate->getLocalSize(1), + glslangIntermediate->getLocalSize(2)); + if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) { + builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV); + builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); + } else if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupLinear) { + builder.addCapability(spv::CapabilityComputeDerivativeGroupLinearNV); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupLinearNV); + builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); + } + break; +#ifndef GLSLANG_WEB case EShLangTessEvaluation: case EShLangTessControl: builder.addCapability(spv::CapabilityTessellation); @@ -1138,43 +1582,37 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); break; - case EShLangFragment: - builder.addCapability(spv::CapabilityShader); - if (glslangIntermediate->getPixelCenterInteger()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger); - - if (glslangIntermediate->getOriginUpperLeft()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft); - else - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginLowerLeft); - - if (glslangIntermediate->getEarlyFragmentTests()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests); - - if (glslangIntermediate->getPostDepthCoverage()) { - builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage); - builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage); - builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); - } - - switch(glslangIntermediate->getDepth()) { - case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; - case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; - default: mode = spv::ExecutionModeMax; break; - } - if (mode != spv::ExecutionModeMax) - builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); - - if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing()) - builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); + case EShLangRayGenNV: + case EShLangIntersectNV: + case EShLangAnyHitNV: + case EShLangClosestHitNV: + case EShLangMissNV: + case EShLangCallableNV: + builder.addCapability(spv::CapabilityRayTracingNV); + builder.addExtension("SPV_NV_ray_tracing"); break; - - case EShLangCompute: - builder.addCapability(spv::CapabilityShader); + case EShLangTaskNV: + case EShLangMeshNV: + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), glslangIntermediate->getLocalSize(1), glslangIntermediate->getLocalSize(2)); + if (glslangIntermediate->getStage() == EShLangMeshNV) { + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, glslangIntermediate->getPrimitives()); + + switch (glslangIntermediate->getOutputPrimitive()) { + case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break; + case glslang::ElgLines: mode = spv::ExecutionModeOutputLinesNV; break; + case glslang::ElgTriangles: mode = spv::ExecutionModeOutputTrianglesNV; break; + default: mode = spv::ExecutionModeMax; break; + } + if (mode != spv::ExecutionModeMax) + builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); + } break; +#endif default: break; @@ -1184,6 +1622,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl // Finish creating SPV, after the traversal is complete. void TGlslangToSpvTraverser::finishSpv() { + // Finish the entry point function if (! entryPointTerminated) { builder.setBuildPoint(shaderEntry->getLastBlock()); builder.leaveFunction(); @@ -1193,7 +1632,11 @@ void TGlslangToSpvTraverser::finishSpv() for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it) entryPoint->addIdOperand(*it); - builder.eliminateDeadDecorations(); + // Add capabilities, extensions, remove unneeded decorations, etc., + // based on the resulting SPIR-V. + // Note: WebGPU code generation must have the opportunity to aggressively + // prune unreachable merge blocks and continue targets. + builder.postProcess(); } // Write the SPV into 'out'. @@ -1220,6 +1663,9 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector& out) void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) { SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); + if (symbol->getType().isStruct()) + glslangTypeToIdMap[symbol->getType().getStruct()] = symbol->getId(); + if (symbol->getType().getQualifier().isSpecConstant()) spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); @@ -1227,13 +1673,27 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) // Formal function parameters were mapped during makeFunctions(). spv::Id id = getSymbolId(symbol); - // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction if (builder.isPointer(id)) { - spv::StorageClass sc = builder.getStorageClass(id); - if (sc == spv::StorageClassInput || sc == spv::StorageClassOutput) { - if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) + // Include all "static use" and "linkage only" interface variables on the OpEntryPoint instruction + // Consider adding to the OpEntryPoint interface list. + // Only looking at structures if they have at least one member. + if (!symbol->getType().isStruct() || symbol->getType().getStruct()->size() > 0) { + spv::StorageClass sc = builder.getStorageClass(id); + // Before SPIR-V 1.4, we only want to include Input and Output. + // Starting with SPIR-V 1.4, we want all globals. + if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && sc != spv::StorageClassFunction) || + (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) { iOSet.insert(id); + } } + + // If the SPIR-V type is required to be different than the AST type, + // translate now from the SPIR-V type to the AST type, for the consuming + // operation. + // Note this turns it from an l-value to an r-value. + // Currently, all symbols needing this are inputs; avoid the map lookup when non-input. + if (symbol->getType().getQualifier().storage == glslang::EvqVaryingIn) + id = translateForcedType(id); } // Only process non-linkage-only nodes for generating actual static uses @@ -1251,13 +1711,16 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) // See comments in handleUserFunctionCall(). // B) Specialization constants (normal constants don't even come in as a variable), // These are also pure R-values. + // C) R-Values from type translation, see above call to translateForcedType() glslang::TQualifier qualifier = symbol->getQualifier(); - if (qualifier.isSpecConstant() || rValueParameters.find(symbol->getId()) != rValueParameters.end()) + if (qualifier.isSpecConstant() || rValueParameters.find(symbol->getId()) != rValueParameters.end() || + !builder.isPointerType(builder.getTypeId(id))) builder.setAccessChainRValue(id); else builder.setAccessChainLValue(id); } +#ifdef ENABLE_HLSL // Process linkage-only nodes for any special additional interface work. if (linkageOnly) { if (glslangIntermediate->getHlslFunctionality1()) { @@ -1289,11 +1752,18 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) } } } +#endif } bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node) { - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); + if (node->getLeft()->getAsSymbolNode() != nullptr && node->getLeft()->getType().isStruct()) { + glslangTypeToIdMap[node->getLeft()->getType().getStruct()] = node->getLeft()->getAsSymbolNode()->getId(); + } + if (node->getRight()->getAsSymbolNode() != nullptr && node->getRight()->getType().isStruct()) { + glslangTypeToIdMap[node->getRight()->getType().getStruct()] = node->getRight()->getAsSymbolNode()->getId(); + } SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); if (node->getType().getQualifier().isSpecConstant()) @@ -1350,7 +1820,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // store the result builder.setAccessChain(lValue); - multiTypeStore(node->getType(), rValue); + multiTypeStore(node->getLeft()->getType(), rValue); // assignments are expressions having an rValue after they are evaluated... builder.clearAccessChain(); @@ -1360,6 +1830,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T case glslang::EOpIndexDirect: case glslang::EOpIndexDirectStruct: { + // Structure, array, matrix, or vector indirection with statically known index. // Get the left part of the access chain. node->getLeft()->traverse(this); @@ -1373,21 +1844,40 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // so short circuit the access-chain stuff with a swizzle. std::vector swizzle; swizzle.push_back(glslangIndex); - builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType())); + int dummySize; + builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), + TranslateCoherent(node->getLeft()->getType()), + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); } else { + + // Load through a block reference is performed with a dot operator that + // is mapped to EOpIndexDirectStruct. When we get to the actual reference, + // do a load and reset the access chain. + if (node->getLeft()->isReference() && + !node->getLeft()->getType().isArray() && + node->getOp() == glslang::EOpIndexDirectStruct) + { + spv::Id left = accessChainLoad(node->getLeft()->getType()); + builder.clearAccessChain(); + builder.setAccessChainLValue(left); + } + int spvIndex = glslangIndex; if (node->getLeft()->getBasicType() == glslang::EbtBlock && node->getOp() == glslang::EOpIndexDirectStruct) { // This may be, e.g., an anonymous block-member selection, which generally need // index remapping due to hidden members in anonymous blocks. - std::vector& remapper = memberRemapper[node->getLeft()->getType().getStruct()]; - assert(remapper.size() > 0); - spvIndex = remapper[glslangIndex]; + int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; + if (memberRemapper.find(glslangId) != memberRemapper.end()) { + std::vector& remapper = memberRemapper[glslangId]; + assert(remapper.size() > 0); + spvIndex = remapper[glslangIndex]; + } } // normal case for indexing array or structure or block - builder.accessChainPush(builder.makeIntConstant(spvIndex)); + builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment()); // Add capabilities here for accessing PointSize and clip/cull distance. // We have deferred generation of associated capabilities until now. @@ -1398,8 +1888,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T return false; case glslang::EOpIndexIndirect: { - // Structure or array or vector indirection. - // Will use native SPIR-V access-chain for struct and array indirection; + // Array, matrix, or vector indirection with variable index. + // Will use native SPIR-V access-chain for and array indirection; // matrices are arrays of vectors, so will also work for a matrix. // Will use the access chain's 'component' for variable index into a vector. @@ -1420,10 +1910,13 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // restore the saved access chain builder.setAccessChain(partial); - if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) - builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType())); - else - builder.accessChainPush(index); + if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) { + int dummySize; + builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()), + TranslateCoherent(node->getLeft()->getType()), + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + } else + builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment()); } return false; case glslang::EOpVectorSwizzle: @@ -1431,7 +1924,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T node->getLeft()->traverse(this); std::vector swizzle; convertSwizzle(*node->getRight()->getAsAggregate(), swizzle); - builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType())); + int dummySize; + builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), + TranslateCoherent(node->getLeft()->getType()), + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); } return false; case glslang::EOpMatrixSwizzle: @@ -1486,9 +1982,74 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T } } +// Figure out what, if any, type changes are needed when accessing a specific built-in. +// Returns . +// Also see comment for 'forceType', regarding tracking SPIR-V-required types. +std::pair TGlslangToSpvTraverser::getForcedType(spv::BuiltIn builtIn, + const glslang::TType& glslangType) +{ + switch(builtIn) + { + case spv::BuiltInSubgroupEqMask: + case spv::BuiltInSubgroupGeMask: + case spv::BuiltInSubgroupGtMask: + case spv::BuiltInSubgroupLeMask: + case spv::BuiltInSubgroupLtMask: { + // these require changing a 64-bit scaler -> a vector of 32-bit components + if (glslangType.isVector()) + break; + std::pair ret(builder.makeVectorType(builder.makeUintType(32), 4), + builder.makeUintType(64)); + return ret; + } + default: + break; + } + + std::pair ret(spv::NoType, spv::NoType); + return ret; +} + +// For an object previously identified (see getForcedType() and forceType) +// as needing type translations, do the translation needed for a load, turning +// an L-value into in R-value. +spv::Id TGlslangToSpvTraverser::translateForcedType(spv::Id object) +{ + const auto forceIt = forceType.find(object); + if (forceIt == forceType.end()) + return object; + + spv::Id desiredTypeId = forceIt->second; + spv::Id objectTypeId = builder.getTypeId(object); + assert(builder.isPointerType(objectTypeId)); + objectTypeId = builder.getContainedTypeId(objectTypeId); + if (builder.isVectorType(objectTypeId) && + builder.getScalarTypeWidth(builder.getContainedTypeId(objectTypeId)) == 32) { + if (builder.getScalarTypeWidth(desiredTypeId) == 64) { + // handle 32-bit v.xy* -> 64-bit + builder.clearAccessChain(); + builder.setAccessChainLValue(object); + object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, objectTypeId); + std::vector components; + components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 0)); + components.push_back(builder.createCompositeExtract(object, builder.getContainedTypeId(objectTypeId), 1)); + + spv::Id vecType = builder.makeVectorType(builder.getContainedTypeId(objectTypeId), 2); + return builder.createUnaryOp(spv::OpBitcast, desiredTypeId, + builder.createCompositeConstruct(vecType, components)); + } else { + logger->missingFunctionality("forcing 32-bit vector type to non 64-bit scalar"); + } + } else { + logger->missingFunctionality("forcing non 32-bit vector type"); + } + + return object; +} + bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TIntermUnary* node) { - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); if (node->getType().getQualifier().isSpecConstant()) @@ -1519,10 +2080,31 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // So, this has to be block.lastMember.length(). // SPV wants "block" and member number as the operands, go get them. - glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); - block->traverse(this); - unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst(); - spv::Id length = builder.createArrayLength(builder.accessChainGetLValue(), member); + spv::Id length; + if (node->getOperand()->getType().isCoopMat()) { + spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); + + spv::Id typeId = convertGlslangToSpvType(node->getOperand()->getType()); + assert(builder.isCooperativeMatrixType(typeId)); + + length = builder.createCooperativeMatrixLength(typeId); + } else { + glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); + block->traverse(this); + unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst(); + length = builder.createArrayLength(builder.accessChainGetLValue(), member); + } + + // GLSL semantics say the result of .length() is an int, while SPIR-V says + // signedness must be 0. So, convert from SPIR-V unsigned back to GLSL's + // AST expectation of a signed result. + if (glslangIntermediate->getSource() == glslang::EShSourceGlsl) { + if (builder.isInSpecConstCodeGenMode()) { + length = builder.createBinOp(spv::OpIAdd, builder.makeIntType(32), length, builder.makeIntConstant(0)); + } else { + length = builder.createUnaryOp(spv::OpBitcast, builder.makeIntType(32), length); + } + } builder.clearAccessChain(); builder.setAccessChainRValue(length); @@ -1540,20 +2122,31 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI invertedType = getInvertedSwizzleType(*node->getOperand()); builder.clearAccessChain(); + TIntermNode *operandNode; if (invertedType != spv::NoType) - node->getOperand()->getAsBinaryNode()->getLeft()->traverse(this); + operandNode = node->getOperand()->getAsBinaryNode()->getLeft(); else - node->getOperand()->traverse(this); + operandNode = node->getOperand(); + + operandNode->traverse(this); spv::Id operand = spv::NoResult; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + +#ifndef GLSLANG_WEB if (node->getOp() == glslang::EOpAtomicCounterIncrement || node->getOp() == glslang::EOpAtomicCounterDecrement || node->getOp() == glslang::EOpAtomicCounter || - node->getOp() == glslang::EOpInterpolateAtCentroid) + node->getOp() == glslang::EOpInterpolateAtCentroid) { operand = builder.accessChainGetLValue(); // Special case l-value operands - else + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); + } else +#endif + { operand = accessChainLoad(node->getOperand()->getType()); + } OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), TranslateNoContractionDecoration(node->getType().getQualifier()), @@ -1565,12 +2158,12 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // if not, then possibly an operation if (! result) - result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType()); + result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType(), lvalueCoherentFlags); if (result) { if (invertedType) { result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); } builder.clearAccessChain(); @@ -1590,6 +2183,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI spv::Id one = 0; if (node->getBasicType() == glslang::EbtFloat) one = builder.makeFloatConstant(1.0F); +#ifndef GLSLANG_WEB else if (node->getBasicType() == glslang::EbtDouble) one = builder.makeDoubleConstant(1.0); else if (node->getBasicType() == glslang::EbtFloat16) @@ -1600,6 +2194,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI one = builder.makeInt16Constant(1); else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64) one = builder.makeInt64Constant(1); +#endif else one = builder.makeIntConstant(1); glslang::TOperator op; @@ -1627,12 +2222,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI return false; +#ifndef GLSLANG_WEB case glslang::EOpEmitStreamVertex: builder.createNoResultOp(spv::OpEmitStreamVertex, operand); return false; case glslang::EOpEndStreamPrimitive: builder.createNoResultOp(spv::OpEndStreamPrimitive, operand); return false; +#endif default: logger->missingFunctionality("unknown glslang unary"); @@ -1640,6 +2237,39 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI } } +// Construct a composite object, recursively copying members if their types don't match +spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, std::vector constituents) +{ + for (int c = 0; c < (int)constituents.size(); ++c) { + spv::Id& constituent = constituents[c]; + spv::Id lType = builder.getContainedTypeId(resultTypeId, c); + spv::Id rType = builder.getTypeId(constituent); + if (lType != rType) { + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + constituent = builder.createUnaryOp(spv::OpCopyLogical, lType, constituent); + } else if (builder.isStructType(rType)) { + std::vector rTypeConstituents; + int numrTypeConstituents = builder.getNumTypeConstituents(rType); + for (int i = 0; i < numrTypeConstituents; ++i) { + rTypeConstituents.push_back(builder.createCompositeExtract(constituent, builder.getContainedTypeId(rType, i), i)); + } + constituents[c] = createCompositeConstruct(lType, rTypeConstituents); + } else { + assert(builder.isArrayType(rType)); + std::vector rTypeConstituents; + int numrTypeConstituents = builder.getNumTypeConstituents(rType); + + spv::Id elementRType = builder.getContainedTypeId(rType); + for (int i = 0; i < numrTypeConstituents; ++i) { + rTypeConstituents.push_back(builder.createCompositeExtract(constituent, elementRType, i)); + } + constituents[c] = createCompositeConstruct(lType, rTypeConstituents); + } + } + } + return builder.createCompositeConstruct(resultTypeId, constituents); +} + bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TIntermAggregate* node) { SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); @@ -1657,14 +2287,15 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.setAccessChainRValue(result); return false; -#ifdef AMD_EXTENSIONS - } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) { -#else - } else if (node->getOp() == glslang::EOpImageStore) { -#endif + } +#ifndef GLSLANG_WEB + else if (node->getOp() == glslang::EOpImageStore || + node->getOp() == glslang::EOpImageStoreLod || + node->getOp() == glslang::EOpImageAtomicStore) { // "imageStore" is a special case, which has no result return false; } +#endif glslang::TOperator binOp = glslang::EOpNull; bool reduceComparison = true; @@ -1672,6 +2303,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt bool noReturnValue = false; bool atomic = false; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + assert(node->getOp()); spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); @@ -1746,7 +2379,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt return false; case glslang::EOpFunctionCall: { - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); if (node->isUserDefined()) result = handleUserFunctionCall(node); // assert(result); // this can happen for bad shaders because the call graph completeness checking is not yet done @@ -1864,18 +2497,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpConstructU64Vec4: case glslang::EOpConstructStruct: case glslang::EOpConstructTextureSampler: + case glslang::EOpConstructReference: + case glslang::EOpConstructCooperativeMatrix: { - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); std::vector arguments; - translateArguments(*node, arguments); + translateArguments(*node, arguments, lvalueCoherentFlags); spv::Id constructed; if (node->getOp() == glslang::EOpConstructTextureSampler) constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments); - else if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) { + else if (node->getOp() == glslang::EOpConstructStruct || + node->getOp() == glslang::EOpConstructCooperativeMatrix || + node->getType().isArray()) { std::vector constituents; for (int c = 0; c < (int)arguments.size(); ++c) constituents.push_back(arguments[c]); - constructed = builder.createCompositeConstruct(resultType(), constituents); + constructed = createCompositeConstruct(resultType(), constituents); } else if (isMatrix) constructed = builder.createMatrixConstructor(precision, arguments, resultType()); else @@ -1928,6 +2565,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // which can be emitted by the one in createBinaryOperation() binOp = glslang::EOpMod; break; + case glslang::EOpEmitVertex: case glslang::EOpEndPrimitive: case glslang::EOpBarrier: @@ -1962,6 +2600,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt atomic = true; break; +#ifndef GLSLANG_WEB + case glslang::EOpAtomicStore: + noReturnValue = true; + // fallthrough + case glslang::EOpAtomicLoad: + atomic = true; + break; + case glslang::EOpAtomicCounterAdd: case glslang::EOpAtomicCounterSubtract: case glslang::EOpAtomicCounterMin: @@ -1976,6 +2622,35 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt atomic = true; break; + case glslang::EOpAbsDifference: + case glslang::EOpAddSaturate: + case glslang::EOpSubSaturate: + case glslang::EOpAverage: + case glslang::EOpAverageRounded: + case glslang::EOpMul32x16: + builder.addCapability(spv::CapabilityIntegerFunctions2INTEL); + builder.addExtension("SPV_INTEL_shader_integer_functions2"); + binOp = node->getOp(); + break; + + case glslang::EOpIgnoreIntersectionNV: + case glslang::EOpTerminateRayNV: + case glslang::EOpTraceNV: + case glslang::EOpExecuteCallableNV: + case glslang::EOpWritePackedPrimitiveIndices4x8NV: + noReturnValue = true; + break; + case glslang::EOpCooperativeMatrixLoad: + case glslang::EOpCooperativeMatrixStore: + noReturnValue = true; + break; + case glslang::EOpBeginInvocationInterlock: + case glslang::EOpEndInvocationInterlock: + builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); + noReturnValue = true; + break; +#endif + default: break; } @@ -1996,7 +2671,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt right->traverse(this); spv::Id rightId = accessChainLoad(right->getType()); - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); OpDecorations decorations = { precision, TranslateNoContractionDecoration(node->getType().getQualifier()), TranslateNonUniformDecoration(node->getType().getQualifier()) }; @@ -2017,20 +2692,36 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // glslang::TIntermSequence& glslangOperands = node->getSequence(); std::vector operands; + std::vector memoryAccessOperands; for (int arg = 0; arg < (int)glslangOperands.size(); ++arg) { // special case l-value operands; there are just a few bool lvalue = false; switch (node->getOp()) { - case glslang::EOpFrexp: case glslang::EOpModf: if (arg == 1) lvalue = true; break; + + case glslang::EOpAtomicAdd: + case glslang::EOpAtomicMin: + case glslang::EOpAtomicMax: + case glslang::EOpAtomicAnd: + case glslang::EOpAtomicOr: + case glslang::EOpAtomicXor: + case glslang::EOpAtomicExchange: + case glslang::EOpAtomicCompSwap: + if (arg == 0) + lvalue = true; + break; + +#ifndef GLSLANG_WEB + case glslang::EOpFrexp: + if (arg == 1) + lvalue = true; + break; case glslang::EOpInterpolateAtSample: case glslang::EOpInterpolateAtOffset: -#ifdef AMD_EXTENSIONS case glslang::EOpInterpolateAtVertex: -#endif if (arg == 0) { lvalue = true; @@ -2041,14 +2732,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); } break; - case glslang::EOpAtomicAdd: - case glslang::EOpAtomicMin: - case glslang::EOpAtomicMax: - case glslang::EOpAtomicAnd: - case glslang::EOpAtomicOr: - case glslang::EOpAtomicXor: - case glslang::EOpAtomicExchange: - case glslang::EOpAtomicCompSwap: + case glslang::EOpAtomicLoad: + case glslang::EOpAtomicStore: case glslang::EOpAtomicCounterAdd: case glslang::EOpAtomicCounterSubtract: case glslang::EOpAtomicCounterMin: @@ -2071,6 +2756,15 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (arg >= 2) lvalue = true; break; + case glslang::EOpCooperativeMatrixLoad: + if (arg == 0 || arg == 1) + lvalue = true; + break; + case glslang::EOpCooperativeMatrixStore: + if (arg == 1) + lvalue = true; + break; +#endif default: break; } @@ -2079,18 +2773,95 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt glslangOperands[0]->getAsBinaryNode()->getLeft()->traverse(this); else glslangOperands[arg]->traverse(this); - if (lvalue) + +#ifndef GLSLANG_WEB + if (node->getOp() == glslang::EOpCooperativeMatrixLoad || + node->getOp() == glslang::EOpCooperativeMatrixStore) { + + if (arg == 1) { + // fold "element" parameter into the access chain + spv::Builder::AccessChain save = builder.getAccessChain(); + builder.clearAccessChain(); + glslangOperands[2]->traverse(this); + + spv::Id elementId = accessChainLoad(glslangOperands[2]->getAsTyped()->getType()); + + builder.setAccessChain(save); + + // Point to the first element of the array. + builder.accessChainPush(elementId, TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()), + glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment()); + + spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; + unsigned int alignment = builder.getAccessChain().alignment; + + int memoryAccess = TranslateMemoryAccess(coherentFlags); + if (node->getOp() == glslang::EOpCooperativeMatrixLoad) + memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask; + if (node->getOp() == glslang::EOpCooperativeMatrixStore) + memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask; + if (builder.getStorageClass(builder.getAccessChain().base) == spv::StorageClassPhysicalStorageBufferEXT) { + memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + } + + memoryAccessOperands.push_back(spv::IdImmediate(false, memoryAccess)); + + if (memoryAccess & spv::MemoryAccessAlignedMask) { + memoryAccessOperands.push_back(spv::IdImmediate(false, alignment)); + } + + if (memoryAccess & (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) { + memoryAccessOperands.push_back(spv::IdImmediate(true, builder.makeUintConstant(TranslateMemoryScope(coherentFlags)))); + } + } else if (arg == 2) { + continue; + } + } +#endif + + if (lvalue) { operands.push_back(builder.accessChainGetLValue()); - else { - builder.setLine(node->getLoc().line); + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()); + } else { + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); } } - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); +#ifndef GLSLANG_WEB + if (node->getOp() == glslang::EOpCooperativeMatrixLoad) { + std::vector idImmOps; + + idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end()); + // get the pointee type + spv::Id typeId = builder.getContainedTypeId(builder.getTypeId(operands[0])); + assert(builder.isCooperativeMatrixType(typeId)); + // do the op + spv::Id result = builder.createOp(spv::OpCooperativeMatrixLoadNV, typeId, idImmOps); + // store the result to the pointer (out param 'm') + builder.createStore(result, operands[0]); + result = 0; + } else if (node->getOp() == glslang::EOpCooperativeMatrixStore) { + std::vector idImmOps; + + idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf + idImmOps.push_back(spv::IdImmediate(true, operands[0])); // object + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end()); + + builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps); + result = 0; + } else +#endif if (atomic) { // Handle all atomics - result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); + result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); } else { // Pass through to generic operations. switch (glslangOperands.size()) { @@ -2105,7 +2876,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = createUnaryOperation( node->getOp(), decorations, resultType(), operands.front(), - glslangOperands[0]->getAsTyped()->getBasicType()); + glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags); } break; default: @@ -2140,6 +2911,19 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // next layer copies r-values into memory to use the access-chain mechanism bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang::TIntermSelection* node) { + // see if OpSelect can handle it + const auto isOpSelectable = [&]() { + if (node->getBasicType() == glslang::EbtVoid) + return false; + // OpSelect can do all other types starting with SPV 1.4 + if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_4) { + // pre-1.4, only scalars and vectors can be handled + if ((!node->getType().isScalar() && !node->getType().isVector())) + return false; + } + return true; + }; + // See if it simple and safe, or required, to execute both sides. // Crucially, side effects must be either semantically required or avoided, // and there are performance trade-offs. @@ -2158,9 +2942,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // if not required to execute both, decide based on performance/practicality... - // see if OpSelect can handle it - if ((!node->getType().isScalar() && !node->getType().isVector()) || - node->getBasicType() == glslang::EbtVoid) + if (!isOpSelectable()) return false; assert(node->getType() == node->getTrueBlock() ->getAsTyped()->getType() && @@ -2188,7 +2970,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang node->getFalseBlock()->traverse(this); spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()); - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); // done if void if (node->getBasicType() == glslang::EbtVoid) @@ -2197,14 +2979,16 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // emit code to select between trueValue and falseValue // see if OpSelect can handle it - if (node->getType().isScalar() || node->getType().isVector()) { + if (isOpSelectable()) { // Emit OpSelect for this selection. // smear condition to vector, if necessary (AST is always scalar) - if (builder.isVector(trueValue)) + // Before 1.4, smear like for mix(), starting with 1.4, keep it scalar + if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_4 && builder.isVector(trueValue)) { condition = builder.smearScalar(spv::NoPrecision, condition, builder.makeVectorType(builder.makeBoolType(), builder.getNumComponents(trueValue))); + } // OpSelect result = builder.createTriOp(spv::OpSelect, @@ -2353,8 +3137,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn builder.createBranch(&blocks.head); // Loop control: - unsigned int dependencyLength = glslang::TIntermLoop::dependencyInfinite; - const spv::LoopControlMask control = TranslateLoopControl(*node, dependencyLength); + std::vector operands; + const spv::LoopControlMask control = TranslateLoopControl(*node, operands); // Spec requires back edges to target header blocks, and every header block // must dominate its merge block. Make a header block first to ensure these @@ -2362,9 +3146,9 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn // by a block-ending branch. But we don't want to put any other body/test // instructions in it, since the body/test may have arbitrary instructions, // including merges of its own. - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); builder.setBuildPoint(&blocks.head); - builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, dependencyLength); + builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, operands); if (node->testFirst() && node->getTest()) { spv::Block& test = builder.makeNewBlock(); builder.createBranch(&test); @@ -2386,7 +3170,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn node->getTerminal()->traverse(this); builder.createBranch(&blocks.head); } else { - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); builder.createBranch(&blocks.body); breakForLoop.push(true); @@ -2421,7 +3205,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T if (node->getExpression()) node->getExpression()->traverse(this); - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); switch (node->getFlowOp()) { case glslang::EOpKill: @@ -2454,6 +3238,14 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T builder.clearAccessChain(); break; +#ifndef GLSLANG_WEB + case glslang::EOpDemote: + builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT); + builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); + builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT); + break; +#endif + default: assert(0); break; @@ -2462,49 +3254,73 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T return false; } -spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* node) +spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* node, spv::Id forcedType) { // First, steer off constants, which are not SPIR-V variables, but // can still have a mapping to a SPIR-V Id. // This includes specialization constants. if (node->getQualifier().isConstant()) { - return createSpvConstant(*node); + spv::Id result = createSpvConstant(*node); + if (result != spv::NoResult) + return result; } // Now, handle actual variables spv::StorageClass storageClass = TranslateStorageClass(node->getType()); - spv::Id spvType = convertGlslangToSpvType(node->getType()); + spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType()) + : forcedType; - const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) || - node->getType().containsBasicType(glslang::EbtInt16) || - node->getType().containsBasicType(glslang::EbtUint16); + const bool contains16BitType = node->getType().contains16BitFloat() || + node->getType().contains16BitInt(); if (contains16BitType) { switch (storageClass) { case spv::StorageClassInput: case spv::StorageClassOutput: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); builder.addCapability(spv::CapabilityStorageInputOutput16); break; - case spv::StorageClassPushConstant: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); - builder.addCapability(spv::CapabilityStoragePushConstant16); - break; case spv::StorageClassUniform: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); if (node->getType().getQualifier().storage == glslang::EvqBuffer) builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); else builder.addCapability(spv::CapabilityStorageUniform16); break; +#ifndef GLSLANG_WEB + case spv::StorageClassPushConstant: + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); + builder.addCapability(spv::CapabilityStoragePushConstant16); + break; case spv::StorageClassStorageBuffer: - addPre13Extension(spv::E_SPV_KHR_16bit_storage); + case spv::StorageClassPhysicalStorageBufferEXT: + builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); break; +#endif default: + if (node->getType().contains16BitFloat()) + builder.addCapability(spv::CapabilityFloat16); + if (node->getType().contains16BitInt()) + builder.addCapability(spv::CapabilityInt16); break; } } + if (node->getType().contains8BitInt()) { + if (storageClass == spv::StorageClassPushConstant) { + builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); + builder.addCapability(spv::CapabilityStoragePushConstant8); + } else if (storageClass == spv::StorageClassUniform) { + builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); + builder.addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess); + } else if (storageClass == spv::StorageClassStorageBuffer) { + builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); + builder.addCapability(spv::CapabilityStorageBuffer8BitAccess); + } else { + builder.addCapability(spv::CapabilityInt8); + } + } + const char* name = node->getName().c_str(); if (glslang::IsAnonymous(name)) name = ""; @@ -2516,15 +3332,15 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) { switch (sampler.type) { + case glslang::EbtInt: return builder.makeIntType(32); + case glslang::EbtUint: return builder.makeUintType(32); case glslang::EbtFloat: return builder.makeFloatType(32); -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB case glslang::EbtFloat16: builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch); builder.addCapability(spv::CapabilityFloat16ImageAMD); return builder.makeFloatType(16); #endif - case glslang::EbtInt: return builder.makeIntType(32); - case glslang::EbtUint: return builder.makeUintType(32); default: assert(0); return builder.makeFloatType(32); @@ -2563,16 +3379,17 @@ void TGlslangToSpvTraverser::convertSwizzle(const glslang::TIntermAggregate& nod // Convert from a glslang type to an SPV type, by calling into a // recursive version of this function. This establishes the inherited // layout state rooted from the top-level type. -spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type) +spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly) { - return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false); + return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false, forwardReferenceOnly); } // Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id. // explicitLayout can be kept the same throughout the hierarchical recursive walk. // Mutually recursive with convertGlslangStructToSpvType(). spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, - glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, bool lastBufferBlockMember) + glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, + bool lastBufferBlockMember, bool forwardReferenceOnly) { spv::Id spvType = spv::NoResult; @@ -2581,20 +3398,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spvType = builder.makeVoidType(); assert (! type.isArray()); break; - case glslang::EbtFloat: - spvType = builder.makeFloatType(32); - break; - case glslang::EbtDouble: - spvType = builder.makeFloatType(64); - break; - case glslang::EbtFloat16: - builder.addCapability(spv::CapabilityFloat16); -#if AMD_EXTENSIONS - if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3) - builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif - spvType = builder.makeFloatType(16); - break; case glslang::EbtBool: // "transparent" bool doesn't exist in SPIR-V. The GLSL convention is // a 32-bit int where non-0 means true. @@ -2603,36 +3406,34 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty else spvType = builder.makeBoolType(); break; - case glslang::EbtInt8: - builder.addCapability(spv::CapabilityInt8); - spvType = builder.makeIntType(8); - break; - case glslang::EbtUint8: - builder.addCapability(spv::CapabilityInt8); - spvType = builder.makeUintType(8); - break; - case glslang::EbtInt16: - builder.addCapability(spv::CapabilityInt16); -#ifdef AMD_EXTENSIONS - if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3) - builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16); -#endif - spvType = builder.makeIntType(16); - break; - case glslang::EbtUint16: - builder.addCapability(spv::CapabilityInt16); -#ifdef AMD_EXTENSIONS - if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3) - builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16); -#endif - spvType = builder.makeUintType(16); - break; case glslang::EbtInt: spvType = builder.makeIntType(32); break; case glslang::EbtUint: spvType = builder.makeUintType(32); break; + case glslang::EbtFloat: + spvType = builder.makeFloatType(32); + break; +#ifndef GLSLANG_WEB + case glslang::EbtDouble: + spvType = builder.makeFloatType(64); + break; + case glslang::EbtFloat16: + spvType = builder.makeFloatType(16); + break; + case glslang::EbtInt8: + spvType = builder.makeIntType(8); + break; + case glslang::EbtUint8: + spvType = builder.makeUintType(8); + break; + case glslang::EbtInt16: + spvType = builder.makeIntType(16); + break; + case glslang::EbtUint16: + spvType = builder.makeUintType(16); + break; case glslang::EbtInt64: spvType = builder.makeIntType(64); break; @@ -2643,17 +3444,38 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty builder.addCapability(spv::CapabilityAtomicStorage); spvType = builder.makeUintType(32); break; + case glslang::EbtAccStructNV: + spvType = builder.makeAccelerationStructureNVType(); + break; + case glslang::EbtReference: + { + // Make the forward pointer, then recurse to convert the structure type, then + // patch up the forward pointer with a real pointer type. + if (forwardPointers.find(type.getReferentType()) == forwardPointers.end()) { + spv::Id forwardId = builder.makeForwardPointer(spv::StorageClassPhysicalStorageBufferEXT); + forwardPointers[type.getReferentType()] = forwardId; + } + spvType = forwardPointers[type.getReferentType()]; + if (!forwardReferenceOnly) { + spv::Id referentType = convertGlslangToSpvType(*type.getReferentType()); + builder.makePointerFromForwardPointer(spv::StorageClassPhysicalStorageBufferEXT, + forwardPointers[type.getReferentType()], + referentType); + } + } + break; +#endif case glslang::EbtSampler: { const glslang::TSampler& sampler = type.getSampler(); - if (sampler.sampler) { - // pure sampler + if (sampler.isPureSampler()) { spvType = builder.makeSamplerType(); } else { // an image is present, make its type - spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms, - sampler.image ? 2 : 1, TranslateImageFormat(type)); - if (sampler.combined) { + spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), + sampler.isShadow(), sampler.isArrayed(), sampler.isMultiSample(), + sampler.isImageClass() ? 2 : 1, TranslateImageFormat(type)); + if (sampler.isCombined()) { // already has both image and sampler, make the combined type spvType = builder.makeSampledImageType(spvType); } @@ -2675,7 +3497,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // else, we haven't seen it... if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangMembers].resize(glslangMembers->size()); + memberRemapper[glslangTypeToIdMap[glslangMembers]].resize(glslangMembers->size()); spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier); } break; @@ -2692,6 +3514,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spvType = builder.makeVectorType(spvType, type.getVectorSize()); } + if (type.isCoopMat()) { + builder.addCapability(spv::CapabilityCooperativeMatrixNV); + builder.addExtension(spv::E_SPV_NV_cooperative_matrix); + if (type.getBasicType() == glslang::EbtFloat16) + builder.addCapability(spv::CapabilityFloat16); + if (type.getBasicType() == glslang::EbtUint8 || + type.getBasicType() == glslang::EbtInt8) { + builder.addCapability(spv::CapabilityInt8); + } + + spv::Id scope = makeArraySizeId(*type.getTypeParameters(), 1); + spv::Id rows = makeArraySizeId(*type.getTypeParameters(), 2); + spv::Id cols = makeArraySizeId(*type.getTypeParameters(), 3); + + spvType = builder.makeCooperativeMatrixType(spvType, scope, rows, cols); + } + if (type.isArray()) { int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride @@ -2730,10 +3569,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty if (type.isSizedArray()) spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride); else { +#ifndef GLSLANG_WEB if (!lastBufferBlockMember) { - builder.addExtension("SPV_EXT_descriptor_indexing"); + builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT); } +#endif spvType = builder.makeRuntimeArray(spvType); } if (stride > 0) @@ -2749,23 +3590,28 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member) { +#ifndef GLSLANG_WEB auto& extensions = glslangIntermediate->getRequestedExtensions(); - if (member.getFieldName() == "gl_ViewportMask" && - extensions.find("GL_NV_viewport_array2") == extensions.end()) - return true; if (member.getFieldName() == "gl_SecondaryViewportMaskNV" && extensions.find("GL_NV_stereo_view_rendering") == extensions.end()) return true; if (member.getFieldName() == "gl_SecondaryPositionNV" && extensions.find("GL_NV_stereo_view_rendering") == extensions.end()) return true; - if (member.getFieldName() == "gl_PositionPerViewNV" && - extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end()) - return true; - if (member.getFieldName() == "gl_ViewportMaskPerViewNV" && - extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end()) - return true; + + if (glslangIntermediate->getStage() != EShLangMeshNV) { + if (member.getFieldName() == "gl_ViewportMask" && + extensions.find("GL_NV_viewport_array2") == extensions.end()) + return true; + if (member.getFieldName() == "gl_PositionPerViewNV" && + extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end()) + return true; + if (member.getFieldName() == "gl_ViewportMaskPerViewNV" && + extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end()) + return true; + } +#endif return false; }; @@ -2781,17 +3627,21 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy // Create a vector of struct types for SPIR-V to consume std::vector spvMembers; int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks + std::vector > deferredForwardPointers; for (int i = 0; i < (int)glslangMembers->size(); i++) { glslang::TType& glslangMember = *(*glslangMembers)[i].type; if (glslangMember.hiddenMember()) { ++memberDelta; if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangMembers][i] = -1; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; } else { if (type.getBasicType() == glslang::EbtBlock) { - memberRemapper[glslangMembers][i] = i - memberDelta; - if (filterMember(glslangMember)) + if (filterMember(glslangMember)) { + memberDelta++; + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; continue; + } + memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = i - memberDelta; } // modify just this child's view of the qualifier glslang::TQualifier memberQualifier = glslangMember.getQualifier(); @@ -2804,8 +3654,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy // recurse bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer && i == (int)glslangMembers->size() - 1; - spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember)); + + // Make forward pointers for any pointer members, and create a list of members to + // convert to spirv types after creating the struct. + if (glslangMember.isReference()) { + if (forwardPointers.find(glslangMember.getReferentType()) == forwardPointers.end()) { + deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier)); + } + spvMembers.push_back( + convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, true)); + } else { + spvMembers.push_back( + convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false)); + } } } @@ -2817,6 +3678,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy // Decorate it decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType); + for (int i = 0; i < (int)deferredForwardPointers.size(); ++i) { + auto it = deferredForwardPointers[i]; + convertGlslangToSpvType(*it.first, explicitLayout, it.second, false); + } + return spvType; } @@ -2833,7 +3699,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, glslang::TType& glslangMember = *(*glslangMembers)[i].type; int member = i; if (type.getBasicType() == glslang::EbtBlock) { - member = memberRemapper[glslangMembers][i]; + member = memberRemapper[glslangTypeToIdMap[glslangMembers]][i]; if (filterMember(glslangMember)) continue; } @@ -2858,19 +3724,25 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, glslangIntermediate->getSource() == glslang::EShSourceHlsl) { builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier)); builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier)); +#ifndef GLSLANG_WEB + addMeshNVDecoration(spvType, member, memberQualifier); +#endif } } builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier)); +#ifndef GLSLANG_WEB if (type.getBasicType() == glslang::EbtBlock && qualifier.storage == glslang::EvqBuffer) { // Add memory decorations only to top-level members of shader storage block std::vector memory; - TranslateMemoryDecoration(memberQualifier, memory); + TranslateMemoryDecoration(memberQualifier, memory, glslangIntermediate->usingVulkanMemoryModel()); for (unsigned int i = 0; i < memory.size(); ++i) builder.addMemberDecoration(spvType, member, memory[i]); } +#endif + // Location assignment was already completed correctly by the front end, // just track whether a member needs to be decorated. // Ignore member locations if the container is an array, as that's @@ -2907,6 +3779,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, if (builtIn != spv::BuiltInMax) builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn); +#ifndef GLSLANG_WEB // nonuniform builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier())); @@ -2916,7 +3789,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, memberQualifier.semanticName); } -#ifdef NV_EXTENSIONS if (builtIn == spv::BuiltInLayer) { // SPV_NV_viewport_array2 extension if (glslangMember.getQualifier().layoutViewportRelative){ @@ -2943,10 +3815,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, // Decorate the structure builder.addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix)); builder.addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer())); - if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) { - builder.addCapability(spv::CapabilityGeometryStreams); - builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream); - } } // Turn the expression forming the array size into an id. @@ -2977,8 +3845,19 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) { spv::Id nominalTypeId = builder.accessChainGetInferredType(); + + spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; + coherentFlags |= TranslateCoherent(type); + + unsigned int alignment = builder.getAccessChain().alignment; + alignment |= type.getBufferReferenceAlignment(); + spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type), - TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId); + TranslateNonUniformDecoration(type.getQualifier()), + nominalTypeId, + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), + TranslateMemoryScope(coherentFlags), + alignment); // Need to convert to abstract types when necessary if (type.getBasicType() == glslang::EbtBool) { @@ -3034,7 +3913,15 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I } } - builder.accessChainStore(rvalue); + spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; + coherentFlags |= TranslateCoherent(type); + + unsigned int alignment = builder.getAccessChain().alignment; + alignment |= type.getBufferReferenceAlignment(); + + builder.accessChainStore(rvalue, + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask), + TranslateMemoryScope(coherentFlags), alignment); } // For storing when types match at the glslang level, but not might match at the @@ -3069,6 +3956,20 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // where the two types were the same type in GLSL. This requires member // by member copy, recursively. + // SPIR-V 1.4 added an instruction to do help do this. + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + // However, bool in uniform space is changed to int, so + // OpCopyLogical does not work for that. + // TODO: It would be more robust to do a full recursive verification of the types satisfying SPIR-V rules. + bool rBool = builder.containsType(builder.getTypeId(rValue), spv::OpTypeBool, 0); + bool lBool = builder.containsType(lType, spv::OpTypeBool, 0); + if (lBool == rBool) { + spv::Id logicalCopy = builder.createUnaryOp(spv::OpCopyLogical, lType, rValue); + accessChainStore(type, logicalCopy); + return; + } + } + // If an array, copy element by element. if (type.isArray()) { glslang::TType glslangElementType(type, 0); @@ -3080,7 +3981,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // set up the target storage builder.clearAccessChain(); builder.setAccessChainLValue(lValue); - builder.accessChainPush(builder.makeIntConstant(index)); + builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangElementType, elementRValue); @@ -3100,7 +4001,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id // set up the target storage builder.clearAccessChain(); builder.setAccessChainLValue(lValue); - builder.accessChainPush(builder.makeIntConstant(m)); + builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangMemberType, memberRValue); @@ -3117,15 +4018,17 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang: if (type.getBasicType() != glslang::EbtBlock) return glslang::ElpNone; - // has to be a uniform or buffer block + // has to be a uniform or buffer block or task in/out blocks if (type.getQualifier().storage != glslang::EvqUniform && - type.getQualifier().storage != glslang::EvqBuffer) + type.getQualifier().storage != glslang::EvqBuffer && + !type.getQualifier().isTaskMemory()) return glslang::ElpNone; // return the layout to use switch (type.getQualifier().layoutPacking) { case glslang::ElpStd140: case glslang::ElpStd430: + case glslang::ElpScalar: return type.getQualifier().layoutPacking; default: return glslang::ElpNone; @@ -3137,7 +4040,7 @@ int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glsl { int size; int stride; - glslangIntermediate->getBaseAlignment(arrayType, size, stride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor); + glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor); return stride; } @@ -3152,7 +4055,7 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl int size; int stride; - glslangIntermediate->getBaseAlignment(elementType, size, stride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor); + glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor); return stride; } @@ -3194,14 +4097,14 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType int memberSize; int dummyStride; - int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, dummyStride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor); + int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, matrixLayout == glslang::ElmRowMajor); // Adjust alignment for HLSL rules // TODO: make this consistent in early phases of code: // adjusting this late means inconsistencies with earlier code, which for reflection is an issue // Until reflection is brought in sync with these adjustments, don't apply to $Global, // which is the most likely to rely on reflection, and least likely to rely implicit layouts - if (glslangIntermediate->usingHlslOFfsets() && + if (glslangIntermediate->usingHlslOffsets() && ! memberType.isArray() && memberType.isVector() && structType.getTypeName().compare("$Global") != 0) { int dummySize; int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, dummySize); @@ -3213,7 +4116,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType glslang::RoundToPow2(currentOffset, memberAlignment); // Bump up to vec4 if there is a bad straddle - if (glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset)) + if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset)) glslang::RoundToPow2(currentOffset, 16); nextOffset = currentOffset + memberSize; @@ -3224,15 +4127,23 @@ void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList& const glslang::TBuiltInVariable glslangBuiltIn = members[glslangMember].type->getQualifier().builtIn; switch (glslangBuiltIn) { + case glslang::EbvPointSize: +#ifndef GLSLANG_WEB case glslang::EbvClipDistance: case glslang::EbvCullDistance: - case glslang::EbvPointSize: -#ifdef NV_EXTENSIONS case glslang::EbvViewportMaskNV: case glslang::EbvSecondaryPositionNV: case glslang::EbvSecondaryViewportMaskNV: case glslang::EbvPositionPerViewNV: case glslang::EbvViewportMaskPerViewNV: + case glslang::EbvTaskCountNV: + case glslang::EbvPrimitiveCountNV: + case glslang::EbvPrimitiveIndicesNV: + case glslang::EbvClipDistancePerViewNV: + case glslang::EbvCullDistancePerViewNV: + case glslang::EbvLayerPerViewNV: + case glslang::EbvMeshViewCountNV: + case glslang::EbvMeshViewIndicesNV: #endif // Generate the associated capability. Delegate to TranslateBuiltInDecoration. // Alternately, we could just call this for any glslang built-in, since the @@ -3277,11 +4188,24 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier, // Make all the functions, skeletally, without actually visiting their bodies. void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions) { - const auto getParamDecorations = [](std::vector& decorations, const glslang::TType& type) { + const auto getParamDecorations = [&](std::vector& decorations, const glslang::TType& type, bool useVulkanMemoryModel) { spv::Decoration paramPrecision = TranslatePrecisionDecoration(type); if (paramPrecision != spv::NoPrecision) decorations.push_back(paramPrecision); - TranslateMemoryDecoration(type.getQualifier(), decorations); + TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel); + if (type.isReference()) { + // Original and non-writable params pass the pointer directly and + // use restrict/aliased, others are stored to a pointer in Function + // memory and use RestrictPointer/AliasedPointer. + if (originalParam(type.getQualifier().storage, type, false) || + !writableParam(type.getQualifier().storage)) { + decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict : + spv::DecorationAliased); + } else { + decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT : + spv::DecorationAliasedPointerEXT); + } + } }; for (int f = 0; f < (int)glslFunctions.size(); ++f) { @@ -3307,8 +4231,12 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF std::vector> paramDecorations; // list of decorations per parameter glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); +#ifdef ENABLE_HLSL bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == glslangIntermediate->implicitThisName; +#else + bool implicitThis = false; +#endif paramDecorations.resize(parameters.size()); for (int p = 0; p < (int)parameters.size(); ++p) { @@ -3320,7 +4248,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF typeId = builder.makePointer(spv::StorageClassFunction, typeId); else rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId()); - getParamDecorations(paramDecorations[p], paramType); + getParamDecorations(paramDecorations[p], paramType, glslangIntermediate->usingVulkanMemoryModel()); paramTypes.push_back(typeId); } @@ -3340,6 +4268,14 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF symbolValues[parameters[p]->getAsSymbolNode()->getId()] = function->getParamId(p); // give a name too builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str()); + + const glslang::TType& paramType = parameters[p]->getAsTyped()->getType(); + if (paramType.contains8BitInt()) + builder.addCapability(spv::CapabilityInt8); + if (paramType.contains16BitInt()) + builder.addCapability(spv::CapabilityInt16); + if (paramType.contains16BitFloat()) + builder.addCapability(spv::CapabilityFloat16); } } } @@ -3378,19 +4314,19 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate builder.setBuildPoint(functionBlock); } -void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments) +void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { const glslang::TIntermSequence& glslangArguments = node.getSequence(); glslang::TSampler sampler = {}; bool cubeCompare = false; -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB bool f16ShadowCompare = false; #endif if (node.isTexture() || node.isImage()) { sampler = glslangArguments[0]->getAsTyped()->getType().getSampler(); cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; #endif } @@ -3399,6 +4335,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& builder.clearAccessChain(); glslangArguments[i]->traverse(this); +#ifndef GLSLANG_WEB // Special case l-value operands bool lvalue = false; switch (node.getOp()) { @@ -3410,6 +4347,8 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& case glslang::EOpImageAtomicXor: case glslang::EOpImageAtomicExchange: case glslang::EOpImageAtomicCompSwap: + case glslang::EOpImageAtomicLoad: + case glslang::EOpImageAtomicStore: if (i == 0) lvalue = true; break; @@ -3417,7 +4356,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((sampler.ms && i == 3) || (! sampler.ms && i == 2)) lvalue = true; break; -#ifdef AMD_EXTENSIONS case glslang::EOpSparseTexture: if (((cubeCompare || f16ShadowCompare) && i == 3) || (! (cubeCompare || f16ShadowCompare) && i == 2)) lvalue = true; @@ -3431,21 +4369,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((f16ShadowCompare && i == 4) || (! f16ShadowCompare && i == 3)) lvalue = true; break; -#else - case glslang::EOpSparseTexture: - if ((cubeCompare && i == 3) || (! cubeCompare && i == 2)) - lvalue = true; - break; - case glslang::EOpSparseTextureClamp: - if ((cubeCompare && i == 4) || (! cubeCompare && i == 3)) - lvalue = true; - break; - case glslang::EOpSparseTextureLod: - case glslang::EOpSparseTextureOffset: - if (i == 3) - lvalue = true; - break; -#endif case glslang::EOpSparseTextureFetch: if ((sampler.dim != glslang::EsdRect && i == 3) || (sampler.dim == glslang::EsdRect && i == 2)) lvalue = true; @@ -3454,7 +4377,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((sampler.dim != glslang::EsdRect && i == 4) || (sampler.dim == glslang::EsdRect && i == 3)) lvalue = true; break; -#ifdef AMD_EXTENSIONS case glslang::EOpSparseTextureLodOffset: case glslang::EOpSparseTextureGrad: case glslang::EOpSparseTextureOffsetClamp: @@ -3470,23 +4392,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((f16ShadowCompare && i == 7) || (! f16ShadowCompare && i == 6)) lvalue = true; break; -#else - case glslang::EOpSparseTextureLodOffset: - case glslang::EOpSparseTextureGrad: - case glslang::EOpSparseTextureOffsetClamp: - if (i == 4) - lvalue = true; - break; - case glslang::EOpSparseTextureGradOffset: - case glslang::EOpSparseTextureGradClamp: - if (i == 5) - lvalue = true; - break; - case glslang::EOpSparseTextureGradOffsetClamp: - if (i == 6) - lvalue = true; - break; -#endif case glslang::EOpSparseTextureGather: if ((sampler.shadow && i == 3) || (! sampler.shadow && i == 2)) lvalue = true; @@ -3496,7 +4401,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if ((sampler.shadow && i == 4) || (! sampler.shadow && i == 3)) lvalue = true; break; -#ifdef AMD_EXTENSIONS case glslang::EOpSparseTextureGatherLod: if (i == 3) lvalue = true; @@ -3510,14 +4414,33 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if (i == 3) lvalue = true; break; -#endif + case glslang::EOpImageSampleFootprintNV: + if (i == 4) + lvalue = true; + break; + case glslang::EOpImageSampleFootprintClampNV: + case glslang::EOpImageSampleFootprintLodNV: + if (i == 5) + lvalue = true; + break; + case glslang::EOpImageSampleFootprintGradNV: + if (i == 6) + lvalue = true; + break; + case glslang::EOpImageSampleFootprintGradClampNV: + if (i == 7) + lvalue = true; + break; default: break; } - if (lvalue) + if (lvalue) { arguments.push_back(builder.accessChainGetLValue()); - else + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType()); + } else +#endif arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); } } @@ -3534,20 +4457,37 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (! node->isImage() && ! node->isTexture()) return spv::NoResult; - builder.setLine(node->getLoc().line); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); // Process a GLSL texturing op (will be SPV image) - const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler() - : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler(); -#ifdef AMD_EXTENSIONS + + const glslang::TType &imageType = node->getAsAggregate() + ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType() + : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType(); + const glslang::TSampler sampler = imageType.getSampler(); +#ifdef GLSLANG_WEB + const bool f16ShadowCompare = false; +#else bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate()) - ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16 - : false; + ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16 + : false; #endif + const auto signExtensionMask = [&]() { + if (builder.getSpvVersion() >= spv::Spv_1_4) { + if (sampler.type == glslang::EbtUint) + return spv::ImageOperandsZeroExtendMask; + else if (sampler.type == glslang::EbtInt) + return spv::ImageOperandsSignExtendMask; + } + return spv::ImageOperandsMaskNone; + }; + + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + std::vector arguments; if (node->getAsAggregate()) - translateArguments(*node->getAsAggregate(), arguments); + translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags); else translateArguments(*node->getAsUnaryNode(), arguments); spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); @@ -3574,6 +4514,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return builder.createTextureQueryCall(spv::OpImageQuerySizeLod, params, isUnsignedResult); } else return builder.createTextureQueryCall(spv::OpImageQuerySize, params, isUnsignedResult); +#ifndef GLSLANG_WEB case glslang::EOpImageQuerySamples: case glslang::EOpTextureQuerySamples: return builder.createTextureQueryCall(spv::OpImageQuerySamples, params, isUnsignedResult); @@ -3584,6 +4525,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return builder.createTextureQueryCall(spv::OpImageQueryLevels, params, isUnsignedResult); case glslang::EOpSparseTexelsResident: return builder.createUnaryOp(spv::OpImageSparseTexelsResident, builder.makeBoolType(), arguments[0]); +#endif default: assert(0); break; @@ -3606,9 +4548,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // Check for image functions other than queries if (node->isImage()) { - std::vector operands; + std::vector operands; auto opIt = arguments.begin(); - operands.push_back(*(opIt++)); + spv::IdImmediate image = { true, *(opIt++) }; + operands.push_back(image); // Handle subpass operations // TODO: GLSL should change to have the "MS" only on the type rather than the @@ -3619,38 +4562,63 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO std::vector comps; comps.push_back(zero); comps.push_back(zero); - operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps)); - if (sampler.ms) { - operands.push_back(spv::ImageOperandsSampleMask); - operands.push_back(*(opIt++)); + spv::IdImmediate coord = { true, + builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) }; + operands.push_back(coord); + spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone }; + imageOperands.word = imageOperands.word | signExtensionMask(); + if (sampler.isMultiSample()) { + imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask; + } + if (imageOperands.word != spv::ImageOperandsMaskNone) { + operands.push_back(imageOperands); + if (sampler.isMultiSample()) { + spv::IdImmediate imageOperand = { true, *(opIt++) }; + operands.push_back(imageOperand); + } } spv::Id result = builder.createOp(spv::OpImageRead, resultType(), operands); builder.setPrecision(result, precision); return result; } - operands.push_back(*(opIt++)); -#ifdef AMD_EXTENSIONS + spv::IdImmediate coord = { true, *(opIt++) }; + operands.push_back(coord); if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) { -#else - if (node->getOp() == glslang::EOpImageLoad) { -#endif - if (sampler.ms) { - operands.push_back(spv::ImageOperandsSampleMask); - operands.push_back(*opIt); -#ifdef AMD_EXTENSIONS - } else if (cracked.lod) { + spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; + if (sampler.isMultiSample()) { + mask = mask | spv::ImageOperandsSampleMask; + } + if (cracked.lod) { builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod); builder.addCapability(spv::CapabilityImageReadWriteLodAMD); - - operands.push_back(spv::ImageOperandsLodMask); - operands.push_back(*opIt); -#endif + mask = mask | spv::ImageOperandsLodMask; } - if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown) + mask = mask | TranslateImageOperands(TranslateCoherent(imageType)); + mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask); + mask = mask | signExtensionMask(); + if (mask != spv::ImageOperandsMaskNone) { + spv::IdImmediate imageOperands = { false, (unsigned int)mask }; + operands.push_back(imageOperands); + } + if (mask & spv::ImageOperandsSampleMask) { + spv::IdImmediate imageOperand = { true, *opIt++ }; + operands.push_back(imageOperand); + } + if (mask & spv::ImageOperandsLodMask) { + spv::IdImmediate imageOperand = { true, *opIt++ }; + operands.push_back(imageOperand); + } + if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) { + spv::IdImmediate imageOperand = { true, + builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + operands.push_back(imageOperand); + } + + if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown) builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat); - std::vector result( 1, builder.createOp(spv::OpImageRead, resultType(), operands) ); + std::vector result(1, builder.createOp(spv::OpImageRead, resultType(), operands)); builder.setPrecision(result[0], precision); // If needed, add a conversion constructor to the proper size. @@ -3658,50 +4626,85 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO result[0] = builder.createConstructor(precision, result, convertGlslangToSpvType(node->getType())); return result[0]; -#ifdef AMD_EXTENSIONS } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) { -#else - } else if (node->getOp() == glslang::EOpImageStore) { -#endif - if (sampler.ms) { - operands.push_back(*(opIt + 1)); - operands.push_back(spv::ImageOperandsSampleMask); - operands.push_back(*opIt); -#ifdef AMD_EXTENSIONS - } else if (cracked.lod) { + + // Push the texel value before the operands + if (sampler.isMultiSample() || cracked.lod) { + spv::IdImmediate texel = { true, *(opIt + 1) }; + operands.push_back(texel); + } else { + spv::IdImmediate texel = { true, *opIt }; + operands.push_back(texel); + } + + spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; + if (sampler.isMultiSample()) { + mask = mask | spv::ImageOperandsSampleMask; + } + if (cracked.lod) { builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod); builder.addCapability(spv::CapabilityImageReadWriteLodAMD); + mask = mask | spv::ImageOperandsLodMask; + } + mask = mask | TranslateImageOperands(TranslateCoherent(imageType)); + mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask); + mask = mask | signExtensionMask(); + if (mask != spv::ImageOperandsMaskNone) { + spv::IdImmediate imageOperands = { false, (unsigned int)mask }; + operands.push_back(imageOperands); + } + if (mask & spv::ImageOperandsSampleMask) { + spv::IdImmediate imageOperand = { true, *opIt++ }; + operands.push_back(imageOperand); + } + if (mask & spv::ImageOperandsLodMask) { + spv::IdImmediate imageOperand = { true, *opIt++ }; + operands.push_back(imageOperand); + } + if (mask & spv::ImageOperandsMakeTexelAvailableKHRMask) { + spv::IdImmediate imageOperand = { true, + builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + operands.push_back(imageOperand); + } - operands.push_back(*(opIt + 1)); - operands.push_back(spv::ImageOperandsLodMask); - operands.push_back(*opIt); -#endif - } else - operands.push_back(*opIt); builder.createNoResultOp(spv::OpImageWrite, operands); - if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown) + if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown) builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat); return spv::NoResult; -#ifdef AMD_EXTENSIONS - } else if (node->getOp() == glslang::EOpSparseImageLoad || node->getOp() == glslang::EOpSparseImageLoadLod) { -#else - } else if (node->getOp() == glslang::EOpSparseImageLoad) { -#endif + } else if (node->getOp() == glslang::EOpSparseImageLoad || + node->getOp() == glslang::EOpSparseImageLoadLod) { builder.addCapability(spv::CapabilitySparseResidency); - if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown) + if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown) builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat); - if (sampler.ms) { - operands.push_back(spv::ImageOperandsSampleMask); - operands.push_back(*opIt++); -#ifdef AMD_EXTENSIONS - } else if (cracked.lod) { + spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; + if (sampler.isMultiSample()) { + mask = mask | spv::ImageOperandsSampleMask; + } + if (cracked.lod) { builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod); builder.addCapability(spv::CapabilityImageReadWriteLodAMD); - operands.push_back(spv::ImageOperandsLodMask); - operands.push_back(*opIt++); -#endif + mask = mask | spv::ImageOperandsLodMask; + } + mask = mask | TranslateImageOperands(TranslateCoherent(imageType)); + mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask); + mask = mask | signExtensionMask(); + if (mask != spv::ImageOperandsMaskNone) { + spv::IdImmediate imageOperands = { false, (unsigned int)mask }; + operands.push_back(imageOperands); + } + if (mask & spv::ImageOperandsSampleMask) { + spv::IdImmediate imageOperand = { true, *opIt++ }; + operands.push_back(imageOperand); + } + if (mask & spv::ImageOperandsLodMask) { + spv::IdImmediate imageOperand = { true, *opIt++ }; + operands.push_back(imageOperand); + } + if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) { + spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) }; + operands.push_back(imageOperand); } // Create the return type that was a special structure @@ -3720,9 +4723,18 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer, // as the first source operand, is required by SPIR-V atomic operations. - operands.push_back(sampler.ms ? *(opIt++) : builder.makeUintConstant(0)); // For non-MS, the value should be 0 + // For non-MS, the sample value should be 0 + spv::IdImmediate sample = { true, sampler.isMultiSample() ? *(opIt++) : builder.makeUintConstant(0) }; + operands.push_back(sample); - spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, resultType()); + spv::Id resultTypeId; + // imageAtomicStore has a void return type so base the pointer type on + // the type of the value operand. + if (node->getOp() == glslang::EOpImageAtomicStore) { + resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(operands[2].word)); + } else { + resultTypeId = builder.makePointer(spv::StorageClassImage, resultType()); + } spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands); std::vector operands; @@ -3730,11 +4742,11 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO for (; opIt != arguments.end(); ++opIt) operands.push_back(*opIt); - return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); + return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); } } -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB // Check for fragment mask functions other than queries if (cracked.fragMask) { assert(sampler.ms); @@ -3775,36 +4787,32 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // Check for texture functions other than queries bool sparse = node->isSparseTexture(); - bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; + bool imageFootprint = node->isImageFootprint(); + bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.isArrayed() && sampler.isShadow(); // check for bias argument bool bias = false; -#ifdef AMD_EXTENSIONS if (! cracked.lod && ! cracked.grad && ! cracked.fetch && ! cubeCompare) { -#else - if (! cracked.lod && ! cracked.gather && ! cracked.grad && ! cracked.fetch && ! cubeCompare) { -#endif int nonBiasArgCount = 2; -#ifdef AMD_EXTENSIONS if (cracked.gather) ++nonBiasArgCount; // comp argument should be present when bias argument is present if (f16ShadowCompare) ++nonBiasArgCount; -#endif if (cracked.offset) ++nonBiasArgCount; -#ifdef AMD_EXTENSIONS else if (cracked.offsets) ++nonBiasArgCount; -#endif if (cracked.grad) nonBiasArgCount += 2; if (cracked.lodClamp) ++nonBiasArgCount; if (sparse) ++nonBiasArgCount; - + if (imageFootprint) + //Following three extra arguments + // int granularity, bool coarse, out gl_TextureFootprint2DNV footprint + nonBiasArgCount += 3; if ((int)arguments.size() > nonBiasArgCount) bias = true; } @@ -3816,7 +4824,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler); } -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB if (cracked.gather) { const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions(); if (bias || cracked.lod || @@ -3834,11 +4842,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO bool noImplicitLod = false; // sort out where Dref is coming from -#ifdef AMD_EXTENSIONS if (cubeCompare || f16ShadowCompare) { -#else - if (cubeCompare) { -#endif params.Dref = arguments[2]; ++extraArgs; } else if (sampler.shadow && cracked.gather) { @@ -3859,13 +4863,15 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (cracked.lod) { params.lod = arguments[2 + extraArgs]; ++extraArgs; - } else if (glslangIntermediate->getStage() != EShLangFragment) { + } else if (glslangIntermediate->getStage() != EShLangFragment && + !(glslangIntermediate->getStage() == EShLangCompute && + glslangIntermediate->hasLayoutDerivativeModeNone())) { // we need to invent the default lod for an explicit lod instruction for a non-fragment stage noImplicitLod = true; } // multisample - if (sampler.ms) { + if (sampler.isMultiSample()) { params.sample = arguments[2 + extraArgs]; // For MS, "sample" should be specified ++extraArgs; } @@ -3886,18 +4892,17 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ++extraArgs; } +#ifndef GLSLANG_WEB // lod clamp if (cracked.lodClamp) { params.lodClamp = arguments[2 + extraArgs]; ++extraArgs; } - // sparse if (sparse) { params.texelOut = arguments[2 + extraArgs]; ++extraArgs; } - // gather component if (cracked.gather && ! sampler.shadow) { // default component is 0, if missing, otherwise an argument @@ -3907,13 +4912,81 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } else params.component = builder.makeIntConstant(0); } - + spv::Id resultStruct = spv::NoResult; + if (imageFootprint) { + //Following three extra arguments + // int granularity, bool coarse, out gl_TextureFootprint2DNV footprint + params.granularity = arguments[2 + extraArgs]; + params.coarse = arguments[3 + extraArgs]; + resultStruct = arguments[4 + extraArgs]; + extraArgs += 3; + } +#endif // bias if (bias) { params.bias = arguments[2 + extraArgs]; ++extraArgs; } +#ifndef GLSLANG_WEB + if (imageFootprint) { + builder.addExtension(spv::E_SPV_NV_shader_image_footprint); + builder.addCapability(spv::CapabilityImageFootprintNV); + + + //resultStructType(OpenGL type) contains 5 elements: + //struct gl_TextureFootprint2DNV { + // uvec2 anchor; + // uvec2 offset; + // uvec2 mask; + // uint lod; + // uint granularity; + //}; + //or + //struct gl_TextureFootprint3DNV { + // uvec3 anchor; + // uvec3 offset; + // uvec2 mask; + // uint lod; + // uint granularity; + //}; + spv::Id resultStructType = builder.getContainedTypeId(builder.getTypeId(resultStruct)); + assert(builder.isStructType(resultStructType)); + + //resType (SPIR-V type) contains 6 elements: + //Member 0 must be a Boolean type scalar(LOD), + //Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor), + //Member 2 must be a vector of integer type, whose Signedness operand is 0(offset), + //Member 3 must be a vector of integer type, whose Signedness operand is 0(mask), + //Member 4 must be a scalar of integer type, whose Signedness operand is 0(lod), + //Member 5 must be a scalar of integer type, whose Signedness operand is 0(granularity). + std::vector members; + members.push_back(resultType()); + for (int i = 0; i < 5; i++) { + members.push_back(builder.getContainedTypeId(resultStructType, i)); + } + spv::Id resType = builder.makeStructType(members, "ResType"); + + //call ImageFootprintNV + spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, + cracked.gather, noImplicitLod, params, signExtensionMask()); + + //copy resType (SPIR-V type) to resultStructType(OpenGL type) + for (int i = 0; i < 5; i++) { + builder.clearAccessChain(); + builder.setAccessChainLValue(resultStruct); + + //Accessing to a struct we created, no coherent flag is set + spv::Builder::AccessChain::CoherentFlags flags; + flags.clear(); + + builder.accessChainPush(builder.makeIntConstant(i), flags, 0); + builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1)); + } + return builder.createCompositeExtract(res, resultType(), 0); + } +#endif + // projective component (might not to move) // GLSL: "The texture coordinates consumed from P, not including the last component of P, // are divided by the last component of P." @@ -3938,8 +5011,21 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } } +#ifndef GLSLANG_WEB + // nonprivate + if (imageType.getQualifier().nonprivate) { + params.nonprivate = true; + } + + // volatile + if (imageType.getQualifier().volatil) { + params.volatil = true; + } +#endif + std::vector result( 1, - builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params) + builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, + noImplicitLod, params, signExtensionMask()) ); if (components != node->getType().getVectorSize()) @@ -4091,7 +5177,9 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD assert(builder.isScalar(right)); needMatchingVectors = false; binOp = spv::OpVectorTimesScalar; - } else + } else if (isFloat) + binOp = spv::OpFMul; + else binOp = spv::OpIMul; break; case glslang::EOpVectorTimesMatrix: @@ -4168,6 +5256,30 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD binOp = spv::OpLogicalNotEqual; break; + case glslang::EOpAbsDifference: + binOp = isUnsigned ? spv::OpAbsUSubINTEL : spv::OpAbsISubINTEL; + break; + + case glslang::EOpAddSaturate: + binOp = isUnsigned ? spv::OpUAddSatINTEL : spv::OpIAddSatINTEL; + break; + + case glslang::EOpSubSaturate: + binOp = isUnsigned ? spv::OpUSubSatINTEL : spv::OpISubSatINTEL; + break; + + case glslang::EOpAverage: + binOp = isUnsigned ? spv::OpUAverageINTEL : spv::OpIAverageINTEL; + break; + + case glslang::EOpAverageRounded: + binOp = isUnsigned ? spv::OpUAverageRoundedINTEL : spv::OpIAverageRoundedINTEL; + break; + + case glslang::EOpMul32x16: + binOp = isUnsigned ? spv::OpUMul32x16INTEL : spv::OpIMul32x16INTEL; + break; + case glslang::EOpLessThan: case glslang::EOpGreaterThan: case glslang::EOpLessThanEqual: @@ -4185,7 +5297,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD // handle mapped binary operations (should be non-comparison) if (binOp != spv::OpNop) { assert(comparison == false); - if (builder.isMatrix(left) || builder.isMatrix(right)) + if (builder.isMatrix(left) || builder.isMatrix(right) || + builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right)) return createBinaryMatrixOperation(binOp, decorations, typeId, left, right); // No matrix involved; make both operands be the same number of components, if needed @@ -4193,8 +5306,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD builder.promoteScalar(decorations.precision, left, right); spv::Id result = builder.createBinOp(binOp, typeId, left, right); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); return builder.setPrecision(result, decorations.precision); } @@ -4206,7 +5319,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual) && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) { spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } @@ -4267,8 +5380,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD if (binOp != spv::OpNop) { spv::Id result = builder.createBinOp(binOp, typeId, left, right); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); return builder.setPrecision(result, decorations.precision); } @@ -4306,7 +5419,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora firstClass = false; break; case spv::OpMatrixTimesScalar: - if (builder.isMatrix(right)) + if (builder.isMatrix(right) || builder.isCooperativeMatrix(right)) std::swap(left, right); assert(builder.isScalar(right)); break; @@ -4327,10 +5440,13 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora break; } + if (builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right)) + firstClass = true; + if (firstClass) { spv::Id result = builder.createBinOp(op, typeId, left, right); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); return builder.setPrecision(result, decorations.precision); } @@ -4369,14 +5485,14 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec; spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec; spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec); - builder.addDecoration(result, decorations.noContraction); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNoContraction(builder, result); + decorations.addNonUniform(builder, result); results.push_back(builder.setPrecision(result, decorations.precision)); } // put the pieces together spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } default: @@ -4386,7 +5502,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora } spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, - spv::Id operand, glslang::TBasicType typeProxy) + spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op unaryOp = spv::OpNop; int extBuiltins = -1; @@ -4554,6 +5670,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpUnpackHalf2x16: libCall = spv::GLSLstd450UnpackHalf2x16; break; +#ifndef GLSLANG_WEB case glslang::EOpPackSnorm4x8: libCall = spv::GLSLstd450PackSnorm4x8; break; @@ -4572,6 +5689,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpUnpackDouble2x32: libCall = spv::GLSLstd450UnpackDouble2x32; break; +#endif case glslang::EOpPackInt2x32: case glslang::EOpUnpackInt2x32: @@ -4605,38 +5723,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpFwidth: unaryOp = spv::OpFwidth; break; - case glslang::EOpDPdxFine: - builder.addCapability(spv::CapabilityDerivativeControl); - unaryOp = spv::OpDPdxFine; - break; - case glslang::EOpDPdyFine: - builder.addCapability(spv::CapabilityDerivativeControl); - unaryOp = spv::OpDPdyFine; - break; - case glslang::EOpFwidthFine: - builder.addCapability(spv::CapabilityDerivativeControl); - unaryOp = spv::OpFwidthFine; - break; - case glslang::EOpDPdxCoarse: - builder.addCapability(spv::CapabilityDerivativeControl); - unaryOp = spv::OpDPdxCoarse; - break; - case glslang::EOpDPdyCoarse: - builder.addCapability(spv::CapabilityDerivativeControl); - unaryOp = spv::OpDPdyCoarse; - break; - case glslang::EOpFwidthCoarse: - builder.addCapability(spv::CapabilityDerivativeControl); - unaryOp = spv::OpFwidthCoarse; - break; - case glslang::EOpInterpolateAtCentroid: -#ifdef AMD_EXTENSIONS - if (typeProxy == glslang::EbtFloat16) - builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif - builder.addCapability(spv::CapabilityInterpolationFunction); - libCall = spv::GLSLstd450InterpolateAtCentroid; - break; + case glslang::EOpAny: unaryOp = spv::OpAny; break; @@ -4657,6 +5744,30 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe libCall = spv::GLSLstd450SSign; break; +#ifndef GLSLANG_WEB + case glslang::EOpDPdxFine: + unaryOp = spv::OpDPdxFine; + break; + case glslang::EOpDPdyFine: + unaryOp = spv::OpDPdyFine; + break; + case glslang::EOpFwidthFine: + unaryOp = spv::OpFwidthFine; + break; + case glslang::EOpDPdxCoarse: + unaryOp = spv::OpDPdxCoarse; + break; + case glslang::EOpDPdyCoarse: + unaryOp = spv::OpDPdyCoarse; + break; + case glslang::EOpFwidthCoarse: + unaryOp = spv::OpFwidthCoarse; + break; + case glslang::EOpInterpolateAtCentroid: + if (typeProxy == glslang::EbtFloat16) + builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); + libCall = spv::GLSLstd450InterpolateAtCentroid; + break; case glslang::EOpAtomicCounterIncrement: case glslang::EOpAtomicCounterDecrement: case glslang::EOpAtomicCounter: @@ -4664,7 +5775,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe // Handle all of the atomics in one place, in createAtomicOperation() std::vector operands; operands.push_back(operand); - return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy); + return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy, lvalueCoherentFlags); } case glslang::EOpBitFieldReverse: @@ -4683,12 +5794,23 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe libCall = spv::GLSLstd450FindSMsb; break; + case glslang::EOpCountLeadingZeros: + builder.addCapability(spv::CapabilityIntegerFunctions2INTEL); + builder.addExtension("SPV_INTEL_shader_integer_functions2"); + unaryOp = spv::OpUCountLeadingZerosINTEL; + break; + + case glslang::EOpCountTrailingZeros: + builder.addCapability(spv::CapabilityIntegerFunctions2INTEL); + builder.addExtension("SPV_INTEL_shader_integer_functions2"); + unaryOp = spv::OpUCountTrailingZerosINTEL; + break; + case glslang::EOpBallot: case glslang::EOpReadFirstInvocation: case glslang::EOpAnyInvocation: case glslang::EOpAllInvocations: case glslang::EOpAllInvocationsEqual: -#ifdef AMD_EXTENSIONS case glslang::EOpMinInvocations: case glslang::EOpMaxInvocations: case glslang::EOpAddInvocations: @@ -4707,7 +5829,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpMinInvocationsExclusiveScanNonUniform: case glslang::EOpMaxInvocationsExclusiveScanNonUniform: case glslang::EOpAddInvocationsExclusiveScanNonUniform: -#endif { std::vector operands; operands.push_back(operand); @@ -4752,7 +5873,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe operands.push_back(operand); return createSubgroupOperation(op, typeId, operands, typeProxy); } -#ifdef AMD_EXTENSIONS case glslang::EOpMbcnt: extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot); libCall = spv::MbcntAMD; @@ -4767,14 +5887,18 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe extBuiltins = getExtBuiltins(spv::E_SPV_AMD_gcn_shader); libCall = spv::CubeFaceCoordAMD; break; -#endif -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartition: - builder.addExtension(spv::E_SPV_NV_shader_subgroup_partitioned); - builder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV); unaryOp = spv::OpGroupNonUniformPartitionNV; break; + case glslang::EOpConstructReference: + unaryOp = spv::OpBitcast; + break; #endif + + case glslang::EOpCopyObject: + unaryOp = spv::OpCopyObject; + break; + default: return 0; } @@ -4788,8 +5912,8 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe id = builder.createUnaryOp(unaryOp, typeId, operand); } - builder.addDecoration(id, decorations.noContraction); - builder.addDecoration(id, decorations.nonUniform); + decorations.addNoContraction(builder, id); + decorations.addNonUniform(builder, id); return builder.setPrecision(id, decorations.precision); } @@ -4817,120 +5941,56 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat indexes.push_back(c); spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes); spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec); - builder.addDecoration(destVec, decorations.noContraction); - builder.addDecoration(destVec, decorations.nonUniform); + decorations.addNoContraction(builder, destVec); + decorations.addNonUniform(builder, destVec); results.push_back(builder.setPrecision(destVec, decorations.precision)); } // put the pieces together spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } -spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize) +// For converting integers where both the bitwidth and the signedness could +// change, but only do the width change here. The caller is still responsible +// for the signedness conversion. +spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize) { - spv::Op convOp = spv::OpNop; - spv::Id type = 0; - - spv::Id result = 0; - + // Get the result type width, based on the type to convert to. + int width = 32; switch(op) { + case glslang::EOpConvInt16ToUint8: + case glslang::EOpConvIntToUint8: + case glslang::EOpConvInt64ToUint8: + case glslang::EOpConvUint16ToInt8: + case glslang::EOpConvUintToInt8: + case glslang::EOpConvUint64ToInt8: + width = 8; + break; case glslang::EOpConvInt8ToUint16: - convOp = spv::OpSConvert; - type = builder.makeIntType(16); + case glslang::EOpConvIntToUint16: + case glslang::EOpConvInt64ToUint16: + case glslang::EOpConvUint8ToInt16: + case glslang::EOpConvUintToInt16: + case glslang::EOpConvUint64ToInt16: + width = 16; break; case glslang::EOpConvInt8ToUint: - convOp = spv::OpSConvert; - type = builder.makeIntType(32); + case glslang::EOpConvInt16ToUint: + case glslang::EOpConvInt64ToUint: + case glslang::EOpConvUint8ToInt: + case glslang::EOpConvUint16ToInt: + case glslang::EOpConvUint64ToInt: + width = 32; break; case glslang::EOpConvInt8ToUint64: - convOp = spv::OpSConvert; - type = builder.makeIntType(64); - break; - case glslang::EOpConvInt16ToUint8: - convOp = spv::OpSConvert; - type = builder.makeIntType(8); - break; - case glslang::EOpConvInt16ToUint: - convOp = spv::OpSConvert; - type = builder.makeIntType(32); - break; case glslang::EOpConvInt16ToUint64: - convOp = spv::OpSConvert; - type = builder.makeIntType(64); - break; - case glslang::EOpConvIntToUint8: - convOp = spv::OpSConvert; - type = builder.makeIntType(8); - break; - case glslang::EOpConvIntToUint16: - convOp = spv::OpSConvert; - type = builder.makeIntType(16); - break; case glslang::EOpConvIntToUint64: - convOp = spv::OpSConvert; - type = builder.makeIntType(64); - break; - case glslang::EOpConvInt64ToUint8: - convOp = spv::OpSConvert; - type = builder.makeIntType(8); - break; - case glslang::EOpConvInt64ToUint16: - convOp = spv::OpSConvert; - type = builder.makeIntType(16); - break; - case glslang::EOpConvInt64ToUint: - convOp = spv::OpSConvert; - type = builder.makeIntType(32); - break; - case glslang::EOpConvUint8ToInt16: - convOp = spv::OpUConvert; - type = builder.makeIntType(16); - break; - case glslang::EOpConvUint8ToInt: - convOp = spv::OpUConvert; - type = builder.makeIntType(32); - break; case glslang::EOpConvUint8ToInt64: - convOp = spv::OpUConvert; - type = builder.makeIntType(64); - break; - case glslang::EOpConvUint16ToInt8: - convOp = spv::OpUConvert; - type = builder.makeIntType(8); - break; - case glslang::EOpConvUint16ToInt: - convOp = spv::OpUConvert; - type = builder.makeIntType(32); - break; case glslang::EOpConvUint16ToInt64: - convOp = spv::OpUConvert; - type = builder.makeIntType(64); - break; - case glslang::EOpConvUintToInt8: - convOp = spv::OpUConvert; - type = builder.makeIntType(8); - break; - case glslang::EOpConvUintToInt16: - convOp = spv::OpUConvert; - type = builder.makeIntType(16); - break; case glslang::EOpConvUintToInt64: - convOp = spv::OpUConvert; - type = builder.makeIntType(64); - break; - case glslang::EOpConvUint64ToInt8: - convOp = spv::OpUConvert; - type = builder.makeIntType(8); - break; - case glslang::EOpConvUint64ToInt16: - convOp = spv::OpUConvert; - type = builder.makeIntType(16); - break; - case glslang::EOpConvUint64ToInt: - convOp = spv::OpUConvert; - type = builder.makeIntType(32); + width = 64; break; default: @@ -4938,11 +5998,36 @@ spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, break; } + // Get the conversion operation and result type, + // based on the target width, but the source type. + spv::Id type = spv::NoType; + spv::Op convOp = spv::OpNop; + switch(op) { + case glslang::EOpConvInt8ToUint16: + case glslang::EOpConvInt8ToUint: + case glslang::EOpConvInt8ToUint64: + case glslang::EOpConvInt16ToUint8: + case glslang::EOpConvInt16ToUint: + case glslang::EOpConvInt16ToUint64: + case glslang::EOpConvIntToUint8: + case glslang::EOpConvIntToUint16: + case glslang::EOpConvIntToUint64: + case glslang::EOpConvInt64ToUint8: + case glslang::EOpConvInt64ToUint16: + case glslang::EOpConvInt64ToUint: + convOp = spv::OpSConvert; + type = builder.makeIntType(width); + break; + default: + convOp = spv::OpUConvert; + type = builder.makeUintType(width); + break; + } + if (vectorSize > 0) type = builder.makeVectorType(type, vectorSize); - result = builder.createUnaryOp(convOp, type, operand); - return result; + return builder.createUnaryOp(convOp, type, operand); } spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecorations& decorations, spv::Id destType, @@ -4955,110 +6040,49 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0; switch (op) { - case glslang::EOpConvInt8ToBool: - case glslang::EOpConvUint8ToBool: - zero = builder.makeUint8Constant(0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); - case glslang::EOpConvInt16ToBool: - case glslang::EOpConvUint16ToBool: - zero = builder.makeUint16Constant(0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); case glslang::EOpConvIntToBool: case glslang::EOpConvUintToBool: zero = builder.makeUintConstant(0); zero = makeSmearedConstant(zero, vectorSize); return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); - case glslang::EOpConvInt64ToBool: - case glslang::EOpConvUint64ToBool: - zero = builder.makeUint64Constant(0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); - case glslang::EOpConvFloatToBool: zero = builder.makeFloatConstant(0.0F); zero = makeSmearedConstant(zero, vectorSize); return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); - - case glslang::EOpConvDoubleToBool: - zero = builder.makeDoubleConstant(0.0); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); - - case glslang::EOpConvFloat16ToBool: - zero = builder.makeFloat16Constant(0.0F); - zero = makeSmearedConstant(zero, vectorSize); - return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); - case glslang::EOpConvBoolToFloat: convOp = spv::OpSelect; zero = builder.makeFloatConstant(0.0F); one = builder.makeFloatConstant(1.0F); break; - case glslang::EOpConvBoolToDouble: - convOp = spv::OpSelect; - zero = builder.makeDoubleConstant(0.0); - one = builder.makeDoubleConstant(1.0); - break; - - case glslang::EOpConvBoolToFloat16: - convOp = spv::OpSelect; - zero = builder.makeFloat16Constant(0.0F); - one = builder.makeFloat16Constant(1.0F); - break; - - case glslang::EOpConvBoolToInt8: - zero = builder.makeInt8Constant(0); - one = builder.makeInt8Constant(1); - convOp = spv::OpSelect; - break; - - case glslang::EOpConvBoolToUint8: - zero = builder.makeUint8Constant(0); - one = builder.makeUint8Constant(1); - convOp = spv::OpSelect; - break; - - case glslang::EOpConvBoolToInt16: - zero = builder.makeInt16Constant(0); - one = builder.makeInt16Constant(1); - convOp = spv::OpSelect; - break; - - case glslang::EOpConvBoolToUint16: - zero = builder.makeUint16Constant(0); - one = builder.makeUint16Constant(1); - convOp = spv::OpSelect; - break; - case glslang::EOpConvBoolToInt: case glslang::EOpConvBoolToInt64: - if (op == glslang::EOpConvBoolToInt64) +#ifndef GLSLANG_WEB + if (op == glslang::EOpConvBoolToInt64) { zero = builder.makeInt64Constant(0); - else - zero = builder.makeIntConstant(0); - - if (op == glslang::EOpConvBoolToInt64) one = builder.makeInt64Constant(1); - else + } else +#endif + { + zero = builder.makeIntConstant(0); one = builder.makeIntConstant(1); + } convOp = spv::OpSelect; break; case glslang::EOpConvBoolToUint: case glslang::EOpConvBoolToUint64: - if (op == glslang::EOpConvBoolToUint64) +#ifndef GLSLANG_WEB + if (op == glslang::EOpConvBoolToUint64) { zero = builder.makeUint64Constant(0); - else - zero = builder.makeUintConstant(0); - - if (op == glslang::EOpConvBoolToUint64) one = builder.makeUint64Constant(1); - else + } else +#endif + { + zero = builder.makeUintConstant(0); one = builder.makeUintConstant(1); + } convOp = spv::OpSelect; break; @@ -5093,17 +6117,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora convOp = spv::OpConvertUToF; break; - case glslang::EOpConvDoubleToFloat: - case glslang::EOpConvFloatToDouble: - case glslang::EOpConvDoubleToFloat16: - case glslang::EOpConvFloat16ToDouble: - case glslang::EOpConvFloatToFloat16: - case glslang::EOpConvFloat16ToFloat: - convOp = spv::OpFConvert; - if (builder.isMatrixType(destType)) - return createUnaryMatrixOperation(convOp, decorations, destType, operand, typeProxy); - break; - case glslang::EOpConvFloat16ToInt8: case glslang::EOpConvFloatToInt8: case glslang::EOpConvDoubleToInt8: @@ -5129,13 +6142,16 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvInt64ToUint64: if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. +#ifndef GLSLANG_WEB if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) { zero = builder.makeUint8Constant(0); } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) { zero = builder.makeUint16Constant(0); } else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) { zero = builder.makeUint64Constant(0); - } else { + } else +#endif + { zero = builder.makeUintConstant(0); } zero = makeSmearedConstant(zero, vectorSize); @@ -5162,6 +6178,71 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora convOp = spv::OpConvertFToU; break; +#ifndef GLSLANG_WEB + case glslang::EOpConvInt8ToBool: + case glslang::EOpConvUint8ToBool: + zero = builder.makeUint8Constant(0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); + case glslang::EOpConvInt16ToBool: + case glslang::EOpConvUint16ToBool: + zero = builder.makeUint16Constant(0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); + case glslang::EOpConvInt64ToBool: + case glslang::EOpConvUint64ToBool: + zero = builder.makeUint64Constant(0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpINotEqual, destType, operand, zero); + case glslang::EOpConvDoubleToBool: + zero = builder.makeDoubleConstant(0.0); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); + case glslang::EOpConvFloat16ToBool: + zero = builder.makeFloat16Constant(0.0F); + zero = makeSmearedConstant(zero, vectorSize); + return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero); + case glslang::EOpConvBoolToDouble: + convOp = spv::OpSelect; + zero = builder.makeDoubleConstant(0.0); + one = builder.makeDoubleConstant(1.0); + break; + case glslang::EOpConvBoolToFloat16: + convOp = spv::OpSelect; + zero = builder.makeFloat16Constant(0.0F); + one = builder.makeFloat16Constant(1.0F); + break; + case glslang::EOpConvBoolToInt8: + zero = builder.makeInt8Constant(0); + one = builder.makeInt8Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvBoolToUint8: + zero = builder.makeUint8Constant(0); + one = builder.makeUint8Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvBoolToInt16: + zero = builder.makeInt16Constant(0); + one = builder.makeInt16Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvBoolToUint16: + zero = builder.makeUint16Constant(0); + one = builder.makeUint16Constant(1); + convOp = spv::OpSelect; + break; + case glslang::EOpConvDoubleToFloat: + case glslang::EOpConvFloatToDouble: + case glslang::EOpConvDoubleToFloat16: + case glslang::EOpConvFloat16ToDouble: + case glslang::EOpConvFloatToFloat16: + case glslang::EOpConvFloat16ToFloat: + convOp = spv::OpFConvert; + if (builder.isMatrixType(destType)) + return createUnaryMatrixOperation(convOp, decorations, destType, operand, typeProxy); + break; + case glslang::EOpConvInt8ToInt16: case glslang::EOpConvInt8ToInt: case glslang::EOpConvInt8ToInt64: @@ -5217,7 +6298,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvUint64ToInt16: case glslang::EOpConvUint64ToInt: // OpSConvert/OpUConvert + OpBitCast - operand = createConversionOperation(op, operand, vectorSize); + operand = createIntWidthConversion(op, operand, vectorSize); if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. @@ -5266,6 +6347,21 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora // For normal run-time conversion instruction, use OpBitcast. convOp = spv::OpBitcast; break; + case glslang::EOpConvUint64ToPtr: + convOp = spv::OpConvertUToPtr; + break; + case glslang::EOpConvPtrToUint64: + convOp = spv::OpConvertPtrToU; + break; + case glslang::EOpConvPtrToUvec2: + case glslang::EOpConvUvec2ToPtr: + if (builder.isVector(operand)) + builder.promoteIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, + spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5); + convOp = spv::OpBitcast; + break; +#endif + default: break; } @@ -5282,7 +6378,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora result = builder.createUnaryOp(convOp, destType, operand); result = builder.setPrecision(result, decorations.precision); - builder.addDecoration(result, decorations.nonUniform); + decorations.addNonUniform(builder, result); return result; } @@ -5299,7 +6395,7 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector } // For glslang ops that map to SPV atomic opCodes -spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op opCode = spv::OpNop; @@ -5354,8 +6450,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv opCode = spv::OpAtomicIDecrement; break; case glslang::EOpAtomicCounter: + case glslang::EOpImageAtomicLoad: + case glslang::EOpAtomicLoad: opCode = spv::OpAtomicLoad; break; + case glslang::EOpAtomicStore: + case glslang::EOpImageAtomicStore: + opCode = spv::OpAtomicStore; + break; default: assert(0); break; @@ -5366,36 +6468,87 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv // Sort out the operands // - mapping from glslang -> SPV - // - there are extra SPV operands with no glslang source + // - there are extra SPV operands that are optional in glslang // - compare-exchange swaps the value and comparator // - compare-exchange has an extra memory semantics // - EOpAtomicCounterDecrement needs a post decrement - std::vector spvAtomicOperands; // hold the spv operands - auto opIt = operands.begin(); // walk the glslang operands - spvAtomicOperands.push_back(*(opIt++)); - spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope? - spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics? - if (opCode == spv::OpAtomicCompareExchange) { - // There are 2 memory semantics for compare-exchange. And the operand order of "comparator" and "new value" in GLSL - // differs from that in SPIR-V. Hence, special processing is required. - spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); - spvAtomicOperands.push_back(*(opIt + 1)); - spvAtomicOperands.push_back(*opIt); - opIt += 2; + spv::Id pointerId = 0, compareId = 0, valueId = 0; + // scope defaults to Device in the old model, QueueFamilyKHR in the new model + spv::Id scopeId; + if (glslangIntermediate->usingVulkanMemoryModel()) { + scopeId = builder.makeUintConstant(spv::ScopeQueueFamilyKHR); + } else { + scopeId = builder.makeUintConstant(spv::ScopeDevice); + } + // semantics default to relaxed + spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && glslangIntermediate->usingVulkanMemoryModel() ? + spv::MemorySemanticsVolatileMask : + spv::MemorySemanticsMaskNone); + spv::Id semanticsId2 = semanticsId; + + pointerId = operands[0]; + if (opCode == spv::OpAtomicIIncrement || opCode == spv::OpAtomicIDecrement) { + // no additional operands + } else if (opCode == spv::OpAtomicCompareExchange) { + compareId = operands[1]; + valueId = operands[2]; + if (operands.size() > 3) { + scopeId = operands[3]; + semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5])); + semanticsId2 = builder.makeUintConstant(builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7])); + } + } else if (opCode == spv::OpAtomicLoad) { + if (operands.size() > 1) { + scopeId = operands[1]; + semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3])); + } + } else { + // atomic store or RMW + valueId = operands[1]; + if (operands.size() > 2) { + scopeId = operands[2]; + semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4])); + } } - // Add the rest of the operands, skipping any that were dealt with above. - for (; opIt != operands.end(); ++opIt) - spvAtomicOperands.push_back(*opIt); + // Check for capabilities + unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2); + if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } - spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands); + if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) { + builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); + } - // GLSL and HLSL atomic-counter decrement return post-decrement value, - // while SPIR-V returns pre-decrement value. Translate between these semantics. - if (op == glslang::EOpAtomicCounterDecrement) - resultId = builder.createBinOp(spv::OpISub, typeId, resultId, builder.makeIntConstant(1)); + std::vector spvAtomicOperands; // hold the spv operands + spvAtomicOperands.push_back(pointerId); + spvAtomicOperands.push_back(scopeId); + spvAtomicOperands.push_back(semanticsId); + if (opCode == spv::OpAtomicCompareExchange) { + spvAtomicOperands.push_back(semanticsId2); + spvAtomicOperands.push_back(valueId); + spvAtomicOperands.push_back(compareId); + } else if (opCode != spv::OpAtomicLoad && opCode != spv::OpAtomicIIncrement && opCode != spv::OpAtomicIDecrement) { + spvAtomicOperands.push_back(valueId); + } - return resultId; + if (opCode == spv::OpAtomicStore) { + builder.createNoResultOp(opCode, spvAtomicOperands); + return 0; + } else { + spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands); + + // GLSL and HLSL atomic-counter decrement return post-decrement value, + // while SPIR-V returns pre-decrement value. Translate between these semantics. + if (op == glslang::EOpAtomicCounterDecrement) + resultId = builder.createBinOp(spv::OpISub, typeId, resultId, builder.makeIntConstant(1)); + + return resultId; + } } // Create group invocation operations. @@ -5405,7 +6558,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op bool isFloat = isTypeFloat(typeProxy); spv::Op opCode = spv::OpNop; - std::vector spvGroupOperands; + std::vector spvGroupOperands; spv::GroupOperation groupOperation = spv::GroupOperationMax; if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation || @@ -5419,7 +6572,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op builder.addCapability(spv::CapabilitySubgroupVoteKHR); } else { builder.addCapability(spv::CapabilityGroups); -#ifdef AMD_EXTENSIONS if (op == glslang::EOpMinInvocationsNonUniform || op == glslang::EOpMaxInvocationsNonUniform || op == glslang::EOpAddInvocationsNonUniform || @@ -5430,10 +6582,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op op == glslang::EOpMaxInvocationsExclusiveScanNonUniform || op == glslang::EOpAddInvocationsExclusiveScanNonUniform) builder.addExtension(spv::E_SPV_AMD_shader_ballot); -#endif - spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup)); -#ifdef AMD_EXTENSIONS switch (op) { case glslang::EOpMinInvocations: case glslang::EOpMaxInvocations: @@ -5442,7 +6591,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op case glslang::EOpMaxInvocationsNonUniform: case glslang::EOpAddInvocationsNonUniform: groupOperation = spv::GroupOperationReduce; - spvGroupOperands.push_back(groupOperation); break; case glslang::EOpMinInvocationsInclusiveScan: case glslang::EOpMaxInvocationsInclusiveScan: @@ -5451,7 +6599,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op case glslang::EOpMaxInvocationsInclusiveScanNonUniform: case glslang::EOpAddInvocationsInclusiveScanNonUniform: groupOperation = spv::GroupOperationInclusiveScan; - spvGroupOperands.push_back(groupOperation); break; case glslang::EOpMinInvocationsExclusiveScan: case glslang::EOpMaxInvocationsExclusiveScan: @@ -5460,16 +6607,22 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op case glslang::EOpMaxInvocationsExclusiveScanNonUniform: case glslang::EOpAddInvocationsExclusiveScanNonUniform: groupOperation = spv::GroupOperationExclusiveScan; - spvGroupOperands.push_back(groupOperation); break; default: break; } -#endif + spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spvGroupOperands.push_back(scope); + if (groupOperation != spv::GroupOperationMax) { + spv::IdImmediate groupOp = { false, (unsigned)groupOperation }; + spvGroupOperands.push_back(groupOp); + } } - for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) - spvGroupOperands.push_back(*opIt); + for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) { + spv::IdImmediate op = { true, *opIt }; + spvGroupOperands.push_back(op); + } switch (op) { case glslang::EOpAnyInvocation: @@ -5510,7 +6663,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op builder.createCompositeConstruct(uvec2Type, components)); } -#ifdef AMD_EXTENSIONS case glslang::EOpMinInvocations: case glslang::EOpMaxInvocations: case glslang::EOpAddInvocations: @@ -5597,7 +6749,6 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands); break; -#endif default: logger->missingFunctionality("invocation operation"); return spv::NoResult; @@ -5608,9 +6759,9 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op } // Create group invocation operations on a vector -spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector& operands) +spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, + spv::Id typeId, std::vector& operands) { -#ifdef AMD_EXTENSIONS assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin || op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax || op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast || @@ -5618,12 +6769,6 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD || op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD || op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD); -#else - assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin || - op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax || - op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast || - op == spv::OpSubgroupReadInvocationKHR); -#endif // Handle group invocation operations scalar by scalar. // The result type is the same type as the original type. @@ -5641,18 +6786,23 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv for (int comp = 0; comp < numComponents; ++comp) { std::vector indexes; indexes.push_back(comp); - spv::Id scalar = builder.createCompositeExtract(operands[0], scalarType, indexes); - std::vector spvGroupOperands; + spv::IdImmediate scalar = { true, builder.createCompositeExtract(operands[0], scalarType, indexes) }; + std::vector spvGroupOperands; if (op == spv::OpSubgroupReadInvocationKHR) { spvGroupOperands.push_back(scalar); - spvGroupOperands.push_back(operands[1]); + spv::IdImmediate operand = { true, operands[1] }; + spvGroupOperands.push_back(operand); } else if (op == spv::OpGroupBroadcast) { - spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup)); + spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spvGroupOperands.push_back(scope); spvGroupOperands.push_back(scalar); - spvGroupOperands.push_back(operands[1]); + spv::IdImmediate operand = { true, operands[1] }; + spvGroupOperands.push_back(operand); } else { - spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup)); - spvGroupOperands.push_back(groupOperation); + spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spvGroupOperands.push_back(scope); + spv::IdImmediate groupOp = { false, (unsigned)groupOperation }; + spvGroupOperands.push_back(groupOp); spvGroupOperands.push_back(scalar); } @@ -5664,7 +6814,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv } // Create subgroup invocation operations. -spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy) { // Add the required capabilities. switch (op) { @@ -5741,7 +6892,6 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s builder.addCapability(spv::CapabilityGroupNonUniform); builder.addCapability(spv::CapabilityGroupNonUniformQuad); break; -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedMin: @@ -5766,12 +6916,12 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s builder.addExtension(spv::E_SPV_NV_shader_subgroup_partitioned); builder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV); break; -#endif default: assert(0 && "Unhandled subgroup operation!"); } - const bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64; - const bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble; + + const bool isUnsigned = isTypeUnsignedInt(typeProxy); + const bool isFloat = isTypeFloat(typeProxy); const bool isBool = typeProxy == glslang::EbtBool; spv::Op opCode = spv::OpNop; @@ -5800,11 +6950,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveAdd: case glslang::EOpSubgroupExclusiveAdd: case glslang::EOpSubgroupClusteredAdd: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedInclusiveAdd: case glslang::EOpSubgroupPartitionedExclusiveAdd: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFAdd; } else { @@ -5815,11 +6963,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveMul: case glslang::EOpSubgroupExclusiveMul: case glslang::EOpSubgroupClusteredMul: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedInclusiveMul: case glslang::EOpSubgroupPartitionedExclusiveMul: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFMul; } else { @@ -5830,11 +6976,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveMin: case glslang::EOpSubgroupExclusiveMin: case glslang::EOpSubgroupClusteredMin: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedMin: case glslang::EOpSubgroupPartitionedInclusiveMin: case glslang::EOpSubgroupPartitionedExclusiveMin: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFMin; } else if (isUnsigned) { @@ -5847,11 +6991,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveMax: case glslang::EOpSubgroupExclusiveMax: case glslang::EOpSubgroupClusteredMax: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedMax: case glslang::EOpSubgroupPartitionedInclusiveMax: case glslang::EOpSubgroupPartitionedExclusiveMax: -#endif if (isFloat) { opCode = spv::OpGroupNonUniformFMax; } else if (isUnsigned) { @@ -5864,11 +7006,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveAnd: case glslang::EOpSubgroupExclusiveAnd: case glslang::EOpSubgroupClusteredAnd: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAnd: case glslang::EOpSubgroupPartitionedInclusiveAnd: case glslang::EOpSubgroupPartitionedExclusiveAnd: -#endif if (isBool) { opCode = spv::OpGroupNonUniformLogicalAnd; } else { @@ -5879,11 +7019,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveOr: case glslang::EOpSubgroupExclusiveOr: case glslang::EOpSubgroupClusteredOr: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedOr: case glslang::EOpSubgroupPartitionedInclusiveOr: case glslang::EOpSubgroupPartitionedExclusiveOr: -#endif if (isBool) { opCode = spv::OpGroupNonUniformLogicalOr; } else { @@ -5894,11 +7032,9 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveXor: case glslang::EOpSubgroupExclusiveXor: case glslang::EOpSubgroupClusteredXor: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedXor: case glslang::EOpSubgroupPartitionedInclusiveXor: case glslang::EOpSubgroupPartitionedExclusiveXor: -#endif if (isBool) { opCode = spv::OpGroupNonUniformLogicalXor; } else { @@ -5912,14 +7048,11 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s default: assert(0 && "Unhandled subgroup operation!"); } - std::vector spvGroupOperands; - - // Every operation begins with the Execution Scope operand. - spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup)); - - // Next, for all operations that use a Group Operation, push that as an operand. + // get the right Group Operation + spv::GroupOperation groupOperation = spv::GroupOperationMax; switch (op) { - default: break; + default: + break; case glslang::EOpSubgroupBallotBitCount: case glslang::EOpSubgroupAdd: case glslang::EOpSubgroupMul: @@ -5928,7 +7061,7 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupAnd: case glslang::EOpSubgroupOr: case glslang::EOpSubgroupXor: - spvGroupOperands.push_back(spv::GroupOperationReduce); + groupOperation = spv::GroupOperationReduce; break; case glslang::EOpSubgroupBallotInclusiveBitCount: case glslang::EOpSubgroupInclusiveAdd: @@ -5938,7 +7071,7 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupInclusiveAnd: case glslang::EOpSubgroupInclusiveOr: case glslang::EOpSubgroupInclusiveXor: - spvGroupOperands.push_back(spv::GroupOperationInclusiveScan); + groupOperation = spv::GroupOperationInclusiveScan; break; case glslang::EOpSubgroupBallotExclusiveBitCount: case glslang::EOpSubgroupExclusiveAdd: @@ -5948,7 +7081,7 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupExclusiveAnd: case glslang::EOpSubgroupExclusiveOr: case glslang::EOpSubgroupExclusiveXor: - spvGroupOperands.push_back(spv::GroupOperationExclusiveScan); + groupOperation = spv::GroupOperationExclusiveScan; break; case glslang::EOpSubgroupClusteredAdd: case glslang::EOpSubgroupClusteredMul: @@ -5957,9 +7090,8 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupClusteredAnd: case glslang::EOpSubgroupClusteredOr: case glslang::EOpSubgroupClusteredXor: - spvGroupOperands.push_back(spv::GroupOperationClusteredReduce); + groupOperation = spv::GroupOperationClusteredReduce; break; -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedMin: @@ -5967,7 +7099,7 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupPartitionedAnd: case glslang::EOpSubgroupPartitionedOr: case glslang::EOpSubgroupPartitionedXor: - spvGroupOperands.push_back(spv::GroupOperationPartitionedReduceNV); + groupOperation = spv::GroupOperationPartitionedReduceNV; break; case glslang::EOpSubgroupPartitionedInclusiveAdd: case glslang::EOpSubgroupPartitionedInclusiveMul: @@ -5976,7 +7108,7 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupPartitionedInclusiveAnd: case glslang::EOpSubgroupPartitionedInclusiveOr: case glslang::EOpSubgroupPartitionedInclusiveXor: - spvGroupOperands.push_back(spv::GroupOperationPartitionedInclusiveScanNV); + groupOperation = spv::GroupOperationPartitionedInclusiveScanNV; break; case glslang::EOpSubgroupPartitionedExclusiveAdd: case glslang::EOpSubgroupPartitionedExclusiveMul: @@ -5985,22 +7117,40 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s case glslang::EOpSubgroupPartitionedExclusiveAnd: case glslang::EOpSubgroupPartitionedExclusiveOr: case glslang::EOpSubgroupPartitionedExclusiveXor: - spvGroupOperands.push_back(spv::GroupOperationPartitionedExclusiveScanNV); + groupOperation = spv::GroupOperationPartitionedExclusiveScanNV; break; -#endif + } + + // build the instruction + std::vector spvGroupOperands; + + // Every operation begins with the Execution Scope operand. + spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spvGroupOperands.push_back(executionScope); + + // Next, for all operations that use a Group Operation, push that as an operand. + if (groupOperation != spv::GroupOperationMax) { + spv::IdImmediate groupOperand = { false, (unsigned)groupOperation }; + spvGroupOperands.push_back(groupOperand); } // Push back the operands next. - for (auto opIt : operands) { - spvGroupOperands.push_back(opIt); + for (auto opIt = operands.cbegin(); opIt != operands.cend(); ++opIt) { + spv::IdImmediate operand = { true, *opIt }; + spvGroupOperands.push_back(operand); } // Some opcodes have additional operands. + spv::Id directionId = spv::NoResult; switch (op) { default: break; - case glslang::EOpSubgroupQuadSwapHorizontal: spvGroupOperands.push_back(builder.makeUintConstant(0)); break; - case glslang::EOpSubgroupQuadSwapVertical: spvGroupOperands.push_back(builder.makeUintConstant(1)); break; - case glslang::EOpSubgroupQuadSwapDiagonal: spvGroupOperands.push_back(builder.makeUintConstant(2)); break; + case glslang::EOpSubgroupQuadSwapHorizontal: directionId = builder.makeUintConstant(0); break; + case glslang::EOpSubgroupQuadSwapVertical: directionId = builder.makeUintConstant(1); break; + case glslang::EOpSubgroupQuadSwapDiagonal: directionId = builder.makeUintConstant(2); break; + } + if (directionId != spv::NoResult) { + spv::IdImmediate direction = { true, directionId }; + spvGroupOperands.push_back(direction); } return builder.createOp(opCode, typeId, spvGroupOperands); @@ -6026,7 +7176,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: switch (op) { case glslang::EOpMin: if (isFloat) - libCall = spv::GLSLstd450FMin; + libCall = nanMinMaxClamp ? spv::GLSLstd450NMin : spv::GLSLstd450FMin; else if (isUnsigned) libCall = spv::GLSLstd450UMin; else @@ -6038,7 +7188,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: break; case glslang::EOpMax: if (isFloat) - libCall = spv::GLSLstd450FMax; + libCall = nanMinMaxClamp ? spv::GLSLstd450NMax : spv::GLSLstd450FMax; else if (isUnsigned) libCall = spv::GLSLstd450UMax; else @@ -6057,7 +7207,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpClamp: if (isFloat) - libCall = spv::GLSLstd450FClamp; + libCall = nanMinMaxClamp ? spv::GLSLstd450NClamp : spv::GLSLstd450FClamp; else if (isUnsigned) libCall = spv::GLSLstd450UClamp; else @@ -6100,20 +7250,57 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpRefract: libCall = spv::GLSLstd450Refract; break; + case glslang::EOpBarrier: + { + // This is for the extended controlBarrier function, with four operands. + // The unextended barrier() goes through createNoArgOperation. + assert(operands.size() == 4); + unsigned int executionScope = builder.getConstantScalar(operands[0]); + unsigned int memoryScope = builder.getConstantScalar(operands[1]); + unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]); + builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); + if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } + if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); + } + return 0; + } + break; + case glslang::EOpMemoryBarrier: + { + // This is for the extended memoryBarrier function, with three operands. + // The unextended memoryBarrier() goes through createNoArgOperation. + assert(operands.size() == 3); + unsigned int memoryScope = builder.getConstantScalar(operands[0]); + unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]); + builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); + if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } + if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) { + builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); + } + return 0; + } + break; + +#ifndef GLSLANG_WEB case glslang::EOpInterpolateAtSample: -#ifdef AMD_EXTENSIONS if (typeProxy == glslang::EbtFloat16) builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif - builder.addCapability(spv::CapabilityInterpolationFunction); libCall = spv::GLSLstd450InterpolateAtSample; break; case glslang::EOpInterpolateAtOffset: -#ifdef AMD_EXTENSIONS if (typeProxy == glslang::EbtFloat16) builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); -#endif - builder.addCapability(spv::CapabilityInterpolationFunction); libCall = spv::GLSLstd450InterpolateAtOffset; break; case glslang::EOpAddCarry: @@ -6155,11 +7342,9 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: assert(builder.isPointerType(typeId1)); typeId1 = builder.getContainedTypeId(typeId1); int width = builder.getScalarTypeWidth(typeId1); -#ifdef AMD_EXTENSIONS if (width == 16) // Using 16-bit exp operand, enable extension SPV_AMD_gpu_shader_int16 builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16); -#endif if (builder.getNumComponents(operands[0]) == 1) frexpIntType = builder.makeIntegerType(width, true); else @@ -6189,7 +7374,6 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpSubgroupClusteredOr: case glslang::EOpSubgroupClusteredXor: case glslang::EOpSubgroupQuadBroadcast: -#ifdef NV_EXTENSIONS case glslang::EOpSubgroupPartitionedAdd: case glslang::EOpSubgroupPartitionedMul: case glslang::EOpSubgroupPartitionedMin: @@ -6211,10 +7395,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpSubgroupPartitionedExclusiveAnd: case glslang::EOpSubgroupPartitionedExclusiveOr: case glslang::EOpSubgroupPartitionedExclusiveXor: -#endif return createSubgroupOperation(op, typeId, operands, typeProxy); -#ifdef AMD_EXTENSIONS case glslang::EOpSwizzleInvocations: extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot); libCall = spv::SwizzleInvocationsAMD; @@ -6268,8 +7450,32 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_explicit_vertex_parameter); libCall = spv::InterpolateAtVertexAMD; break; -#endif + case glslang::EOpReportIntersectionNV: + { + typeId = builder.makeBoolType(); + opCode = spv::OpReportIntersectionNV; + } + break; + case glslang::EOpTraceNV: + { + builder.createNoResultOp(spv::OpTraceNV, operands); + return 0; + } + break; + case glslang::EOpExecuteCallableNV: + { + builder.createNoResultOp(spv::OpExecuteCallableNV, operands); + return 0; + } + break; + case glslang::EOpWritePackedPrimitiveIndices4x8NV: + builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands); + return 0; + case glslang::EOpCooperativeMatrixMulAdd: + opCode = spv::OpCooperativeMatrixMulAddNV; + break; +#endif // GLSLANG_WEB default: return 0; } @@ -6281,6 +7487,17 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: // We might need the remaining arguments, e.g. in the EOpFrexp case. std::vector callArguments(operands.begin(), operands.begin() + consumedOperands); id = builder.createBuiltinCall(typeId, extBuiltins >= 0 ? extBuiltins : stdBuiltins, libCall, callArguments); + } else if (opCode == spv::OpDot && !isFloat) { + // int dot(int, int) + // NOTE: never called for scalar/vector1, this is turned into simple mul before this can be reached + const int componentCount = builder.getNumComponents(operands[0]); + spv::Id mulOp = builder.createBinOp(spv::OpIMul, builder.getTypeId(operands[0]), operands[0], operands[1]); + builder.setPrecision(mulOp, precision); + id = builder.createCompositeExtract(mulOp, typeId, 0); + for (int i = 1; i < componentCount; ++i) { + builder.setPrecision(id, precision); + id = builder.createBinOp(spv::OpIAdd, typeId, id, builder.createCompositeExtract(mulOp, typeId, i)); + } } else { switch (consumedOperands) { case 0: @@ -6302,6 +7519,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: } } +#ifndef GLSLANG_WEB // Decode the return types that were structures switch (op) { case glslang::EOpAddCarry: @@ -6331,6 +7549,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: default: break; } +#endif return builder.setPrecision(id, precision); } @@ -6338,22 +7557,20 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: // Intrinsics with no arguments (or no return value, and no precision). spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId) { - // TODO: get the barrier operands correct + // GLSL memory barriers use queuefamily scope in new model, device scope in old model + spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; switch (op) { - case glslang::EOpEmitVertex: - builder.createNoResultOp(spv::OpEmitVertex); - return 0; - case glslang::EOpEndPrimitive: - builder.createNoResultOp(spv::OpEndPrimitive); - return 0; case glslang::EOpBarrier: if (glslangIntermediate->getStage() == EShLangTessControl) { - builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone); - // TODO: prefer the following, when available: - // builder.createControlBarrier(spv::ScopePatch, spv::ScopePatch, - // spv::MemorySemanticsPatchMask | - // spv::MemorySemanticsAcquireReleaseMask); + if (glslangIntermediate->usingVulkanMemoryModel()) { + builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsAcquireReleaseMask); + builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); + } else { + builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone); + } } else { builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, spv::MemorySemanticsWorkgroupMemoryMask | @@ -6361,29 +7578,30 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: } return 0; case glslang::EOpMemoryBarrier: - builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory | - spv::MemorySemanticsAcquireReleaseMask); - return 0; - case glslang::EOpMemoryBarrierAtomicCounter: - builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAllMemory | + spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpMemoryBarrierBuffer: - builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); - return 0; - case glslang::EOpMemoryBarrierImage: - builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsUniformMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpMemoryBarrierShared: - builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsWorkgroupMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpGroupMemoryBarrier: builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; +#ifndef GLSLANG_WEB + case glslang::EOpMemoryBarrierAtomicCounter: + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); + return 0; + case glslang::EOpMemoryBarrierImage: + builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); + return 0; case glslang::EOpAllMemoryBarrierWithGroupSync: builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, spv::MemorySemanticsAllMemory | @@ -6428,22 +7646,69 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; + + case glslang::EOpEmitVertex: + builder.createNoResultOp(spv::OpEmitVertex); + return 0; + case glslang::EOpEndPrimitive: + builder.createNoResultOp(spv::OpEndPrimitive); + return 0; + case glslang::EOpSubgroupElect: { std::vector operands; return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid); } -#ifdef AMD_EXTENSIONS case glslang::EOpTime: { std::vector args; // Dummy arguments spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args); return builder.setPrecision(id, precision); } + case glslang::EOpIgnoreIntersectionNV: + builder.createNoResultOp(spv::OpIgnoreIntersectionNV); + return 0; + case glslang::EOpTerminateRayNV: + builder.createNoResultOp(spv::OpTerminateRayNV); + return 0; + + case glslang::EOpBeginInvocationInterlock: + builder.createNoResultOp(spv::OpBeginInvocationInterlockEXT); + return 0; + case glslang::EOpEndInvocationInterlock: + builder.createNoResultOp(spv::OpEndInvocationInterlockEXT); + return 0; + + case glslang::EOpIsHelperInvocation: + { + std::vector args; // Dummy arguments + builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); + builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT); + return builder.createOp(spv::OpIsHelperInvocationEXT, typeId, args); + } + + case glslang::EOpReadClockSubgroupKHR: { + std::vector args; + args.push_back(builder.makeUintConstant(spv::ScopeSubgroup)); + builder.addExtension(spv::E_SPV_KHR_shader_clock); + builder.addCapability(spv::CapabilityShaderClockKHR); + return builder.createOp(spv::OpReadClockKHR, typeId, args); + } + + case glslang::EOpReadClockDeviceKHR: { + std::vector args; + args.push_back(builder.makeUintConstant(spv::ScopeDevice)); + builder.addExtension(spv::E_SPV_KHR_shader_clock); + builder.addCapability(spv::CapabilityShaderClockKHR); + return builder.createOp(spv::OpReadClockKHR, typeId, args); + } #endif default: - logger->missingFunctionality("unknown operation with no arguments"); - return 0; + break; } + + logger->missingFunctionality("unknown operation with no arguments"); + + return 0; } spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol) @@ -6456,19 +7721,26 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol } // it was not found, create it - id = createSpvVariable(symbol); + spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false); + auto forcedType = getForcedType(builtIn, symbol->getType()); + id = createSpvVariable(symbol, forcedType.first); symbolValues[symbol->getId()] = id; + if (forcedType.second != spv::NoType) + forceType[id] = forcedType.second; if (symbol->getBasicType() != glslang::EbtBlock) { builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType())); builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier())); builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier())); - if (symbol->getType().getQualifier().hasSpecConstantId()) - builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId); - if (symbol->getQualifier().hasIndex()) - builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex); +#ifndef GLSLANG_WEB + addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier()); if (symbol->getQualifier().hasComponent()) builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent); + if (symbol->getQualifier().hasIndex()) + builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex); +#endif + if (symbol->getType().getQualifier().hasSpecConstantId()) + builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId); // atomic counters use this: if (symbol->getQualifier().hasOffset()) builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset); @@ -6489,12 +7761,14 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol } if (symbol->getQualifier().hasBinding()) builder.addDecoration(id, spv::DecorationBinding, symbol->getQualifier().layoutBinding); + else if (IsDescriptorResource(symbol->getType())) { + // default to 0 + builder.addDecoration(id, spv::DecorationBinding, 0); + } if (symbol->getQualifier().hasAttachment()) builder.addDecoration(id, spv::DecorationInputAttachmentIndex, symbol->getQualifier().layoutAttachment); if (glslangIntermediate->getXfbMode()) { builder.addCapability(spv::CapabilityTransformFeedback); - if (symbol->getQualifier().hasXfbStride()) - builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride); if (symbol->getQualifier().hasXfbBuffer()) { builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer); unsigned stride = glslangIntermediate->getXfbStride(symbol->getQualifier().layoutXfbBuffer); @@ -6505,22 +7779,22 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset); } + // add built-in variable decoration + if (builtIn != spv::BuiltInMax) { + builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn); + } + +#ifndef GLSLANG_WEB if (symbol->getType().isImage()) { std::vector memory; - TranslateMemoryDecoration(symbol->getType().getQualifier(), memory); + TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel()); for (unsigned int i = 0; i < memory.size(); ++i) builder.addDecoration(id, memory[i]); } - // built-in variable decorations - spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false); - if (builtIn != spv::BuiltInMax) - builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn); - // nonuniform builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier())); -#ifdef NV_EXTENSIONS if (builtIn == spv::BuiltInSampleMask) { spv::Decoration decoration; // GL_NV_sample_mask_override_coverage extension @@ -6530,6 +7804,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol decoration = (spv::Decoration)spv::DecorationMax; builder.addDecoration(id, decoration); if (decoration != spv::DecorationMax) { + builder.addCapability(spv::CapabilitySampleMaskOverrideCoverageNV); builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage); } } @@ -6553,7 +7828,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV); builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough); } -#endif + if (symbol->getQualifier().pervertexNV) { + builder.addDecoration(id, spv::DecorationPerVertexNV); + builder.addCapability(spv::CapabilityFragmentBarycentricNV); + builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); + } if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) { builder.addExtension("SPV_GOOGLE_hlsl_functionality1"); @@ -6561,9 +7840,50 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol symbol->getType().getQualifier().semanticName); } + if (symbol->isReference()) { + builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); + } +#endif + return id; } +#ifndef GLSLANG_WEB +// add per-primitive, per-view. per-task decorations to a struct member (member >= 0) or an object +void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier) +{ + if (member >= 0) { + if (qualifier.perPrimitiveNV) { + // Need to add capability/extension for fragment shader. + // Mesh shader already adds this by default. + if (glslangIntermediate->getStage() == EShLangFragment) { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } + builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerPrimitiveNV); + } + if (qualifier.perViewNV) + builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerViewNV); + if (qualifier.perTaskNV) + builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerTaskNV); + } else { + if (qualifier.perPrimitiveNV) { + // Need to add capability/extension for fragment shader. + // Mesh shader already adds this by default. + if (glslangIntermediate->getStage() == EShLangFragment) { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } + builder.addDecoration(id, spv::DecorationPerPrimitiveNV); + } + if (qualifier.perViewNV) + builder.addDecoration(id, spv::DecorationPerViewNV); + if (qualifier.perTaskNV) + builder.addDecoration(id, spv::DecorationPerTaskNV); + } +} +#endif + // Make a full tree of instructions to build a SPIR-V specialization constant, // or regular constant if possible. // @@ -6607,24 +7927,27 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n // An AST node labelled as specialization constant should be a symbol node. // Its initializer should either be a sub tree with constant nodes, or a constant union array. if (auto* sn = node.getAsSymbolNode()) { + spv::Id result; if (auto* sub_tree = sn->getConstSubtree()) { // Traverse the constant constructor sub tree like generating normal run-time instructions. // During the AST traversal, if the node is marked as 'specConstant', SpecConstantOpModeGuard // will set the builder into spec constant op instruction generating mode. sub_tree->traverse(this); - return accessChainLoad(sub_tree->getType()); - } else if (auto* const_union_array = &sn->getConstArray()){ + result = accessChainLoad(sub_tree->getType()); + } else if (auto* const_union_array = &sn->getConstArray()) { int nextConst = 0; - spv::Id id = createSpvConstantFromConstUnionArray(sn->getType(), *const_union_array, nextConst, true); - builder.addName(id, sn->getName().c_str()); - return id; + result = createSpvConstantFromConstUnionArray(sn->getType(), *const_union_array, nextConst, true); + } else { + logger->missingFunctionality("Invalid initializer for spec onstant."); + return spv::NoResult; } + builder.addName(result, sn->getName().c_str()); + return result; } // Neither a front-end constant node, nor a specialization constant node with constant union array or // constant sub tree as initializer. logger->missingFunctionality("Neither a front-end constant nor a spec constant."); - exit(1); return spv::NoResult; } @@ -6650,7 +7973,10 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla glslang::TType vectorType(glslangType, 0); for (int col = 0; col < glslangType.getMatrixCols(); ++col) spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false)); - } else if (glslangType.getStruct()) { + } else if (glslangType.isCoopMat()) { + glslang::TType componentType(glslangType.getBasicType()); + spvConsts.push_back(createSpvConstantFromConstUnionArray(componentType, consts, nextConst, false)); + } else if (glslangType.isStruct()) { glslang::TVector::const_iterator iter; for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter) spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false)); @@ -6658,6 +7984,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) { bool zero = nextConst >= consts.size(); switch (glslangType.getBasicType()) { + case glslang::EbtInt: + spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst())); + break; + case glslang::EbtUint: + spvConsts.push_back(builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst())); + break; + case glslang::EbtFloat: + spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst())); + break; + case glslang::EbtBool: + spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst())); + break; +#ifndef GLSLANG_WEB case glslang::EbtInt8: spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const())); break; @@ -6670,30 +8009,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla case glslang::EbtUint16: spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const())); break; - case glslang::EbtInt: - spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst())); - break; - case glslang::EbtUint: - spvConsts.push_back(builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst())); - break; case glslang::EbtInt64: spvConsts.push_back(builder.makeInt64Constant(zero ? 0 : consts[nextConst].getI64Const())); break; case glslang::EbtUint64: spvConsts.push_back(builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const())); break; - case glslang::EbtFloat: - spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst())); - break; case glslang::EbtDouble: spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst())); break; case glslang::EbtFloat16: spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst())); break; - case glslang::EbtBool: - spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst())); - break; +#endif default: assert(0); break; @@ -6705,6 +8033,19 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla bool zero = nextConst >= consts.size(); spv::Id scalar = 0; switch (glslangType.getBasicType()) { + case glslang::EbtInt: + scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant); + break; + case glslang::EbtUint: + scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst(), specConstant); + break; + case glslang::EbtFloat: + scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); + break; + case glslang::EbtBool: + scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant); + break; +#ifndef GLSLANG_WEB case glslang::EbtInt8: scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant); break; @@ -6717,30 +8058,23 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla case glslang::EbtUint16: scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant); break; - case glslang::EbtInt: - scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant); - break; - case glslang::EbtUint: - scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst(), specConstant); - break; case glslang::EbtInt64: scalar = builder.makeInt64Constant(zero ? 0 : consts[nextConst].getI64Const(), specConstant); break; case glslang::EbtUint64: scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant); break; - case glslang::EbtFloat: - scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); - break; case glslang::EbtDouble: scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant); break; case glslang::EbtFloat16: scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); break; - case glslang::EbtBool: - scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant); + case glslang::EbtReference: + scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant); + scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar); break; +#endif default: assert(0); break; @@ -6884,7 +8218,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan return builder.createOp(spv::OpPhi, boolTypeId, phiOperands); } -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB // Return type Id of the imported set of extended instructions corresponds to the name. // Import this set if it has not been imported yet. spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name) @@ -6922,8 +8256,10 @@ int GetSpirvGeneratorVersion() // return 3; // change/correct barrier-instruction operands, to match memory model group decisions // return 4; // some deeper access chains: for dynamic vector component, and local Boolean component // return 5; // make OpArrayLength result type be an int with signedness of 0 - return 6; // revert version 5 change, which makes a different (new) kind of incorrect code, - // versions 4 and 6 each generate OpArrayLength as it has long been done + // return 6; // revert version 5 change, which makes a different (new) kind of incorrect code, + // versions 4 and 6 each generate OpArrayLength as it has long been done + // return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent + return 8; // switch to new dead block eliminator; use OpUnreachable } // Write SPIR-V out to a binary file @@ -6943,12 +8279,13 @@ void OutputSpvBin(const std::vector& spirv, const char* baseName) // Write SPIR-V out to a text file with 32-bit hexadecimal words void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) { +#ifndef GLSLANG_WEB std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); if (out.fail()) printf("ERROR: Failed to open file: %s\n", baseName); out << "\t// " << - glslang::GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL << + GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL << std::endl; if (varName != nullptr) { out << "\t #pragma once" << std::endl; @@ -6970,18 +8307,19 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, out << "};"; } out.close(); +#endif } // // Set up the glslang traversal // -void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, SpvOptions* options) +void GlslangToSpv(const TIntermediate& intermediate, std::vector& spirv, SpvOptions* options) { spv::SpvBuildLogger logger; GlslangToSpv(intermediate, spirv, &logger, options); } -void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, +void GlslangToSpv(const TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger* logger, SpvOptions* options) { TIntermNode* root = intermediate.getTreeRoot(); @@ -6989,11 +8327,11 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vectortraverse(&it); @@ -7003,54 +8341,21 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vectoroptimizeSize) && - !options->disableOptimizer) { - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; - - spvtools::Optimizer optimizer(target_env); - optimizer.SetMessageConsumer([](spv_message_level_t level, - const char* source, - const spv_position_t& position, - const char* message) { - std::cerr << StringifyMessage(level, source, position, message) - << std::endl; - }); - - optimizer.RegisterPass(CreateMergeReturnPass()); - optimizer.RegisterPass(CreateInlineExhaustivePass()); - optimizer.RegisterPass(CreateEliminateDeadFunctionsPass()); - optimizer.RegisterPass(CreateScalarReplacementPass()); - optimizer.RegisterPass(CreateLocalAccessChainConvertPass()); - optimizer.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass()); - optimizer.RegisterPass(CreateLocalSingleStoreElimPass()); - optimizer.RegisterPass(CreateSimplificationPass()); - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateVectorDCEPass()); - optimizer.RegisterPass(CreateDeadInsertElimPass()); - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateDeadBranchElimPass()); - optimizer.RegisterPass(CreateBlockMergePass()); - optimizer.RegisterPass(CreateLocalMultiStoreElimPass()); - optimizer.RegisterPass(CreateIfConversionPass()); - optimizer.RegisterPass(CreateSimplificationPass()); - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateVectorDCEPass()); - optimizer.RegisterPass(CreateDeadInsertElimPass()); - if (options->optimizeSize) { - optimizer.RegisterPass(CreateRedundancyEliminationPass()); - // TODO(greg-lunarg): Add this when AMD driver issues are resolved - // optimizer.RegisterPass(CreateCommonUniformElimPass()); - } - optimizer.RegisterPass(CreateAggressiveDCEPass()); - optimizer.RegisterPass(CreateCFGCleanupPass()); - - if (!optimizer.Run(spirv.data(), spirv.size(), &spirv)) - return; + bool prelegalization = intermediate.getSource() == EShSourceHlsl; + if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer) { + SpirvToolsLegalize(intermediate, spirv, logger, options); + prelegalization = false; } + + if (options->validate) + SpirvToolsValidate(intermediate, spirv, logger, prelegalization); + + if (options->disassemble) + SpirvToolsDisassemble(std::cout, spirv); + #endif - glslang::GetThreadPoolAllocator().pop(); + GetThreadPoolAllocator().pop(); } }; // end namespace glslang diff --git a/Externals/glslang/SPIRV/GlslangToSpv.h b/Externals/glslang/SPIRV/GlslangToSpv.h index f7f7cff620..3907be43b7 100644 --- a/Externals/glslang/SPIRV/GlslangToSpv.h +++ b/Externals/glslang/SPIRV/GlslangToSpv.h @@ -1,5 +1,6 @@ // // Copyright (C) 2014 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -38,7 +39,8 @@ #pragma warning(disable : 4464) // relative include path contains '..' #endif -#include "../glslang/Include/intermediate.h" +#include "SpvTools.h" +#include "glslang/Include/intermediate.h" #include #include @@ -47,14 +49,6 @@ namespace glslang { -struct SpvOptions { - SpvOptions() : generateDebugInfo(false), disableOptimizer(true), - optimizeSize(false) { } - bool generateDebugInfo; - bool disableOptimizer; - bool optimizeSize; -}; - void GetSpirvVersion(std::string&); int GetSpirvGeneratorVersion(); void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, diff --git a/Externals/glslang/SPIRV/InReadableOrder.cpp b/Externals/glslang/SPIRV/InReadableOrder.cpp index 52b29613a4..9d9410be93 100644 --- a/Externals/glslang/SPIRV/InReadableOrder.cpp +++ b/Externals/glslang/SPIRV/InReadableOrder.cpp @@ -61,17 +61,22 @@ namespace { // Use by calling visit() on the root block. class ReadableOrderTraverser { public: - explicit ReadableOrderTraverser(std::function callback) : callback_(callback) {} + ReadableOrderTraverser(std::function callback) + : callback_(callback) {} // Visits the block if it hasn't been visited already and isn't currently - // being delayed. Invokes callback(block), then descends into its + // being delayed. Invokes callback(block, why, header), then descends into its // successors. Delays merge-block and continue-block processing until all - // the branches have been completed. - void visit(Block* block) + // the branches have been completed. If |block| is an unreachable merge block or + // an unreachable continue target, then |header| is the corresponding header block. + void visit(Block* block, spv::ReachReason why, Block* header) { assert(block); + if (why == spv::ReachViaControlFlow) { + reachableViaControlFlow_.insert(block); + } if (visited_.count(block) || delayed_.count(block)) return; - callback_(block); + callback_(block, why, header); visited_.insert(block); Block* mergeBlock = nullptr; Block* continueBlock = nullptr; @@ -87,27 +92,40 @@ public: delayed_.insert(continueBlock); } } - const auto successors = block->getSuccessors(); - for (auto it = successors.cbegin(); it != successors.cend(); ++it) - visit(*it); + if (why == spv::ReachViaControlFlow) { + const auto& successors = block->getSuccessors(); + for (auto it = successors.cbegin(); it != successors.cend(); ++it) + visit(*it, why, nullptr); + } if (continueBlock) { + const spv::ReachReason continueWhy = + (reachableViaControlFlow_.count(continueBlock) > 0) + ? spv::ReachViaControlFlow + : spv::ReachDeadContinue; delayed_.erase(continueBlock); - visit(continueBlock); + visit(continueBlock, continueWhy, block); } if (mergeBlock) { + const spv::ReachReason mergeWhy = + (reachableViaControlFlow_.count(mergeBlock) > 0) + ? spv::ReachViaControlFlow + : spv::ReachDeadMerge; delayed_.erase(mergeBlock); - visit(mergeBlock); + visit(mergeBlock, mergeWhy, block); } } private: - std::function callback_; + std::function callback_; // Whether a block has already been visited or is being delayed. std::unordered_set visited_, delayed_; + + // The set of blocks that actually are reached via control flow. + std::unordered_set reachableViaControlFlow_; }; } -void spv::inReadableOrder(Block* root, std::function callback) +void spv::inReadableOrder(Block* root, std::function callback) { - ReadableOrderTraverser(callback).visit(root); + ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr); } diff --git a/Externals/glslang/SPIRV/Logger.cpp b/Externals/glslang/SPIRV/Logger.cpp index 48bd4e3ade..7ea0c6342b 100644 --- a/Externals/glslang/SPIRV/Logger.cpp +++ b/Externals/glslang/SPIRV/Logger.cpp @@ -32,6 +32,8 @@ // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +#ifndef GLSLANG_WEB + #include "Logger.h" #include @@ -66,3 +68,5 @@ std::string SpvBuildLogger::getAllMessages() const { } } // end spv namespace + +#endif \ No newline at end of file diff --git a/Externals/glslang/SPIRV/Logger.h b/Externals/glslang/SPIRV/Logger.h index 2e4ddaf517..411367c030 100644 --- a/Externals/glslang/SPIRV/Logger.h +++ b/Externals/glslang/SPIRV/Logger.h @@ -46,6 +46,14 @@ class SpvBuildLogger { public: SpvBuildLogger() {} +#ifdef GLSLANG_WEB + void tbdFunctionality(const std::string& f) { } + void missingFunctionality(const std::string& f) { } + void warning(const std::string& w) { } + void error(const std::string& e) { errors.push_back(e); } + std::string getAllMessages() { return ""; } +#else + // Registers a TBD functionality. void tbdFunctionality(const std::string& f); // Registers a missing functionality. @@ -59,6 +67,7 @@ public: // Returns all messages accumulated in the order of: // TBD functionalities, missing functionalities, warnings, errors. std::string getAllMessages() const; +#endif private: SpvBuildLogger(const SpvBuildLogger&); diff --git a/Externals/glslang/SPIRV/SPVRemapper.cpp b/Externals/glslang/SPIRV/SPVRemapper.cpp old mode 100755 new mode 100644 index 4bac145305..fd0bb8950c --- a/Externals/glslang/SPIRV/SPVRemapper.cpp +++ b/Externals/glslang/SPIRV/SPVRemapper.cpp @@ -220,11 +220,11 @@ namespace spv { bool spirvbin_t::isConstOp(spv::Op opCode) const { switch (opCode) { - case spv::OpConstantNull: case spv::OpConstantSampler: error("unimplemented constant type"); return true; + case spv::OpConstantNull: case spv::OpConstantTrue: case spv::OpConstantFalse: case spv::OpConstantComposite: @@ -1326,10 +1326,6 @@ namespace spv { case spv::OpTypeReserveId: return 300002; case spv::OpTypeQueue: return 300003; case spv::OpTypePipe: return 300004; - - case spv::OpConstantNull: return 300005; - case spv::OpConstantSampler: return 300006; - case spv::OpConstantTrue: return 300007; case spv::OpConstantFalse: return 300008; case spv::OpConstantComposite: @@ -1346,6 +1342,18 @@ namespace spv { hash += w * spv[typeStart+w]; return hash; } + case spv::OpConstantNull: + { + std::uint32_t hash = 500009 + hashType(idPos(spv[typeStart+1])); + return hash; + } + case spv::OpConstantSampler: + { + std::uint32_t hash = 600011 + hashType(idPos(spv[typeStart+1])); + for (unsigned w=3; w < wordCount; ++w) + hash += w * spv[typeStart+w]; + return hash; + } default: error("unknown type opcode"); diff --git a/Externals/glslang/SPIRV/SPVRemapper.h b/Externals/glslang/SPIRV/SPVRemapper.h old mode 100755 new mode 100644 index 97e3f31fa6..d6b9c346dd --- a/Externals/glslang/SPIRV/SPVRemapper.h +++ b/Externals/glslang/SPIRV/SPVRemapper.h @@ -45,7 +45,7 @@ namespace spv { // MSVC defines __cplusplus as an older value, even when it supports almost all of 11. // We handle that here by making our own symbol. -#if __cplusplus >= 201103L || _MSC_VER >= 1700 +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700) # define use_cpp11 1 #endif @@ -195,7 +195,7 @@ private: // Header access & set methods spirword_t magic() const { return spv[0]; } // return magic number spirword_t bound() const { return spv[3]; } // return Id bound from header - spirword_t bound(spirword_t b) { return spv[3] = b; }; + spirword_t bound(spirword_t b) { return spv[3] = b; } spirword_t genmagic() const { return spv[2]; } // generator magic spirword_t genmagic(spirword_t m) { return spv[2] = m; } spirword_t schemaNum() const { return spv[4]; } // schema number from header diff --git a/Externals/glslang/SPIRV/SpvBuilder.cpp b/Externals/glslang/SPIRV/SpvBuilder.cpp index 27ce71caa3..bd208952e0 100644 --- a/Externals/glslang/SPIRV/SpvBuilder.cpp +++ b/Externals/glslang/SPIRV/SpvBuilder.cpp @@ -1,6 +1,6 @@ // // Copyright (C) 2014-2015 LunarG, Inc. -// Copyright (C) 2015-2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -46,7 +46,9 @@ #include "SpvBuilder.h" +#ifndef GLSLANG_WEB #include "hex_float.h" +#endif #ifndef _WIN32 #include @@ -60,6 +62,7 @@ Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogg sourceVersion(0), sourceFileStringId(NoResult), currentLine(0), + currentFile(nullptr), emitOpLines(false), addressModel(AddressingModelLogical), memoryModel(MemoryModelGLSL450), @@ -81,13 +84,15 @@ Id Builder::import(const char* name) { Instruction* import = new Instruction(getUniqueId(), NoType, OpExtInstImport); import->addStringOperand(name); + module.mapInstruction(import); imports.push_back(std::unique_ptr(import)); return import->getResultId(); } -// Emit an OpLine if we've been asked to emit OpLines and the line number -// has changed since the last time, and is a valid line number. +// Emit instruction for non-filename-based #line directives (ie. no filename +// seen yet): emit an OpLine if we've been asked to emit OpLines and the line +// number has changed since the last time, and is a valid line number. void Builder::setLine(int lineNum) { if (lineNum != 0 && lineNum != currentLine) { @@ -97,6 +102,26 @@ void Builder::setLine(int lineNum) } } +// If no filename, do non-filename-based #line emit. Else do filename-based emit. +// Emit OpLine if we've been asked to emit OpLines and the line number or filename +// has changed since the last time, and line number is valid. +void Builder::setLine(int lineNum, const char* filename) +{ + if (filename == nullptr) { + setLine(lineNum); + return; + } + if ((lineNum != 0 && lineNum != currentLine) || currentFile == nullptr || + strncmp(filename, currentFile, strlen(currentFile) + 1) != 0) { + currentLine = lineNum; + currentFile = filename; + if (emitOpLines) { + spv::Id strId = getStringId(filename); + addLine(strId, currentLine, 0); + } + } +} + void Builder::addLine(Id fileName, int lineNum, int column) { Instruction* line = new Instruction(OpLine); @@ -171,8 +196,47 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee) return type->getResultId(); } +Id Builder::makeForwardPointer(StorageClass storageClass) +{ + // Caching/uniquifying doesn't work here, because we don't know the + // pointee type and there can be multiple forward pointers of the same + // storage type. Somebody higher up in the stack must keep track. + Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeForwardPointer); + type->addImmediateOperand(storageClass); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardPointerType, Id pointee) +{ + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) { + type = groupedTypes[OpTypePointer][t]; + if (type->getImmediateOperand(0) == (unsigned)storageClass && + type->getIdOperand(1) == pointee) + return type->getResultId(); + } + + type = new Instruction(forwardPointerType, NoType, OpTypePointer); + type->addImmediateOperand(storageClass); + type->addIdOperand(pointee); + groupedTypes[OpTypePointer].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + Id Builder::makeIntegerType(int width, bool hasSign) { +#ifdef GLSLANG_WEB + assert(width == 32); + width = 32; +#endif + // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) { @@ -193,10 +257,8 @@ Id Builder::makeIntegerType(int width, bool hasSign) // deal with capabilities switch (width) { case 8: - addCapability(CapabilityInt8); - break; case 16: - addCapability(CapabilityInt16); + // these are currently handled by storage-type declarations and post processing break; case 64: addCapability(CapabilityInt64); @@ -210,6 +272,11 @@ Id Builder::makeIntegerType(int width, bool hasSign) Id Builder::makeFloatType(int width) { +#ifdef GLSLANG_WEB + assert(width == 32); + width = 32; +#endif + // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) { @@ -228,7 +295,7 @@ Id Builder::makeFloatType(int width) // deal with capabilities switch (width) { case 16: - addCapability(CapabilityFloat16); + // currently handled by storage-type declarations and post processing break; case 64: addCapability(CapabilityFloat64); @@ -333,6 +400,33 @@ Id Builder::makeMatrixType(Id component, int cols, int rows) return type->getResultId(); } +Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols) +{ + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixNV].size(); ++t) { + type = groupedTypes[OpTypeCooperativeMatrixNV][t]; + if (type->getIdOperand(0) == component && + type->getIdOperand(1) == scope && + type->getIdOperand(2) == rows && + type->getIdOperand(3) == cols) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixNV); + type->addIdOperand(component); + type->addIdOperand(scope); + type->addIdOperand(rows); + type->addIdOperand(cols); + groupedTypes[OpTypeCooperativeMatrixNV].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + + // TODO: performance: track arrays per stride // If a stride is supplied (non-zero) make an array. // If no stride (0), reuse previous array types. @@ -434,6 +528,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); +#ifndef GLSLANG_WEB // deal with capabilities switch (dim) { case DimBuffer: @@ -479,6 +574,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo addCapability(CapabilityImageMSArray); } } +#endif return type->getResultId(); } @@ -504,12 +600,29 @@ Id Builder::makeSampledImageType(Id imageType) return type->getResultId(); } +#ifndef GLSLANG_WEB +Id Builder::makeAccelerationStructureNVType() +{ + Instruction *type; + if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) { + type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV); + groupedTypes[OpTypeAccelerationStructureNV].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + } else { + type = groupedTypes[OpTypeAccelerationStructureNV].back(); + } + + return type->getResultId(); +} +#endif + Id Builder::getDerefTypeId(Id resultId) const { Id typeId = getTypeId(resultId); assert(isPointerType(typeId)); - return module.getInstruction(typeId)->getImmediateOperand(1); + return module.getInstruction(typeId)->getIdOperand(1); } Op Builder::getMostBasicTypeClass(Id typeId) const @@ -519,12 +632,6 @@ Op Builder::getMostBasicTypeClass(Id typeId) const Op typeClass = instr->getOpCode(); switch (typeClass) { - case OpTypeVoid: - case OpTypeBool: - case OpTypeInt: - case OpTypeFloat: - case OpTypeStruct: - return typeClass; case OpTypeVector: case OpTypeMatrix: case OpTypeArray: @@ -533,8 +640,7 @@ Op Builder::getMostBasicTypeClass(Id typeId) const case OpTypePointer: return getMostBasicTypeClass(instr->getIdOperand(1)); default: - assert(0); - return OpTypeFloat; + return typeClass; } } @@ -547,17 +653,21 @@ int Builder::getNumTypeConstituents(Id typeId) const case OpTypeBool: case OpTypeInt: case OpTypeFloat: + case OpTypePointer: return 1; case OpTypeVector: case OpTypeMatrix: return instr->getImmediateOperand(1); case OpTypeArray: { - Id lengthId = instr->getImmediateOperand(1); + Id lengthId = instr->getIdOperand(1); return module.getInstruction(lengthId)->getImmediateOperand(0); } case OpTypeStruct: return instr->getNumOperands(); + case OpTypeCooperativeMatrixNV: + // has only one constituent when used with OpCompositeConstruct. + return 1; default: assert(0); return 1; @@ -604,6 +714,7 @@ Id Builder::getContainedTypeId(Id typeId, int member) const case OpTypeMatrix: case OpTypeArray: case OpTypeRuntimeArray: + case OpTypeCooperativeMatrixNV: return instr->getIdOperand(0); case OpTypePointer: return instr->getIdOperand(1); @@ -621,6 +732,55 @@ Id Builder::getContainedTypeId(Id typeId) const return getContainedTypeId(typeId, 0); } +// Returns true if 'typeId' is or contains a scalar type declared with 'typeOp' +// of width 'width'. The 'width' is only consumed for int and float types. +// Returns false otherwise. +bool Builder::containsType(Id typeId, spv::Op typeOp, unsigned int width) const +{ + const Instruction& instr = *module.getInstruction(typeId); + + Op typeClass = instr.getOpCode(); + switch (typeClass) + { + case OpTypeInt: + case OpTypeFloat: + return typeClass == typeOp && instr.getImmediateOperand(0) == width; + case OpTypeStruct: + for (int m = 0; m < instr.getNumOperands(); ++m) { + if (containsType(instr.getIdOperand(m), typeOp, width)) + return true; + } + return false; + case OpTypePointer: + return false; + case OpTypeVector: + case OpTypeMatrix: + case OpTypeArray: + case OpTypeRuntimeArray: + return containsType(getContainedTypeId(typeId), typeOp, width); + default: + return typeClass == typeOp; + } +} + +// return true if the type is a pointer to PhysicalStorageBufferEXT or an +// array of such pointers. These require restrict/aliased decorations. +bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const +{ + const Instruction& instr = *module.getInstruction(typeId); + + Op typeClass = instr.getOpCode(); + switch (typeClass) + { + case OpTypePointer: + return getTypeStorageClass(typeId) == StorageClassPhysicalStorageBufferEXT; + case OpTypeArray: + return containsPhysicalStorageBufferOrArray(getContainedTypeId(typeId)); + default: + return false; + } +} + // See if a scalar constant of this type has already been created, so it // can be reused rather than duplicated. (Required by the specification). Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) @@ -794,6 +954,10 @@ Id Builder::makeFloatConstant(float f, bool specConstant) Id Builder::makeDoubleConstant(double d, bool specConstant) { +#ifdef GLSLANG_WEB + assert(0); + return NoResult; +#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(64); union { double db; unsigned long long ull; } u; @@ -818,10 +982,15 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) module.mapInstruction(c); return c->getResultId(); +#endif } Id Builder::makeFloat16Constant(float f16, bool specConstant) { +#ifdef GLSLANG_WEB + assert(0); + return NoResult; +#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(16); @@ -846,36 +1015,43 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant) module.mapInstruction(c); return c->getResultId(); +#endif } Id Builder::makeFpConstant(Id type, double d, bool specConstant) { - assert(isFloatType(type)); +#ifdef GLSLANG_WEB + const int width = 32; + assert(width == getScalarTypeWidth(type)); +#else + const int width = getScalarTypeWidth(type); +#endif - switch (getScalarTypeWidth(type)) { - case 16: - return makeFloat16Constant((float)d, specConstant); - case 32: - return makeFloatConstant((float)d, specConstant); - case 64: - return makeDoubleConstant(d, specConstant); - default: - break; - } + assert(isFloatType(type)); - assert(false); - return NoResult; + switch (width) { + case 16: + return makeFloat16Constant((float)d, specConstant); + case 32: + return makeFloatConstant((float)d, specConstant); + case 64: + return makeDoubleConstant(d, specConstant); + default: + break; + } + + assert(false); + return NoResult; } -Id Builder::findCompositeConstant(Op typeClass, const std::vector& comps) +Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector& comps) { Instruction* constant = 0; bool found = false; for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) { constant = groupedConstants[typeClass][i]; - // same shape? - if (constant->getNumOperands() != (int)comps.size()) + if (constant->getTypeId() != typeId) continue; // same contents? @@ -930,8 +1106,9 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector& members, boo case OpTypeVector: case OpTypeArray: case OpTypeMatrix: + case OpTypeCooperativeMatrixNV: if (! specConstant) { - Id existing = findCompositeConstant(typeClass, members); + Id existing = findCompositeConstant(typeClass, typeId, members); if (existing) return existing; } @@ -1161,11 +1338,13 @@ void Builder::makeDiscard() } // Comments in header -Id Builder::createVariable(StorageClass storageClass, Id type, const char* name) +Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer) { Id pointerType = makePointer(storageClass, type); Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable); inst->addImmediateOperand(storageClass); + if (initializer != NoResult) + inst->addIdOperand(initializer); switch (storageClass) { case StorageClassFunction: @@ -1193,20 +1372,65 @@ Id Builder::createUndefined(Id type) return inst->getResultId(); } +// av/vis/nonprivate are unnecessary and illegal for some storage classes. +spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const +{ + switch (sc) { + case spv::StorageClassUniform: + case spv::StorageClassWorkgroup: + case spv::StorageClassStorageBuffer: + case spv::StorageClassPhysicalStorageBufferEXT: + break; + default: + memoryAccess = spv::MemoryAccessMask(memoryAccess & + ~(spv::MemoryAccessMakePointerAvailableKHRMask | + spv::MemoryAccessMakePointerVisibleKHRMask | + spv::MemoryAccessNonPrivatePointerKHRMask)); + break; + } + return memoryAccess; +} + // Comments in header -void Builder::createStore(Id rValue, Id lValue) +void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { Instruction* store = new Instruction(OpStore); store->addIdOperand(lValue); store->addIdOperand(rValue); + + memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue)); + + if (memoryAccess != MemoryAccessMaskNone) { + store->addImmediateOperand(memoryAccess); + if (memoryAccess & spv::MemoryAccessAlignedMask) { + store->addImmediateOperand(alignment); + } + if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) { + store->addIdOperand(makeUintConstant(scope)); + } + } + buildPoint->addInstruction(std::unique_ptr(store)); } // Comments in header -Id Builder::createLoad(Id lValue) +Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad); load->addIdOperand(lValue); + + memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue)); + + if (memoryAccess != MemoryAccessMaskNone) { + load->addImmediateOperand(memoryAccess); + if (memoryAccess & spv::MemoryAccessAlignedMask) { + load->addImmediateOperand(alignment); + } + if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) { + load->addIdOperand(makeUintConstant(scope)); + } + } + buildPoint->addInstruction(std::unique_ptr(load)); return load->getResultId(); @@ -1240,7 +1464,7 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vec Id Builder::createArrayLength(Id base, unsigned int member) { - spv::Id intType = makeIntType(32); + spv::Id intType = makeUintType(32); Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength); length->addIdOperand(base); length->addImmediateOperand(member); @@ -1249,6 +1473,23 @@ Id Builder::createArrayLength(Id base, unsigned int member) return length->getResultId(); } +Id Builder::createCooperativeMatrixLength(Id type) +{ + spv::Id intType = makeUintType(32); + + // Generate code for spec constants if in spec constant operation + // generation mode. + if (generatingOpCodeForSpecConst) { + return createSpecConstantOp(OpCooperativeMatrixLengthNV, intType, std::vector(1, type), std::vector()); + } + + Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthNV); + length->addIdOperand(type); + buildPoint->addInstruction(std::unique_ptr(length)); + + return length->getResultId(); +} + Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index) { // Generate code for spec constants if in spec constant operation @@ -1331,7 +1572,7 @@ void Builder::createNoResultOp(Op opCode) buildPoint->addInstruction(std::unique_ptr(op)); } -// An opcode that has one operand, no result id, and no type +// An opcode that has one id operand, no result id, and no type void Builder::createNoResultOp(Op opCode, Id operand) { Instruction* op = new Instruction(opCode); @@ -1339,29 +1580,43 @@ void Builder::createNoResultOp(Op opCode, Id operand) buildPoint->addInstruction(std::unique_ptr(op)); } -// An opcode that has one operand, no result id, and no type +// An opcode that has one or more operands, no result id, and no type void Builder::createNoResultOp(Op opCode, const std::vector& operands) { Instruction* op = new Instruction(opCode); - for (auto it = operands.cbegin(); it != operands.cend(); ++it) + for (auto it = operands.cbegin(); it != operands.cend(); ++it) { op->addIdOperand(*it); + } + buildPoint->addInstruction(std::unique_ptr(op)); +} + +// An opcode that has multiple operands, no result id, and no type +void Builder::createNoResultOp(Op opCode, const std::vector& operands) +{ + Instruction* op = new Instruction(opCode); + for (auto it = operands.cbegin(); it != operands.cend(); ++it) { + if (it->isId) + op->addIdOperand(it->word); + else + op->addImmediateOperand(it->word); + } buildPoint->addInstruction(std::unique_ptr(op)); } void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics) { Instruction* op = new Instruction(OpControlBarrier); - op->addImmediateOperand(makeUintConstant(execution)); - op->addImmediateOperand(makeUintConstant(memory)); - op->addImmediateOperand(makeUintConstant(semantics)); + op->addIdOperand(makeUintConstant(execution)); + op->addIdOperand(makeUintConstant(memory)); + op->addIdOperand(makeUintConstant(semantics)); buildPoint->addInstruction(std::unique_ptr(op)); } void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics) { Instruction* op = new Instruction(OpMemoryBarrier); - op->addImmediateOperand(makeUintConstant(executionScope)); - op->addImmediateOperand(makeUintConstant(memorySemantics)); + op->addIdOperand(makeUintConstant(executionScope)); + op->addIdOperand(makeUintConstant(memorySemantics)); buildPoint->addInstruction(std::unique_ptr(op)); } @@ -1428,6 +1683,20 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector& operands) return op->getResultId(); } +Id Builder::createOp(Op opCode, Id typeId, const std::vector& operands) +{ + Instruction* op = new Instruction(getUniqueId(), typeId, opCode); + for (auto it = operands.cbegin(); it != operands.cend(); ++it) { + if (it->isId) + op->addIdOperand(it->word); + else + op->addImmediateOperand(it->word); + } + buildPoint->addInstruction(std::unique_ptr(op)); + + return op->getResultId(); +} + Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& operands, const std::vector& literals) { Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp); @@ -1570,7 +1839,8 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const // Accept all parameters needed to create a texture instruction. // Create the correct instruction based on the inputs, and make the call. -Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicitLod, const TextureParameters& parameters) +Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, + bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask) { static const int maxTextureArgs = 10; Id texArgs[maxTextureArgs] = {}; @@ -1587,11 +1857,18 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, if (parameters.component != NoResult) texArgs[numArgs++] = parameters.component; +#ifndef GLSLANG_WEB + if (parameters.granularity != NoResult) + texArgs[numArgs++] = parameters.granularity; + if (parameters.coarse != NoResult) + texArgs[numArgs++] = parameters.coarse; +#endif + // // Set up the optional arguments // - int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments - ++numArgs; // speculatively make room for the mask operand + int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments + ++numArgs; // speculatively make room for the mask operand ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand if (parameters.bias) { mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask); @@ -1623,9 +1900,11 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, texArgs[numArgs++] = parameters.offset; } if (parameters.offsets) { + addCapability(CapabilityImageGatherExtended); mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask); texArgs[numArgs++] = parameters.offsets; } +#ifndef GLSLANG_WEB if (parameters.sample) { mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask); texArgs[numArgs++] = parameters.sample; @@ -1637,6 +1916,14 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask); texArgs[numArgs++] = parameters.lodClamp; } + if (parameters.nonprivate) { + mask = mask | ImageOperandsNonPrivateTexelKHRMask; + } + if (parameters.volatil) { + mask = mask | ImageOperandsVolatileTexelKHRMask; + } +#endif + mask = mask | signExtensionMask; if (mask == ImageOperandsMaskNone) --numArgs; // undo speculative reservation for the mask argument else @@ -1651,6 +1938,9 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseFetch; else opCode = OpImageFetch; +#ifndef GLSLANG_WEB + } else if (parameters.granularity && parameters.coarse) { + opCode = OpImageSampleFootprintNV; } else if (gather) { if (parameters.Dref) if (sparse) @@ -1662,6 +1952,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseGather; else opCode = OpImageGather; +#endif } else if (explicitLod) { if (parameters.Dref) { if (proj) @@ -1772,9 +2063,6 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // Comments in header Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameters, bool isUnsignedResult) { - // All these need a capability - addCapability(CapabilityImageQuery); - // Figure out the result type Id resultType = 0; switch (opCode) { @@ -1813,11 +2101,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter break; } case OpImageQueryLod: -#ifdef AMD_EXTENSIONS resultType = makeVectorType(getScalarTypeId(getTypeId(parameters.coords)), 2); -#else - resultType = makeVectorType(makeFloatType(32), 2); -#endif break; case OpImageQueryLevels: case OpImageQuerySamples: @@ -1835,6 +2119,7 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter if (parameters.lod) query->addIdOperand(parameters.lod); buildPoint->addInstruction(std::unique_ptr(query)); + addCapability(CapabilityImageQuery); return query->getResultId(); } @@ -1999,7 +2284,8 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc // Go through the source arguments, each one could have either // a single or multiple components to contribute. for (unsigned int i = 0; i < sources.size(); ++i) { - if (isScalar(sources[i])) + + if (isScalar(sources[i]) || isPointer(sources[i])) latchResult(sources[i]); else if (isVector(sources[i])) accumulateVectorConstituents(sources[i]); @@ -2027,9 +2313,44 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& int numRows = getTypeNumRows(resultTypeId); Instruction* instr = module.getInstruction(componentTypeId); - Id bitCount = instr->getIdOperand(0); +#ifdef GLSLANG_WEB + const unsigned bitCount = 32; + assert(bitCount == instr->getImmediateOperand(0)); +#else + const unsigned bitCount = instr->getImmediateOperand(0); +#endif - // Will use a two step process + // Optimize matrix constructed from a bigger matrix + if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) { + // To truncate the matrix to a smaller number of rows/columns, we need to: + // 1. For each column, extract the column and truncate it to the required size using shuffle + // 2. Assemble the resulting matrix from all columns + Id matrix = sources[0]; + Id columnTypeId = getContainedTypeId(resultTypeId); + Id sourceColumnTypeId = getContainedTypeId(getTypeId(matrix)); + + std::vector channels; + for (int row = 0; row < numRows; ++row) + channels.push_back(row); + + std::vector matrixColumns; + for (int col = 0; col < numCols; ++col) { + std::vector indexes; + indexes.push_back(col); + Id colv = createCompositeExtract(matrix, sourceColumnTypeId, indexes); + setPrecision(colv, precision); + + if (numRows != getNumRows(matrix)) { + matrixColumns.push_back(createRvalueSwizzle(precision, columnTypeId, colv, channels)); + } else { + matrixColumns.push_back(colv); + } + } + + return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision); + } + + // Otherwise, will use a two step process // 1. make a compile-time 2D array of values // 2. construct a matrix from that array @@ -2283,11 +2604,16 @@ void Builder::clearAccessChain() accessChain.component = NoResult; accessChain.preSwizzleBaseType = NoType; accessChain.isRValue = false; + accessChain.coherentFlags.clear(); + accessChain.alignment = 0; } // Comments in header -void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType) +void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) { + accessChain.coherentFlags |= coherentFlags; + accessChain.alignment |= alignment; + // swizzles can be stacked in GLSL, but simplified to a single // one here; the base type doesn't change if (accessChain.preSwizzleBaseType == NoType) @@ -2309,7 +2635,7 @@ void Builder::accessChainPushSwizzle(std::vector& swizzle, Id preSwizz } // Comments in header -void Builder::accessChainStore(Id rvalue) +void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { assert(accessChain.isRValue == false); @@ -2327,11 +2653,17 @@ void Builder::accessChainStore(Id rvalue) source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle); } - createStore(source, base); + // take LSB of alignment + alignment = alignment & ~(alignment & (alignment-1)); + if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) { + memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + } + + createStore(source, base, memoryAccess, scope, alignment); } // Comments in header -Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType) +Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment) { Id id; @@ -2353,15 +2685,22 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu } } - if (constant) + if (constant) { id = createCompositeExtract(accessChain.base, swizzleBase, indexes); - else { - // make a new function variable for this r-value - Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable"); - - // store into it - createStore(accessChain.base, lValue); - + } else { + Id lValue = NoResult; + if (spvVersion >= Spv_1_4) { + // make a new function variable for this r-value, using an initializer, + // and mark it as NonWritable so that downstream it can be detected as a lookup + // table + lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable", + accessChain.base); + addDecoration(lValue, DecorationNonWritable); + } else { + lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable"); + // store into it + createStore(accessChain.base, lValue); + } // move base to the new variable accessChain.base = lValue; accessChain.isRValue = false; @@ -2374,8 +2713,15 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu id = accessChain.base; // no precision, it was set when this was defined } else { transferAccessChainSwizzle(true); + + // take LSB of alignment + alignment = alignment & ~(alignment & (alignment-1)); + if (getStorageClass(accessChain.base) == StorageClassPhysicalStorageBufferEXT) { + memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask); + } + // load through the access chain - id = createLoad(collapseAccessChain()); + id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment); setPrecision(id, precision); addDecoration(id, nonUniform); } @@ -2451,42 +2797,6 @@ Id Builder::accessChainGetInferredType() return type; } -// comment in header -void Builder::eliminateDeadDecorations() { - std::unordered_set reachable_blocks; - std::unordered_set unreachable_definitions; - // Collect IDs defined in unreachable blocks. For each function, label the - // reachable blocks first. Then for each unreachable block, collect the - // result IDs of the instructions in it. - for (std::vector::const_iterator fi = module.getFunctions().cbegin(); - fi != module.getFunctions().cend(); fi++) { - Function* f = *fi; - Block* entry = f->getEntryBlock(); - inReadableOrder(entry, [&reachable_blocks](const Block* b) { - reachable_blocks.insert(b); - }); - for (std::vector::const_iterator bi = f->getBlocks().cbegin(); - bi != f->getBlocks().cend(); bi++) { - Block* b = *bi; - if (!reachable_blocks.count(b)) { - for (std::vector >::const_iterator - ii = b->getInstructions().cbegin(); - ii != b->getInstructions().cend(); ii++) { - Instruction* i = ii->get(); - unreachable_definitions.insert(i->getResultId()); - } - } - } - } - decorations.erase(std::remove_if(decorations.begin(), decorations.end(), - [&unreachable_definitions](std::unique_ptr& I) -> bool { - Instruction* inst = I.get(); - Id decoration_id = inst->getIdOperand(0); - return unreachable_definitions.count(decoration_id) != 0; - }), - decorations.end()); -} - void Builder::dump(std::vector& out) const { // Header, before first instructions: @@ -2692,14 +3002,14 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control) } void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, - unsigned int dependencyLength) + const std::vector& operands) { Instruction* merge = new Instruction(OpLoopMerge); merge->addIdOperand(mergeBlock->getId()); merge->addIdOperand(continueBlock->getId()); merge->addImmediateOperand(control); - if ((control & LoopControlDependencyLengthMask) != 0) - merge->addImmediateOperand(dependencyLength); + for (int op = 0; op < (int)operands.size(); ++op) + merge->addImmediateOperand(operands[op]); buildPoint->addInstruction(std::unique_ptr(merge)); } @@ -2717,7 +3027,8 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els // OpSource // [OpSourceContinued] // ... -void Builder::dumpSourceInstructions(std::vector& out) const +void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& text, + std::vector& out) const { const int maxWordCount = 0xFFFF; const int opSourceWordCount = 4; @@ -2729,14 +3040,14 @@ void Builder::dumpSourceInstructions(std::vector& out) const sourceInst.addImmediateOperand(source); sourceInst.addImmediateOperand(sourceVersion); // File operand - if (sourceFileStringId != NoResult) { - sourceInst.addIdOperand(sourceFileStringId); + if (fileId != NoResult) { + sourceInst.addIdOperand(fileId); // Source operand - if (sourceText.size() > 0) { + if (text.size() > 0) { int nextByte = 0; std::string subString; - while ((int)sourceText.size() - nextByte > 0) { - subString = sourceText.substr(nextByte, nonNullBytesPerInstruction); + while ((int)text.size() - nextByte > 0) { + subString = text.substr(nextByte, nonNullBytesPerInstruction); if (nextByte == 0) { // OpSource sourceInst.addStringOperand(subString.c_str()); @@ -2756,6 +3067,14 @@ void Builder::dumpSourceInstructions(std::vector& out) const } } +// Dump an OpSource[Continued] sequence for the source and every include file +void Builder::dumpSourceInstructions(std::vector& out) const +{ + dumpSourceInstructions(sourceFileStringId, sourceText, out); + for (auto iItr = includeFiles.begin(); iItr != includeFiles.end(); ++iItr) + dumpSourceInstructions(iItr->first, *iItr->second, out); +} + void Builder::dumpInstructions(std::vector& out, const std::vector >& instructions) const { for (int i = 0; i < (int)instructions.size(); ++i) { diff --git a/Externals/glslang/SPIRV/SpvBuilder.h b/Externals/glslang/SPIRV/SpvBuilder.h old mode 100755 new mode 100644 index 099b1d957f..31fee975fc --- a/Externals/glslang/SPIRV/SpvBuilder.h +++ b/Externals/glslang/SPIRV/SpvBuilder.h @@ -1,6 +1,6 @@ // // Copyright (C) 2014-2015 LunarG, Inc. -// Copyright (C) 2015-2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. // Copyright (C) 2017 ARM Limited. // // All rights reserved. @@ -57,9 +57,19 @@ #include #include #include +#include namespace spv { +typedef enum { + Spv_1_0 = (1 << 16), + Spv_1_1 = (1 << 16) | (1 << 8), + Spv_1_2 = (1 << 16) | (2 << 8), + Spv_1_3 = (1 << 16) | (3 << 8), + Spv_1_4 = (1 << 16) | (4 << 8), + Spv_1_5 = (1 << 16) | (5 << 8), +} SpvVersion; + class Builder { public: Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger); @@ -74,18 +84,47 @@ public: source = lang; sourceVersion = version; } + spv::Id getStringId(const std::string& str) + { + auto sItr = stringIds.find(str); + if (sItr != stringIds.end()) + return sItr->second; + spv::Id strId = getUniqueId(); + Instruction* fileString = new Instruction(strId, NoType, OpString); + const char* file_c_str = str.c_str(); + fileString->addStringOperand(file_c_str); + strings.push_back(std::unique_ptr(fileString)); + stringIds[file_c_str] = strId; + return strId; + } void setSourceFile(const std::string& file) { - Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString); - fileString->addStringOperand(file.c_str()); - sourceFileStringId = fileString->getResultId(); - strings.push_back(std::unique_ptr(fileString)); + sourceFileStringId = getStringId(file); } void setSourceText(const std::string& text) { sourceText = text; } void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); } void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); } void setEmitOpLines() { emitOpLines = true; } void addExtension(const char* ext) { extensions.insert(ext); } + void removeExtension(const char* ext) + { + extensions.erase(ext); + } + void addIncorporatedExtension(const char* ext, SpvVersion incorporatedVersion) + { + if (getSpvVersion() < static_cast(incorporatedVersion)) + addExtension(ext); + } + void promoteIncorporatedExtension(const char* baseExt, const char* promoExt, SpvVersion incorporatedVersion) + { + removeExtension(baseExt); + addIncorporatedExtension(promoExt, incorporatedVersion); + } + void addInclude(const std::string& name, const std::string& text) + { + spv::Id incId = getStringId(name); + includeFiles[incId] = &text; + } Id import(const char*); void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem) { @@ -106,16 +145,25 @@ public: return id; } - // Log the current line, and if different than the last one, - // issue a new OpLine, using the current file name. + // Generate OpLine for non-filename-based #line directives (ie no filename + // seen yet): Log the current line, and if different than the last one, + // issue a new OpLine using the new line and current source file name. void setLine(int line); + + // If filename null, generate OpLine for non-filename-based line directives, + // else do filename-based: Log the current line and file, and if different + // than the last one, issue a new OpLine using the new line and file + // name. + void setLine(int line, const char* filename); // Low-level OpLine. See setLine() for a layered helper. void addLine(Id fileName, int line, int column); // For creating new types (will return old type if the requested one was already made). Id makeVoidType(); Id makeBoolType(); - Id makePointer(StorageClass, Id type); + Id makePointer(StorageClass, Id pointee); + Id makeForwardPointer(StorageClass); + Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee); Id makeIntegerType(int width, bool hasSign); // generic Id makeIntType(int width) { return makeIntegerType(width, true); } Id makeUintType(int width) { return makeIntegerType(width, false); } @@ -130,6 +178,10 @@ public: Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format); Id makeSamplerType(); Id makeSampledImageType(Id imageType); + Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols); + + // accelerationStructureNV type + Id makeAccelerationStructureNVType(); // For querying about types. Id getTypeId(Id resultId) const { return module.getTypeId(resultId); } @@ -150,6 +202,7 @@ public: bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); } bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); } bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); } + bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); } bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); } bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); } @@ -163,10 +216,17 @@ public: bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; } bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; } bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; } - bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId); } +#ifdef GLSLANG_WEB + bool isCooperativeMatrixType(Id typeId)const { return false; } +#else + bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; } +#endif + bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); } bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; } bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; } bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; } + bool containsType(Id typeId, Op typeOp, unsigned int width) const; + bool containsPhysicalStorageBufferOrArray(Id typeId) const; bool isConstantOpCode(Op opcode) const; bool isSpecConstantOpCode(Op opcode) const; @@ -267,16 +327,16 @@ public: void makeDiscard(); // Create a global or function local or IO variable. - Id createVariable(StorageClass, Id type, const char* name = 0); + Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult); // Create an intermediate with an undefined value. Id createUndefined(Id type); // Store into an Id and return the l-value - void createStore(Id rValue, Id lValue); + void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // Load from an Id and return it - Id createLoad(Id lValue); + Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // Create an OpAccessChain instruction Id createAccessChain(StorageClass, Id base, const std::vector& offsets); @@ -284,6 +344,9 @@ public: // Create an OpArrayLength instruction Id createArrayLength(Id base, unsigned int member); + // Create an OpCooperativeMatrixLengthNV instruction + Id createCooperativeMatrixLength(Id type); + // Create an OpCompositeExtract instruction Id createCompositeExtract(Id composite, Id typeId, unsigned index); Id createCompositeExtract(Id composite, Id typeId, const std::vector& indexes); @@ -296,12 +359,14 @@ public: void createNoResultOp(Op); void createNoResultOp(Op, Id operand); void createNoResultOp(Op, const std::vector& operands); + void createNoResultOp(Op, const std::vector& operands); void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask); void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics); Id createUnaryOp(Op, Id typeId, Id operand); Id createBinOp(Op, Id typeId, Id operand1, Id operand2); Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3); Id createOp(Op, Id typeId, const std::vector& operands); + Id createOp(Op, Id typeId, const std::vector& operands); Id createFunctionCall(spv::Function*, const std::vector&); Id createSpecConstantOp(Op, Id typeId, const std::vector& operands, const std::vector& literals); @@ -363,10 +428,15 @@ public: Id component; Id texelOut; Id lodClamp; + Id granularity; + Id coarse; + bool nonprivate; + bool volatil; }; // Select the correct texture operation based on all inputs, and emit the correct instruction - Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicit, const TextureParameters&); + Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, + bool noImplicit, const TextureParameters&, ImageOperandsMask); // Emit the OpTextureQuery* instruction that was passed in. // Figure out the right return value and type, and return it. @@ -502,6 +572,52 @@ public: Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value + unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment. + + // Accumulate whether anything in the chain of structures has coherent decorations. + struct CoherentFlags { + CoherentFlags() { clear(); } +#ifdef GLSLANG_WEB + void clear() { } + bool isVolatile() const { return false; } + CoherentFlags operator |=(const CoherentFlags &other) { return *this; } +#else + bool isVolatile() const { return volatil; } + + unsigned coherent : 1; + unsigned devicecoherent : 1; + unsigned queuefamilycoherent : 1; + unsigned workgroupcoherent : 1; + unsigned subgroupcoherent : 1; + unsigned nonprivate : 1; + unsigned volatil : 1; + unsigned isImage : 1; + + void clear() { + coherent = 0; + devicecoherent = 0; + queuefamilycoherent = 0; + workgroupcoherent = 0; + subgroupcoherent = 0; + nonprivate = 0; + volatil = 0; + isImage = 0; + } + + CoherentFlags operator |=(const CoherentFlags &other) { + coherent |= other.coherent; + devicecoherent |= other.devicecoherent; + queuefamilycoherent |= other.queuefamilycoherent; + workgroupcoherent |= other.workgroupcoherent; + subgroupcoherent |= other.subgroupcoherent; + nonprivate |= other.nonprivate; + volatil |= other.volatil; + isImage |= other.isImage; + return *this; + } +#endif + }; + CoherentFlags coherentFlags; }; // @@ -531,30 +647,34 @@ public: } // push offset onto the end of the chain - void accessChainPush(Id offset) + void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) { accessChain.indexChain.push_back(offset); + accessChain.coherentFlags |= coherentFlags; + accessChain.alignment |= alignment; } // push new swizzle onto the end of any existing swizzle, merging into a single swizzle - void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType); + void accessChainPushSwizzle(std::vector& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment); // push a dynamic component selection onto the access chain, only applicable with a // non-trivial swizzle or no swizzle - void accessChainPushComponent(Id component, Id preSwizzleBaseType) + void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment) { if (accessChain.swizzle.size() != 1) { accessChain.component = component; if (accessChain.preSwizzleBaseType == NoType) accessChain.preSwizzleBaseType = preSwizzleBaseType; } + accessChain.coherentFlags |= coherentFlags; + accessChain.alignment |= alignment; } // use accessChain and swizzle to store value - void accessChainStore(Id rvalue); + void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // use accessChain and swizzle to load an r-value - Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType); + Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0); // get the direct pointer for an l-value Id accessChainGetLValue(); @@ -563,14 +683,27 @@ public: // based on the type of the base and the chain of dereferences. Id accessChainGetInferredType(); - // Remove OpDecorate instructions whose operands are defined in unreachable - // blocks. - void eliminateDeadDecorations(); + // Add capabilities, extensions, remove unneeded decorations, etc., + // based on the resulting SPIR-V. + void postProcess(); + + // Prune unreachable blocks in the CFG and remove unneeded decorations. + void postProcessCFG(); + +#ifndef GLSLANG_WEB + // Add capabilities, extensions based on instructions in the module. + void postProcessFeatures(); + // Hook to visit each instruction in a block in a function + void postProcess(Instruction&); + // Hook to visit each non-32-bit sized float/int operation in a block. + void postProcessType(const Instruction&, spv::Id typeId); +#endif + void dump(std::vector&) const; void createBranch(Block* block); void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock); - void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, unsigned int dependencyLength); + void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, const std::vector& operands); // Sets to generate opcode for specialization constants. void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; } @@ -584,7 +717,7 @@ public: Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant); Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value); Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2); - Id findCompositeConstant(Op typeClass, const std::vector& comps); + Id findCompositeConstant(Op typeClass, Id typeId, const std::vector& comps); Id findStructConstant(Id typeId, const std::vector& comps); Id collapseAccessChain(); void remapDynamicSwizzle(); @@ -593,8 +726,10 @@ public: void createAndSetNoPredecessorBlock(const char*); void createSelectionMerge(Block* mergeBlock, unsigned int control); void dumpSourceInstructions(std::vector&) const; + void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector&) const; void dumpInstructions(std::vector&, const std::vector >&) const; void dumpModuleProcesses(std::vector&) const; + spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const; unsigned int spvVersion; // the version of SPIR-V to emit in the header SourceLanguage source; @@ -602,6 +737,7 @@ public: spv::Id sourceFileStringId; std::string sourceText; int currentLine; + const char* currentFile; bool emitOpLines; std::set extensions; std::vector sourceExtensions; @@ -639,6 +775,12 @@ public: // Our loop stack. std::stack loops; + // map from strings to their string ids + std::unordered_map stringIds; + + // map from include file name ids to their contents + std::map includeFiles; + // The stream for outputting warnings and errors. SpvBuildLogger* logger; }; // end Builder class diff --git a/Externals/glslang/SPIRV/SpvPostProcess.cpp b/Externals/glslang/SPIRV/SpvPostProcess.cpp new file mode 100644 index 0000000000..d40174d172 --- /dev/null +++ b/Externals/glslang/SPIRV/SpvPostProcess.cpp @@ -0,0 +1,450 @@ +// +// 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. + +// +// Post-processing for SPIR-V IR, in internal form, not standard binary form. +// + +#include +#include + +#include +#include +#include + +#include "SpvBuilder.h" + +#include "spirv.hpp" +#include "GlslangToSpv.h" +#include "SpvBuilder.h" +namespace spv { + #include "GLSL.std.450.h" + #include "GLSL.ext.KHR.h" + #include "GLSL.ext.EXT.h" + #include "GLSL.ext.AMD.h" + #include "GLSL.ext.NV.h" +} + +namespace spv { + +#ifndef GLSLANG_WEB +// Hook to visit each operand type and result type of an instruction. +// Will be called multiple times for one instruction, once for each typed +// operand and the result. +void Builder::postProcessType(const Instruction& inst, Id typeId) +{ + // Characterize the type being questioned + Id basicTypeOp = getMostBasicTypeClass(typeId); + int width = 0; + if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt) + width = getScalarTypeWidth(typeId); + + // Do opcode-specific checks + switch (inst.getOpCode()) { + case OpLoad: + case OpStore: + if (basicTypeOp == OpTypeStruct) { + if (containsType(typeId, OpTypeInt, 8)) + addCapability(CapabilityInt8); + if (containsType(typeId, OpTypeInt, 16)) + addCapability(CapabilityInt16); + if (containsType(typeId, OpTypeFloat, 16)) + addCapability(CapabilityFloat16); + } else { + StorageClass storageClass = getStorageClass(inst.getIdOperand(0)); + if (width == 8) { + switch (storageClass) { + case StorageClassPhysicalStorageBufferEXT: + case StorageClassUniform: + case StorageClassStorageBuffer: + case StorageClassPushConstant: + break; + default: + addCapability(CapabilityInt8); + break; + } + } else if (width == 16) { + switch (storageClass) { + case StorageClassPhysicalStorageBufferEXT: + case StorageClassUniform: + case StorageClassStorageBuffer: + case StorageClassPushConstant: + case StorageClassInput: + case StorageClassOutput: + break; + default: + if (basicTypeOp == OpTypeInt) + addCapability(CapabilityInt16); + if (basicTypeOp == OpTypeFloat) + addCapability(CapabilityFloat16); + break; + } + } + } + break; + case OpAccessChain: + case OpPtrAccessChain: + case OpCopyObject: + break; + case OpFConvert: + case OpSConvert: + case OpUConvert: + // Look for any 8/16-bit storage capabilities. If there are none, assume that + // the convert instruction requires the Float16/Int8/16 capability. + if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) { + bool foundStorage = false; + for (auto it = capabilities.begin(); it != capabilities.end(); ++it) { + spv::Capability cap = *it; + if (cap == spv::CapabilityStorageInputOutput16 || + cap == spv::CapabilityStoragePushConstant16 || + cap == spv::CapabilityStorageUniformBufferBlock16 || + cap == spv::CapabilityStorageUniform16) { + foundStorage = true; + break; + } + } + if (!foundStorage) { + if (containsType(typeId, OpTypeFloat, 16)) + addCapability(CapabilityFloat16); + if (containsType(typeId, OpTypeInt, 16)) + addCapability(CapabilityInt16); + } + } + if (containsType(typeId, OpTypeInt, 8)) { + bool foundStorage = false; + for (auto it = capabilities.begin(); it != capabilities.end(); ++it) { + spv::Capability cap = *it; + if (cap == spv::CapabilityStoragePushConstant8 || + cap == spv::CapabilityUniformAndStorageBuffer8BitAccess || + cap == spv::CapabilityStorageBuffer8BitAccess) { + foundStorage = true; + break; + } + } + if (!foundStorage) { + addCapability(CapabilityInt8); + } + } + break; + case OpExtInst: + switch (inst.getImmediateOperand(1)) { + case GLSLstd450Frexp: + case GLSLstd450FrexpStruct: + if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeInt, 16)) + addExtension(spv::E_SPV_AMD_gpu_shader_int16); + break; + case GLSLstd450InterpolateAtCentroid: + case GLSLstd450InterpolateAtSample: + case GLSLstd450InterpolateAtOffset: + if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeFloat, 16)) + addExtension(spv::E_SPV_AMD_gpu_shader_half_float); + break; + default: + break; + } + break; + default: + if (basicTypeOp == OpTypeFloat && width == 16) + addCapability(CapabilityFloat16); + if (basicTypeOp == OpTypeInt && width == 16) + addCapability(CapabilityInt16); + if (basicTypeOp == OpTypeInt && width == 8) + addCapability(CapabilityInt8); + break; + } +} + +// Called for each instruction that resides in a block. +void Builder::postProcess(Instruction& inst) +{ + // Add capabilities based simply on the opcode. + switch (inst.getOpCode()) { + case OpExtInst: + switch (inst.getImmediateOperand(1)) { + case GLSLstd450InterpolateAtCentroid: + case GLSLstd450InterpolateAtSample: + case GLSLstd450InterpolateAtOffset: + addCapability(CapabilityInterpolationFunction); + break; + default: + break; + } + break; + case OpDPdxFine: + case OpDPdyFine: + case OpFwidthFine: + case OpDPdxCoarse: + case OpDPdyCoarse: + case OpFwidthCoarse: + addCapability(CapabilityDerivativeControl); + break; + + case OpImageQueryLod: + case OpImageQuerySize: + case OpImageQuerySizeLod: + case OpImageQuerySamples: + case OpImageQueryLevels: + addCapability(CapabilityImageQuery); + break; + + case OpGroupNonUniformPartitionNV: + addExtension(E_SPV_NV_shader_subgroup_partitioned); + addCapability(CapabilityGroupNonUniformPartitionedNV); + break; + + case OpLoad: + case OpStore: + { + // For any load/store to a PhysicalStorageBufferEXT, walk the accesschain + // index list to compute the misalignment. The pre-existing alignment value + // (set via Builder::AccessChain::alignment) only accounts for the base of + // the reference type and any scalar component selection in the accesschain, + // and this function computes the rest from the SPIR-V Offset decorations. + Instruction *accessChain = module.getInstruction(inst.getIdOperand(0)); + if (accessChain->getOpCode() == OpAccessChain) { + Instruction *base = module.getInstruction(accessChain->getIdOperand(0)); + // Get the type of the base of the access chain. It must be a pointer type. + Id typeId = base->getTypeId(); + Instruction *type = module.getInstruction(typeId); + assert(type->getOpCode() == OpTypePointer); + if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) { + break; + } + // Get the pointee type. + typeId = type->getIdOperand(1); + type = module.getInstruction(typeId); + // Walk the index list for the access chain. For each index, find any + // misalignment that can apply when accessing the member/element via + // Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all + // together. + int alignment = 0; + for (int i = 1; i < accessChain->getNumOperands(); ++i) { + Instruction *idx = module.getInstruction(accessChain->getIdOperand(i)); + if (type->getOpCode() == OpTypeStruct) { + assert(idx->getOpCode() == OpConstant); + unsigned int c = idx->getImmediateOperand(0); + + const auto function = [&](const std::unique_ptr& decoration) { + if (decoration.get()->getOpCode() == OpMemberDecorate && + decoration.get()->getIdOperand(0) == typeId && + decoration.get()->getImmediateOperand(1) == c && + (decoration.get()->getImmediateOperand(2) == DecorationOffset || + decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) { + alignment |= decoration.get()->getImmediateOperand(3); + } + }; + std::for_each(decorations.begin(), decorations.end(), function); + // get the next member type + typeId = type->getIdOperand(c); + type = module.getInstruction(typeId); + } else if (type->getOpCode() == OpTypeArray || + type->getOpCode() == OpTypeRuntimeArray) { + const auto function = [&](const std::unique_ptr& decoration) { + if (decoration.get()->getOpCode() == OpDecorate && + decoration.get()->getIdOperand(0) == typeId && + decoration.get()->getImmediateOperand(1) == DecorationArrayStride) { + alignment |= decoration.get()->getImmediateOperand(2); + } + }; + std::for_each(decorations.begin(), decorations.end(), function); + // Get the element type + typeId = type->getIdOperand(0); + type = module.getInstruction(typeId); + } else { + // Once we get to any non-aggregate type, we're done. + break; + } + } + assert(inst.getNumOperands() >= 3); + unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1); + assert(memoryAccess & MemoryAccessAlignedMask); + static_cast(memoryAccess); + // Compute the index of the alignment operand. + int alignmentIdx = 2; + if (inst.getOpCode() == OpStore) + alignmentIdx++; + // Merge new and old (mis)alignment + alignment |= inst.getImmediateOperand(alignmentIdx); + // Pick the LSB + alignment = alignment & ~(alignment & (alignment-1)); + // update the Aligned operand + inst.setImmediateOperand(alignmentIdx, alignment); + } + break; + } + + default: + break; + } + + // Checks based on type + if (inst.getTypeId() != NoType) + postProcessType(inst, inst.getTypeId()); + for (int op = 0; op < inst.getNumOperands(); ++op) { + if (inst.isIdOperand(op)) { + // In blocks, these are always result ids, but we are relying on + // getTypeId() to return NoType for things like OpLabel. + if (getTypeId(inst.getIdOperand(op)) != NoType) + postProcessType(inst, getTypeId(inst.getIdOperand(op))); + } + } +} +#endif + +// comment in header +void Builder::postProcessCFG() +{ + // reachableBlocks is the set of blockss reached via control flow, or which are + // unreachable continue targert or unreachable merge. + std::unordered_set reachableBlocks; + std::unordered_map headerForUnreachableContinue; + std::unordered_set unreachableMerges; + std::unordered_set unreachableDefinitions; + // Collect IDs defined in unreachable blocks. For each function, label the + // reachable blocks first. Then for each unreachable block, collect the + // result IDs of the instructions in it. + for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) { + Function* f = *fi; + Block* entry = f->getEntryBlock(); + inReadableOrder(entry, + [&reachableBlocks, &unreachableMerges, &headerForUnreachableContinue] + (Block* b, ReachReason why, Block* header) { + reachableBlocks.insert(b); + if (why == ReachDeadContinue) headerForUnreachableContinue[b] = header; + if (why == ReachDeadMerge) unreachableMerges.insert(b); + }); + for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) { + Block* b = *bi; + if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) { + auto ii = b->getInstructions().cbegin(); + ++ii; // Keep potential decorations on the label. + for (; ii != b->getInstructions().cend(); ++ii) + unreachableDefinitions.insert(ii->get()->getResultId()); + } else if (reachableBlocks.count(b) == 0) { + // The normal case for unreachable code. All definitions are considered dead. + for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ++ii) + unreachableDefinitions.insert(ii->get()->getResultId()); + } + } + } + + // Modify unreachable merge blocks and unreachable continue targets. + // Delete their contents. + for (auto mergeIter = unreachableMerges.begin(); mergeIter != unreachableMerges.end(); ++mergeIter) { + (*mergeIter)->rewriteAsCanonicalUnreachableMerge(); + } + for (auto continueIter = headerForUnreachableContinue.begin(); + continueIter != headerForUnreachableContinue.end(); + ++continueIter) { + Block* continue_target = continueIter->first; + Block* header = continueIter->second; + continue_target->rewriteAsCanonicalUnreachableContinue(header); + } + + // Remove unneeded decorations, for unreachable instructions + decorations.erase(std::remove_if(decorations.begin(), decorations.end(), + [&unreachableDefinitions](std::unique_ptr& I) -> bool { + Id decoration_id = I.get()->getIdOperand(0); + return unreachableDefinitions.count(decoration_id) != 0; + }), + decorations.end()); +} + +#ifndef GLSLANG_WEB +// comment in header +void Builder::postProcessFeatures() { + // Add per-instruction capabilities, extensions, etc., + + // Look for any 8/16 bit type in physical storage buffer class, and set the + // appropriate capability. This happens in createSpvVariable for other storage + // classes, but there isn't always a variable for physical storage buffer. + for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) { + Instruction* type = groupedTypes[OpTypePointer][t]; + if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) { + if (containsType(type->getIdOperand(1), OpTypeInt, 8)) { + addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5); + addCapability(spv::CapabilityStorageBuffer8BitAccess); + } + if (containsType(type->getIdOperand(1), OpTypeInt, 16) || + containsType(type->getIdOperand(1), OpTypeFloat, 16)) { + addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); + addCapability(spv::CapabilityStorageBuffer16BitAccess); + } + } + } + + // process all block-contained instructions + for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) { + Function* f = *fi; + for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) { + Block* b = *bi; + for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++) + postProcess(*ii->get()); + + // For all local variables that contain pointers to PhysicalStorageBufferEXT, check whether + // there is an existing restrict/aliased decoration. If we don't find one, add Aliased as the + // default. + for (auto vi = b->getLocalVariables().cbegin(); vi != b->getLocalVariables().cend(); vi++) { + const Instruction& inst = *vi->get(); + Id resultId = inst.getResultId(); + if (containsPhysicalStorageBufferOrArray(getDerefTypeId(resultId))) { + bool foundDecoration = false; + const auto function = [&](const std::unique_ptr& decoration) { + if (decoration.get()->getIdOperand(0) == resultId && + decoration.get()->getOpCode() == OpDecorate && + (decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT || + decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) { + foundDecoration = true; + } + }; + std::for_each(decorations.begin(), decorations.end(), function); + if (!foundDecoration) { + addDecoration(resultId, spv::DecorationAliasedPointerEXT); + } + } + } + } + } +} +#endif + +// comment in header +void Builder::postProcess() { + postProcessCFG(); +#ifndef GLSLANG_WEB + postProcessFeatures(); +#endif +} + +}; // end spv namespace diff --git a/Externals/glslang/SPIRV/SpvTools.cpp b/Externals/glslang/SPIRV/SpvTools.cpp new file mode 100644 index 0000000000..97bd4e7427 --- /dev/null +++ b/Externals/glslang/SPIRV/SpvTools.cpp @@ -0,0 +1,216 @@ +// +// Copyright (C) 2014-2016 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. + +// +// Call into SPIRV-Tools to disassemble, validate, and optimize. +// + +#if ENABLE_OPT + +#include +#include + +#include "SpvTools.h" +#include "spirv-tools/optimizer.hpp" +#include "spirv-tools/libspirv.h" + +namespace glslang { + +// Translate glslang's view of target versioning to what SPIRV-Tools uses. +spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger) +{ + switch (spvVersion.vulkan) { + case glslang::EShTargetVulkan_1_0: + return spv_target_env::SPV_ENV_VULKAN_1_0; + case glslang::EShTargetVulkan_1_1: + switch (spvVersion.spv) { + case EShTargetSpv_1_0: + case EShTargetSpv_1_1: + case EShTargetSpv_1_2: + case EShTargetSpv_1_3: + return spv_target_env::SPV_ENV_VULKAN_1_1; + case EShTargetSpv_1_4: + return spv_target_env::SPV_ENV_VULKAN_1_1_SPIRV_1_4; + default: + logger->missingFunctionality("Target version for SPIRV-Tools validator"); + return spv_target_env::SPV_ENV_VULKAN_1_1; + } + case glslang::EShTargetVulkan_1_2: + return spv_target_env::SPV_ENV_VULKAN_1_2; + default: + break; + } + + if (spvVersion.openGl > 0) + return spv_target_env::SPV_ENV_OPENGL_4_5; + + logger->missingFunctionality("Target version for SPIRV-Tools validator"); + return spv_target_env::SPV_ENV_UNIVERSAL_1_0; +} + + +// Use the SPIRV-Tools disassembler to print SPIR-V. +void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv) +{ + // disassemble + spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3); + spv_text text; + spv_diagnostic diagnostic = nullptr; + spvBinaryToText(context, spirv.data(), spirv.size(), + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT, + &text, &diagnostic); + + // dump + if (diagnostic == nullptr) + out << text->str; + else + spvDiagnosticPrint(diagnostic); + + // teardown + spvDiagnosticDestroy(diagnostic); + spvContextDestroy(context); +} + +// Apply the SPIRV-Tools validator to generated SPIR-V. +void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger* logger, bool prelegalization) +{ + // validate + spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); + spv_const_binary_t binary = { spirv.data(), spirv.size() }; + spv_diagnostic diagnostic = nullptr; + spv_validator_options options = spvValidatorOptionsCreate(); + spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); + spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization); + spvValidateWithOptions(context, options, &binary, &diagnostic); + + // report + if (diagnostic != nullptr) { + logger->error("SPIRV-Tools Validation Errors"); + logger->error(diagnostic->error); + } + + // tear down + spvValidatorOptionsDestroy(options); + spvDiagnosticDestroy(diagnostic); + spvContextDestroy(context); +} + +// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of +// legalizing HLSL SPIR-V. +void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector& spirv, + spv::SpvBuildLogger*, const SpvOptions* options) +{ + spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; + + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer( + [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { + auto &out = std::cerr; + switch (level) + { + case SPV_MSG_FATAL: + case SPV_MSG_INTERNAL_ERROR: + case SPV_MSG_ERROR: + out << "error: "; + break; + case SPV_MSG_WARNING: + out << "warning: "; + break; + case SPV_MSG_INFO: + case SPV_MSG_DEBUG: + out << "info: "; + break; + default: + break; + } + if (source) + { + out << source << ":"; + } + out << position.line << ":" << position.column << ":" << position.index << ":"; + if (message) + { + out << " " << message; + } + out << std::endl; + }); + + // If debug (specifically source line info) is being generated, propagate + // line information into all SPIR-V instructions. This avoids loss of + // information when instructions are deleted or moved. Later, remove + // redundant information to minimize final SPRIR-V size. + if (options->generateDebugInfo) { + optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass()); + } + optimizer.RegisterPass(spvtools::CreateWrapOpKillPass()); + optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass()); + optimizer.RegisterPass(spvtools::CreateMergeReturnPass()); + optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass()); + optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass()); + optimizer.RegisterPass(spvtools::CreateScalarReplacementPass()); + optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass()); + optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass()); + optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass()); + optimizer.RegisterPass(spvtools::CreateSimplificationPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateVectorDCEPass()); + optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass()); + optimizer.RegisterPass(spvtools::CreateBlockMergePass()); + optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass()); + optimizer.RegisterPass(spvtools::CreateIfConversionPass()); + optimizer.RegisterPass(spvtools::CreateSimplificationPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateVectorDCEPass()); + optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass()); + if (options->optimizeSize) { + optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); + } + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); + if (options->generateDebugInfo) { + optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass()); + } + + spvtools::OptimizerOptions spvOptOptions; + spvOptOptions.set_run_validator(false); // The validator may run as a seperate step later on + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +}; // end namespace glslang + +#endif diff --git a/Externals/glslang/SPIRV/SpvTools.h b/Externals/glslang/SPIRV/SpvTools.h new file mode 100644 index 0000000000..59c914da0b --- /dev/null +++ b/Externals/glslang/SPIRV/SpvTools.h @@ -0,0 +1,82 @@ +// +// Copyright (C) 2014-2016 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. + +// +// Call into SPIRV-Tools to disassemble, validate, and optimize. +// + +#pragma once +#ifndef GLSLANG_SPV_TOOLS_H +#define GLSLANG_SPV_TOOLS_H + +#ifdef ENABLE_OPT +#include +#include +#endif + +#include "glslang/MachineIndependent/localintermediate.h" +#include "Logger.h" + +namespace glslang { + +struct SpvOptions { + SpvOptions() : generateDebugInfo(false), disableOptimizer(true), + optimizeSize(false), disassemble(false), validate(false) { } + bool generateDebugInfo; + bool disableOptimizer; + bool optimizeSize; + bool disassemble; + bool validate; +}; + +#ifdef ENABLE_OPT + +// Use the SPIRV-Tools disassembler to print SPIR-V. +void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); + +// Apply the SPIRV-Tools validator to generated SPIR-V. +void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, bool prelegalization); + +// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of +// legalizing HLSL SPIR-V. +void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, const SpvOptions*); + +#endif + +} // end namespace glslang + +#endif // GLSLANG_SPV_TOOLS_H diff --git a/Externals/glslang/SPIRV/bitutils.h b/Externals/glslang/SPIRV/bitutils.h index 31288ab69d..22e44cec26 100644 --- a/Externals/glslang/SPIRV/bitutils.h +++ b/Externals/glslang/SPIRV/bitutils.h @@ -26,7 +26,7 @@ Dest BitwiseCast(Src source) { Dest dest; static_assert(sizeof(source) == sizeof(dest), "BitwiseCast: Source and destination must have the same size"); - std::memcpy(&dest, &source, sizeof(dest)); + std::memcpy(static_cast(&dest), &source, sizeof(dest)); return dest; } diff --git a/Externals/glslang/SPIRV/disassemble.cpp b/Externals/glslang/SPIRV/disassemble.cpp old mode 100755 new mode 100644 index b432e65d0f..930e799493 --- a/Externals/glslang/SPIRV/disassemble.cpp +++ b/Externals/glslang/SPIRV/disassemble.cpp @@ -46,31 +46,22 @@ #include "disassemble.h" #include "doc.h" +#include "SpvTools.h" namespace spv { extern "C" { // Include C-based headers that don't have a namespace #include "GLSL.std.450.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif - -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif } } const char* GlslStd450DebugNames[spv::GLSLstd450Count]; namespace spv { -#ifdef AMD_EXTENSIONS static const char* GLSLextAMDGetDebugNames(const char*, unsigned); -#endif - -#ifdef NV_EXTENSIONS static const char* GLSLextNVGetDebugNames(const char*, unsigned); -#endif static void Kill(std::ostream& out, const char* message) { @@ -81,15 +72,8 @@ static void Kill(std::ostream& out, const char* message) // used to identify the extended instruction library imported when printing enum ExtInstSet { GLSL450Inst, - -#ifdef AMD_EXTENSIONS GLSLextAMDInst, -#endif - -#ifdef NV_EXTENSIONS GLSLextNVInst, -#endif - OpenCLExtInst, }; @@ -498,35 +482,29 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, const char* name = idDescriptor[stream[word - 2]].c_str(); if (0 == memcmp("OpenCL", name, 6)) { extInstSet = OpenCLExtInst; -#ifdef AMD_EXTENSIONS } else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 || strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 || strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 || strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) { extInstSet = GLSLextAMDInst; -#endif -#ifdef NV_EXTENSIONS - }else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 || + } else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 || strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 || strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 || - strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) { + strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 || + strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 || + strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) { extInstSet = GLSLextNVInst; -#endif } unsigned entrypoint = stream[word - 1]; if (extInstSet == GLSL450Inst) { if (entrypoint < GLSLstd450Count) { out << "(" << GlslStd450DebugNames[entrypoint] << ")"; } -#ifdef AMD_EXTENSIONS } else if (extInstSet == GLSLextAMDInst) { out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")"; -#endif -#ifdef NV_EXTENSIONS } else if (extInstSet == GLSLextNVInst) { out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")"; -#endif } } break; @@ -534,6 +512,19 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, case OperandLiteralString: numOperands -= disassembleString(); break; + case OperandMemoryAccess: + outputMask(OperandMemoryAccess, stream[word++]); + --numOperands; + // Aligned is the only memory access operand that uses an immediate + // value, and it is also the first operand that uses a value at all. + if (stream[word-1] & MemoryAccessAlignedMask) { + disassembleImmediates(1); + numOperands--; + if (numOperands) + out << " "; + } + disassembleIds(numOperands); + return; default: assert(operandClass >= OperandSource && operandClass < OperandOpcode); @@ -632,9 +623,11 @@ static void GLSLstd450GetDebugNames(const char** names) names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid"; names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample"; names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset"; + names[GLSLstd450NMin] = "NMin"; + names[GLSLstd450NMax] = "NMax"; + names[GLSLstd450NClamp] = "NClamp"; } -#ifdef AMD_EXTENSIONS static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint) { if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) { @@ -676,36 +669,60 @@ static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint return "Bad"; } -#endif -#ifdef NV_EXTENSIONS static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint) { if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 || strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 || strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 || strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 || - strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) { + strcmp(name, spv::E_SPV_NVX_multiview_per_view_attributes) == 0 || + strcmp(name, spv::E_SPV_NV_fragment_shader_barycentric) == 0 || + strcmp(name, spv::E_SPV_NV_mesh_shader) == 0 || + strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) { switch (entrypoint) { - case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; - case DecorationPassthroughNV: return "PassthroughNV"; - case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; - case DecorationViewportRelativeNV: return "ViewportRelativeNV"; + // NV builtins case BuiltInViewportMaskNV: return "ViewportMaskNV"; - case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; - case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; - case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; case BuiltInPositionPerViewNV: return "PositionPerViewNV"; case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltInBaryCoordNV: return "BaryCoordNV"; + case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; + case BuiltInTaskCountNV: return "TaskCountNV"; + case BuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case BuiltInLayerPerViewNV: return "LayerPerViewNV"; + case BuiltInMeshViewCountNV: return "MeshViewCountNV"; + case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + + // NV Capabilities + case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; + case CapabilityMeshShadingNV: return "MeshShadingNV"; + case CapabilityImageFootprintNV: return "ImageFootprintNV"; + case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV"; + + // NV Decorations + case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; + case DecorationPassthroughNV: return "PassthroughNV"; + case DecorationViewportRelativeNV: return "ViewportRelativeNV"; + case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case DecorationPerVertexNV: return "PerVertexNV"; + case DecorationPerPrimitiveNV: return "PerPrimitiveNV"; + case DecorationPerViewNV: return "PerViewNV"; + case DecorationPerTaskNV: return "PerTaskNV"; + default: return "Bad"; } } return "Bad"; } -#endif void Disassemble(std::ostream& out, const std::vector& stream) { diff --git a/Externals/glslang/SPIRV/disassemble.h b/Externals/glslang/SPIRV/disassemble.h old mode 100755 new mode 100644 index 47cef65a57..b6a4635775 --- a/Externals/glslang/SPIRV/disassemble.h +++ b/Externals/glslang/SPIRV/disassemble.h @@ -45,8 +45,9 @@ namespace spv { + // disassemble with glslang custom disassembler void Disassemble(std::ostream& out, const std::vector&); -}; // end namespace spv +} // end namespace spv #endif // disassembler_H diff --git a/Externals/glslang/SPIRV/doc.cpp b/Externals/glslang/SPIRV/doc.cpp old mode 100755 new mode 100644 index a905968735..bee5c79729 --- a/Externals/glslang/SPIRV/doc.cpp +++ b/Externals/glslang/SPIRV/doc.cpp @@ -50,12 +50,8 @@ namespace spv { // Include C-based headers that don't have a namespace #include "GLSL.ext.KHR.h" #include "GLSL.ext.EXT.h" -#ifdef AMD_EXTENSIONS #include "GLSL.ext.AMD.h" -#endif -#ifdef NV_EXTENSIONS #include "GLSL.ext.NV.h" -#endif } } @@ -98,8 +94,17 @@ const char* ExecutionModelString(int model) case 4: return "Fragment"; case 5: return "GLCompute"; case 6: return "Kernel"; + case ExecutionModelTaskNV: return "TaskNV"; + case ExecutionModelMeshNV: return "MeshNV"; default: return "Bad"; + + case ExecutionModelRayGenerationNV: return "RayGenerationNV"; + case ExecutionModelIntersectionNV: return "IntersectionNV"; + case ExecutionModelAnyHitNV: return "AnyHitNV"; + case ExecutionModelClosestHitNV: return "ClosestHitNV"; + case ExecutionModelMissNV: return "MissNV"; + case ExecutionModelCallableNV: return "CallableNV"; } } @@ -110,6 +115,8 @@ const char* AddressingString(int addr) case 1: return "Physical32"; case 2: return "Physical64"; + case AddressingModelPhysicalStorageBuffer64EXT: return "PhysicalStorageBuffer64EXT"; + default: return "Bad"; } } @@ -117,9 +124,10 @@ const char* AddressingString(int addr) const char* MemoryString(int mem) { switch (mem) { - case 0: return "Simple"; - case 1: return "GLSL450"; - case 2: return "OpenCL"; + case MemoryModelSimple: return "Simple"; + case MemoryModelGLSL450: return "GLSL450"; + case MemoryModelOpenCL: return "OpenCL"; + case MemoryModelVulkanKHR: return "VulkanKHR"; default: return "Bad"; } @@ -165,6 +173,20 @@ const char* ExecutionModeString(int mode) case 32: return "Bad"; case 4446: return "PostDepthCoverage"; + + case ExecutionModeOutputLinesNV: return "OutputLinesNV"; + case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV"; + case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV"; + case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + + case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case ExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case ExecutionModeCeiling: default: return "Bad"; } @@ -187,6 +209,15 @@ const char* StorageClassString(int StorageClass) case 11: return "Image"; case 12: return "StorageBuffer"; + case StorageClassRayPayloadNV: return "RayPayloadNV"; + case StorageClassHitAttributeNV: return "HitAttributeNV"; + case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV"; + case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV"; + case StorageClassCallableDataNV: return "CallableDataNV"; + case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV"; + + case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT"; + default: return "Bad"; } } @@ -245,19 +276,21 @@ const char* DecorationString(int decoration) case DecorationCeiling: default: return "Bad"; -#ifdef AMD_EXTENSIONS case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; -#endif -#ifdef NV_EXTENSIONS case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; case DecorationPassthroughNV: return "PassthroughNV"; case DecorationViewportRelativeNV: return "ViewportRelativeNV"; case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; -#endif + case DecorationPerPrimitiveNV: return "PerPrimitiveNV"; + case DecorationPerViewNV: return "PerViewNV"; + case DecorationPerTaskNV: return "PerTaskNV"; + case DecorationPerVertexNV: return "PerVertexNV"; case DecorationNonUniformEXT: return "DecorationNonUniformEXT"; case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE"; case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE"; + case DecorationRestrictPointerEXT: return "DecorationRestrictPointerEXT"; + case DecorationAliasedPointerEXT: return "DecorationAliasedPointerEXT"; } } @@ -321,7 +354,6 @@ const char* BuiltInString(int builtIn) case 4426: return "DrawIndex"; case 5014: return "FragStencilRefEXT"; -#ifdef AMD_EXTENSIONS case 4992: return "BaryCoordNoPerspAMD"; case 4993: return "BaryCoordNoPerspCentroidAMD"; case 4994: return "BaryCoordNoPerspSampleAMD"; @@ -329,18 +361,48 @@ const char* BuiltInString(int builtIn) case 4996: return "BaryCoordSmoothCentroidAMD"; case 4997: return "BaryCoordSmoothSampleAMD"; case 4998: return "BaryCoordPullModelAMD"; -#endif + case BuiltInLaunchIdNV: return "LaunchIdNV"; + case BuiltInLaunchSizeNV: return "LaunchSizeNV"; + case BuiltInWorldRayOriginNV: return "WorldRayOriginNV"; + case BuiltInWorldRayDirectionNV: return "WorldRayDirectionNV"; + case BuiltInObjectRayOriginNV: return "ObjectRayOriginNV"; + case BuiltInObjectRayDirectionNV: return "ObjectRayDirectionNV"; + case BuiltInRayTminNV: return "RayTminNV"; + case BuiltInRayTmaxNV: return "RayTmaxNV"; + case BuiltInInstanceCustomIndexNV: return "InstanceCustomIndexNV"; + case BuiltInObjectToWorldNV: return "ObjectToWorldNV"; + case BuiltInWorldToObjectNV: return "WorldToObjectNV"; + case BuiltInHitTNV: return "HitTNV"; + case BuiltInHitKindNV: return "HitKindNV"; + case BuiltInIncomingRayFlagsNV: return "IncomingRayFlagsNV"; + case BuiltInViewportMaskNV: return "ViewportMaskNV"; + case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltInPositionPerViewNV: return "PositionPerViewNV"; + case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; +// case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT +// case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT + case BuiltInBaryCoordNV: return "BaryCoordNV"; + case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; -#ifdef NV_EXTENSIONS - case 5253: return "ViewportMaskNV"; - case 5257: return "SecondaryPositionNV"; - case 5258: return "SecondaryViewportMaskNV"; - case 5261: return "PositionPerViewNV"; - case 5262: return "ViewportMaskPerViewNV"; -#endif + case BuiltInFragSizeEXT: return "FragSizeEXT"; + case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; case 5264: return "FullyCoveredEXT"; + case BuiltInTaskCountNV: return "TaskCountNV"; + case BuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case BuiltInLayerPerViewNV: return "LayerPerViewNV"; + case BuiltInMeshViewCountNV: return "MeshViewCountNV"; + case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + case BuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case BuiltInSMCountNV: return "SMCountNV"; + case BuiltInWarpIDNV: return "WarpIDNV"; + case BuiltInSMIDNV: return "SMIDNV"; + default: return "Bad"; } } @@ -499,19 +561,25 @@ const char* ImageChannelDataTypeString(int type) } } -const int ImageOperandsCeiling = 8; +const int ImageOperandsCeiling = 14; const char* ImageOperandsString(int format) { switch (format) { - case 0: return "Bias"; - case 1: return "Lod"; - case 2: return "Grad"; - case 3: return "ConstOffset"; - case 4: return "Offset"; - case 5: return "ConstOffsets"; - case 6: return "Sample"; - case 7: return "MinLod"; + case ImageOperandsBiasShift: return "Bias"; + case ImageOperandsLodShift: return "Lod"; + case ImageOperandsGradShift: return "Grad"; + case ImageOperandsConstOffsetShift: return "ConstOffset"; + case ImageOperandsOffsetShift: return "Offset"; + case ImageOperandsConstOffsetsShift: return "ConstOffsets"; + case ImageOperandsSampleShift: return "Sample"; + case ImageOperandsMinLodShift: return "MinLod"; + case ImageOperandsMakeTexelAvailableKHRShift: return "MakeTexelAvailableKHR"; + case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR"; + case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR"; + case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR"; + case ImageOperandsSignExtendShift: return "SignExtend"; + case ImageOperandsZeroExtendShift: return "ZeroExtend"; case ImageOperandsCeiling: default: @@ -594,15 +662,20 @@ const char* SelectControlString(int cont) } } -const int LoopControlCeiling = 4; +const int LoopControlCeiling = LoopControlPartialCountShift + 1; const char* LoopControlString(int cont) { switch (cont) { - case 0: return "Unroll"; - case 1: return "DontUnroll"; - case 2: return "DependencyInfinite"; - case 3: return "DependencyLength"; + case LoopControlUnrollShift: return "Unroll"; + case LoopControlDontUnrollShift: return "DontUnroll"; + case LoopControlDependencyInfiniteShift: return "DependencyInfinite"; + case LoopControlDependencyLengthShift: return "DependencyLength"; + case LoopControlMinIterationsShift: return "MinIterations"; + case LoopControlMaxIterationsShift: return "MaxIterations"; + case LoopControlIterationMultipleShift: return "IterationMultiple"; + case LoopControlPeelCountShift: return "PeelCount"; + case LoopControlPartialCountShift: return "PartialCount"; case LoopControlCeiling: default: return "Bad"; @@ -645,12 +718,17 @@ const char* MemorySemanticsString(int mem) } } +const int MemoryAccessCeiling = 6; + const char* MemoryAccessString(int mem) { switch (mem) { - case 0: return "Volatile"; - case 1: return "Aligned"; - case 2: return "Nontemporal"; + case MemoryAccessVolatileShift: return "Volatile"; + case MemoryAccessAlignedShift: return "Aligned"; + case MemoryAccessNontemporalShift: return "Nontemporal"; + case MemoryAccessMakePointerAvailableKHRShift: return "MakePointerAvailableKHR"; + case MemoryAccessMakePointerVisibleKHRShift: return "MakePointerVisibleKHR"; + case MemoryAccessNonPrivatePointerKHRShift: return "NonPrivatePointerKHR"; default: return "Bad"; } @@ -678,11 +756,9 @@ const char* GroupOperationString(int gop) case GroupOperationInclusiveScan: return "InclusiveScan"; case GroupOperationExclusiveScan: return "ExclusiveScan"; case GroupOperationClusteredReduce: return "ClusteredReduce"; -#ifdef NV_EXTENSIONS case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; -#endif default: return "Bad"; } @@ -790,44 +866,72 @@ const char* CapabilityString(int info) case CapabilityStoragePushConstant16: return "StoragePushConstant16"; case CapabilityStorageInputOutput16: return "StorageInputOutput16"; + case CapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case CapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case CapabilityStoragePushConstant8: return "StoragePushConstant8"; + case CapabilityDeviceGroup: return "DeviceGroup"; case CapabilityMultiView: return "MultiView"; case CapabilityStencilExportEXT: return "StencilExportEXT"; -#ifdef AMD_EXTENSIONS case CapabilityFloat16ImageAMD: return "Float16ImageAMD"; case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; case CapabilityFragmentMaskAMD: return "FragmentMaskAMD"; case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; -#endif case CapabilityAtomicStorageOps: return "AtomicStorageOps"; case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; -#ifdef NV_EXTENSIONS - case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; - case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV"; - case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; - case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; - case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; - case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; -#endif + case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case CapabilityShaderViewportIndexLayerNV: return "ShaderViewportIndexLayerNV"; + case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; + case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case CapabilityRayTracingNV: return "RayTracingNV"; + case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; + case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; + case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; + case CapabilityMeshShadingNV: return "MeshShadingNV"; + case CapabilityImageFootprintNV: return "ImageFootprintNV"; +// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT + case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case CapabilityFragmentDensityEXT: return "FragmentDensityEXT"; case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; - case CapabilityShaderNonUniformEXT: return "CapabilityShaderNonUniformEXT"; - case CapabilityRuntimeDescriptorArrayEXT: return "CapabilityRuntimeDescriptorArrayEXT"; - case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "CapabilityInputAttachmentArrayDynamicIndexingEXT"; - case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "CapabilityUniformTexelBufferArrayDynamicIndexingEXT"; - case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "CapabilityStorageTexelBufferArrayDynamicIndexingEXT"; - case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "CapabilityUniformBufferArrayNonUniformIndexingEXT"; - case CapabilitySampledImageArrayNonUniformIndexingEXT: return "CapabilitySampledImageArrayNonUniformIndexingEXT"; - case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "CapabilityStorageBufferArrayNonUniformIndexingEXT"; - case CapabilityStorageImageArrayNonUniformIndexingEXT: return "CapabilityStorageImageArrayNonUniformIndexingEXT"; - case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "CapabilityInputAttachmentArrayNonUniformIndexingEXT"; - case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT"; - case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT"; + case CapabilityShaderNonUniformEXT: return "ShaderNonUniformEXT"; + case CapabilityRuntimeDescriptorArrayEXT: return "RuntimeDescriptorArrayEXT"; + case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "InputAttachmentArrayDynamicIndexingEXT"; + case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "UniformTexelBufferArrayDynamicIndexingEXT"; + case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "StorageTexelBufferArrayDynamicIndexingEXT"; + case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "UniformBufferArrayNonUniformIndexingEXT"; + case CapabilitySampledImageArrayNonUniformIndexingEXT: return "SampledImageArrayNonUniformIndexingEXT"; + case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "StorageBufferArrayNonUniformIndexingEXT"; + case CapabilityStorageImageArrayNonUniformIndexingEXT: return "StorageImageArrayNonUniformIndexingEXT"; + case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "InputAttachmentArrayNonUniformIndexingEXT"; + case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "UniformTexelBufferArrayNonUniformIndexingEXT"; + case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "StorageTexelBufferArrayNonUniformIndexingEXT"; + + case CapabilityVulkanMemoryModelKHR: return "VulkanMemoryModelKHR"; + case CapabilityVulkanMemoryModelDeviceScopeKHR: return "VulkanMemoryModelDeviceScopeKHR"; + + case CapabilityPhysicalStorageBufferAddressesEXT: return "PhysicalStorageBufferAddressesEXT"; + + case CapabilityVariablePointers: return "VariablePointers"; + + case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case CapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + + case CapabilityFragmentShaderSampleInterlockEXT: return "CapabilityFragmentShaderSampleInterlockEXT"; + case CapabilityFragmentShaderPixelInterlockEXT: return "CapabilityFragmentShaderPixelInterlockEXT"; + case CapabilityFragmentShaderShadingRateInterlockEXT: return "CapabilityFragmentShaderShadingRateInterlockEXT"; + + case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT"; + case CapabilityShaderClockKHR: return "ShaderClockKHR"; + + case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL"; default: return "Bad"; } @@ -921,6 +1025,7 @@ const char* OpcodeString(int op) case 82: return "OpCompositeInsert"; case 83: return "OpCopyObject"; case 84: return "OpTranspose"; + case OpCopyLogical: return "OpCopyLogical"; case 85: return "Bad"; case 86: return "OpSampledImage"; case 87: return "OpImageSampleImplicitLod"; @@ -1203,7 +1308,6 @@ const char* OpcodeString(int op) case 4430: return "OpSubgroupAllEqualKHR"; case 4432: return "OpSubgroupReadInvocationKHR"; -#ifdef AMD_EXTENSIONS case 5000: return "OpGroupIAddNonUniformAMD"; case 5001: return "OpGroupFAddNonUniformAMD"; case 5002: return "OpGroupFMinNonUniformAMD"; @@ -1215,14 +1319,33 @@ const char* OpcodeString(int op) case 5011: return "OpFragmentMaskFetchAMD"; case 5012: return "OpFragmentFetchAMD"; -#endif + + case OpReadClockKHR: return "OpReadClockKHR"; case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE"; case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE"; -#ifdef NV_EXTENSIONS - case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; -#endif + case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case OpReportIntersectionNV: return "OpReportIntersectionNV"; + case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case OpTerminateRayNV: return "OpTerminateRayNV"; + case OpTraceNV: return "OpTraceNV"; + case OpTypeAccelerationStructureNV: return "OpTypeAccelerationStructureNV"; + case OpExecuteCallableNV: return "OpExecuteCallableNV"; + case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + + case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case OpDemoteToHelperInvocationEXT: return "OpDemoteToHelperInvocationEXT"; + case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + + case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + default: return "Bad"; } @@ -1241,6 +1364,7 @@ EnumParameters DecorationParams[DecorationCeiling]; EnumParameters LoopControlParams[FunctionControlCeiling]; EnumParameters SelectionControlParams[SelectControlCeiling]; EnumParameters FunctionControlParams[FunctionControlCeiling]; +EnumParameters MemoryAccessParams[MemoryAccessCeiling]; // Set up all the parameterizing descriptions of the opcodes, operands, etc. void Parameterize() @@ -1333,6 +1457,10 @@ void Parameterize() InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false); InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false); InstructionDesc[OpModuleProcessed].setResultAndType(false, false); + InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false); + InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false); + InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false); + InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false); // Specific additional context-dependent operands @@ -1396,7 +1524,7 @@ void Parameterize() OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true); OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true); OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true); - OperandClassParams[OperandMemoryAccess].set(0, MemoryAccessString, nullptr, true); + OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true); OperandClassParams[OperandScope].set(0, ScopeString, nullptr); OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr); OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr); @@ -1518,10 +1646,14 @@ void Parameterize() InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true); + InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpLoad].operands.push(OperandId, "", true); InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpStore].operands.push(OperandId, "'Object'"); InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true); + InstructionDesc[OpStore].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpStore].operands.push(OperandId, "", true); InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'"); @@ -1806,6 +1938,8 @@ void Parameterize() InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'"); + InstructionDesc[OpCopyLogical].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpIsNan].operands.push(OperandId, "'x'"); InstructionDesc[OpIsInf].operands.push(OperandId, "'x'"); @@ -2519,7 +2653,6 @@ void Parameterize() InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'"); -#ifdef AMD_EXTENSIONS InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'"); InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'"); @@ -2558,11 +2691,74 @@ void Parameterize() InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'"); InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'"); -#endif -#ifdef NV_EXTENSIONS InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X"); -#endif + + InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false); + + InstructionDesc[OpTraceNV].operands.push(OperandId, "'NV Acceleration Structure'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceNV].setResultAndType(false, false); + + InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'"); + InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'"); + + InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false); + + InstructionDesc[OpTerminateRayNV].setResultAndType(false, false); + + InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index"); + InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID"); + InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false); + + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coarse'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'"); + InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'"); + + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Component Type'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Scope'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Rows'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Columns'"); + + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Column Major'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "", true); + + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Object'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Column Major'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "", true); + + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'A'"); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'B'"); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'C'"); + + InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'"); + + InstructionDesc[OpDemoteToHelperInvocationEXT].setResultAndType(false, false); + + InstructionDesc[OpReadClockKHR].operands.push(OperandScope, "'Scope'"); } }; // end spv namespace diff --git a/Externals/glslang/SPIRV/doc.h b/Externals/glslang/SPIRV/doc.h index 7d0475d3eb..293256a2c6 100644 --- a/Externals/glslang/SPIRV/doc.h +++ b/Externals/glslang/SPIRV/doc.h @@ -255,4 +255,4 @@ const char* AccessQualifierString(int attr); void PrintOperands(const OperandParameters& operands, int reservedOperands); -}; // end namespace spv +} // end namespace spv diff --git a/Externals/glslang/SPIRV/spirv.hpp b/Externals/glslang/SPIRV/spirv.hpp index e21762dbec..1e96f7b4a9 100644 --- a/Externals/glslang/SPIRV/spirv.hpp +++ b/Externals/glslang/SPIRV/spirv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 The Khronos Group Inc. +// Copyright (c) 2014-2019 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"), @@ -26,13 +26,16 @@ // the Binary Section of the SPIR-V specification. // Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python +// C, C++, C++11, JSON, Lua, Python, C#, D // // - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL // - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL // - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL // - Lua will use tables, e.g.: spv.SourceLanguage.GLSL // - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL // // Some tokens act like mask values, which can be OR'd together, // while others are mutually exclusive. The mask-like ones have @@ -46,11 +49,11 @@ namespace spv { typedef unsigned int Id; -#define SPV_VERSION 0x10300 +#define SPV_VERSION 0x10400 #define SPV_REVISION 1 static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010300; +static const unsigned int Version = 0x00010400; static const unsigned int Revision = 1; static const unsigned int OpCodeMask = 0xffff; static const unsigned int WordCountShift = 16; @@ -73,6 +76,14 @@ enum ExecutionModel { ExecutionModelFragment = 4, ExecutionModelGLCompute = 5, ExecutionModelKernel = 6, + ExecutionModelTaskNV = 5267, + ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitNV = 5316, + ExecutionModelMissNV = 5317, + ExecutionModelCallableNV = 5318, ExecutionModelMax = 0x7fffffff, }; @@ -80,6 +91,8 @@ enum AddressingModel { AddressingModelLogical = 0, AddressingModelPhysical32 = 1, AddressingModelPhysical64 = 2, + AddressingModelPhysicalStorageBuffer64 = 5348, + AddressingModelPhysicalStorageBuffer64EXT = 5348, AddressingModelMax = 0x7fffffff, }; @@ -87,6 +100,8 @@ enum MemoryModel { MemoryModelSimple = 0, MemoryModelGLSL450 = 1, MemoryModelOpenCL = 2, + MemoryModelVulkan = 3, + MemoryModelVulkanKHR = 3, MemoryModelMax = 0x7fffffff, }; @@ -130,7 +145,23 @@ enum ExecutionMode { ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeHintId = 39, ExecutionModePostDepthCoverage = 4446, + ExecutionModeDenormPreserve = 4459, + ExecutionModeDenormFlushToZero = 4460, + ExecutionModeSignedZeroInfNanPreserve = 4461, + ExecutionModeRoundingModeRTE = 4462, + ExecutionModeRoundingModeRTZ = 4463, ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeOutputLinesNV = 5269, + ExecutionModeOutputPrimitivesNV = 5270, + ExecutionModeDerivativeGroupQuadsNV = 5289, + ExecutionModeDerivativeGroupLinearNV = 5290, + ExecutionModeOutputTrianglesNV = 5298, + ExecutionModePixelInterlockOrderedEXT = 5366, + ExecutionModePixelInterlockUnorderedEXT = 5367, + ExecutionModeSampleInterlockOrderedEXT = 5368, + ExecutionModeSampleInterlockUnorderedEXT = 5369, + ExecutionModeShadingRateInterlockOrderedEXT = 5370, + ExecutionModeShadingRateInterlockUnorderedEXT = 5371, ExecutionModeMax = 0x7fffffff, }; @@ -148,6 +179,14 @@ enum StorageClass { StorageClassAtomicCounter = 10, StorageClassImage = 11, StorageClassStorageBuffer = 12, + StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferNV = 5343, + StorageClassPhysicalStorageBuffer = 5349, + StorageClassPhysicalStorageBufferEXT = 5349, StorageClassMax = 0x7fffffff, }; @@ -275,6 +314,16 @@ enum ImageOperandsShift { ImageOperandsConstOffsetsShift = 5, ImageOperandsSampleShift = 6, ImageOperandsMinLodShift = 7, + ImageOperandsMakeTexelAvailableShift = 8, + ImageOperandsMakeTexelAvailableKHRShift = 8, + ImageOperandsMakeTexelVisibleShift = 9, + ImageOperandsMakeTexelVisibleKHRShift = 9, + ImageOperandsNonPrivateTexelShift = 10, + ImageOperandsNonPrivateTexelKHRShift = 10, + ImageOperandsVolatileTexelShift = 11, + ImageOperandsVolatileTexelKHRShift = 11, + ImageOperandsSignExtendShift = 12, + ImageOperandsZeroExtendShift = 13, ImageOperandsMax = 0x7fffffff, }; @@ -288,6 +337,16 @@ enum ImageOperandsMask { ImageOperandsConstOffsetsMask = 0x00000020, ImageOperandsSampleMask = 0x00000040, ImageOperandsMinLodMask = 0x00000080, + ImageOperandsMakeTexelAvailableMask = 0x00000100, + ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + ImageOperandsMakeTexelVisibleMask = 0x00000200, + ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + ImageOperandsNonPrivateTexelMask = 0x00000400, + ImageOperandsNonPrivateTexelKHRMask = 0x00000400, + ImageOperandsVolatileTexelMask = 0x00000800, + ImageOperandsVolatileTexelKHRMask = 0x00000800, + ImageOperandsSignExtendMask = 0x00001000, + ImageOperandsZeroExtendMask = 0x00002000, }; enum FPFastMathModeShift { @@ -368,6 +427,7 @@ enum Decoration { DecorationNonWritable = 24, DecorationNonReadable = 25, DecorationUniform = 26, + DecorationUniformId = 27, DecorationSaturatedConversion = 28, DecorationStream = 29, DecorationLocation = 30, @@ -388,14 +448,28 @@ enum Decoration { DecorationMaxByteOffset = 45, DecorationAlignmentId = 46, DecorationMaxByteOffsetId = 47, + DecorationNoSignedWrap = 4469, + DecorationNoUnsignedWrap = 4470, DecorationExplicitInterpAMD = 4999, DecorationOverrideCoverageNV = 5248, DecorationPassthroughNV = 5250, DecorationViewportRelativeNV = 5252, DecorationSecondaryViewportRelativeNV = 5256, + DecorationPerPrimitiveNV = 5271, + DecorationPerViewNV = 5272, + DecorationPerTaskNV = 5273, + DecorationPerVertexNV = 5285, + DecorationNonUniform = 5300, DecorationNonUniformEXT = 5300, + DecorationRestrictPointer = 5355, + DecorationRestrictPointerEXT = 5355, + DecorationAliasedPointer = 5356, + DecorationAliasedPointerEXT = 5356, + DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, + DecorationUserSemantic = 5635, + DecorationUserTypeGOOGLE = 5636, DecorationMax = 0x7fffffff, }; @@ -470,6 +544,38 @@ enum BuiltIn { BuiltInPositionPerViewNV = 5261, BuiltInViewportMaskPerViewNV = 5262, BuiltInFullyCoveredEXT = 5264, + BuiltInTaskCountNV = 5274, + BuiltInPrimitiveCountNV = 5275, + BuiltInPrimitiveIndicesNV = 5276, + BuiltInClipDistancePerViewNV = 5277, + BuiltInCullDistancePerViewNV = 5278, + BuiltInLayerPerViewNV = 5279, + BuiltInMeshViewCountNV = 5280, + BuiltInMeshViewIndicesNV = 5281, + BuiltInBaryCoordNV = 5286, + BuiltInBaryCoordNoPerspNV = 5287, + BuiltInFragSizeEXT = 5292, + BuiltInFragmentSizeNV = 5292, + BuiltInFragInvocationCountEXT = 5293, + BuiltInInvocationsPerPixelNV = 5293, + BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminNV = 5325, + BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectNV = 5331, + BuiltInHitTNV = 5332, + BuiltInHitKindNV = 5333, + BuiltInIncomingRayFlagsNV = 5351, + BuiltInWarpsPerSMNV = 5374, + BuiltInSMCountNV = 5375, + BuiltInWarpIDNV = 5376, + BuiltInSMIDNV = 5377, BuiltInMax = 0x7fffffff, }; @@ -490,6 +596,11 @@ enum LoopControlShift { LoopControlDontUnrollShift = 1, LoopControlDependencyInfiniteShift = 2, LoopControlDependencyLengthShift = 3, + LoopControlMinIterationsShift = 4, + LoopControlMaxIterationsShift = 5, + LoopControlIterationMultipleShift = 6, + LoopControlPeelCountShift = 7, + LoopControlPartialCountShift = 8, LoopControlMax = 0x7fffffff, }; @@ -499,6 +610,11 @@ enum LoopControlMask { LoopControlDontUnrollMask = 0x00000002, LoopControlDependencyInfiniteMask = 0x00000004, LoopControlDependencyLengthMask = 0x00000008, + LoopControlMinIterationsMask = 0x00000010, + LoopControlMaxIterationsMask = 0x00000020, + LoopControlIterationMultipleMask = 0x00000040, + LoopControlPeelCountMask = 0x00000080, + LoopControlPartialCountMask = 0x00000100, }; enum FunctionControlShift { @@ -528,6 +644,13 @@ enum MemorySemanticsShift { MemorySemanticsCrossWorkgroupMemoryShift = 9, MemorySemanticsAtomicCounterMemoryShift = 10, MemorySemanticsImageMemoryShift = 11, + MemorySemanticsOutputMemoryShift = 12, + MemorySemanticsOutputMemoryKHRShift = 12, + MemorySemanticsMakeAvailableShift = 13, + MemorySemanticsMakeAvailableKHRShift = 13, + MemorySemanticsMakeVisibleShift = 14, + MemorySemanticsMakeVisibleKHRShift = 14, + MemorySemanticsVolatileShift = 15, MemorySemanticsMax = 0x7fffffff, }; @@ -543,12 +666,25 @@ enum MemorySemanticsMask { MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, MemorySemanticsAtomicCounterMemoryMask = 0x00000400, MemorySemanticsImageMemoryMask = 0x00000800, + MemorySemanticsOutputMemoryMask = 0x00001000, + MemorySemanticsOutputMemoryKHRMask = 0x00001000, + MemorySemanticsMakeAvailableMask = 0x00002000, + MemorySemanticsMakeAvailableKHRMask = 0x00002000, + MemorySemanticsMakeVisibleMask = 0x00004000, + MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsVolatileMask = 0x00008000, }; enum MemoryAccessShift { MemoryAccessVolatileShift = 0, MemoryAccessAlignedShift = 1, MemoryAccessNontemporalShift = 2, + MemoryAccessMakePointerAvailableShift = 3, + MemoryAccessMakePointerAvailableKHRShift = 3, + MemoryAccessMakePointerVisibleShift = 4, + MemoryAccessMakePointerVisibleKHRShift = 4, + MemoryAccessNonPrivatePointerShift = 5, + MemoryAccessNonPrivatePointerKHRShift = 5, MemoryAccessMax = 0x7fffffff, }; @@ -557,6 +693,12 @@ enum MemoryAccessMask { MemoryAccessVolatileMask = 0x00000001, MemoryAccessAlignedMask = 0x00000002, MemoryAccessNontemporalMask = 0x00000004, + MemoryAccessMakePointerAvailableMask = 0x00000008, + MemoryAccessMakePointerAvailableKHRMask = 0x00000008, + MemoryAccessMakePointerVisibleMask = 0x00000010, + MemoryAccessMakePointerVisibleKHRMask = 0x00000010, + MemoryAccessNonPrivatePointerMask = 0x00000020, + MemoryAccessNonPrivatePointerKHRMask = 0x00000020, }; enum Scope { @@ -565,6 +707,8 @@ enum Scope { ScopeWorkgroup = 2, ScopeSubgroup = 3, ScopeInvocation = 4, + ScopeQueueFamily = 5, + ScopeQueueFamilyKHR = 5, ScopeMax = 0x7fffffff, }; @@ -664,6 +808,8 @@ enum Capability { CapabilityGroupNonUniformShuffleRelative = 66, CapabilityGroupNonUniformClustered = 67, CapabilityGroupNonUniformQuad = 68, + CapabilityShaderLayer = 69, + CapabilityShaderViewportIndex = 70, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, CapabilitySubgroupVoteKHR = 4431, @@ -679,11 +825,20 @@ enum Capability { CapabilityVariablePointers = 4442, CapabilityAtomicStorageOps = 4445, CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityStorageBuffer8BitAccess = 4448, + CapabilityUniformAndStorageBuffer8BitAccess = 4449, + CapabilityStoragePushConstant8 = 4450, + CapabilityDenormPreserve = 4464, + CapabilityDenormFlushToZero = 4465, + CapabilitySignedZeroInfNanPreserve = 4466, + CapabilityRoundingModeRTE = 4467, + CapabilityRoundingModeRTZ = 4468, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, CapabilityStencilExportEXT = 5013, CapabilityImageReadWriteLodAMD = 5015, + CapabilityShaderClockKHR = 5055, CapabilitySampleMaskOverrideCoverageNV = 5249, CapabilityGeometryShaderPassthroughNV = 5251, CapabilityShaderViewportIndexLayerEXT = 5254, @@ -692,22 +847,59 @@ enum Capability { CapabilityShaderStereoViewNV = 5259, CapabilityPerViewAttributesNV = 5260, CapabilityFragmentFullyCoveredEXT = 5265, + CapabilityMeshShadingNV = 5266, + CapabilityImageFootprintNV = 5282, + CapabilityFragmentBarycentricNV = 5284, + CapabilityComputeDerivativeGroupQuadsNV = 5288, + CapabilityFragmentDensityEXT = 5291, + CapabilityShadingRateNV = 5291, CapabilityGroupNonUniformPartitionedNV = 5297, + CapabilityShaderNonUniform = 5301, CapabilityShaderNonUniformEXT = 5301, + CapabilityRuntimeDescriptorArray = 5302, CapabilityRuntimeDescriptorArrayEXT = 5302, + CapabilityInputAttachmentArrayDynamicIndexing = 5303, CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + CapabilityUniformBufferArrayNonUniformIndexing = 5306, CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + CapabilitySampledImageArrayNonUniformIndexing = 5307, CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + CapabilityStorageBufferArrayNonUniformIndexing = 5308, CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + CapabilityStorageImageArrayNonUniformIndexing = 5309, CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + CapabilityInputAttachmentArrayNonUniformIndexing = 5310, CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + CapabilityRayTracingNV = 5340, + CapabilityVulkanMemoryModel = 5345, + CapabilityVulkanMemoryModelKHR = 5345, + CapabilityVulkanMemoryModelDeviceScope = 5346, + CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + CapabilityPhysicalStorageBufferAddresses = 5347, + CapabilityPhysicalStorageBufferAddressesEXT = 5347, + CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityCooperativeMatrixNV = 5357, + CapabilityFragmentShaderSampleInterlockEXT = 5363, + CapabilityFragmentShaderShadingRateInterlockEXT = 5372, + CapabilityShaderSMBuiltinsNV = 5373, + CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocationEXT = 5379, CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityIntegerFunctions2INTEL = 5584, + CapabilitySubgroupAvcMotionEstimationINTEL = 5696, + CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, CapabilityMax = 0x7fffffff, }; @@ -1052,6 +1244,10 @@ enum Op { OpGroupNonUniformLogicalXor = 364, OpGroupNonUniformQuadBroadcast = 365, OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, OpSubgroupBallotKHR = 4421, OpSubgroupFirstInvocationKHR = 4422, OpSubgroupAllKHR = 4428, @@ -1068,7 +1264,25 @@ enum Op { OpGroupSMaxNonUniformAMD = 5007, OpFragmentMaskFetchAMD = 5011, OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpImageSampleFootprintNV = 5283, OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, @@ -1077,11 +1291,679 @@ enum Op { OpSubgroupBlockWriteINTEL = 5576, OpSubgroupImageBlockReadINTEL = 5577, OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, OpMax = 0x7fffffff, }; +#ifdef SPV_ENABLE_UTILITY_CODE +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case OpNop: *hasResult = false; *hasResultType = false; break; + case OpUndef: *hasResult = true; *hasResultType = true; break; + case OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case OpSource: *hasResult = false; *hasResultType = false; break; + case OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case OpName: *hasResult = false; *hasResultType = false; break; + case OpMemberName: *hasResult = false; *hasResultType = false; break; + case OpString: *hasResult = true; *hasResultType = false; break; + case OpLine: *hasResult = false; *hasResultType = false; break; + case OpExtension: *hasResult = false; *hasResultType = false; break; + case OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case OpExtInst: *hasResult = true; *hasResultType = true; break; + case OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case OpCapability: *hasResult = false; *hasResultType = false; break; + case OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case OpTypeBool: *hasResult = true; *hasResultType = false; break; + case OpTypeInt: *hasResult = true; *hasResultType = false; break; + case OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case OpTypeVector: *hasResult = true; *hasResultType = false; break; + case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case OpTypeImage: *hasResult = true; *hasResultType = false; break; + case OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case OpTypeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case OpTypePointer: *hasResult = true; *hasResultType = false; break; + case OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case OpTypePipe: *hasResult = true; *hasResultType = false; break; + case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpConstant: *hasResult = true; *hasResultType = true; break; + case OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case OpConstantNull: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case OpFunction: *hasResult = true; *hasResultType = true; break; + case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case OpVariable: *hasResult = true; *hasResultType = true; break; + case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case OpLoad: *hasResult = true; *hasResultType = true; break; + case OpStore: *hasResult = false; *hasResultType = false; break; + case OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case OpAccessChain: *hasResult = true; *hasResultType = true; break; + case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpArrayLength: *hasResult = true; *hasResultType = true; break; + case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpDecorate: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case OpCopyObject: *hasResult = true; *hasResultType = true; break; + case OpTranspose: *hasResult = true; *hasResultType = true; break; + case OpSampledImage: *hasResult = true; *hasResultType = true; break; + case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageFetch: *hasResult = true; *hasResultType = true; break; + case OpImageGather: *hasResult = true; *hasResultType = true; break; + case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageRead: *hasResult = true; *hasResultType = true; break; + case OpImageWrite: *hasResult = false; *hasResultType = false; break; + case OpImage: *hasResult = true; *hasResultType = true; break; + case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case OpUConvert: *hasResult = true; *hasResultType = true; break; + case OpSConvert: *hasResult = true; *hasResultType = true; break; + case OpFConvert: *hasResult = true; *hasResultType = true; break; + case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case OpBitcast: *hasResult = true; *hasResultType = true; break; + case OpSNegate: *hasResult = true; *hasResultType = true; break; + case OpFNegate: *hasResult = true; *hasResultType = true; break; + case OpIAdd: *hasResult = true; *hasResultType = true; break; + case OpFAdd: *hasResult = true; *hasResultType = true; break; + case OpISub: *hasResult = true; *hasResultType = true; break; + case OpFSub: *hasResult = true; *hasResultType = true; break; + case OpIMul: *hasResult = true; *hasResultType = true; break; + case OpFMul: *hasResult = true; *hasResultType = true; break; + case OpUDiv: *hasResult = true; *hasResultType = true; break; + case OpSDiv: *hasResult = true; *hasResultType = true; break; + case OpFDiv: *hasResult = true; *hasResultType = true; break; + case OpUMod: *hasResult = true; *hasResultType = true; break; + case OpSRem: *hasResult = true; *hasResultType = true; break; + case OpSMod: *hasResult = true; *hasResultType = true; break; + case OpFRem: *hasResult = true; *hasResultType = true; break; + case OpFMod: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case OpDot: *hasResult = true; *hasResultType = true; break; + case OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case OpAny: *hasResult = true; *hasResultType = true; break; + case OpAll: *hasResult = true; *hasResultType = true; break; + case OpIsNan: *hasResult = true; *hasResultType = true; break; + case OpIsInf: *hasResult = true; *hasResultType = true; break; + case OpIsFinite: *hasResult = true; *hasResultType = true; break; + case OpIsNormal: *hasResult = true; *hasResultType = true; break; + case OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case OpOrdered: *hasResult = true; *hasResultType = true; break; + case OpUnordered: *hasResult = true; *hasResultType = true; break; + case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case OpSelect: *hasResult = true; *hasResultType = true; break; + case OpIEqual: *hasResult = true; *hasResultType = true; break; + case OpINotEqual: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpULessThan: *hasResult = true; *hasResultType = true; break; + case OpSLessThan: *hasResult = true; *hasResultType = true; break; + case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpNot: *hasResult = true; *hasResultType = true; break; + case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case OpBitReverse: *hasResult = true; *hasResultType = true; break; + case OpBitCount: *hasResult = true; *hasResultType = true; break; + case OpDPdx: *hasResult = true; *hasResultType = true; break; + case OpDPdy: *hasResult = true; *hasResultType = true; break; + case OpFwidth: *hasResult = true; *hasResultType = true; break; + case OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case OpPhi: *hasResult = true; *hasResultType = true; break; + case OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case OpLabel: *hasResult = true; *hasResultType = false; break; + case OpBranch: *hasResult = false; *hasResultType = false; break; + case OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case OpSwitch: *hasResult = false; *hasResultType = false; break; + case OpKill: *hasResult = false; *hasResultType = false; break; + case OpReturn: *hasResult = false; *hasResultType = false; break; + case OpReturnValue: *hasResult = false; *hasResultType = false; break; + case OpUnreachable: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case OpGroupAll: *hasResult = true; *hasResultType = true; break; + case OpGroupAny: *hasResult = true; *hasResultType = true; break; + case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case OpReadPipe: *hasResult = true; *hasResultType = true; break; + case OpWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case OpNoLine: *hasResult = false; *hasResultType = false; break; + case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case OpSizeOf: *hasResult = true; *hasResultType = true; break; + case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case OpDecorateId: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; + case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpDecorateString: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + // Overload operator| for mask bit combining inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } diff --git a/Externals/glslang/SPIRV/spvIR.h b/Externals/glslang/SPIRV/spvIR.h old mode 100755 new mode 100644 index 8b6c6447f4..cf6a71159a --- a/Externals/glslang/SPIRV/spvIR.h +++ b/Externals/glslang/SPIRV/spvIR.h @@ -1,5 +1,6 @@ // // Copyright (C) 2014 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -79,6 +80,12 @@ const MemorySemanticsMask MemorySemanticsAllMemory = MemorySemanticsAtomicCounterMemoryMask | MemorySemanticsImageMemoryMask); +struct IdImmediate { + bool isId; // true if word is an Id, false if word is an immediate + unsigned word; + IdImmediate(bool i, unsigned w) : isId(i), word(w) {} +}; + // // SPIR-V IR instruction. // @@ -88,8 +95,19 @@ public: Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { } explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { } virtual ~Instruction() {} - void addIdOperand(Id id) { operands.push_back(id); } - void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); } + void addIdOperand(Id id) { + operands.push_back(id); + idOperand.push_back(true); + } + void addImmediateOperand(unsigned int immediate) { + operands.push_back(immediate); + idOperand.push_back(false); + } + void setImmediateOperand(unsigned idx, unsigned int immediate) { + assert(!idOperand[idx]); + operands[idx] = immediate; + } + void addStringOperand(const char* str) { unsigned int word; @@ -116,14 +134,25 @@ public: addImmediateOperand(word); } } + bool isIdOperand(int op) const { return idOperand[op]; } void setBlock(Block* b) { block = b; } Block* getBlock() const { return block; } Op getOpCode() const { return opCode; } - int getNumOperands() const { return (int)operands.size(); } + int getNumOperands() const + { + assert(operands.size() == idOperand.size()); + return (int)operands.size(); + } Id getResultId() const { return resultId; } Id getTypeId() const { return typeId; } - Id getIdOperand(int op) const { return operands[op]; } - unsigned int getImmediateOperand(int op) const { return operands[op]; } + Id getIdOperand(int op) const { + assert(idOperand[op]); + return operands[op]; + } + unsigned int getImmediateOperand(int op) const { + assert(!idOperand[op]); + return operands[op]; + } // Write out the binary form. void dump(std::vector& out) const @@ -153,7 +182,8 @@ protected: Id resultId; Id typeId; Op opCode; - std::vector operands; + std::vector operands; // operands, both and immediates (both are unsigned int) + std::vector idOperand; // true for operands that are , false for immediates Block* block; }; @@ -179,6 +209,7 @@ public: const std::vector >& getInstructions() const { return instructions; } + const std::vector >& getLocalVariables() const { return localVariables; } void setUnreachable() { unreachable = true; } bool isUnreachable() const { return unreachable; } // Returns the block's merge instruction, if one exists (otherwise null). @@ -195,6 +226,36 @@ public: return nullptr; } + // Change this block into a canonical dead merge block. Delete instructions + // as necessary. A canonical dead merge block has only an OpLabel and an + // OpUnreachable. + void rewriteAsCanonicalUnreachableMerge() { + assert(localVariables.empty()); + // Delete all instructions except for the label. + assert(instructions.size() > 0); + instructions.resize(1); + successors.clear(); + Instruction* unreachable = new Instruction(OpUnreachable); + addInstruction(std::unique_ptr(unreachable)); + } + // Change this block into a canonical dead continue target branching to the + // given header ID. Delete instructions as necessary. A canonical dead continue + // target has only an OpLabel and an unconditional branch back to the corresponding + // header. + void rewriteAsCanonicalUnreachableContinue(Block* header) { + assert(localVariables.empty()); + // Delete all instructions except for the label. + assert(instructions.size() > 0); + instructions.resize(1); + successors.clear(); + // Add OpBranch back to the header. + assert(header != nullptr); + Instruction* branch = new Instruction(OpBranch); + branch->addIdOperand(header->getId()); + addInstruction(std::unique_ptr(branch)); + successors.push_back(header); + } + bool isTerminated() const { switch (instructions.back()->getOpCode()) { @@ -204,6 +265,7 @@ public: case OpKill: case OpReturn: case OpReturnValue: + case OpUnreachable: return true; default: return false; @@ -237,10 +299,24 @@ protected: bool unreachable; }; +// The different reasons for reaching a block in the inReadableOrder traversal. +enum ReachReason { + // Reachable from the entry block via transfers of control, i.e. branches. + ReachViaControlFlow = 0, + // A continue target that is not reachable via control flow. + ReachDeadContinue, + // A merge block that is not reachable via control flow. + ReachDeadMerge +}; + // Traverses the control-flow graph rooted at root in an order suited for // readable code generation. Invokes callback at every node in the traversal -// order. -void inReadableOrder(Block* root, std::function callback); +// order. The callback arguments are: +// - the block, +// - the reason we reached the block, +// - if the reason was that block is an unreachable continue or unreachable merge block +// then the last parameter is the corresponding header block. +void inReadableOrder(Block* root, std::function callback); // // SPIR-V IR Function. @@ -290,7 +366,7 @@ public: parameterInstructions[p]->dump(out); // Blocks - inReadableOrder(blocks[0], [&out](const Block* b) { b->dump(out); }); + inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); }); Instruction end(0, 0, OpFunctionEnd); end.dump(out); } @@ -331,7 +407,9 @@ public: Instruction* getInstruction(Id id) const { return idToInstruction[id]; } const std::vector& getFunctions() const { return functions; } - spv::Id getTypeId(Id resultId) const { return idToInstruction[resultId]->getTypeId(); } + spv::Id getTypeId(Id resultId) const { + return idToInstruction[resultId] == nullptr ? NoType : idToInstruction[resultId]->getTypeId(); + } StorageClass getStorageClass(Id typeId) const { assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer); @@ -403,6 +481,6 @@ __inline void Block::addInstruction(std::unique_ptr inst) parent.getParent().mapInstruction(raw_instruction); } -}; // end spv namespace +} // end spv namespace #endif // spvIR_H diff --git a/Externals/glslang/StandAlone/CMakeLists.txt b/Externals/glslang/StandAlone/CMakeLists.txt old mode 100755 new mode 100644 index d500121df5..2cf2899c41 --- a/Externals/glslang/StandAlone/CMakeLists.txt +++ b/Externals/glslang/StandAlone/CMakeLists.txt @@ -4,25 +4,25 @@ set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang) set_property(TARGET glslang-default-resource-limits PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(glslang-default-resource-limits - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC ${PROJECT_SOURCE_DIR}) + PUBLIC $ + PUBLIC $) + set(SOURCES StandAlone.cpp DirStackFileIncluder.h) -set(REMAPPER_SOURCES spirv-remap.cpp) add_executable(glslangValidator ${SOURCES}) -add_executable(spirv-remap ${REMAPPER_SOURCES}) set_property(TARGET glslangValidator PROPERTY FOLDER tools) -set_property(TARGET spirv-remap PROPERTY FOLDER tools) glslang_set_link_args(glslangValidator) -glslang_set_link_args(spirv-remap) set(LIBRARIES glslang SPIRV - SPVRemapper glslang-default-resource-limits) +if(ENABLE_SPVREMAPPER) + set(LIBRARIES ${LIBRARIES} SPVRemapper) +endif() + if(WIN32) set(LIBRARIES ${LIBRARIES} psapi) elseif(UNIX) @@ -32,21 +32,36 @@ elseif(UNIX) endif(WIN32) target_link_libraries(glslangValidator ${LIBRARIES}) -target_link_libraries(spirv-remap ${LIBRARIES}) +target_include_directories(glslangValidator PUBLIC + $ + $) + +if(ENABLE_SPVREMAPPER) + set(REMAPPER_SOURCES spirv-remap.cpp) + add_executable(spirv-remap ${REMAPPER_SOURCES}) + set_property(TARGET spirv-remap PROPERTY FOLDER tools) + glslang_set_link_args(spirv-remap) + target_link_libraries(spirv-remap ${LIBRARIES}) +endif() if(WIN32) source_group("Source" FILES ${SOURCES}) endif(WIN32) if(ENABLE_GLSLANG_INSTALL) - install(TARGETS glslangValidator + install(TARGETS glslangValidator EXPORT glslangValidatorTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(EXPORT glslangValidatorTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) - install(TARGETS spirv-remap + if(ENABLE_SPVREMAPPER) + install(TARGETS spirv-remap EXPORT spirv-remapTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - + install(EXPORT spirv-remapTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) + endif() + if(BUILD_SHARED_LIBS) - install(TARGETS glslang-default-resource-limits + install(TARGETS glslang-default-resource-limits EXPORT glslang-default-resource-limitsTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT glslang-default-resource-limitsTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif() endif(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/StandAlone/ResourceLimits.cpp b/Externals/glslang/StandAlone/ResourceLimits.cpp index e22ec8015c..028caa66d1 100644 --- a/Externals/glslang/StandAlone/ResourceLimits.cpp +++ b/Externals/glslang/StandAlone/ResourceLimits.cpp @@ -125,6 +125,16 @@ const TBuiltInResource DefaultTBuiltInResource = { /* .MaxCullDistances = */ 8, /* .MaxCombinedClipAndCullDistances = */ 8, /* .MaxSamples = */ 4, + /* .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, @@ -224,7 +234,15 @@ std::string GetDefaultTBuiltInResourceString() << "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n" << "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n" << "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n" - + << "MaxMeshOutputVerticesNV " << DefaultTBuiltInResource.maxMeshOutputVerticesNV << "\n" + << "MaxMeshOutputPrimitivesNV " << DefaultTBuiltInResource.maxMeshOutputPrimitivesNV << "\n" + << "MaxMeshWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_NV << "\n" + << "MaxMeshWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeY_NV << "\n" + << "MaxMeshWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeZ_NV << "\n" + << "MaxTaskWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeX_NV << "\n" + << "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n" + << "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n" + << "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n" << "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n" << "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n" << "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n" @@ -431,6 +449,24 @@ void DecodeResourceLimits(TBuiltInResource* resources, char* config) resources->maxCombinedClipAndCullDistances = value; else if (tokenStr == "MaxSamples") resources->maxSamples = value; + else if (tokenStr == "MaxMeshOutputVerticesNV") + resources->maxMeshOutputVerticesNV = value; + else if (tokenStr == "MaxMeshOutputPrimitivesNV") + resources->maxMeshOutputPrimitivesNV = value; + else if (tokenStr == "MaxMeshWorkGroupSizeX_NV") + resources->maxMeshWorkGroupSizeX_NV = value; + else if (tokenStr == "MaxMeshWorkGroupSizeY_NV") + resources->maxMeshWorkGroupSizeY_NV = value; + else if (tokenStr == "MaxMeshWorkGroupSizeZ_NV") + resources->maxMeshWorkGroupSizeZ_NV = value; + else if (tokenStr == "MaxTaskWorkGroupSizeX_NV") + resources->maxTaskWorkGroupSizeX_NV = value; + else if (tokenStr == "MaxTaskWorkGroupSizeY_NV") + resources->maxTaskWorkGroupSizeY_NV = value; + else if (tokenStr == "MaxTaskWorkGroupSizeZ_NV") + resources->maxTaskWorkGroupSizeZ_NV = value; + else if (tokenStr == "MaxMeshViewCountNV") + resources->maxMeshViewCountNV = value; else if (tokenStr == "nonInductiveForLoops") resources->limits.nonInductiveForLoops = (value != 0); else if (tokenStr == "whileLoops") diff --git a/Externals/glslang/StandAlone/ResourceLimits.h b/Externals/glslang/StandAlone/ResourceLimits.h index 9c3eb3e9fb..736248eb39 100644 --- a/Externals/glslang/StandAlone/ResourceLimits.h +++ b/Externals/glslang/StandAlone/ResourceLimits.h @@ -37,7 +37,7 @@ #include -#include "glslang/Include/ResourceLimits.h" +#include "../glslang/Include/ResourceLimits.h" namespace glslang { diff --git a/Externals/glslang/StandAlone/StandAlone.cpp b/Externals/glslang/StandAlone/StandAlone.cpp index 6736dbcbf3..6e4c8d30d7 100644 --- a/Externals/glslang/StandAlone/StandAlone.cpp +++ b/Externals/glslang/StandAlone/StandAlone.cpp @@ -102,6 +102,9 @@ enum TOptions { EOptionDumpBareVersion = (1 << 31), }; bool targetHlslFunctionality1 = false; +bool SpvToolsDisassembler = false; +bool SpvToolsValidate = false; +bool NaNClamp = false; // // Return codes from main/exit(). @@ -143,13 +146,16 @@ void ProcessConfigFile() { if (ConfigFile.size() == 0) Resources = glslang::DefaultTBuiltInResource; +#ifndef GLSLANG_WEB else { char* configString = ReadFileData(ConfigFile.c_str()); glslang::DecodeResourceLimits(&Resources, configString); FreeFileData(configString); } +#endif } +int ReflectOptions = EShReflectionDefault; int Options = 0; const char* ExecutableName = nullptr; const char* binaryFileName = nullptr; @@ -158,19 +164,28 @@ const char* sourceEntryPointName = nullptr; const char* shaderStageName = nullptr; const char* variableName = nullptr; bool HlslEnable16BitTypes = false; +bool HlslDX9compatible = false; +bool DumpBuiltinSymbols = false; std::vector IncludeDirectoryList; -int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 -glslang::EShTargetClientVersion VulkanClientVersion = - glslang::EShTargetVulkan_1_0; // would map to, say, Vulkan 1.0 -glslang::EShTargetClientVersion OpenGLClientVersion = - glslang::EShTargetOpenGL_450; // doesn't influence anything yet, but maps to OpenGL 4.50 -glslang::EShTargetLanguageVersion TargetVersion = - glslang::EShTargetSpv_1_0; // maps to, say, SPIR-V 1.0 + +// Source environment +// (source 'Client' is currently the same as target 'Client') +int ClientInputSemanticsVersion = 100; + +// Target environment +glslang::EShClient Client = glslang::EShClientNone; // will stay EShClientNone if only validating +glslang::EShTargetClientVersion ClientVersion; // not valid until Client is set +glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone; +glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set + std::vector Processes; // what should be recorded by OpModuleProcessed, or equivalent // Per descriptor-set binding base data typedef std::map TPerSetBaseBinding; +std::vector> uniformLocationOverrides; +int uniformBase = 0; + std::array, glslang::EResCount> baseBinding; std::array, glslang::EResCount> baseBindingForSet; std::array, EShLangCount> baseResourceSetBinding; @@ -189,7 +204,7 @@ public: text.append("#define "); fixLine(def); - Processes.push_back("D"); + Processes.push_back("define-macro "); Processes.back().append(def); // The first "=" needs to turn into a space @@ -207,7 +222,7 @@ public: text.append("#undef "); fixLine(undef); - Processes.push_back("U"); + Processes.push_back("undef-macro "); Processes.back().append(undef); text.append(undef); @@ -242,6 +257,14 @@ const char* GetBinaryName(EShLanguage stage) case EShLangGeometry: name = "geom.spv"; break; case EShLangFragment: name = "frag.spv"; break; case EShLangCompute: name = "comp.spv"; break; + case EShLangRayGenNV: name = "rgen.spv"; break; + case EShLangIntersectNV: name = "rint.spv"; break; + case EShLangAnyHitNV: name = "rahit.spv"; break; + case EShLangClosestHitNV: name = "rchit.spv"; break; + case EShLangMissNV: name = "rmiss.spv"; break; + case EShLangCallableNV: name = "rcall.spv"; break; + case EShLangMeshNV: name = "mesh.spv"; break; + case EShLangTaskNV: name = "task.spv"; break; default: name = "unknown"; break; } } else @@ -269,9 +292,12 @@ bool SetConfigFile(const std::string& name) // // Give error and exit with failure code. // -void Error(const char* message) +void Error(const char* message, const char* detail = nullptr) { - fprintf(stderr, "%s: Error %s (use -h for usage)\n", ExecutableName, message); + fprintf(stderr, "%s: Error: ", ExecutableName); + if (detail != nullptr) + fprintf(stderr, "%s: ", detail); + fprintf(stderr, "%s (use -h for usage)\n", message); exit(EFailUsage); } @@ -321,7 +347,7 @@ void ProcessBindingBase(int& argc, char**& argv, glslang::TResourceType res) for (int lang = langMin; lang < langMax; ++lang) { if (!perSetBase.empty()) - baseBindingForSet[res][lang] = perSetBase; + baseBindingForSet[res][lang].insert(perSetBase.begin(), perSetBase.end()); else baseBinding[res][lang] = singleBase; } @@ -406,6 +432,9 @@ void ProcessArguments(std::vector>& workItem // minimum needed (without overriding something else) to target Vulkan SPIR-V const auto setVulkanSpv = []() { + if (Client == glslang::EShClientNone) + ClientVersion = glslang::EShTargetVulkan_1_0; + Client = glslang::EShClientVulkan; Options |= EOptionSpv; Options |= EOptionVulkanRules; Options |= EOptionLinkProgram; @@ -413,12 +442,31 @@ void ProcessArguments(std::vector>& workItem // minimum needed (without overriding something else) to target OpenGL SPIR-V const auto setOpenGlSpv = []() { + if (Client == glslang::EShClientNone) + ClientVersion = glslang::EShTargetOpenGL_450; + Client = glslang::EShClientOpenGL; Options |= EOptionSpv; Options |= EOptionLinkProgram; // undo a -H default to Vulkan Options &= ~EOptionVulkanRules; }; + const auto getUniformOverride = [getStringOperand]() { + const char *arg = getStringOperand("-u:"); + const char *split = strchr(arg, ':'); + if (split == NULL) { + printf("%s: missing location\n", arg); + exit(EFailUsage); + } + errno = 0; + int location = ::strtol(split + 1, NULL, 10); + if (errno) { + printf("%s: invalid location\n", arg); + exit(EFailUsage); + } + return std::make_pair(std::string(arg, split - arg), location); + }; + for (bumpArg(); argc >= 1; bumpArg()) { if (argv[0][0] == '-') { switch (argv[0][1]) { @@ -435,6 +483,12 @@ void ProcessArguments(std::vector>& workItem } else if (lowerword == "auto-map-locations" || // synonyms lowerword == "aml") { Options |= EOptionAutoMapLocations; + } else if (lowerword == "uniform-base") { + if (argc <= 1) + Error("no provided", lowerword.c_str()); + uniformBase = ::strtol(argv[1], NULL, 10); + bumpArg(); + break; } else if (lowerword == "client") { if (argc > 1) { if (strcmp(argv[1], "vulkan100") == 0) @@ -442,8 +496,23 @@ void ProcessArguments(std::vector>& workItem else if (strcmp(argv[1], "opengl100") == 0) setOpenGlSpv(); else - Error("--client expects vulkan100 or opengl100"); - } + Error("expects vulkan100 or opengl100", lowerword.c_str()); + } else + Error("expects vulkan100 or opengl100", lowerword.c_str()); + bumpArg(); + } else if (lowerword == "define-macro" || + lowerword == "d") { + if (argc > 1) + UserPreamble.addDef(argv[1]); + else + Error("expects ", argv[0]); + bumpArg(); + } else if (lowerword == "dump-builtin-symbols") { + DumpBuiltinSymbols = true; + } else if (lowerword == "entry-point") { + entryPointName = argv[1]; + if (argc <= 1) + Error("no provided", lowerword.c_str()); bumpArg(); } else if (lowerword == "flatten-uniform-arrays" || // synonyms lowerword == "flatten-uniform-array" || @@ -457,17 +526,33 @@ void ProcessArguments(std::vector>& workItem Options |= EOptionHlslIoMapping; } else if (lowerword == "hlsl-enable-16bit-types") { HlslEnable16BitTypes = true; + } else if (lowerword == "hlsl-dx9-compatible") { + HlslDX9compatible = true; } else if (lowerword == "invert-y" || // synonyms lowerword == "iy") { Options |= EOptionInvertY; } else if (lowerword == "keep-uncalled" || // synonyms lowerword == "ku") { Options |= EOptionKeepUncalled; + } else if (lowerword == "nan-clamp") { + NaNClamp = true; } else if (lowerword == "no-storage-format" || // synonyms lowerword == "nsf") { Options |= EOptionNoStorageFormat; } else if (lowerword == "relaxed-errors") { Options |= EOptionRelaxedErrors; + } else if (lowerword == "reflect-strict-array-suffix") { + ReflectOptions |= EShReflectionStrictArraySuffix; + } else if (lowerword == "reflect-basic-array-suffix") { + ReflectOptions |= EShReflectionBasicArraySuffix; + } else if (lowerword == "reflect-intermediate-io") { + ReflectOptions |= EShReflectionIntermediateIO; + } else if (lowerword == "reflect-separate-buffers") { + ReflectOptions |= EShReflectionSeparateBuffers; + } else if (lowerword == "reflect-all-block-variables") { + ReflectOptions |= EShReflectionAllBlockVariables; + } else if (lowerword == "reflect-unwrap-io-blocks") { + ReflectOptions |= EShReflectionUnwrapIOBlocks; } else if (lowerword == "resource-set-bindings" || // synonyms lowerword == "resource-set-binding" || lowerword == "rsb") { @@ -477,8 +562,8 @@ void ProcessArguments(std::vector>& workItem lowerword == "sib") { ProcessBindingBase(argc, argv, glslang::EResImage); } else if (lowerword == "shift-sampler-bindings" || // synonyms - lowerword == "shift-sampler-binding" || - lowerword == "ssb") { + lowerword == "shift-sampler-binding" || + lowerword == "ssb") { ProcessBindingBase(argc, argv, glslang::EResSampler); } else if (lowerword == "shift-uav-bindings" || // synonyms lowerword == "shift-uav-binding" || @@ -502,10 +587,14 @@ void ProcessArguments(std::vector>& workItem } else if (lowerword == "source-entrypoint" || // synonyms lowerword == "sep") { if (argc <= 1) - Error("no provided for --source-entrypoint"); + Error("no provided", lowerword.c_str()); sourceEntryPointName = argv[1]; bumpArg(); break; + } else if (lowerword == "spirv-dis") { + SpvToolsDisassembler = true; + } else if (lowerword == "spirv-val") { + SpvToolsValidate = true; } else if (lowerword == "stdin") { Options |= EOptionStdin; shaderStageName = argv[1]; @@ -515,30 +604,58 @@ void ProcessArguments(std::vector>& workItem if (argc > 1) { if (strcmp(argv[1], "vulkan1.0") == 0) { setVulkanSpv(); - VulkanClientVersion = glslang::EShTargetVulkan_1_0; + ClientVersion = glslang::EShTargetVulkan_1_0; } else if (strcmp(argv[1], "vulkan1.1") == 0) { setVulkanSpv(); - TargetVersion = glslang::EShTargetSpv_1_3; - VulkanClientVersion = glslang::EShTargetVulkan_1_1; + ClientVersion = glslang::EShTargetVulkan_1_1; + } else if (strcmp(argv[1], "vulkan1.2") == 0) { + setVulkanSpv(); + ClientVersion = glslang::EShTargetVulkan_1_2; } else if (strcmp(argv[1], "opengl") == 0) { setOpenGlSpv(); - OpenGLClientVersion = glslang::EShTargetOpenGL_450; + ClientVersion = glslang::EShTargetOpenGL_450; + } else if (strcmp(argv[1], "spirv1.0") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_0; + } else if (strcmp(argv[1], "spirv1.1") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_1; + } else if (strcmp(argv[1], "spirv1.2") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_2; + } else if (strcmp(argv[1], "spirv1.3") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_3; + } else if (strcmp(argv[1], "spirv1.4") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_4; + } else if (strcmp(argv[1], "spirv1.5") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_5; } else - Error("--target-env expected vulkan1.0, vulkan1.1, or opengl"); + Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2, opengl,\n" + "spirv1.0, spirv1.1, spirv1.2, spirv1.3, spirv1.4, or spirv1.5"); } bumpArg(); + } else if (lowerword == "undef-macro" || + lowerword == "u") { + if (argc > 1) + UserPreamble.addUndef(argv[1]); + else + Error("expects ", argv[0]); + bumpArg(); } else if (lowerword == "variable-name" || // synonyms lowerword == "vn") { Options |= EOptionOutputHexadecimal; if (argc <= 1) - Error("no provided for --variable-name"); + Error("no provided", lowerword.c_str()); variableName = argv[1]; bumpArg(); break; } else if (lowerword == "version") { Options |= EOptionDumpVersions; } else { - usage(); + Error("unrecognized command-line option", argv[0]); } } break; @@ -549,13 +666,16 @@ void ProcessArguments(std::vector>& workItem if (argv[0][2] == 0) Options |= EOptionReadHlsl; else - UserPreamble.addDef(getStringOperand("-D macro name")); + UserPreamble.addDef(getStringOperand("-D")); + break; + case 'u': + uniformLocationOverrides.push_back(getUniformOverride()); break; case 'E': Options |= EOptionOutputPreprocessed; break; case 'G': - // OpenGL Client + // OpenGL client setOpenGlSpv(); if (argv[0][2] != 0) ClientInputSemanticsVersion = getAttachedNumber("-G client input semantics"); @@ -589,7 +709,7 @@ void ProcessArguments(std::vector>& workItem bumpArg(); break; case 'U': - UserPreamble.addUndef(getStringOperand("-U: macro name")); + UserPreamble.addUndef(getStringOperand("-U")); break; case 'V': setVulkanSpv(); @@ -607,8 +727,6 @@ void ProcessArguments(std::vector>& workItem Options |= EOptionDefaultDesktop; break; case 'e': - // HLSL todo: entry point handle needs much more sophistication. - // This is okay for one compilation unit with one entry point. entryPointName = argv[1]; if (argc <= 1) Error("no provided for -e"); @@ -663,7 +781,7 @@ void ProcessArguments(std::vector>& workItem Options |= EOptionOutputHexadecimal; break; default: - usage(); + Error("unrecognized command-line option", argv[0]); break; } } else { @@ -679,8 +797,17 @@ void ProcessArguments(std::vector>& workItem Error("must provide -S when --stdin is given"); // Make sure that -E is not specified alongside linking (which includes SPV generation) - if ((Options & EOptionOutputPreprocessed) && (Options & EOptionLinkProgram)) - Error("can't use -E when linking is selected"); + // Or things that require linking + if (Options & EOptionOutputPreprocessed) { + if (Options & EOptionLinkProgram) + Error("can't use -E when linking is selected"); + if (Options & EOptionDumpReflection) + Error("reflection requires linking, which can't be used when -E when is selected"); + } + + // reflection requires linking + if ((Options & EOptionDumpReflection) && !(Options & EOptionLinkProgram)) + Error("reflection requires -l for linking"); // -o or -x makes no sense if there is no target binary if (binaryFileName && (Options & EOptionSpv) == 0) @@ -689,6 +816,32 @@ void ProcessArguments(std::vector>& workItem if ((Options & EOptionFlattenUniformArrays) != 0 && (Options & EOptionReadHlsl) == 0) Error("uniform array flattening only valid when compiling HLSL source."); + + // rationalize client and target language + if (TargetLanguage == glslang::EShTargetNone) { + switch (ClientVersion) { + case glslang::EShTargetVulkan_1_0: + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_0; + break; + case glslang::EShTargetVulkan_1_1: + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_3; + break; + case glslang::EShTargetVulkan_1_2: + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_5; + break; + case glslang::EShTargetOpenGL_450: + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_0; + break; + default: + break; + } + } + if (TargetLanguage != glslang::EShTargetNone && Client == glslang::EShClientNone) + Error("To generate SPIR-V, also specify client semantics. See -G and -V."); } // @@ -722,6 +875,10 @@ void SetMessageOptions(EShMessages& messages) messages = (EShMessages)(messages | EShMsgHlslEnable16BitTypes); if ((Options & EOptionOptimizeDisable) || !ENABLE_OPT) messages = (EShMessages)(messages | EShMsgHlslLegalization); + if (HlslDX9compatible) + messages = (EShMessages)(messages | EShMsgHlslDX9Compatible); + if (DumpBuiltinSymbols) + messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable); } // @@ -734,17 +891,18 @@ void CompileShaders(glslang::TWorklist& worklist) glslang::TWorkItem* workItem; if (Options & EOptionStdin) { - worklist.remove(workItem); - ShHandle compiler = ShConstructCompiler(FindLanguage("stdin"), Options); - if (compiler == 0) - return; + if (worklist.remove(workItem)) { + ShHandle compiler = ShConstructCompiler(FindLanguage("stdin"), Options); + if (compiler == nullptr) + return; - CompileFile("stdin", compiler); + CompileFile("stdin", compiler); if (! (Options & EOptionSuppressInfolog)) workItem->results = ShGetInfoLog(compiler); - ShDestruct(compiler); + ShDestruct(compiler); + } } else { while (worklist.remove(workItem)) { ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options); @@ -836,7 +994,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) const auto &compUnit = *it; glslang::TShader* shader = new glslang::TShader(compUnit.stage); shader->setStringsWithLengthsAndNames(compUnit.text, NULL, compUnit.fileNameList, compUnit.count); - if (entryPointName) // HLSL todo: this needs to be tracked per compUnits + if (entryPointName) shader->setEntryPoint(entryPointName); if (sourceEntryPointName) { if (entryPointName == nullptr) @@ -848,53 +1006,60 @@ void CompileAndLinkShaderUnits(std::vector compUnits) shader->setPreamble(UserPreamble.get()); shader->addProcesses(Processes); +#ifndef GLSLANG_WEB // Set IO mapper binding shift values for (int r = 0; r < glslang::EResCount; ++r) { const glslang::TResourceType res = glslang::TResourceType(r); // Set base bindings shader->setShiftBinding(res, baseBinding[res][compUnit.stage]); - + // Set bindings for particular resource sets // TODO: use a range based for loop here, when available in all environments. for (auto i = baseBindingForSet[res][compUnit.stage].begin(); i != baseBindingForSet[res][compUnit.stage].end(); ++i) shader->setShiftBindingForSet(res, i->second, i->first); } - - shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0); shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0); shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]); - if (Options & EOptionHlslIoMapping) - shader->setHlslIoMapping(true); - if (Options & EOptionAutoMapBindings) shader->setAutoMapBindings(true); if (Options & EOptionAutoMapLocations) shader->setAutoMapLocations(true); + for (auto& uniOverride : uniformLocationOverrides) { + shader->addUniformLocationOverride(uniOverride.first.c_str(), + uniOverride.second); + } + + shader->setUniformLocationBase(uniformBase); +#endif + + shader->setNanMinMaxClamp(NaNClamp); + +#ifdef ENABLE_HLSL + shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0); + if (Options & EOptionHlslIoMapping) + shader->setHlslIoMapping(true); +#endif + if (Options & EOptionInvertY) shader->setInvertY(true); // Set up the environment, some subsettings take precedence over earlier // ways of setting things. if (Options & EOptionSpv) { - if (Options & EOptionVulkanRules) { - shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl - : glslang::EShSourceGlsl, - compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion); - shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion); - } else { - shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl - : glslang::EShSourceGlsl, - compUnit.stage, glslang::EShClientOpenGL, ClientInputSemanticsVersion); - shader->setEnvClient(glslang::EShClientOpenGL, OpenGLClientVersion); - } - shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion); + shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl + : glslang::EShSourceGlsl, + compUnit.stage, Client, ClientInputSemanticsVersion); + shader->setEnvClient(Client, ClientVersion); + shader->setEnvTarget(TargetLanguage, TargetVersion); +#ifdef ENABLE_HLSL if (targetHlslFunctionality1) shader->setEnvTargetHlslFunctionality1(); +#endif } shaders.push_back(shader); @@ -904,10 +1069,10 @@ void CompileAndLinkShaderUnits(std::vector compUnits) DirStackFileIncluder includer; std::for_each(IncludeDirectoryList.rbegin(), IncludeDirectoryList.rend(), [&includer](const std::string& dir) { includer.pushExternalLocalDirectory(dir); }); +#ifndef GLSLANG_WEB if (Options & EOptionOutputPreprocessed) { std::string str; - if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false, - messages, &str, includer)) { + if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false, messages, &str, includer)) { PutsIfNonEmpty(str.c_str()); } else { CompileFailed = true; @@ -916,6 +1081,8 @@ void CompileAndLinkShaderUnits(std::vector compUnits) StderrIfNonEmpty(shader->getInfoDebugLog()); continue; } +#endif + if (! shader->parse(&Resources, defaultVersion, false, messages, includer)) CompileFailed = true; @@ -937,11 +1104,13 @@ void CompileAndLinkShaderUnits(std::vector compUnits) if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages)) LinkFailed = true; +#ifndef GLSLANG_WEB // Map IO if (Options & EOptionSpv) { if (!program.mapIO()) LinkFailed = true; } +#endif // Report if (! (Options & EOptionSuppressInfolog) && @@ -950,11 +1119,13 @@ void CompileAndLinkShaderUnits(std::vector compUnits) PutsIfNonEmpty(program.getInfoDebugLog()); } +#ifndef GLSLANG_WEB // Reflect if (Options & EOptionDumpReflection) { - program.buildReflection(); + program.buildReflection(ReflectOptions); program.dumpReflection(); } +#endif // Dump SPIR-V if (Options & EOptionSpv) { @@ -971,6 +1142,8 @@ void CompileAndLinkShaderUnits(std::vector compUnits) spvOptions.generateDebugInfo = true; spvOptions.disableOptimizer = (Options & EOptionOptimizeDisable) != 0; spvOptions.optimizeSize = (Options & EOptionOptimizeSize) != 0; + spvOptions.disassemble = SpvToolsDisassembler; + spvOptions.validate = SpvToolsValidate; glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions); // Dump the spv to a file or stdout, etc., but only if not doing @@ -982,9 +1155,10 @@ void CompileAndLinkShaderUnits(std::vector compUnits) } else { glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage)); } - if (Options & EOptionHumanReadableSpv) { +#ifndef GLSLANG_WEB + if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv)) spv::Disassemble(std::cout, spirv); - } +#endif } } } @@ -1072,11 +1246,13 @@ int singleMain() workList.add(item.get()); }); +#ifndef GLSLANG_WEB if (Options & EOptionDumpConfig) { printf("%s", glslang::GetDefaultTBuiltInResourceString().c_str()); if (workList.empty()) return ESuccess; } +#endif if (Options & EOptionDumpBareVersion) { printf("%d.%d.%d\n", @@ -1111,13 +1287,15 @@ int singleMain() ProcessConfigFile(); + if ((Options & EOptionReadHlsl) && !((Options & EOptionOutputPreprocessed) || (Options & EOptionSpv))) + Error("HLSL requires SPIR-V code generation (or preprocessing only)"); + // // Two modes: // 1) linking all arguments together, single-threaded, new C++ interface // 2) independent arguments, can be tackled by multiple asynchronous threads, for testing thread safety, using the old handle interface // - if (Options & EOptionLinkProgram || - Options & EOptionOutputPreprocessed) { + if (Options & (EOptionLinkProgram | EOptionOutputPreprocessed)) { glslang::InitializeProcess(); glslang::InitializeProcess(); // also test reference counting of users glslang::InitializeProcess(); // also test reference counting of users @@ -1195,7 +1373,14 @@ int C_DECL main(int argc, char* argv[]) // .geom = geometry // .frag = fragment // .comp = compute -// +// .rgen = ray generation +// .rint = ray intersection +// .rahit = ray any hit +// .rchit = ray closest hit +// .rmiss = ray miss +// .rcall = ray callable +// .mesh = mesh +// .task = task // Additionally, the file names may end in ..glsl and ..hlsl // where is one of the stages listed above. // @@ -1239,6 +1424,22 @@ EShLanguage FindLanguage(const std::string& name, bool parseStageName) return EShLangFragment; else if (stageName == "comp") return EShLangCompute; + else if (stageName == "rgen") + return EShLangRayGenNV; + else if (stageName == "rint") + return EShLangIntersectNV; + else if (stageName == "rahit") + return EShLangAnyHitNV; + else if (stageName == "rchit") + return EShLangClosestHitNV; + else if (stageName == "rmiss") + return EShLangMissNV; + else if (stageName == "rcall") + return EShLangCallableNV; + else if (stageName == "mesh") + return EShLangMeshNV; + else if (stageName == "task") + return EShLangTaskNV; usage(); return EShLangVertex; @@ -1308,30 +1509,39 @@ void usage() " .geom for a geometry shader\n" " .frag for a fragment shader\n" " .comp for a compute shader\n" + " .mesh for a mesh shader\n" + " .task for a task shader\n" + " .rgen for a ray generation shader\n" + " .rint for a ray intersection shader\n" + " .rahit for a ray any hit shader\n" + " .rchit for a ray closest hit shader\n" + " .rmiss for a ray miss shader\n" + " .rcall for a ray callable shader\n" " .glsl for .vert.glsl, .tesc.glsl, ..., .comp.glsl compound suffixes\n" " .hlsl for .vert.hlsl, .tesc.hlsl, ..., .comp.hlsl compound suffixes\n" "\n" "Options:\n" " -C cascading errors; risk crash from accumulation of error recoveries\n" - " -D input is HLSL (default when any suffix is .hlsl)\n" - " -D\n" - " -D define a pre-processor macro\n" + " -D input is HLSL (this is the default when any suffix is .hlsl)\n" + " -D | --define-macro | --D \n" + " define a pre-processor macro\n" " -E print pre-processed GLSL; cannot be used with -l;\n" - " errors will appear on stderr.\n" + " errors will appear on stderr\n" " -G[ver] create SPIR-V binary, under OpenGL semantics; turns on -l;\n" - " default file name is .spv (-o overrides this)\n" + " default file name is .spv (-o overrides this);\n" " 'ver', when present, is the version of the input semantics,\n" - " which will appear in #define GL_SPIRV ver\n" - " '--client opengl100' is the same as -G100\n" + " which will appear in #define GL_SPIRV ver;\n" + " '--client opengl100' is the same as -G100;\n" " a '--target-env' for OpenGL will also imply '-G'\n" " -H print human readable form of SPIR-V; turns on -V\n" " -I add dir to the include search path; includer's directory\n" " is searched first, followed by left-to-right order of -I\n" - " -Od disables optimization. May cause illegal SPIR-V for HLSL.\n" - " -Os optimizes SPIR-V to minimize size.\n" + " -Od disables optimization; may cause illegal SPIR-V for HLSL\n" + " -Os optimizes SPIR-V to minimize size\n" " -S uses specified stage rather than parsing the file extension\n" " choices for are vert, tesc, tese, geom, frag, or comp\n" - " -U undefine a pre-processor macro\n" + " -U | --undef-macro | --U \n" + " undefine a pre-processor macro\n" " -V[ver] create SPIR-V binary, under Vulkan semantics; turns on -l;\n" " default file name is .spv (-o overrides this)\n" " 'ver', when present, is the version of the input semantics,\n" @@ -1342,89 +1552,116 @@ void usage() " creates the default configuration file (redirect to a .conf file)\n" " -d default to desktop (#version 110) when there is no shader #version\n" " (default is ES version 100)\n" - " -e specify as the entry-point name\n" + " -e | --entry-point \n" + " specify as the entry-point function name\n" " -f{hlsl_functionality1}\n" " 'hlsl_functionality1' enables use of the\n" - " SPV_GOOGLE_hlsl_functionality1 extension\n" + " SPV_GOOGLE_hlsl_functionality1 extension\n" " -g generate debug information\n" " -h print this usage message\n" " -i intermediate tree (glslang AST) is printed out\n" " -l link all input files together to form a single module\n" " -m memory leak mode\n" " -o save binary to , requires a binary option (e.g., -V)\n" - " -q dump reflection query database\n" - " -r synonym for --relaxed-errors\n" + " -q dump reflection query database; requires -l for linking\n" + " -r | --relaxed-errors" + " relaxed GLSL semantic error-checking mode\n" " -s silence syntax and semantic error reporting\n" " -t multi-threaded mode\n" - " -v print version strings\n" - " -w synonym for --suppress-warnings\n" + " -v | --version\n" + " print version strings\n" + " -w | --suppress-warnings\n" + " suppress GLSL warnings, except as required by \"#extension : warn\"\n" " -x save binary output as text-based 32-bit hexadecimal numbers\n" - " --auto-map-bindings automatically bind uniform variables\n" - " without explicit bindings.\n" - " --amb synonym for --auto-map-bindings\n" - " --auto-map-locations automatically locate input/output lacking\n" - " 'location' (fragile, not cross stage)\n" - " --aml synonym for --auto-map-locations\n" - " --client {vulkan|opengl} see -V and -G\n" - " -dumpfullversion print bare major.minor.patchlevel\n" - " -dumpversion same as -dumpfullversion\n" - " --flatten-uniform-arrays flatten uniform texture/sampler arrays to\n" - " scalars\n" - " --fua synonym for --flatten-uniform-arrays\n" - " --hlsl-offsets Allow block offsets to follow HLSL rules\n" - " Works independently of source language\n" - " --hlsl-iomap Perform IO mapping in HLSL register space\n" - " --hlsl-enable-16bit-types Allow use of 16-bit types in SPIR-V for HLSL\n" - " --invert-y | --iy invert position.Y output in vertex shader\n" - " --keep-uncalled don't eliminate uncalled functions\n" - " --ku synonym for --keep-uncalled\n" - " --no-storage-format use Unknown image format\n" - " --nsf synonym for --no-storage-format\n" - " --relaxed-errors relaxed GLSL semantic error-checking mode\n" + " -u: specify a uniform location override for --aml\n" + " --uniform-base set a base to use for generated uniform locations\n" + " --auto-map-bindings | --amb automatically bind uniform variables\n" + " without explicit bindings\n" + " --auto-map-locations | --aml automatically locate input/output lacking\n" + " 'location' (fragile, not cross stage)\n" + " --client {vulkan|opengl} see -V and -G\n" + " --dump-builtin-symbols prints builtin symbol table prior each compile\n" + " -dumpfullversion | -dumpversion print bare major.minor.patchlevel\n" + " --flatten-uniform-arrays | --fua flatten uniform texture/sampler arrays to\n" + " scalars\n" + " --hlsl-offsets allow block offsets to follow HLSL rules\n" + " works independently of source language\n" + " --hlsl-iomap perform IO mapping in HLSL register space\n" + " --hlsl-enable-16bit-types allow 16-bit types in SPIR-V for HLSL\n" + " --hlsl-dx9-compatible interprets sampler declarations as a\n" + " texture/sampler combo like DirectX9 would.\n" + " --invert-y | --iy invert position.Y output in vertex shader\n" + " --keep-uncalled | --ku don't eliminate uncalled functions\n" + " --nan-clamp favor non-NaN operand in min, max, and clamp\n" + " --no-storage-format | --nsf use Unknown image format\n" + " --reflect-strict-array-suffix use strict array suffix rules when\n" + " reflecting\n" + " --reflect-basic-array-suffix arrays of basic types will have trailing [0]\n" + " --reflect-intermediate-io reflection includes inputs/outputs of linked\n" + " shaders rather than just vertex/fragment\n" + " --reflect-separate-buffers reflect buffer variables and blocks\n" + " separately to uniforms\n" + " --reflect-all-block-variables reflect all variables in blocks, whether\n" + " inactive or active\n" + " --reflect-unwrap-io-blocks unwrap input/output blocks the same as\n" + " uniform blocks\n" " --resource-set-binding [stage] name set binding\n" - " Set descriptor set and binding for individual resources\n" + " set descriptor set and binding for\n" + " individual resources\n" " --resource-set-binding [stage] set\n" - " Set descriptor set for all resources\n" - " --rsb [stage] type set binding synonym for --resource-set-binding\n" - " --shift-image-binding [stage] num base binding number for images (uav)\n" - " --shift-image-binding [stage] [num set]... per-descriptor-set shift values\n" - " --sib [stage] num synonym for --shift-image-binding\n" - " --shift-sampler-binding [stage] num base binding number for samplers\n" - " --shift-sampler-binding [stage] [num set]... per-descriptor-set shift values\n" - " --ssb [stage] num synonym for --shift-sampler-binding\n" - " --shift-ssbo-binding [stage] num base binding number for SSBOs\n" - " --shift-ssbo-binding [stage] [num set]... per-descriptor-set shift values\n" - " --sbb [stage] num synonym for --shift-ssbo-binding\n" - " --shift-texture-binding [stage] num base binding number for textures\n" - " --shift-texture-binding [stage] [num set]... per-descriptor-set shift values\n" - " --stb [stage] num synonym for --shift-texture-binding\n" - " --shift-uav-binding [stage] num base binding number for UAVs\n" - " --shift-uav-binding [stage] [num set]... per-descriptor-set shift values\n" - " --suavb [stage] num synonym for --shift-uav-binding\n" - " --shift-UBO-binding [stage] num base binding number for UBOs\n" - " --shift-UBO-binding [stage] [num set]... per-descriptor-set shift values\n" - " --shift-cbuffer-binding [stage] num synonym for --shift-UBO-binding\n" - " --shift-cbuffer-binding [stage] [num set]... per-descriptor-set shift values\n" - " --sub [stage] num synonym for --shift-UBO-binding\n" - " --source-entrypoint the given shader source function is\n" - " renamed to be the given in -e\n" - " --sep synonym for --source-entrypoint\n" - " --stdin Read from stdin instead of from a file.\n" - " You'll have to provide the shader stage\n" - " using -S.\n" - " --suppress-warnings suppress GLSL warnings\n" - " (except as required by #extension : warn)\n" - " --target-env {vulkan1.0 | vulkan1.1 | opengl} \n" - " set execution environment that emitted code\n" - " will execute in (as opposed to the language\n" - " semantics selected by --client) defaults:\n" - " 'vulkan1.0' under '--client vulkan'\n" - " 'opengl' under '--client opengl'\n" - " --variable-name Creates a C header file that contains a\n" - " uint32_t array named \n" - " initialized with the shader binary code.\n" - " --version synonym for -v\n" - " --vn synonym for --variable-name \n" + " set descriptor set for all resources\n" + " --rsb synonym for --resource-set-binding\n" + " --shift-image-binding [stage] num\n" + " base binding number for images (uav)\n" + " --shift-image-binding [stage] [num set]...\n" + " per-descriptor-set shift values\n" + " --sib synonym for --shift-image-binding\n" + " --shift-sampler-binding [stage] num\n" + " base binding number for samplers\n" + " --shift-sampler-binding [stage] [num set]...\n" + " per-descriptor-set shift values\n" + " --ssb synonym for --shift-sampler-binding\n" + " --shift-ssbo-binding [stage] num base binding number for SSBOs\n" + " --shift-ssbo-binding [stage] [num set]...\n" + " per-descriptor-set shift values\n" + " --sbb synonym for --shift-ssbo-binding\n" + " --shift-texture-binding [stage] num\n" + " base binding number for textures\n" + " --shift-texture-binding [stage] [num set]...\n" + " per-descriptor-set shift values\n" + " --stb synonym for --shift-texture-binding\n" + " --shift-uav-binding [stage] num base binding number for UAVs\n" + " --shift-uav-binding [stage] [num set]...\n" + " per-descriptor-set shift values\n" + " --suavb synonym for --shift-uav-binding\n" + " --shift-UBO-binding [stage] num base binding number for UBOs\n" + " --shift-UBO-binding [stage] [num set]...\n" + " per-descriptor-set shift values\n" + " --sub synonym for --shift-UBO-binding\n" + " --shift-cbuffer-binding | --scb synonyms for --shift-UBO-binding\n" + " --spirv-dis output standard-form disassembly; works only\n" + " when a SPIR-V generation option is also used\n" + " --spirv-val execute the SPIRV-Tools validator\n" + " --source-entrypoint the given shader source function is\n" + " renamed to be the given in -e\n" + " --sep synonym for --source-entrypoint\n" + " --stdin read from stdin instead of from a file;\n" + " requires providing the shader stage using -S\n" + " --target-env {vulkan1.0 | vulkan1.1 | vulkan1.2 | opengl | \n" + " spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 | spirv1.5}\n" + " Set the execution environment that the\n" + " generated code will be executed in.\n" + " Defaults to:\n" + " * vulkan1.0 under --client vulkan\n" + " * opengl under --client opengl\n" + " * spirv1.0 under --target-env vulkan1.0\n" + " * spirv1.3 under --target-env vulkan1.1\n" + " * spirv1.5 under --target-env vulkan1.2\n" + " Multiple --target-env can be specified.\n" + " --variable-name \n" + " --vn creates a C header file that contains a\n" + " uint32_t array named \n" + " initialized with the shader binary code\n" ); exit(EFailUsage); diff --git a/Externals/glslang/StandAlone/spirv-remap.cpp b/Externals/glslang/StandAlone/spirv-remap.cpp index 998f7428aa..5e2ed0aeaf 100644 --- a/Externals/glslang/StandAlone/spirv-remap.cpp +++ b/Externals/glslang/StandAlone/spirv-remap.cpp @@ -227,7 +227,7 @@ namespace { } } else if (arg == "--version" || arg == "-V") { - std::cout << basename(argv[0]) << " version 0.97 " << __DATE__ << " " << __TIME__ << std::endl; + std::cout << basename(argv[0]) << " version 0.97" << std::endl; exit(0); } else if (arg == "--input" || arg == "-i") { // Collect input files diff --git a/Externals/glslang/build_overrides/glslang.gni b/Externals/glslang/build_overrides/glslang.gni new file mode 100644 index 0000000000..500578ccd7 --- /dev/null +++ b/Externals/glslang/build_overrides/glslang.gni @@ -0,0 +1,37 @@ +# 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. + +# These are variables that are overridable by projects that include glslang. + +# The path to glslang dependencies. +glslang_spirv_tools_dir = "//Externals/spirv-tools" diff --git a/Externals/glslang/glslang/CMakeLists.txt b/Externals/glslang/glslang/CMakeLists.txt old mode 100755 new mode 100644 index 1efde2edd4..446cabb91c --- a/Externals/glslang/glslang/CMakeLists.txt +++ b/Externals/glslang/glslang/CMakeLists.txt @@ -6,7 +6,12 @@ else(WIN32) message("unknown platform") endif(WIN32) +if(EMSCRIPTEN OR ENABLE_GLSLANG_WEB) + add_subdirectory(OSDependent/Web) +endif(EMSCRIPTEN OR ENABLE_GLSLANG_WEB) + set(SOURCES + MachineIndependent/glslang.m4 MachineIndependent/glslang.y MachineIndependent/glslang_tab.cpp MachineIndependent/attribute.cpp @@ -71,20 +76,15 @@ set(HEADERS MachineIndependent/preprocessor/PpContext.h MachineIndependent/preprocessor/PpTokens.h) -# This might be useful for making grammar changes: -# -# find_package(BISON) -# add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp.h -# COMMAND ${BISON_EXECUTABLE} --defines=${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp.h -t ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang.y -o ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp -# MAIN_DEPENDENCY MachineIndependent/glslang.y -# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -# set(BISON_GLSLParser_OUTPUT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp) +glslang_pch(SOURCES MachineIndependent/pch.cpp) add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS}) set_property(TARGET glslang PROPERTY FOLDER glslang) set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(glslang OGLCompiler OSDependent) -target_include_directories(glslang PUBLIC ..) +target_include_directories(glslang PUBLIC + $ + $) if(WIN32 AND BUILD_SHARED_LIBS) set_target_properties(glslang PROPERTIES PREFIX "") @@ -104,13 +104,15 @@ endif(WIN32) if(ENABLE_GLSLANG_INSTALL) if(BUILD_SHARED_LIBS) - install(TARGETS glslang + install(TARGETS glslang EXPORT glslangTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) else() - install(TARGETS glslang + install(TARGETS glslang EXPORT glslangTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() + install(EXPORT glslangTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif(ENABLE_GLSLANG_INSTALL) if(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/glslang/Include/BaseTypes.h b/Externals/glslang/glslang/Include/BaseTypes.h index 46fe159b49..6d4b4ff8e3 100644 --- a/Externals/glslang/glslang/Include/BaseTypes.h +++ b/Externals/glslang/glslang/Include/BaseTypes.h @@ -61,6 +61,8 @@ enum TBasicType { EbtSampler, EbtStruct, EbtBlock, + EbtAccStructNV, + EbtReference, // HLSL types that live only temporarily. EbtString, @@ -88,6 +90,12 @@ enum TStorageQualifier { EvqBuffer, // read/write, shared with app EvqShared, // compute shader's read/write 'shared' qualifier + EvqPayloadNV, + EvqPayloadInNV, + EvqHitAttrNV, + EvqCallableDataNV, + EvqCallableDataInNV, + // 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 @@ -207,7 +215,6 @@ enum TBuiltInVariable { EbvSampleMask, EbvHelperInvocation, -#ifdef AMD_EXTENSIONS EbvBaryCoordNoPersp, EbvBaryCoordNoPerspCentroid, EbvBaryCoordNoPerspSample, @@ -215,19 +222,54 @@ enum TBuiltInVariable { EbvBaryCoordSmoothCentroid, EbvBaryCoordSmoothSample, EbvBaryCoordPullModel, -#endif EbvViewIndex, EbvDeviceIndex, -#ifdef NV_EXTENSIONS + EbvFragSizeEXT, + EbvFragInvocationCountEXT, + EbvViewportMaskNV, EbvSecondaryPositionNV, EbvSecondaryViewportMaskNV, EbvPositionPerViewNV, EbvViewportMaskPerViewNV, EbvFragFullyCoveredNV, -#endif + EbvFragmentSizeNV, + EbvInvocationsPerPixelNV, + // ray tracing + EbvLaunchIdNV, + EbvLaunchSizeNV, + EbvInstanceCustomIndexNV, + EbvWorldRayOriginNV, + EbvWorldRayDirectionNV, + EbvObjectRayOriginNV, + EbvObjectRayDirectionNV, + EbvRayTminNV, + EbvRayTmaxNV, + EbvHitTNV, + EbvHitKindNV, + EbvObjectToWorldNV, + EbvWorldToObjectNV, + EbvIncomingRayFlagsNV, + // barycentrics + EbvBaryCoordNV, + EbvBaryCoordNoPerspNV, + // mesh shaders + EbvTaskCountNV, + EbvPrimitiveCountNV, + EbvPrimitiveIndicesNV, + EbvClipDistancePerViewNV, + EbvCullDistancePerViewNV, + EbvLayerPerViewNV, + EbvMeshViewCountNV, + EbvMeshViewIndicesNV, + + // sm builtins + EbvWarpsPerSM, + EbvSMCount, + EbvWarpID, + EbvSMID, // HLSL built-ins that live only temporarily, until they get remapped // to one of the above. @@ -247,6 +289,19 @@ enum TBuiltInVariable { EbvLast }; +// In this enum, order matters; users can assume higher precision is a bigger value +// and EpqNone is 0. +enum TPrecisionQualifier { + EpqNone = 0, + EpqLow, + EpqMedium, + EpqHigh +}; + +#ifdef GLSLANG_WEB +__inline const char* GetStorageQualifierString(TStorageQualifier q) { return ""; } +__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { return ""; } +#else // These will show up in error messages __inline const char* GetStorageQualifierString(TStorageQualifier q) { @@ -273,6 +328,11 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q) case EvqPointCoord: return "gl_PointCoord"; break; case EvqFragColor: return "fragColor"; break; case EvqFragDepth: return "gl_FragDepth"; break; + 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; default: return "unknown qualifier"; } } @@ -287,6 +347,8 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvLocalInvocationId: return "LocalInvocationID"; case EbvGlobalInvocationId: return "GlobalInvocationID"; case EbvLocalInvocationIndex: return "LocalInvocationIndex"; + case EbvNumSubgroups: return "NumSubgroups"; + case EbvSubgroupID: return "SubgroupID"; case EbvSubGroupSize: return "SubGroupSize"; case EbvSubGroupInvocation: return "SubGroupInvocation"; case EbvSubGroupEqMask: return "SubGroupEqMask"; @@ -294,6 +356,13 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvSubGroupGtMask: return "SubGroupGtMask"; case EbvSubGroupLeMask: return "SubGroupLeMask"; case EbvSubGroupLtMask: return "SubGroupLtMask"; + case EbvSubgroupSize2: return "SubgroupSize"; + case EbvSubgroupInvocation2: return "SubgroupInvocationID"; + case EbvSubgroupEqMask2: return "SubgroupEqMask"; + case EbvSubgroupGeMask2: return "SubgroupGeMask"; + case EbvSubgroupGtMask2: return "SubgroupGtMask"; + case EbvSubgroupLeMask2: return "SubgroupLeMask"; + case EbvSubgroupLtMask2: return "SubgroupLtMask"; case EbvVertexId: return "VertexId"; case EbvInstanceId: return "InstanceId"; case EbvVertexIndex: return "VertexIndex"; @@ -345,7 +414,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvSampleMask: return "SampleMaskIn"; case EbvHelperInvocation: return "HelperInvocation"; -#ifdef AMD_EXTENSIONS case EbvBaryCoordNoPersp: return "BaryCoordNoPersp"; case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid"; case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample"; @@ -353,32 +421,57 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid"; case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample"; case EbvBaryCoordPullModel: return "BaryCoordPullModel"; -#endif case EbvViewIndex: return "ViewIndex"; case EbvDeviceIndex: return "DeviceIndex"; -#ifdef NV_EXTENSIONS + case EbvFragSizeEXT: return "FragSizeEXT"; + case EbvFragInvocationCountEXT: return "FragInvocationCountEXT"; + case EbvViewportMaskNV: return "ViewportMaskNV"; case EbvSecondaryPositionNV: return "SecondaryPositionNV"; case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; case EbvPositionPerViewNV: return "PositionPerViewNV"; case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; case EbvFragFullyCoveredNV: return "FragFullyCoveredNV"; -#endif + 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"; + + case EbvWarpsPerSM: return "WarpsPerSMNV"; + case EbvSMCount: return "SMCountNV"; + case EbvWarpID: return "WarpIDNV"; + case EbvSMID: return "SMIDNV"; + default: return "unknown built-in variable"; } } -// In this enum, order matters; users can assume higher precision is a bigger value -// and EpqNone is 0. -enum TPrecisionQualifier { - EpqNone = 0, - EpqLow, - EpqMedium, - EpqHigh -}; - __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { switch (p) { @@ -389,6 +482,7 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) default: return "unknown precision qualifier"; } } +#endif __inline bool isTypeSignedInt(TBasicType type) { @@ -433,7 +527,8 @@ __inline bool isTypeFloat(TBasicType type) } } -__inline int getTypeRank(TBasicType type) { +__inline int getTypeRank(TBasicType type) +{ int res = -1; switch(type) { case EbtInt8: diff --git a/Externals/glslang/glslang/Include/Common.h b/Externals/glslang/glslang/Include/Common.h index 35eaa31048..733a790cfd 100644 --- a/Externals/glslang/glslang/Include/Common.h +++ b/Externals/glslang/glslang/Include/Common.h @@ -38,7 +38,7 @@ #define _COMMON_INCLUDED_ -#if defined(__ANDROID__) || _MSC_VER < 1700 +#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700) #include namespace std { template @@ -102,6 +102,7 @@ std::string to_string(const T& val) { #include #include #include +#include #include #include "PoolAlloc.h" @@ -229,16 +230,29 @@ inline const TString String(const int i, const int /*base*/ = 10) #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 --git a/Externals/glslang/glslang/Include/ConstantUnion.h b/Externals/glslang/glslang/Include/ConstantUnion.h index 3e93340151..76b2d9c08b 100644 --- a/Externals/glslang/glslang/Include/ConstantUnion.h +++ b/Externals/glslang/glslang/Include/ConstantUnion.h @@ -213,6 +213,28 @@ public: return false; switch (type) { + case EbtInt: + if (constant.iConst == iConst) + return true; + + break; + case EbtUint: + if (constant.uConst == uConst) + return true; + + break; + case EbtBool: + if (constant.bConst == bConst) + return true; + + break; + case EbtDouble: + if (constant.dConst == dConst) + return true; + + break; + +#ifndef GLSLANG_WEB case EbtInt16: if (constant.i16Const == i16Const) return true; @@ -232,16 +254,6 @@ public: if (constant.u8Const == u8Const) return true; - break; - case EbtInt: - if (constant.iConst == iConst) - return true; - - break; - case EbtUint: - if (constant.uConst == uConst) - return true; - break; case EbtInt64: if (constant.i64Const == i64Const) @@ -253,16 +265,7 @@ public: return true; break; - case EbtDouble: - if (constant.dConst == dConst) - return true; - - break; - case EbtBool: - if (constant.bConst == bConst) - return true; - - break; +#endif default: assert(false && "Default missing"); } @@ -329,6 +332,22 @@ public: { assert(type == constant.type); switch (type) { + case EbtInt: + if (iConst > constant.iConst) + return true; + + return false; + case EbtUint: + if (uConst > constant.uConst) + return true; + + return false; + case EbtDouble: + if (dConst > constant.dConst) + return true; + + return false; +#ifndef GLSLANG_WEB case EbtInt8: if (i8Const > constant.i8Const) return true; @@ -348,16 +367,6 @@ public: if (u16Const > constant.u16Const) return true; - return false; - case EbtInt: - if (iConst > constant.iConst) - return true; - - return false; - case EbtUint: - if (uConst > constant.uConst) - return true; - return false; case EbtInt64: if (i64Const > constant.i64Const) @@ -369,11 +378,7 @@ public: return true; return false; - case EbtDouble: - if (dConst > constant.dConst) - return true; - - return false; +#endif default: assert(false && "Default missing"); return false; @@ -384,6 +389,7 @@ public: { assert(type == constant.type); switch (type) { +#ifndef GLSLANG_WEB case EbtInt8: if (i8Const < constant.i8Const) return true; @@ -394,7 +400,7 @@ public: return true; return false; - case EbtInt16: + case EbtInt16: if (i16Const < constant.i16Const) return true; @@ -402,17 +408,6 @@ public: case EbtUint16: if (u16Const < constant.u16Const) return true; - - return false; - case EbtInt: - if (iConst < constant.iConst) - return true; - - return false; - case EbtUint: - if (uConst < constant.uConst) - return true; - return false; case EbtInt64: if (i64Const < constant.i64Const) @@ -424,10 +419,21 @@ public: return true; return false; +#endif case EbtDouble: if (dConst < constant.dConst) return true; + return false; + case EbtInt: + if (iConst < constant.iConst) + return true; + + return false; + case EbtUint: + if (uConst < constant.uConst) + return true; + return false; default: assert(false && "Default missing"); @@ -440,15 +446,17 @@ public: 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 EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -460,15 +468,17 @@ public: 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 EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -480,15 +490,17 @@ public: 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 EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -500,14 +512,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -518,6 +532,7 @@ public: { TConstUnion returnValue; switch (type) { +#ifndef GLSLANG_WEB case EbtInt8: switch (constant.type) { case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break; @@ -570,32 +585,38 @@ public: default: assert(false && "Default missing"); } break; +#endif case EbtInt: switch (constant.type) { + case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; + case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break; +#ifndef GLSLANG_WEB 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; case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break; +#endif default: assert(false && "Default missing"); } break; case EbtUint: switch (constant.type) { + case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break; +#ifndef GLSLANG_WEB 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; case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break; +#endif default: assert(false && "Default missing"); } break; +#ifndef GLSLANG_WEB case EbtInt64: switch (constant.type) { case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break; @@ -622,6 +643,7 @@ public: default: assert(false && "Default missing"); } break; +#endif default: assert(false && "Default missing"); } @@ -632,6 +654,7 @@ public: { TConstUnion returnValue; switch (type) { +#ifndef GLSLANG_WEB case EbtInt8: switch (constant.type) { case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break; @@ -684,32 +707,6 @@ public: 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; - case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; - default: assert(false && "Default missing"); - } - 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; - case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; - default: assert(false && "Default missing"); - } - break; case EbtInt64: switch (constant.type) { case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break; @@ -736,6 +733,37 @@ public: default: assert(false && "Default missing"); } break; +#endif + case EbtInt: + switch (constant.type) { + case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; + case EbtUint: returnValue.setIConst(iConst << constant.uConst); break; +#ifndef GLSLANG_WEB + 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 EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break; + case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break; +#endif + default: assert(false && "Default missing"); + } + break; + case EbtUint: + switch (constant.type) { + case EbtInt: returnValue.setUConst(uConst << constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst << constant.uConst); break; +#ifndef GLSLANG_WEB + 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 EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break; + case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break; +#endif + default: assert(false && "Default missing"); + } + break; default: assert(false && "Default missing"); } @@ -747,14 +775,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst & constant.uConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -766,14 +796,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst | constant.uConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -785,14 +817,16 @@ public: TConstUnion returnValue; assert(type == constant.type); switch (type) { + case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; + case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } @@ -803,14 +837,16 @@ public: { TConstUnion returnValue; switch (type) { + case EbtInt: returnValue.setIConst(~iConst); break; + case EbtUint: returnValue.setUConst(~uConst); break; +#ifndef GLSLANG_WEB 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; +#endif default: assert(false && "Default missing"); } diff --git a/Externals/glslang/glslang/Include/PoolAlloc.h b/Externals/glslang/glslang/Include/PoolAlloc.h index 0e237a6a2c..b8eccb8832 100644 --- a/Externals/glslang/glslang/Include/PoolAlloc.h +++ b/Externals/glslang/glslang/Include/PoolAlloc.h @@ -304,7 +304,6 @@ public: size_type max_size() const { return static_cast(-1) / sizeof(T); } size_type max_size(int size) const { return static_cast(-1) / size; } - void setAllocator(TPoolAllocator* a) { allocator = *a; } TPoolAllocator& getAllocator() const { return allocator; } protected: diff --git a/Externals/glslang/glslang/Include/ResourceLimits.h b/Externals/glslang/glslang/Include/ResourceLimits.h index 0d07b8c841..106b21d9ca 100644 --- a/Externals/glslang/glslang/Include/ResourceLimits.h +++ b/Externals/glslang/glslang/Include/ResourceLimits.h @@ -133,6 +133,15 @@ struct TBuiltInResource { 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 --git a/Externals/glslang/glslang/Include/Types.h b/Externals/glslang/glslang/Include/Types.h index 39d6737cfc..3572099e3d 100644 --- a/Externals/glslang/glslang/Include/Types.h +++ b/Externals/glslang/glslang/Include/Types.h @@ -80,30 +80,59 @@ struct TSampler { // misnomer now; includes images, textures without sampler, bool image : 1; // image, combined should be false 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 - unsigned int vectorSize : 3; // vector return type size. +#ifdef GLSLANG_WEB + bool is1D() const { return false; } + bool isBuffer() const { return false; } + bool isRect() const { return false; } + bool isSubpass() const { return false; } + bool isCombined() const { return true; } + bool isImage() const { return false; } + bool isImageClass() const { return false; } + bool isMultiSample() const { return false; } + bool isExternal() const { return false; } + void setExternal(bool e) { } + bool isYuv() const { return false; } +#else + unsigned int vectorSize : 3; // vector return type size. // Some languages support structures as sample results. Storing the whole structure in the // TSampler is too large, so there is an index to a separate table. static const unsigned structReturnIndexBits = 4; // number of index bits to use. static const unsigned structReturnSlots = (1< 1) localSize[i] = src.localSize[i]; } + for (int i = 0; i < 3; ++i) { + localSizeNotDefault[i] = src.localSizeNotDefault[i] || localSizeNotDefault[i]; + } for (int i = 0; i < 3; ++i) { if (src.localSizeSpecId[i] != TQualifier::layoutNotSet) localSizeSpecId[i] = src.localSizeSpecId[i]; } +#ifndef GLSLANG_WEB if (src.earlyFragmentTests) earlyFragmentTests = true; if (src.postDepthCoverage) @@ -1085,9 +1305,16 @@ struct TShaderQualifiers { blendEquation = src.blendEquation; if (src.numViews != TQualifier::layoutNotSet) numViews = src.numViews; -#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; + if (src.interlockOrdering != EioNone) + interlockOrdering = src.interlockOrdering; #endif } }; @@ -1109,9 +1336,17 @@ public: int vectorSize : 4; int matrixCols : 4; int matrixRows : 4; + bool coopmat : 1; TArraySizes* arraySizes; const TType* userDef; TSourceLoc loc; + TArraySizes* typeParameters; + +#ifdef GLSLANG_WEB + bool isCoopmat() const { return false; } +#else + bool isCoopmat() const { return coopmat; } +#endif void initType(const TSourceLoc& l) { @@ -1122,6 +1357,8 @@ public: arraySizes = nullptr; userDef = nullptr; loc = l; + typeParameters = nullptr; + coopmat = false; } void initQualifiers(bool global = false) @@ -1173,8 +1410,8 @@ public: // 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(); @@ -1184,8 +1421,8 @@ public: // 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(); @@ -1197,8 +1434,8 @@ public: // 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; @@ -1206,15 +1443,33 @@ public: 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.isCoopmat() && p.typeParameters && p.typeParameters->getNumDims() > 0) { + int numBits = p.typeParameters->getDimSize(0); + if (p.basicType == EbtFloat && numBits == 16) { + basicType = EbtFloat16; + qualifier.precision = EpqNone; + } else if (p.basicType == EbtUint && numBits == 8) { + basicType = EbtUint8; + qualifier.precision = EpqNone; + } else if (p.basicType == EbtInt && numBits == 8) { + basicType = EbtInt8; + 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; @@ -1255,13 +1510,16 @@ public: // 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(); @@ -1269,12 +1527,23 @@ public: } // 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. @@ -1290,9 +1559,15 @@ public: 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.isCoopMat(); } // Make complete copy of the whole type graph rooted at 'copyOf'. @@ -1351,10 +1626,17 @@ public: virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); } virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); } virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); } - virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } +#ifdef GLSLANG_WEB + bool isArrayOfArrays() const { return false; } +#else + bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } +#endif virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } virtual const TArraySizes* getArraySizes() const { 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; } @@ -1366,7 +1648,7 @@ public: 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 structure != nullptr; } + virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; } virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; } virtual bool isIntegerDomain() const { @@ -1386,13 +1668,29 @@ public: } return false; } - virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint; } + virtual bool isOpaque() const { return basicType == EbtSampler +#ifndef GLSLANG_WEB + || basicType == EbtAtomicUint || 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 isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } + // Check the block-name convention of creating a block without populating it's members: + virtual bool isUnusableName() const { return isStruct() && structure == nullptr; } + virtual bool isParameterized() const { return typeParameters != nullptr; } +#ifdef GLSLANG_WEB + bool isAtomic() const { return false; } + bool isCoopMat() const { return false; } + bool isReference() const { return false; } +#else + bool isAtomic() const { return basicType == EbtAtomicUint; } + bool isCoopMat() const { return coopmat; } + bool isReference() const { return getBasicType() == EbtReference; } +#endif // return true if this type contains any subtype which satisfies the given predicate. template @@ -1403,7 +1701,7 @@ public: 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 @@ -1458,6 +1756,7 @@ public: case EbtInt64: case EbtUint64: case EbtBool: + case EbtReference: return true; default: return false; @@ -1472,6 +1771,45 @@ public: return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } ); } +#ifdef GLSLANG_WEB + bool containsDouble() const { return false; } + bool contains16BitFloat() const { return false; } + bool contains64BitInt() const { return false; } + bool contains16BitInt() const { return false; } + bool contains8BitInt() const { return false; } + bool containsCoopMat() const { return false; } + bool containsReference() const { return false; } +#else + bool containsDouble() const + { + return containsBasicType(EbtDouble); + } + bool contains16BitFloat() const + { + return containsBasicType(EbtFloat16); + } + bool contains64BitInt() const + { + return containsBasicType(EbtInt64) || containsBasicType(EbtUint64); + } + bool contains16BitInt() const + { + return containsBasicType(EbtInt16) || containsBasicType(EbtUint16); + } + bool contains8BitInt() const + { + return containsBasicType(EbtInt8) || containsBasicType(EbtUint8); + } + bool containsCoopMat() const + { + return contains([](const TType* t) { return t->coopmat; } ); + } + bool containsReference() const + { + return containsBasicType(EbtReference); + } +#endif + // 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 @@ -1530,6 +1868,9 @@ public: { if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed())) changeOuterArraySize(getImplicitArraySize()); + // For multi-dim per-view arrays, set unsized inner dimension size to 1 + if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized()) + arraySizes->clearInnerUnsized(); if (isStruct() && structure->size() > 0) { int lastMember = (int)structure->size() - 1; for (int i = 0; i < lastMember; ++i) @@ -1539,6 +1880,46 @@ public: } } + + 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); @@ -1547,27 +1928,38 @@ public: static const char* getBasicString(TBasicType t) { switch (t) { - case EbtVoid: return "void"; case EbtFloat: return "float"; + case EbtInt: return "int"; + case EbtUint: return "uint"; + case EbtSampler: return "sampler/image"; +#ifndef GLSLANG_WEB + case EbtVoid: return "void"; case EbtDouble: return "double"; case EbtFloat16: return "float16_t"; 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"; case EbtBool: return "bool"; case EbtAtomicUint: return "atomic_uint"; - case EbtSampler: return "sampler/image"; case EbtStruct: return "structure"; case EbtBlock: return "block"; + case EbtAccStructNV: return "accelerationStructureNV"; + case EbtReference: return "reference"; +#endif default: return "unknown type"; } } +#ifdef GLSLANG_WEB + TString getCompleteString() const { return ""; } + const char* getStorageQualifierString() const { return ""; } + const char* getBuiltInVariableString() const { return ""; } + const char* getPrecisionQualifierString() const { return ""; } + TString getBasicTypeString() const { return ""; } +#else TString getCompleteString() const { TString typeString; @@ -1649,8 +2041,13 @@ public: } 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) appendStr(" passthrough"); if (qualifier.layoutViewportRelative) @@ -1659,7 +2056,8 @@ public: appendStr(" layoutSecondaryViewportRelativeOffset="); appendInt(qualifier.layoutSecondaryViewportRelativeOffset); } -#endif + if (qualifier.layoutShaderRecordNV) + appendStr(" shaderRecordNV"); appendStr(")"); } @@ -1677,16 +2075,32 @@ public: appendStr(" flat"); if (qualifier.nopersp) appendStr(" noperspective"); -#ifdef AMD_EXTENSIONS if (qualifier.explicitInterp) appendStr(" __explicitInterpAMD"); -#endif + if (qualifier.pervertexNV) + appendStr(" pervertexNV"); + if (qualifier.perPrimitiveNV) + appendStr(" perprimitiveNV"); + if (qualifier.perViewNV) + appendStr(" perviewNV"); + if (qualifier.perTaskNV) + appendStr(" taskNV"); 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) @@ -1721,6 +2135,15 @@ public: } } } + 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()); @@ -1746,15 +2169,17 @@ public: } // Add struct/block members - if (structure) { + if (isStruct() && structure) { appendStr("{"); + bool hasHiddenMember = true; for (size_t i = 0; i < structure->size(); ++i) { if (! (*structure)[i].type->hiddenMember()) { + if (!hasHiddenMember) + appendStr(", "); typeString.append((*structure)[i].type->getCompleteString()); typeString.append(" "); typeString.append((*structure)[i].type->getFieldName()); - if (i < structure->size() - 1) - appendStr(", "); + hasHiddenMember = false; } } appendStr("}"); @@ -1774,10 +2199,13 @@ public: 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 +#endif + 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 + void setBasicType(const TBasicType& t) { basicType = t; } + int computeNumComponents() const { int components = 0; @@ -1815,11 +2243,12 @@ public: 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; @@ -1839,7 +2268,24 @@ public: return true; } - // See if two types match, in all aspects except arrayness + bool sameReferenceType(const TType& right) const + { + if (isReference() != right.isReference()) + return false; + + if (!isReference() && !right.isReference()) + 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 { return basicType == right.basicType && sameElementShape(right); @@ -1859,6 +2305,13 @@ public: 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 { @@ -1867,13 +2320,37 @@ public: matrixCols == right.matrixCols && matrixRows == right.matrixRows && vector1 == right.vector1 && - sameStructType(right); + isCoopMat() == right.isCoopMat() && + 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 isCoopMat() && right.isCoopMat() && (getBasicType() == right.getBasicType()) && + typeParameters == nullptr && right.typeParameters != nullptr; + } + + bool sameCoopMatBaseType(const TType &right) const { + bool rv = coopmat && right.coopmat; + if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16) + rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16; + else if (getBasicType() == EbtUint || getBasicType() == EbtUint8) + rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8; + else if (getBasicType() == EbtInt || getBasicType() == EbtInt8) + rv = right.getBasicType() == EbtInt || right.getBasicType() == EbtInt8; + else + rv = false; + return rv; + } + + // 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 @@ -1881,6 +2358,17 @@ public: return ! operator==(right); } + unsigned int getBufferReferenceAlignment() const + { +#ifndef GLSLANG_WEB + if (getBasicType() == glslang::EbtReference) { + return getReferentType()->getQualifier().hasBufferReferenceAlign() ? + (1u << getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u; + } +#endif + return 0; + } + protected: // Require consumer to pick between deep copy and shallow copy. TType(const TType& type); @@ -1898,7 +2386,12 @@ protected: *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; @@ -1933,13 +2426,20 @@ protected: // 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 --git a/Externals/glslang/glslang/Include/arrays.h b/Externals/glslang/glslang/Include/arrays.h index af8f560b3b..7f047d9fb1 100644 --- a/Externals/glslang/glslang/Include/arrays.h +++ b/Externals/glslang/glslang/Include/arrays.h @@ -254,7 +254,9 @@ struct TArraySizes { 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 implicitArraySize; } @@ -318,8 +320,8 @@ struct TArraySizes { void setVariablyIndexed() { variablyIndexed = true; } bool isVariablyIndexed() const { return variablyIndexed; } - bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; } - bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; } + bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; } + bool operator!=(const TArraySizes& rhs) const { return sizes != rhs.sizes; } protected: TSmallArrayVector sizes; diff --git a/Externals/glslang/glslang/Include/intermediate.h b/Externals/glslang/glslang/Include/intermediate.h old mode 100755 new mode 100644 index 19eb7aa876..29d58ca635 --- a/Externals/glslang/glslang/Include/intermediate.h +++ b/Externals/glslang/glslang/Include/intermediate.h @@ -85,6 +85,8 @@ enum TOperator { EOpPreIncrement, EOpPreDecrement, + EOpCopyObject, + // (u)int* -> bool EOpConvInt8ToBool, EOpConvUint8ToBool, @@ -269,6 +271,14 @@ enum TOperator { EOpConvDoubleToFloat16, EOpConvDoubleToFloat, + // uint64_t <-> pointer + EOpConvUint64ToPtr, + EOpConvPtrToUint64, + + // uvec2 <-> pointer + EOpConvUvec2ToPtr, + EOpConvPtrToUvec2, + // // binary operations // @@ -416,11 +426,9 @@ enum TOperator { EOpReflect, EOpRefract, -#ifdef AMD_EXTENSIONS EOpMin3, EOpMax3, EOpMid3, -#endif EOpDPdx, // Fragment only EOpDPdy, // Fragment only @@ -435,10 +443,7 @@ enum TOperator { EOpInterpolateAtCentroid, // Fragment only EOpInterpolateAtSample, // Fragment only EOpInterpolateAtOffset, // Fragment only - -#ifdef AMD_EXTENSIONS EOpInterpolateAtVertex, -#endif EOpMatrixTimesMatrix, EOpOuterProduct, @@ -528,7 +533,6 @@ enum TOperator { EOpSubgroupQuadSwapVertical, EOpSubgroupQuadSwapDiagonal, -#ifdef NV_EXTENSIONS EOpSubgroupPartition, EOpSubgroupPartitionedAdd, EOpSubgroupPartitionedMul, @@ -551,11 +555,9 @@ enum TOperator { EOpSubgroupPartitionedExclusiveAnd, EOpSubgroupPartitionedExclusiveOr, EOpSubgroupPartitionedExclusiveXor, -#endif EOpSubgroupGuardStop, -#ifdef AMD_EXTENSIONS EOpMinInvocations, EOpMaxInvocations, EOpAddInvocations, @@ -582,7 +584,6 @@ enum TOperator { EOpCubeFaceIndex, EOpCubeFaceCoord, EOpTime, -#endif EOpAtomicAdd, EOpAtomicMin, @@ -592,6 +593,8 @@ enum TOperator { EOpAtomicXor, EOpAtomicExchange, EOpAtomicCompSwap, + EOpAtomicLoad, + EOpAtomicStore, EOpAtomicCounterIncrement, // results in pre-increment value EOpAtomicCounterDecrement, // results in post-decrement value @@ -609,6 +612,15 @@ enum TOperator { EOpAny, EOpAll, + EOpCooperativeMatrixLoad, + EOpCooperativeMatrixStore, + EOpCooperativeMatrixMulAdd, + + EOpBeginInvocationInterlock, // Fragment only + EOpEndInvocationInterlock, // Fragment only + + EOpIsHelperInvocation, + // // Branch // @@ -619,6 +631,7 @@ enum TOperator { EOpContinue, EOpCase, EOpDefault, + EOpDemote, // Fragment only // // Constructors @@ -636,9 +649,21 @@ enum TOperator { EOpConstructBool, EOpConstructFloat, EOpConstructDouble, + // Keep vector and matrix constructors in a consistent relative order for + // TParseContext::constructBuiltIn, which converts between 8/16/32 bit + // vector constructors EOpConstructVec2, EOpConstructVec3, EOpConstructVec4, + EOpConstructMat2x2, + EOpConstructMat2x3, + EOpConstructMat2x4, + EOpConstructMat3x2, + EOpConstructMat3x3, + EOpConstructMat3x4, + EOpConstructMat4x2, + EOpConstructMat4x3, + EOpConstructMat4x4, EOpConstructDVec2, EOpConstructDVec3, EOpConstructDVec4, @@ -669,15 +694,6 @@ enum TOperator { EOpConstructU64Vec2, EOpConstructU64Vec3, EOpConstructU64Vec4, - EOpConstructMat2x2, - EOpConstructMat2x3, - EOpConstructMat2x4, - EOpConstructMat3x2, - EOpConstructMat3x3, - EOpConstructMat3x4, - EOpConstructMat4x2, - EOpConstructMat4x3, - EOpConstructMat4x4, EOpConstructDMat2x2, EOpConstructDMat2x3, EOpConstructDMat2x4, @@ -730,6 +746,8 @@ enum TOperator { EOpConstructStruct, EOpConstructTextureSampler, EOpConstructNonuniform, // expected to be transformed away, not present in final AST + EOpConstructReference, + EOpConstructCooperativeMatrix, EOpConstructGuardEnd, // @@ -772,10 +790,8 @@ enum TOperator { EOpImageQuerySamples, EOpImageLoad, EOpImageStore, -#ifdef AMD_EXTENSIONS EOpImageLoadLod, EOpImageStoreLod, -#endif EOpImageAtomicAdd, EOpImageAtomicMin, EOpImageAtomicMax, @@ -784,13 +800,13 @@ enum TOperator { EOpImageAtomicXor, EOpImageAtomicExchange, EOpImageAtomicCompSwap, + EOpImageAtomicLoad, + EOpImageAtomicStore, EOpSubpassLoad, EOpSubpassLoadMS, EOpSparseImageLoad, -#ifdef AMD_EXTENSIONS EOpSparseImageLoadLod, -#endif EOpImageGuardEnd, @@ -828,13 +844,11 @@ enum TOperator { EOpTextureOffsetClamp, EOpTextureGradClamp, EOpTextureGradOffsetClamp, -#ifdef AMD_EXTENSIONS EOpTextureGatherLod, EOpTextureGatherLodOffset, EOpTextureGatherLodOffsets, EOpFragmentMaskFetch, EOpFragmentFetch, -#endif EOpSparseTextureGuardBegin, @@ -854,13 +868,19 @@ enum TOperator { EOpSparseTextureOffsetClamp, EOpSparseTextureGradClamp, EOpSparseTextureGradOffsetClamp, -#ifdef AMD_EXTENSIONS EOpSparseTextureGatherLod, EOpSparseTextureGatherLodOffset, EOpSparseTextureGatherLodOffsets, -#endif EOpSparseTextureGuardEnd, + + EOpImageFootprintGuardBegin, + EOpImageSampleFootprintNV, + EOpImageSampleFootprintClampNV, + EOpImageSampleFootprintLodNV, + EOpImageSampleFootprintGradNV, + EOpImageSampleFootprintGradClampNV, + EOpImageFootprintGuardEnd, EOpSamplingGuardEnd, EOpTextureGuardEnd, @@ -879,6 +899,21 @@ enum TOperator { EOpFindLSB, EOpFindMSB, + EOpCountLeadingZeros, + EOpCountTrailingZeros, + EOpAbsDifference, + EOpAddSaturate, + EOpSubSaturate, + EOpAverage, + EOpAverageRounded, + EOpMul32x16, + + EOpTraceNV, + EOpReportIntersectionNV, + EOpIgnoreIntersectionNV, + EOpTerminateRayNV, + EOpExecuteCallableNV, + EOpWritePackedPrimitiveIndices4x8NV, // // HLSL operations // @@ -962,6 +997,10 @@ enum TOperator { EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID. EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()). EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()). + + // Shader Clock Ops + EOpReadClockSubgroupKHR, + EOpReadClockDeviceKHR, }; class TIntermTraverser; @@ -1063,6 +1102,8 @@ public: virtual bool isStruct() const { return type.isStruct(); } virtual bool isFloatingDomain() const { return type.isFloatingDomain(); } virtual bool isIntegerDomain() const { return type.isIntegerDomain(); } + bool isAtomic() const { return type.isAtomic(); } + bool isReference() const { return type.isReference(); } TString getCompleteString() const { return type.getCompleteString(); } protected: @@ -1082,7 +1123,12 @@ public: first(testFirst), unroll(false), dontUnroll(false), - dependency(0) + dependency(0), + minIterations(0), + maxIterations(iterationsInfinite), + iterationMultiple(1), + peelCount(0), + partialCount(0) { } virtual TIntermLoop* getAsLoopNode() { return this; } @@ -1094,14 +1140,36 @@ public: bool testFirst() const { return first; } void setUnroll() { unroll = true; } - void setDontUnroll() { dontUnroll = 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 @@ -1110,6 +1178,11 @@ protected: 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 }; // @@ -1125,6 +1198,7 @@ public: virtual void traverse(TIntermTraverser*); TOperator getFlowOp() const { return flowOp; } TIntermTyped* getExpression() const { return expression; } + void setExpression(TIntermTyped* pExpression) { expression = pExpression; } protected: TOperator flowOp; TIntermTyped* expression; @@ -1158,12 +1232,13 @@ public: // it is essential to use "symbol = sym" to assign to symbol TIntermSymbol(int i, const TString& n, const TType& t) : TIntermTyped(t), id(i), -#ifdef ENABLE_HLSL +#ifndef GLSLANG_WEB flattenSubset(-1), #endif 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; } @@ -1172,7 +1247,7 @@ public: const TConstUnionArray& getConstArray() const { return constArray; } void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } TIntermTyped* getConstSubtree() const { return constSubtree; } -#ifdef ENABLE_HLSL +#ifndef GLSLANG_WEB void setFlattenSubset(int subset) { flattenSubset = subset; } int getFlattenSubset() const { return flattenSubset; } // -1 means full object #endif @@ -1183,7 +1258,7 @@ public: protected: int id; // the unique id of the symbol this node represents -#ifdef ENABLE_HLSL +#ifndef GLSLANG_WEB int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced #endif TString name; // the name of the symbol this node represents @@ -1223,9 +1298,7 @@ struct TCrackedTextureOp { bool grad; bool subpass; bool lodClamp; -#ifdef AMD_EXTENSIONS bool fragMask; -#endif }; // @@ -1241,9 +1314,19 @@ public: bool isConstructor() const; bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; } bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; } +#ifdef GLSLANG_WEB + bool isImage() const { return false; } + bool isSparseTexture() const { return false; } + bool isImageFootprint() const { return false; } + bool isSparseImage() const { return false; } + bool isSubgroup() const { return false; } +#else bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; } + bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; } bool isSparseImage() const { return op == EOpSparseImageLoad; } + bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; } +#endif void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; } TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ? @@ -1273,9 +1356,7 @@ public: cracked.grad = false; cracked.subpass = false; cracked.lodClamp = false; -#ifdef AMD_EXTENSIONS cracked.fragMask = false; -#endif switch (op) { case EOpImageQuerySize: @@ -1290,10 +1371,6 @@ public: case EOpTexture: case EOpSparseTexture: break; - case EOpTextureClamp: - case EOpSparseTextureClamp: - cracked.lodClamp = true; - break; case EOpTextureProj: cracked.proj = true; break; @@ -1305,22 +1382,17 @@ public: case EOpSparseTextureOffset: cracked.offset = true; break; - case EOpTextureOffsetClamp: - case EOpSparseTextureOffsetClamp: - cracked.offset = true; - cracked.lodClamp = true; - break; case EOpTextureFetch: case EOpSparseTextureFetch: cracked.fetch = true; - if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D) cracked.lod = true; break; case EOpTextureFetchOffset: case EOpSparseTextureFetchOffset: cracked.fetch = true; cracked.offset = true; - if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) + if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D) cracked.lod = true; break; case EOpTextureProjOffset: @@ -1345,11 +1417,6 @@ public: case EOpSparseTextureGrad: cracked.grad = true; break; - case EOpTextureGradClamp: - case EOpSparseTextureGradClamp: - cracked.grad = true; - cracked.lodClamp = true; - break; case EOpTextureGradOffset: case EOpSparseTextureGradOffset: cracked.grad = true; @@ -1364,6 +1431,21 @@ public: cracked.offset = true; cracked.proj = true; break; +#ifndef GLSLANG_WEB + case EOpTextureClamp: + case EOpSparseTextureClamp: + cracked.lodClamp = true; + break; + case EOpTextureOffsetClamp: + case EOpSparseTextureOffsetClamp: + cracked.offset = true; + cracked.lodClamp = true; + break; + case EOpTextureGradClamp: + case EOpSparseTextureGradClamp: + cracked.grad = true; + cracked.lodClamp = true; + break; case EOpTextureGradOffsetClamp: case EOpSparseTextureGradOffsetClamp: cracked.grad = true; @@ -1384,7 +1466,6 @@ public: cracked.gather = true; cracked.offsets = true; break; -#ifdef AMD_EXTENSIONS case EOpTextureGatherLod: case EOpSparseTextureGatherLod: cracked.gather = true; @@ -1415,11 +1496,26 @@ public: cracked.subpass = sampler.dim == EsdSubpass; cracked.fragMask = true; break; -#endif + 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; case EOpSubpassLoad: case EOpSubpassLoadMS: cracked.subpass = true; break; +#endif default: break; } diff --git a/Externals/glslang/glslang/Include/revision.h b/Externals/glslang/glslang/Include/revision.h index 3d66a6679e..a0e4b2066c 100644 --- a/Externals/glslang/glslang/Include/revision.h +++ b/Externals/glslang/glslang/Include/revision.h @@ -1,3 +1,3 @@ // This header is generated by the make-revision script. -#define GLSLANG_PATCH_LEVEL 2743 +#define GLSLANG_PATCH_LEVEL 3559 diff --git a/Externals/glslang/glslang/MachineIndependent/Constant.cpp b/Externals/glslang/glslang/MachineIndependent/Constant.cpp index 142492dc33..98c2666fbb 100644 --- a/Externals/glslang/glslang/MachineIndependent/Constant.cpp +++ b/Externals/glslang/glslang/MachineIndependent/Constant.cpp @@ -2,6 +2,7 @@ // 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. // @@ -179,73 +180,83 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right case EbtDouble: case EbtFloat: case EbtFloat16: - newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst()); - break; - case EbtInt8: - if (rightUnionArray[i] == 0) - newConstArray[i].setI8Const(0x7F); - else if (rightUnionArray[i].getI8Const() == -1 && leftUnionArray[i].getI8Const() == (signed char)0x80) - newConstArray[i].setI8Const((signed char)0x80); + 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].setI8Const(leftUnionArray[i].getI8Const() / rightUnionArray[i].getI8Const()); - break; - - case EbtUint8: - if (rightUnionArray[i] == 0) { - newConstArray[i].setU8Const(0xFF); - } else - newConstArray[i].setU8Const(leftUnionArray[i].getU8Const() / rightUnionArray[i].getU8Const()); - break; - - case EbtInt16: - if (rightUnionArray[i] == 0) - newConstArray[i].setI16Const(0x7FFF); - else if (rightUnionArray[i].getI16Const() == -1 && leftUnionArray[i].getI16Const() == (signed short)0x8000) - newConstArray[i].setI16Const(short(0x8000)); - else - newConstArray[i].setI16Const(leftUnionArray[i].getI16Const() / rightUnionArray[i].getI16Const()); - break; - - case EbtUint16: - if (rightUnionArray[i] == 0) { - newConstArray[i].setU16Const(0xFFFF); - } else - newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const()); + newConstArray[i].setDConst((double)NAN); 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; +#ifndef GLSLANG_WEB + 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 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 + else newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const()); break; default: return 0; +#endif } } break; @@ -284,13 +295,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setIConst(0); break; } else goto modulo_default; - +#ifndef GLSLANG_WEB case EbtInt64: if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) { newConstArray[i].setI64Const(0); break; } else goto modulo_default; -#ifdef AMD_EXTENSIONS case EbtInt16: if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) { newConstArray[i].setIConst(0); @@ -407,8 +417,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpEmitStreamVertex: case EOpEndStreamPrimitive: - // These don't actually fold - return 0; + // These don't fold + return nullptr; case EOpPackSnorm2x16: case EOpPackUnorm2x16: @@ -483,8 +493,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) break; } - // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out - case EOpPackSnorm2x16: case EOpPackUnorm2x16: case EOpPackHalf2x16: @@ -502,7 +510,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpDeterminant: case EOpMatrixInverse: case EOpTranspose: - return 0; + return nullptr; default: assert(componentWise); @@ -521,16 +529,18 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EbtDouble: case EbtFloat16: case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; + case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; + case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; +#ifndef GLSLANG_WEB 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; - 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; +#endif default: - return 0; + return nullptr; } break; case EOpLogicalNot: @@ -538,7 +548,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) switch (getType().getBasicType()) { case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break; default: - return 0; + return nullptr; } break; case EOpBitwiseNot: @@ -663,6 +673,284 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) break; } + case EOpConvIntToBool: + newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break; + case EOpConvUintToBool: + newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break; + case EOpConvBoolToInt: + newConstArray[i].setIConst(unionArray[i].getBConst()); break; + case EOpConvBoolToUint: + newConstArray[i].setUConst(unionArray[i].getBConst()); break; + case EOpConvIntToUint: + newConstArray[i].setUConst(unionArray[i].getIConst()); break; + case EOpConvUintToInt: + newConstArray[i].setIConst(unionArray[i].getUConst()); break; + + case EOpConvFloatToBool: + case EOpConvDoubleToBool: + newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; + + case EOpConvBoolToFloat: + case EOpConvBoolToDouble: + newConstArray[i].setDConst(unionArray[i].getBConst()); break; + + case EOpConvIntToFloat: + case EOpConvIntToDouble: + newConstArray[i].setDConst(unionArray[i].getIConst()); break; + + case EOpConvUintToFloat: + case EOpConvUintToDouble: + newConstArray[i].setDConst(unionArray[i].getUConst()); break; + + case EOpConvDoubleToFloat: + case EOpConvFloatToDouble: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + + case EOpConvFloatToUint: + case EOpConvDoubleToUint: + newConstArray[i].setUConst(static_cast(unionArray[i].getDConst())); break; + + case EOpConvFloatToInt: + case EOpConvDoubleToInt: + newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; + +#ifndef GLSLANG_WEB + 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 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 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 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 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 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 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 EOpConvUintToFloat16: + 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 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 EOpConvFloatToUint64: + newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvFloatToFloat16: + 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 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 EOpConvDoubleToUint64: + newConstArray[i].setU64Const(static_cast(unionArray[i].getDConst())); break; + case EOpConvDoubleToFloat16: + newConstArray[i].setDConst(unionArray[i].getDConst()); break; + case EOpConvPtrToUint64: + case EOpConvUint64ToPtr: + case EOpConstructReference: + newConstArray[i].setU64Const(unionArray[i].getU64Const()); break; +#endif + // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out case EOpSinh: @@ -685,7 +973,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpInt16BitsToFloat16: case EOpUint16BitsToFloat16: default: - return 0; + return nullptr; } } @@ -793,6 +1081,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtDouble: newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); 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; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); break; @@ -805,18 +1100,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) 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; +#endif default: assert(false && "Default missing"); } break; @@ -827,6 +1117,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtDouble: newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); 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; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); break; @@ -839,18 +1136,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) 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; +#endif default: assert(false && "Default missing"); } break; @@ -862,6 +1154,11 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()), childConstUnions[2][arg2comp].getDConst())); break; + case EbtUint: + newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), + childConstUnions[2][arg2comp].getUConst())); + break; +#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()), childConstUnions[2][arg2comp].getI8Const())); @@ -882,10 +1179,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), childConstUnions[2][arg2comp].getIConst())); 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())); @@ -894,6 +1187,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()), childConstUnions[2][arg2comp].getU64Const())); break; +#endif default: assert(false && "Default missing"); } break; @@ -916,12 +1210,17 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]); break; case EOpMix: - if (children[2]->getAsTyped()->getBasicType() == EbtBool) - newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() ? childConstUnions[1][arg1comp].getDConst() : - childConstUnions[0][arg0comp].getDConst()); - else - newConstArray[comp].setDConst(childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) + - childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst()); + if (!children[0]->getAsTyped()->isFloatingDomain()) + return aggrNode; + if (children[2]->getAsTyped()->getBasicType() == EbtBool) { + newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() + ? childConstUnions[1][arg1comp].getDConst() + : childConstUnions[0][arg0comp].getDConst()); + } else { + newConstArray[comp].setDConst( + childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) + + childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst()); + } break; case EOpStep: newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0); @@ -1073,7 +1372,9 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons // 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 --git a/Externals/glslang/glslang/MachineIndependent/Initialize.cpp b/Externals/glslang/glslang/MachineIndependent/Initialize.cpp old mode 100755 new mode 100644 index a5ab093949..de55742649 --- a/Externals/glslang/glslang/MachineIndependent/Initialize.cpp +++ b/Externals/glslang/glslang/MachineIndependent/Initialize.cpp @@ -1,7 +1,7 @@ // // 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. @@ -64,6 +64,420 @@ const bool ForwardCompatibility = false; // Using PureOperatorBuiltins=false is deprecated. bool PureOperatorBuiltins = true; +namespace { + +// +// A set of definitions for tabling of the built-in functions. +// + +// Order matters here, as does correlation with the subsequent +// "const int ..." declarations and the ArgType enumerants. +const char* TypeString[] = { + "bool", "bvec2", "bvec3", "bvec4", + "float", "vec2", "vec3", "vec4", + "int", "ivec2", "ivec3", "ivec4", + "uint", "uvec2", "uvec3", "uvec4", +}; +const int TypeStringCount = sizeof(TypeString) / sizeof(char*); // number of entries in 'TypeString' +const int TypeStringRowShift = 2; // shift amount to go downe one row in 'TypeString' +const int TypeStringColumnMask = (1 << TypeStringRowShift) - 1; // reduce type to its column number in 'TypeString' +const int TypeStringScalarMask = ~TypeStringColumnMask; // take type to its scalar column in 'TypeString' + +enum ArgType { + // numbers hardcoded to correspond to 'TypeString'; order and value matter + TypeB = 1 << 0, // Boolean + TypeF = 1 << 1, // float 32 + TypeI = 1 << 2, // int 32 + TypeU = 1 << 3, // uint 32 + TypeF16 = 1 << 4, // float 16 + TypeF64 = 1 << 5, // float 64 + TypeI8 = 1 << 6, // int 8 + TypeI16 = 1 << 7, // int 16 + TypeI64 = 1 << 8, // int 64 + TypeU8 = 1 << 9, // uint 8 + TypeU16 = 1 << 10, // uint 16 + TypeU64 = 1 << 11, // uint 64 +}; +// Mixtures of the above, to help the function tables +const ArgType TypeFI = static_cast(TypeF | TypeI); +const ArgType TypeFIB = static_cast(TypeF | TypeI | TypeB); +const ArgType TypeIU = static_cast(TypeI | TypeU); + +// The relationships between arguments and return type, whether anything is +// output, or other unusual situations. +enum ArgClass { + ClassRegular = 0, // nothing special, just all vector widths with matching return type; traditional arithmetic + ClassLS = 1 << 0, // the last argument is also held fixed as a (type-matched) scalar while the others cycle + ClassXLS = 1 << 1, // the last argument is exclusively a (type-matched) scalar while the others cycle + ClassLS2 = 1 << 2, // the last two arguments are held fixed as a (type-matched) scalar while the others cycle + ClassFS = 1 << 3, // the first argument is held fixed as a (type-matched) scalar while the others cycle + ClassFS2 = 1 << 4, // the first two arguments are held fixed as a (type-matched) scalar while the others cycle + ClassLO = 1 << 5, // the last argument is an output + ClassB = 1 << 6, // return type cycles through only bool/bvec, matching vector width of args + ClassLB = 1 << 7, // last argument cycles through only bool/bvec, matching vector width of args + ClassV1 = 1 << 8, // scalar only + ClassFIO = 1 << 9, // first argument is inout + ClassRS = 1 << 10, // the return is held scalar as the arguments cycle + ClassNS = 1 << 11, // no scalar prototype + ClassCV = 1 << 12, // first argument is 'coherent volatile' + ClassFO = 1 << 13, // first argument is output + ClassV3 = 1 << 14, // vec3 only +}; +// Mixtures of the above, to help the function tables +const ArgClass ClassV1FIOCV = (ArgClass)(ClassV1 | ClassFIO | ClassCV); +const ArgClass ClassV1FOCV = (ArgClass)(ClassV1 | ClassFO | ClassCV); +const ArgClass ClassV1CV = (ArgClass)(ClassV1 | ClassCV); +const ArgClass ClassBNS = (ArgClass)(ClassB | ClassNS); +const ArgClass ClassRSNS = (ArgClass)(ClassRS | ClassNS); + +// A descriptor, for a single profile, of when something is available. +// If the current profile does not match 'profile' mask below, the other fields +// do not apply (nor validate). +// profiles == EBadProfile is the end of an array of these +struct Versioning { + EProfile profiles; // the profile(s) (mask) that the following fields are valid for + int minExtendedVersion; // earliest version when extensions are enabled; ignored if numExtensions is 0 + int minCoreVersion; // earliest version function is in core; 0 means never + int numExtensions; // how many extensions are in the 'extensions' list + const char** extensions; // list of extension names enabling the function +}; + +EProfile EDesktopProfile = static_cast(ENoProfile | ECoreProfile | ECompatibilityProfile); + +// Declare pointers to put into the table for versioning. +#ifdef GLSLANG_WEB + const Versioning* Es300Desktop130 = nullptr; + const Versioning* Es310Desktop430 = nullptr; +#else + const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr }, + { EDesktopProfile, 0, 130, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es300Desktop130 = &Es300Desktop130Version[0]; + + const Versioning Es310Desktop430Version[] = { { EEsProfile, 0, 310, 0, nullptr }, + { EDesktopProfile, 0, 430, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es310Desktop430 = &Es310Desktop430Version[0]; + + const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr }, + { EDesktopProfile, 0, 450, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es310Desktop450 = &Es310Desktop450Version[0]; +#endif + +// The main descriptor of what a set of function prototypes can look like, and +// a pointer to extra versioning information, when needed. +struct BuiltInFunction { + TOperator op; // operator to map the name to + const char* name; // function name + int numArguments; // number of arguments (overloads with varying arguments need different entries) + ArgType types; // ArgType mask + ArgClass classes; // the ways this particular function entry manifests + const Versioning* versioning; // nullptr means always a valid version +}; + +// The tables can have the same built-in function name more than one time, +// but the exact same prototype must be indicated at most once. +// The prototypes that get declared are the union of all those indicated. +// This is important when different releases add new prototypes for the same name. +// It also also congnitively simpler tiling of the prototype space. +// In practice, most names can be fully represented with one entry. +// +// Table is terminated by an OpNull TOperator. + +const BuiltInFunction BaseFunctions[] = { +// TOperator, name, arg-count, ArgType, ArgClass, versioning +// --------- ---- --------- ------- -------- ---------- + { EOpRadians, "radians", 1, TypeF, ClassRegular, nullptr }, + { EOpDegrees, "degrees", 1, TypeF, ClassRegular, nullptr }, + { EOpSin, "sin", 1, TypeF, ClassRegular, nullptr }, + { EOpCos, "cos", 1, TypeF, ClassRegular, nullptr }, + { EOpTan, "tan", 1, TypeF, ClassRegular, nullptr }, + { EOpAsin, "asin", 1, TypeF, ClassRegular, nullptr }, + { EOpAcos, "acos", 1, TypeF, ClassRegular, nullptr }, + { EOpAtan, "atan", 2, TypeF, ClassRegular, nullptr }, + { EOpAtan, "atan", 1, TypeF, ClassRegular, nullptr }, + { EOpPow, "pow", 2, TypeF, ClassRegular, nullptr }, + { EOpExp, "exp", 1, TypeF, ClassRegular, nullptr }, + { EOpLog, "log", 1, TypeF, ClassRegular, nullptr }, + { EOpExp2, "exp2", 1, TypeF, ClassRegular, nullptr }, + { EOpLog2, "log2", 1, TypeF, ClassRegular, nullptr }, + { EOpSqrt, "sqrt", 1, TypeF, ClassRegular, nullptr }, + { EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, nullptr }, + { EOpAbs, "abs", 1, TypeF, ClassRegular, nullptr }, + { EOpSign, "sign", 1, TypeF, ClassRegular, nullptr }, + { EOpFloor, "floor", 1, TypeF, ClassRegular, nullptr }, + { EOpCeil, "ceil", 1, TypeF, ClassRegular, nullptr }, + { EOpFract, "fract", 1, TypeF, ClassRegular, nullptr }, + { EOpMod, "mod", 2, TypeF, ClassLS, nullptr }, + { EOpMin, "min", 2, TypeF, ClassLS, nullptr }, + { EOpMax, "max", 2, TypeF, ClassLS, nullptr }, + { EOpClamp, "clamp", 3, TypeF, ClassLS2, nullptr }, + { EOpMix, "mix", 3, TypeF, ClassLS, nullptr }, + { EOpStep, "step", 2, TypeF, ClassFS, nullptr }, + { EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, nullptr }, + { EOpNormalize, "normalize", 1, TypeF, ClassRegular, nullptr }, + { EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, nullptr }, + { EOpReflect, "reflect", 2, TypeF, ClassRegular, nullptr }, + { EOpRefract, "refract", 3, TypeF, ClassXLS, nullptr }, + { EOpLength, "length", 1, TypeF, ClassRS, nullptr }, + { EOpDistance, "distance", 2, TypeF, ClassRS, nullptr }, + { EOpDot, "dot", 2, TypeF, ClassRS, nullptr }, + { EOpCross, "cross", 2, TypeF, ClassV3, nullptr }, + { EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, nullptr }, + { EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, nullptr }, + { EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, nullptr }, + { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, nullptr }, + { EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, nullptr }, + { EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, nullptr }, + { EOpAny, "any", 1, TypeB, ClassRSNS, nullptr }, + { EOpAll, "all", 1, TypeB, ClassRSNS, nullptr }, + { EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, nullptr }, + { EOpSinh, "sinh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpCosh, "cosh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpTanh, "tanh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAsinh, "asinh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAcosh, "acosh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAtanh, "atanh", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpAbs, "abs", 1, TypeI, ClassRegular, Es300Desktop130 }, + { EOpSign, "sign", 1, TypeI, ClassRegular, Es300Desktop130 }, + { EOpTrunc, "trunc", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpRound, "round", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, Es300Desktop130 }, + { EOpModf, "modf", 2, TypeF, ClassLO, Es300Desktop130 }, + { EOpMin, "min", 2, TypeIU, ClassLS, Es300Desktop130 }, + { EOpMax, "max", 2, TypeIU, ClassLS, Es300Desktop130 }, + { EOpClamp, "clamp", 3, TypeIU, ClassLS2, Es300Desktop130 }, + { EOpMix, "mix", 3, TypeF, ClassLB, Es300Desktop130 }, + { EOpIsInf, "isinf", 1, TypeF, ClassB, Es300Desktop130 }, + { EOpIsNan, "isnan", 1, TypeF, ClassB, Es300Desktop130 }, + { EOpLessThan, "lessThan", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, + { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop430 }, +#ifndef GLSLANG_WEB + { EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 }, + { EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 }, +#endif + + { EOpNull } +}; + +const BuiltInFunction DerivativeFunctions[] = { + { EOpDPdx, "dFdx", 1, TypeF, ClassRegular, nullptr }, + { EOpDPdy, "dFdy", 1, TypeF, ClassRegular, nullptr }, + { EOpFwidth, "fwidth", 1, TypeF, ClassRegular, nullptr }, + { EOpNull } +}; + +// For functions declared some other way, but still use the table to relate to operator. +struct CustomFunction { + TOperator op; // operator to map the name to + const char* name; // function name + const Versioning* versioning; // nullptr means always a valid version +}; + +const CustomFunction CustomFunctions[] = { + { EOpBarrier, "barrier", nullptr }, + { EOpMemoryBarrierShared, "memoryBarrierShared", nullptr }, + { EOpGroupMemoryBarrier, "groupMemoryBarrier", nullptr }, + { EOpMemoryBarrier, "memoryBarrier", nullptr }, + { EOpMemoryBarrierBuffer, "memoryBarrierBuffer", nullptr }, + + { EOpPackSnorm2x16, "packSnorm2x16", nullptr }, + { EOpUnpackSnorm2x16, "unpackSnorm2x16", nullptr }, + { EOpPackUnorm2x16, "packUnorm2x16", nullptr }, + { EOpUnpackUnorm2x16, "unpackUnorm2x16", nullptr }, + { EOpPackHalf2x16, "packHalf2x16", nullptr }, + { EOpUnpackHalf2x16, "unpackHalf2x16", nullptr }, + + { EOpMul, "matrixCompMult", nullptr }, + { EOpOuterProduct, "outerProduct", nullptr }, + { EOpTranspose, "transpose", nullptr }, + { EOpDeterminant, "determinant", nullptr }, + { EOpMatrixInverse, "inverse", nullptr }, + { EOpFloatBitsToInt, "floatBitsToInt", nullptr }, + { EOpFloatBitsToUint, "floatBitsToUint", nullptr }, + { EOpIntBitsToFloat, "intBitsToFloat", nullptr }, + { EOpUintBitsToFloat, "uintBitsToFloat", nullptr }, + + { EOpTextureQuerySize, "textureSize", nullptr }, + { EOpTextureQueryLod, "textureQueryLod", nullptr }, + { EOpTextureQueryLevels, "textureQueryLevels", nullptr }, + { EOpTextureQuerySamples, "textureSamples", nullptr }, + { EOpTexture, "texture", nullptr }, + { EOpTextureProj, "textureProj", nullptr }, + { EOpTextureLod, "textureLod", nullptr }, + { EOpTextureOffset, "textureOffset", nullptr }, + { EOpTextureFetch, "texelFetch", nullptr }, + { EOpTextureFetchOffset, "texelFetchOffset", nullptr }, + { EOpTextureProjOffset, "textureProjOffset", nullptr }, + { EOpTextureLodOffset, "textureLodOffset", nullptr }, + { EOpTextureProjLod, "textureProjLod", nullptr }, + { EOpTextureProjLodOffset, "textureProjLodOffset", nullptr }, + { EOpTextureGrad, "textureGrad", nullptr }, + { EOpTextureGradOffset, "textureGradOffset", nullptr }, + { EOpTextureProjGrad, "textureProjGrad", nullptr }, + { EOpTextureProjGradOffset, "textureProjGradOffset", nullptr }, + + { EOpNull } +}; + +// For the given table of functions, add all the indicated prototypes for each +// one, to be returned in the passed in decls. +void AddTabledBuiltin(TString& decls, const BuiltInFunction& function) +{ + const auto isScalarType = [](int type) { return (type & TypeStringColumnMask) == 0; }; + + // loop across these two: + // 0: the varying arg set, and + // 1: the fixed scalar args + const ArgClass ClassFixed = (ArgClass)(ClassLS | ClassXLS | ClassLS2 | ClassFS | ClassFS2); + for (int fixed = 0; fixed < ((function.classes & ClassFixed) > 0 ? 2 : 1); ++fixed) { + + if (fixed == 0 && (function.classes & ClassXLS)) + continue; + + // walk the type strings in TypeString[] + for (int type = 0; type < TypeStringCount; ++type) { + // skip types not selected: go from type to row number to type bit + if ((function.types & (1 << (type >> TypeStringRowShift))) == 0) + continue; + + // if we aren't on a scalar, and should be, skip + if ((function.classes & ClassV1) && !isScalarType(type)) + continue; + + // if we aren't on a 3-vector, and should be, skip + if ((function.classes & ClassV3) && (type & TypeStringColumnMask) != 2) + continue; + + // skip replication of all arg scalars between the varying arg set and the fixed args + if (fixed == 1 && type == (type & TypeStringScalarMask) && (function.classes & ClassXLS) == 0) + continue; + + // skip scalars when we are told to + if ((function.classes & ClassNS) && isScalarType(type)) + continue; + + // return type + if (function.classes & ClassB) + decls.append(TypeString[type & TypeStringColumnMask]); + else if (function.classes & ClassRS) + decls.append(TypeString[type & TypeStringScalarMask]); + else + decls.append(TypeString[type]); + decls.append(" "); + decls.append(function.name); + decls.append("("); + + // arguments + for (int arg = 0; arg < function.numArguments; ++arg) { + if (arg == function.numArguments - 1 && (function.classes & ClassLO)) + decls.append("out "); + if (arg == 0) { +#ifndef GLSLANG_WEB + if (function.classes & ClassCV) + decls.append("coherent volatile "); +#endif + if (function.classes & ClassFIO) + decls.append("inout "); + if (function.classes & ClassFO) + decls.append("out "); + } + if ((function.classes & ClassLB) && arg == function.numArguments - 1) + decls.append(TypeString[type & TypeStringColumnMask]); + else if (fixed && ((arg == function.numArguments - 1 && (function.classes & (ClassLS | ClassXLS | + ClassLS2))) || + (arg == function.numArguments - 2 && (function.classes & ClassLS2)) || + (arg == 0 && (function.classes & (ClassFS | ClassFS2))) || + (arg == 1 && (function.classes & ClassFS2)))) + decls.append(TypeString[type & TypeStringScalarMask]); + else + decls.append(TypeString[type]); + if (arg < function.numArguments - 1) + decls.append(","); + } + decls.append(");\n"); + } + } +} + +// See if the tabled versioning information allows the current version. +bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */) +{ +#ifdef GLSLANG_WEB + // all entries in table are valid + return true; +#endif + + // nullptr means always valid + if (function.versioning == nullptr) + return true; + + // check for what is said about our current profile + for (const Versioning* v = function.versioning; v->profiles != EBadProfile; ++v) { + if ((v->profiles & profile) != 0) { + if (v->minCoreVersion <= version || (v->numExtensions > 0 && v->minExtendedVersion <= version)) + return true; + } + } + + return false; +} + +// Relate a single table of built-ins to their AST operator. +// This can get called redundantly (especially for the common built-ins, when +// called once per stage). This is a performance issue only, not a correctness +// concern. It is done for quality arising from simplicity, as there are subtleties +// to get correct if instead trying to do it surgically. +template +void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable) +{ + while (functions->op != EOpNull) { + symbolTable.relateToOperator(functions->name, functions->op); + ++functions; + } +} + +} // end anonymous namespace + +// Add declarations for all tables of built-in functions. +void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion) +{ + const auto forEachFunction = [&](TString& decls, const BuiltInFunction* function) { + while (function->op != EOpNull) { + if (ValidVersion(*function, version, profile, spvVersion)) + AddTabledBuiltin(decls, *function); + ++function; + } + }; + + forEachFunction(commonBuiltins, BaseFunctions); + forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions); + + if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) + forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions); +} + +// Relate all tables of built-ins to the AST operators. +void TBuiltIns::relateTabledBuiltins(int /* version */, EProfile /* profile */, const SpvVersion& /* spvVersion */, EShLanguage /* stage */, TSymbolTable& symbolTable) +{ + RelateTabledBuiltins(BaseFunctions, symbolTable); + RelateTabledBuiltins(DerivativeFunctions, symbolTable); + RelateTabledBuiltins(CustomFunctions, symbolTable); +} + inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion) { return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && ARBCompatibility) || profile == ECompatibilityProfile); @@ -84,27 +498,30 @@ TBuiltIns::TBuiltIns() // Set up textual representations for making all the permutations // of texturing/imaging functions. prefixes[EbtFloat] = ""; -#ifdef AMD_EXTENSIONS + prefixes[EbtInt] = "i"; + prefixes[EbtUint] = "u"; +#ifndef GLSLANG_WEB prefixes[EbtFloat16] = "f16"; -#endif prefixes[EbtInt8] = "i8"; prefixes[EbtUint8] = "u8"; prefixes[EbtInt16] = "i16"; prefixes[EbtUint16] = "u16"; - prefixes[EbtInt] = "i"; - prefixes[EbtUint] = "u"; +#endif + postfixes[2] = "2"; postfixes[3] = "3"; postfixes[4] = "4"; // Map from symbolic class of texturing dimension to numeric dimensions. - dimMap[Esd1D] = 1; dimMap[Esd2D] = 2; - dimMap[EsdRect] = 2; dimMap[Esd3D] = 3; dimMap[EsdCube] = 3; +#ifndef GLSLANG_WEB + dimMap[Esd1D] = 1; + dimMap[EsdRect] = 2; dimMap[EsdBuffer] = 1; - dimMap[EsdSubpass] = 2; // potientially unused for now + dimMap[EsdSubpass] = 2; // potentially unused for now +#endif } TBuiltIns::~TBuiltIns() @@ -122,328 +539,158 @@ TBuiltIns::~TBuiltIns() // void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvVersion) { +#ifdef GLSLANG_WEB + version = 310; + profile = EEsProfile; +#endif + addTabledBuiltins(version, profile, spvVersion); + + //============================================================================ + // + // Prototypes for built-in functions used repeatly by different shaders + // + //============================================================================ + +#ifndef GLSLANG_WEB + // + // Derivatives Functions. + // + 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. // //============================================================================ - // - // Angle and Trigonometric Functions. - // - commonBuiltins.append( - "float radians(float degrees);" - "vec2 radians(vec2 degrees);" - "vec3 radians(vec3 degrees);" - "vec4 radians(vec4 degrees);" - - "float degrees(float radians);" - "vec2 degrees(vec2 radians);" - "vec3 degrees(vec3 radians);" - "vec4 degrees(vec4 radians);" - - "float sin(float angle);" - "vec2 sin(vec2 angle);" - "vec3 sin(vec3 angle);" - "vec4 sin(vec4 angle);" - - "float cos(float angle);" - "vec2 cos(vec2 angle);" - "vec3 cos(vec3 angle);" - "vec4 cos(vec4 angle);" - - "float tan(float angle);" - "vec2 tan(vec2 angle);" - "vec3 tan(vec3 angle);" - "vec4 tan(vec4 angle);" - - "float asin(float x);" - "vec2 asin(vec2 x);" - "vec3 asin(vec3 x);" - "vec4 asin(vec4 x);" - - "float acos(float x);" - "vec2 acos(vec2 x);" - "vec3 acos(vec3 x);" - "vec4 acos(vec4 x);" - - "float atan(float y, float x);" - "vec2 atan(vec2 y, vec2 x);" - "vec3 atan(vec3 y, vec3 x);" - "vec4 atan(vec4 y, vec4 x);" - - "float atan(float y_over_x);" - "vec2 atan(vec2 y_over_x);" - "vec3 atan(vec3 y_over_x);" - "vec4 atan(vec4 y_over_x);" - - "\n"); - - if (version >= 130) { - commonBuiltins.append( - "float sinh(float angle);" - "vec2 sinh(vec2 angle);" - "vec3 sinh(vec3 angle);" - "vec4 sinh(vec4 angle);" - - "float cosh(float angle);" - "vec2 cosh(vec2 angle);" - "vec3 cosh(vec3 angle);" - "vec4 cosh(vec4 angle);" - - "float tanh(float angle);" - "vec2 tanh(vec2 angle);" - "vec3 tanh(vec3 angle);" - "vec4 tanh(vec4 angle);" - - "float asinh(float x);" - "vec2 asinh(vec2 x);" - "vec3 asinh(vec3 x);" - "vec4 asinh(vec4 x);" - - "float acosh(float x);" - "vec2 acosh(vec2 x);" - "vec3 acosh(vec3 x);" - "vec4 acosh(vec4 x);" - - "float atanh(float y_over_x);" - "vec2 atanh(vec2 y_over_x);" - "vec3 atanh(vec3 y_over_x);" - "vec4 atanh(vec4 y_over_x);" - - "\n"); - } - - // - // Exponential Functions. - // - commonBuiltins.append( - "float pow(float x, float y);" - "vec2 pow(vec2 x, vec2 y);" - "vec3 pow(vec3 x, vec3 y);" - "vec4 pow(vec4 x, vec4 y);" - - "float exp(float x);" - "vec2 exp(vec2 x);" - "vec3 exp(vec3 x);" - "vec4 exp(vec4 x);" - - "float log(float x);" - "vec2 log(vec2 x);" - "vec3 log(vec3 x);" - "vec4 log(vec4 x);" - - "float exp2(float x);" - "vec2 exp2(vec2 x);" - "vec3 exp2(vec3 x);" - "vec4 exp2(vec4 x);" - - "float log2(float x);" - "vec2 log2(vec2 x);" - "vec3 log2(vec3 x);" - "vec4 log2(vec4 x);" - - "float sqrt(float x);" - "vec2 sqrt(vec2 x);" - "vec3 sqrt(vec3 x);" - "vec4 sqrt(vec4 x);" - - "float inversesqrt(float x);" - "vec2 inversesqrt(vec2 x);" - "vec3 inversesqrt(vec3 x);" - "vec4 inversesqrt(vec4 x);" - - "\n"); - - // - // Common Functions. - // - commonBuiltins.append( - "float abs(float x);" - "vec2 abs(vec2 x);" - "vec3 abs(vec3 x);" - "vec4 abs(vec4 x);" - - "float sign(float x);" - "vec2 sign(vec2 x);" - "vec3 sign(vec3 x);" - "vec4 sign(vec4 x);" - - "float floor(float x);" - "vec2 floor(vec2 x);" - "vec3 floor(vec3 x);" - "vec4 floor(vec4 x);" - - "float ceil(float x);" - "vec2 ceil(vec2 x);" - "vec3 ceil(vec3 x);" - "vec4 ceil(vec4 x);" - - "float fract(float x);" - "vec2 fract(vec2 x);" - "vec3 fract(vec3 x);" - "vec4 fract(vec4 x);" - - "float mod(float x, float y);" - "vec2 mod(vec2 x, float y);" - "vec3 mod(vec3 x, float y);" - "vec4 mod(vec4 x, float y);" - "vec2 mod(vec2 x, vec2 y);" - "vec3 mod(vec3 x, vec3 y);" - "vec4 mod(vec4 x, vec4 y);" - - "float min(float x, float y);" - "vec2 min(vec2 x, float y);" - "vec3 min(vec3 x, float y);" - "vec4 min(vec4 x, float y);" - "vec2 min(vec2 x, vec2 y);" - "vec3 min(vec3 x, vec3 y);" - "vec4 min(vec4 x, vec4 y);" - - "float max(float x, float y);" - "vec2 max(vec2 x, float y);" - "vec3 max(vec3 x, float y);" - "vec4 max(vec4 x, float y);" - "vec2 max(vec2 x, vec2 y);" - "vec3 max(vec3 x, vec3 y);" - "vec4 max(vec4 x, vec4 y);" - - "float clamp(float x, float minVal, float maxVal);" - "vec2 clamp(vec2 x, float minVal, float maxVal);" - "vec3 clamp(vec3 x, float minVal, float maxVal);" - "vec4 clamp(vec4 x, float minVal, float maxVal);" - "vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);" - "vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);" - "vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);" - - "float mix(float x, float y, float a);" - "vec2 mix(vec2 x, vec2 y, float a);" - "vec3 mix(vec3 x, vec3 y, float a);" - "vec4 mix(vec4 x, vec4 y, float a);" - "vec2 mix(vec2 x, vec2 y, vec2 a);" - "vec3 mix(vec3 x, vec3 y, vec3 a);" - "vec4 mix(vec4 x, vec4 y, vec4 a);" - - "float step(float edge, float x);" - "vec2 step(vec2 edge, vec2 x);" - "vec3 step(vec3 edge, vec3 x);" - "vec4 step(vec4 edge, vec4 x);" - "vec2 step(float edge, vec2 x);" - "vec3 step(float edge, vec3 x);" - "vec4 step(float edge, vec4 x);" - - "float smoothstep(float edge0, float edge1, float x);" - "vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);" - "vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);" - "vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);" - "vec2 smoothstep(float edge0, float edge1, vec2 x);" - "vec3 smoothstep(float edge0, float edge1, vec3 x);" - "vec4 smoothstep(float edge0, float edge1, vec4 x);" - - "\n"); - - if (version >= 130) { - commonBuiltins.append( - " int abs( int x);" - "ivec2 abs(ivec2 x);" - "ivec3 abs(ivec3 x);" - "ivec4 abs(ivec4 x);" - - " int sign( int x);" - "ivec2 sign(ivec2 x);" - "ivec3 sign(ivec3 x);" - "ivec4 sign(ivec4 x);" - - "float trunc(float x);" - "vec2 trunc(vec2 x);" - "vec3 trunc(vec3 x);" - "vec4 trunc(vec4 x);" - - "float round(float x);" - "vec2 round(vec2 x);" - "vec3 round(vec3 x);" - "vec4 round(vec4 x);" - - "float roundEven(float x);" - "vec2 roundEven(vec2 x);" - "vec3 roundEven(vec3 x);" - "vec4 roundEven(vec4 x);" - - "float modf(float, out float);" - "vec2 modf(vec2, out vec2 );" - "vec3 modf(vec3, out vec3 );" - "vec4 modf(vec4, out vec4 );" - - " int min(int x, int y);" - "ivec2 min(ivec2 x, int y);" - "ivec3 min(ivec3 x, int y);" - "ivec4 min(ivec4 x, int y);" - "ivec2 min(ivec2 x, ivec2 y);" - "ivec3 min(ivec3 x, ivec3 y);" - "ivec4 min(ivec4 x, ivec4 y);" - - " uint min(uint x, uint y);" - "uvec2 min(uvec2 x, uint y);" - "uvec3 min(uvec3 x, uint y);" - "uvec4 min(uvec4 x, uint y);" - "uvec2 min(uvec2 x, uvec2 y);" - "uvec3 min(uvec3 x, uvec3 y);" - "uvec4 min(uvec4 x, uvec4 y);" - - " int max(int x, int y);" - "ivec2 max(ivec2 x, int y);" - "ivec3 max(ivec3 x, int y);" - "ivec4 max(ivec4 x, int y);" - "ivec2 max(ivec2 x, ivec2 y);" - "ivec3 max(ivec3 x, ivec3 y);" - "ivec4 max(ivec4 x, ivec4 y);" - - " uint max(uint x, uint y);" - "uvec2 max(uvec2 x, uint y);" - "uvec3 max(uvec3 x, uint y);" - "uvec4 max(uvec4 x, uint y);" - "uvec2 max(uvec2 x, uvec2 y);" - "uvec3 max(uvec3 x, uvec3 y);" - "uvec4 max(uvec4 x, uvec4 y);" - - "int clamp(int x, int minVal, int maxVal);" - "ivec2 clamp(ivec2 x, int minVal, int maxVal);" - "ivec3 clamp(ivec3 x, int minVal, int maxVal);" - "ivec4 clamp(ivec4 x, int minVal, int maxVal);" - "ivec2 clamp(ivec2 x, ivec2 minVal, ivec2 maxVal);" - "ivec3 clamp(ivec3 x, ivec3 minVal, ivec3 maxVal);" - "ivec4 clamp(ivec4 x, ivec4 minVal, ivec4 maxVal);" - - "uint clamp(uint x, uint minVal, uint maxVal);" - "uvec2 clamp(uvec2 x, uint minVal, uint maxVal);" - "uvec3 clamp(uvec3 x, uint minVal, uint maxVal);" - "uvec4 clamp(uvec4 x, uint minVal, uint maxVal);" - "uvec2 clamp(uvec2 x, uvec2 minVal, uvec2 maxVal);" - "uvec3 clamp(uvec3 x, uvec3 minVal, uvec3 maxVal);" - "uvec4 clamp(uvec4 x, uvec4 minVal, uvec4 maxVal);" - - "float mix(float x, float y, bool a);" - "vec2 mix(vec2 x, vec2 y, bvec2 a);" - "vec3 mix(vec3 x, vec3 y, bvec3 a);" - "vec4 mix(vec4 x, vec4 y, bvec4 a);" - - "bool isnan(float x);" - "bvec2 isnan(vec2 x);" - "bvec3 isnan(vec3 x);" - "bvec4 isnan(vec4 x);" - - "bool isinf(float x);" - "bvec2 isinf(vec2 x);" - "bvec3 isinf(vec3 x);" - "bvec4 isinf(vec4 x);" - - "\n"); - } - // // double functions added to desktop 4.00, but not fma, frexp, ldexp, or pack/unpack // - if (profile != EEsProfile && version >= 400) { + if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double sqrt(double);" @@ -603,10 +850,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "dvec3 reflect(dvec3 , dvec3 );" "dvec4 reflect(dvec4 , dvec4 );" - "double refract(double, double, float);" - "dvec2 refract(dvec2 , dvec2 , float);" - "dvec3 refract(dvec3 , dvec3 , float);" - "dvec4 refract(dvec4 , dvec4 , float);" + "double refract(double, double, double);" + "dvec2 refract(dvec2 , dvec2 , double);" + "dvec3 refract(dvec3 , dvec3 , double);" + "dvec4 refract(dvec4 , dvec4 , double);" "dmat2 matrixCompMult(dmat2, dmat2);" "dmat3 matrixCompMult(dmat3, dmat3);" @@ -807,31 +1054,30 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bvec3 notEqual(u64vec3, u64vec3);" "bvec4 notEqual(u64vec4, u64vec4);" - "int findLSB(int64_t);" - "ivec2 findLSB(i64vec2);" - "ivec3 findLSB(i64vec3);" - "ivec4 findLSB(i64vec4);" + "int64_t findLSB(int64_t);" + "i64vec2 findLSB(i64vec2);" + "i64vec3 findLSB(i64vec3);" + "i64vec4 findLSB(i64vec4);" - "int findLSB(uint64_t);" - "ivec2 findLSB(u64vec2);" - "ivec3 findLSB(u64vec3);" - "ivec4 findLSB(u64vec4);" + "int64_t findLSB(uint64_t);" + "i64vec2 findLSB(u64vec2);" + "i64vec3 findLSB(u64vec3);" + "i64vec4 findLSB(u64vec4);" - "int findMSB(int64_t);" - "ivec2 findMSB(i64vec2);" - "ivec3 findMSB(i64vec3);" - "ivec4 findMSB(i64vec4);" + "int64_t findMSB(int64_t);" + "i64vec2 findMSB(i64vec2);" + "i64vec3 findMSB(i64vec3);" + "i64vec4 findMSB(i64vec4);" - "int findMSB(uint64_t);" - "ivec2 findMSB(u64vec2);" - "ivec3 findMSB(u64vec3);" - "ivec4 findMSB(u64vec4);" + "int64_t findMSB(uint64_t);" + "i64vec2 findMSB(u64vec2);" + "i64vec3 findMSB(u64vec3);" + "i64vec4 findMSB(u64vec4);" "\n" ); } -#ifdef AMD_EXTENSIONS // GL_AMD_shader_trinary_minmax if (profile != EEsProfile && version >= 430) { commonBuiltins.append( @@ -928,85 +1174,94 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n" ); } -#endif if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 430)) { 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)) { - commonBuiltins.append( - "int mix(int x, int y, bool a);" - "ivec2 mix(ivec2 x, ivec2 y, bvec2 a);" - "ivec3 mix(ivec3 x, ivec3 y, bvec3 a);" - "ivec4 mix(ivec4 x, ivec4 y, bvec4 a);" - - "uint mix(uint x, uint y, bool a);" - "uvec2 mix(uvec2 x, uvec2 y, bvec2 a);" - "uvec3 mix(uvec3 x, uvec3 y, bvec3 a);" - "uvec4 mix(uvec4 x, uvec4 y, bvec4 a);" - - "bool mix(bool x, bool y, bool a);" - "bvec2 mix(bvec2 x, bvec2 y, bvec2 a);" - "bvec3 mix(bvec3 x, bvec3 y, bvec3 a);" - "bvec4 mix(bvec4 x, bvec4 y, bvec4 a);" - - "\n"); - } - if ((profile == EEsProfile && version >= 300) || (profile != EEsProfile && version >= 330)) { commonBuiltins.append( @@ -1033,6 +1288,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 400) || (profile == EEsProfile && version >= 310)) { // GL_OES_gpu_shader5 @@ -1042,15 +1298,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec3 fma(vec3, vec3, vec3 );" "vec4 fma(vec4, vec4, vec4 );" "\n"); + } - if (profile != EEsProfile) { + if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double fma(double, double, double);" "dvec2 fma(dvec2, dvec2, dvec2 );" "dvec3 fma(dvec3, dvec3, dvec3 );" "dvec4 fma(dvec4, dvec4, dvec4 );" "\n"); - } } if ((profile == EEsProfile && version >= 310) || @@ -1069,7 +1325,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } - if (profile != EEsProfile && version >= 400) { + if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double frexp(double, out int);" "dvec2 frexp( dvec2, out ivec2);" @@ -1086,6 +1342,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#endif if ((profile == EEsProfile && version >= 300) || (profile != EEsProfile && version >= 400)) { @@ -1114,6 +1371,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_WEB if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 400)) { commonBuiltins.append( @@ -1133,48 +1391,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 unpackUnorm4x8(highp uint);" "\n"); } - - // - // Geometric Functions. - // - commonBuiltins.append( - "float length(float x);" - "float length(vec2 x);" - "float length(vec3 x);" - "float length(vec4 x);" - - "float distance(float p0, float p1);" - "float distance(vec2 p0, vec2 p1);" - "float distance(vec3 p0, vec3 p1);" - "float distance(vec4 p0, vec4 p1);" - - "float dot(float x, float y);" - "float dot(vec2 x, vec2 y);" - "float dot(vec3 x, vec3 y);" - "float dot(vec4 x, vec4 y);" - - "vec3 cross(vec3 x, vec3 y);" - "float normalize(float x);" - "vec2 normalize(vec2 x);" - "vec3 normalize(vec3 x);" - "vec4 normalize(vec4 x);" - - "float faceforward(float N, float I, float Nref);" - "vec2 faceforward(vec2 N, vec2 I, vec2 Nref);" - "vec3 faceforward(vec3 N, vec3 I, vec3 Nref);" - "vec4 faceforward(vec4 N, vec4 I, vec4 Nref);" - - "float reflect(float I, float N);" - "vec2 reflect(vec2 I, vec2 N);" - "vec3 reflect(vec3 I, vec3 N);" - "vec4 reflect(vec4 I, vec4 N);" - - "float refract(float I, float N, float eta);" - "vec2 refract(vec2 I, vec2 N, float eta);" - "vec3 refract(vec3 I, vec3 N, float eta);" - "vec4 refract(vec4 I, vec4 N, float eta);" - - "\n"); +#endif // // Matrix Functions. @@ -1233,109 +1450,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } } - // - // Vector relational functions. - // - commonBuiltins.append( - "bvec2 lessThan(vec2 x, vec2 y);" - "bvec3 lessThan(vec3 x, vec3 y);" - "bvec4 lessThan(vec4 x, vec4 y);" - - "bvec2 lessThan(ivec2 x, ivec2 y);" - "bvec3 lessThan(ivec3 x, ivec3 y);" - "bvec4 lessThan(ivec4 x, ivec4 y);" - - "bvec2 lessThanEqual(vec2 x, vec2 y);" - "bvec3 lessThanEqual(vec3 x, vec3 y);" - "bvec4 lessThanEqual(vec4 x, vec4 y);" - - "bvec2 lessThanEqual(ivec2 x, ivec2 y);" - "bvec3 lessThanEqual(ivec3 x, ivec3 y);" - "bvec4 lessThanEqual(ivec4 x, ivec4 y);" - - "bvec2 greaterThan(vec2 x, vec2 y);" - "bvec3 greaterThan(vec3 x, vec3 y);" - "bvec4 greaterThan(vec4 x, vec4 y);" - - "bvec2 greaterThan(ivec2 x, ivec2 y);" - "bvec3 greaterThan(ivec3 x, ivec3 y);" - "bvec4 greaterThan(ivec4 x, ivec4 y);" - - "bvec2 greaterThanEqual(vec2 x, vec2 y);" - "bvec3 greaterThanEqual(vec3 x, vec3 y);" - "bvec4 greaterThanEqual(vec4 x, vec4 y);" - - "bvec2 greaterThanEqual(ivec2 x, ivec2 y);" - "bvec3 greaterThanEqual(ivec3 x, ivec3 y);" - "bvec4 greaterThanEqual(ivec4 x, ivec4 y);" - - "bvec2 equal(vec2 x, vec2 y);" - "bvec3 equal(vec3 x, vec3 y);" - "bvec4 equal(vec4 x, vec4 y);" - - "bvec2 equal(ivec2 x, ivec2 y);" - "bvec3 equal(ivec3 x, ivec3 y);" - "bvec4 equal(ivec4 x, ivec4 y);" - - "bvec2 equal(bvec2 x, bvec2 y);" - "bvec3 equal(bvec3 x, bvec3 y);" - "bvec4 equal(bvec4 x, bvec4 y);" - - "bvec2 notEqual(vec2 x, vec2 y);" - "bvec3 notEqual(vec3 x, vec3 y);" - "bvec4 notEqual(vec4 x, vec4 y);" - - "bvec2 notEqual(ivec2 x, ivec2 y);" - "bvec3 notEqual(ivec3 x, ivec3 y);" - "bvec4 notEqual(ivec4 x, ivec4 y);" - - "bvec2 notEqual(bvec2 x, bvec2 y);" - "bvec3 notEqual(bvec3 x, bvec3 y);" - "bvec4 notEqual(bvec4 x, bvec4 y);" - - "bool any(bvec2 x);" - "bool any(bvec3 x);" - "bool any(bvec4 x);" - - "bool all(bvec2 x);" - "bool all(bvec3 x);" - "bool all(bvec4 x);" - - "bvec2 not(bvec2 x);" - "bvec3 not(bvec3 x);" - "bvec4 not(bvec4 x);" - - "\n"); - - if (version >= 130) { - commonBuiltins.append( - "bvec2 lessThan(uvec2 x, uvec2 y);" - "bvec3 lessThan(uvec3 x, uvec3 y);" - "bvec4 lessThan(uvec4 x, uvec4 y);" - - "bvec2 lessThanEqual(uvec2 x, uvec2 y);" - "bvec3 lessThanEqual(uvec3 x, uvec3 y);" - "bvec4 lessThanEqual(uvec4 x, uvec4 y);" - - "bvec2 greaterThan(uvec2 x, uvec2 y);" - "bvec3 greaterThan(uvec3 x, uvec3 y);" - "bvec4 greaterThan(uvec4 x, uvec4 y);" - - "bvec2 greaterThanEqual(uvec2 x, uvec2 y);" - "bvec3 greaterThanEqual(uvec3 x, uvec3 y);" - "bvec4 greaterThanEqual(uvec4 x, uvec4 y);" - - "bvec2 equal(uvec2 x, uvec2 y);" - "bvec3 equal(uvec3 x, uvec3 y);" - "bvec4 equal(uvec4 x, uvec4 y);" - - "bvec2 notEqual(uvec2 x, uvec2 y);" - "bvec3 notEqual(uvec3 x, uvec3 y);" - "bvec4 notEqual(uvec4 x, uvec4 y);" - - "\n"); - } - +#ifndef GLSLANG_WEB // // Original-style texture functions existing in all stages. // (Per-stage functions below.) @@ -1405,6 +1520,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 texelFetch(samplerExternalOES, ivec2, int lod);" // GL_OES_EGL_image_external_essl3 "\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 @@ -1665,7 +1790,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { commonBuiltins.append( "void subgroupBarrier();" "void subgroupMemoryBarrier();" @@ -1675,58 +1801,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "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" @@ -1735,1012 +1809,142 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "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"); + ); + + // Generate all flavors of subgroup ops. + static const char *subgroupOps[] = + { + "bool subgroupAllEqual(%s);\n", + "%s subgroupBroadcast(%s, uint);\n", + "%s subgroupBroadcastFirst(%s);\n", + "%s subgroupShuffle(%s, uint);\n", + "%s subgroupShuffleXor(%s, uint);\n", + "%s subgroupShuffleUp(%s, uint delta);\n", + "%s subgroupShuffleDown(%s, uint delta);\n", + "%s subgroupAdd(%s);\n", + "%s subgroupMul(%s);\n", + "%s subgroupMin(%s);\n", + "%s subgroupMax(%s);\n", + "%s subgroupAnd(%s);\n", + "%s subgroupOr(%s);\n", + "%s subgroupXor(%s);\n", + "%s subgroupInclusiveAdd(%s);\n", + "%s subgroupInclusiveMul(%s);\n", + "%s subgroupInclusiveMin(%s);\n", + "%s subgroupInclusiveMax(%s);\n", + "%s subgroupInclusiveAnd(%s);\n", + "%s subgroupInclusiveOr(%s);\n", + "%s subgroupInclusiveXor(%s);\n", + "%s subgroupExclusiveAdd(%s);\n", + "%s subgroupExclusiveMul(%s);\n", + "%s subgroupExclusiveMin(%s);\n", + "%s subgroupExclusiveMax(%s);\n", + "%s subgroupExclusiveAnd(%s);\n", + "%s subgroupExclusiveOr(%s);\n", + "%s subgroupExclusiveXor(%s);\n", + "%s subgroupClusteredAdd(%s, uint);\n", + "%s subgroupClusteredMul(%s, uint);\n", + "%s subgroupClusteredMin(%s, uint);\n", + "%s subgroupClusteredMax(%s, uint);\n", + "%s subgroupClusteredAnd(%s, uint);\n", + "%s subgroupClusteredOr(%s, uint);\n", + "%s subgroupClusteredXor(%s, uint);\n", + "%s subgroupQuadBroadcast(%s, uint);\n", + "%s subgroupQuadSwapHorizontal(%s);\n", + "%s subgroupQuadSwapVertical(%s);\n", + "%s subgroupQuadSwapDiagonal(%s);\n", + "uvec4 subgroupPartitionNV(%s);\n", + "%s subgroupPartitionedAddNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedMulNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedMinNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedMaxNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedAndNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedOrNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedXorNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveAddNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveMulNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveMinNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveMaxNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveAndNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveOrNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedInclusiveXorNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveAddNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveMulNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveMinNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveMaxNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveAndNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveOrNV(%s, uvec4 ballot);\n", + "%s subgroupPartitionedExclusiveXorNV(%s, uvec4 ballot);\n", + }; + + static const char *floatTypes[] = { + "float", "vec2", "vec3", "vec4", + "float16_t", "f16vec2", "f16vec3", "f16vec4", + }; + static const char *doubleTypes[] = { + "double", "dvec2", "dvec3", "dvec4", + }; + static const char *intTypes[] = { + "int8_t", "i8vec2", "i8vec3", "i8vec4", + "int16_t", "i16vec2", "i16vec3", "i16vec4", + "int", "ivec2", "ivec3", "ivec4", + "int64_t", "i64vec2", "i64vec3", "i64vec4", + "uint8_t", "u8vec2", "u8vec3", "u8vec4", + "uint16_t", "u16vec2", "u16vec3", "u16vec4", + "uint", "uvec2", "uvec3", "uvec4", + "uint64_t", "u64vec2", "u64vec3", "u64vec4", + }; + static const char *boolTypes[] = { + "bool", "bvec2", "bvec3", "bvec4", + }; + + for (size_t i = 0; i < sizeof(subgroupOps)/sizeof(subgroupOps[0]); ++i) { + const char *op = subgroupOps[i]; + + // Logical operations don't support float + bool logicalOp = strstr(op, "Or") || strstr(op, "And") || + (strstr(op, "Xor") && !strstr(op, "ShuffleXor")); + // Math operations don't support bool + bool mathOp = strstr(op, "Add") || strstr(op, "Mul") || strstr(op, "Min") || strstr(op, "Max"); + + const int bufSize = 256; + char buf[bufSize]; + + if (!logicalOp) { + for (size_t j = 0; j < sizeof(floatTypes)/sizeof(floatTypes[0]); ++j) { + snprintf(buf, bufSize, op, floatTypes[j], floatTypes[j]); + commonBuiltins.append(buf); + } + if (profile != EEsProfile && version >= 400) { + for (size_t j = 0; j < sizeof(doubleTypes)/sizeof(doubleTypes[0]); ++j) { + snprintf(buf, bufSize, op, doubleTypes[j], doubleTypes[j]); + commonBuiltins.append(buf); + } + } } + if (!mathOp) { + for (size_t j = 0; j < sizeof(boolTypes)/sizeof(boolTypes[0]); ++j) { + snprintf(buf, bufSize, op, boolTypes[j], boolTypes[j]); + commonBuiltins.append(buf); + } + } + for (size_t j = 0; j < sizeof(intTypes)/sizeof(intTypes[0]); ++j) { + snprintf(buf, bufSize, op, intTypes[j], intTypes[j]); + commonBuiltins.append(buf); + } + } stageBuiltins[EShLangCompute].append( "void subgroupMemoryBarrierShared();" + "\n" + ); + stageBuiltins[EShLangMeshNV].append( + "void subgroupMemoryBarrierShared();" + "\n" + ); + stageBuiltins[EShLangTaskNV].append( + "void subgroupMemoryBarrierShared();" "\n" ); } @@ -2754,7 +1958,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifdef AMD_EXTENSIONS // GL_AMD_shader_ballot if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -3619,12 +2822,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } // GL_AMD_gcn_shader - if (profile != EEsProfile && version >= 450) { + if (profile != EEsProfile && version >= 440) { commonBuiltins.append( "float cubeFaceIndexAMD(vec3);" "vec2 cubeFaceCoordAMD(vec3);" "uint64_t timeAMD();" + "in int gl_SIMDGroupSizeAMD;" "\n"); } @@ -3650,7 +2854,213 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif // AMD_EXTENSIONS + if ((profile != EEsProfile && version >= 130) || + (profile == EEsProfile && version >= 300)) { + commonBuiltins.append( + "uint countLeadingZeros(uint);" + "uvec2 countLeadingZeros(uvec2);" + "uvec3 countLeadingZeros(uvec3);" + "uvec4 countLeadingZeros(uvec4);" + + "uint countTrailingZeros(uint);" + "uvec2 countTrailingZeros(uvec2);" + "uvec3 countTrailingZeros(uvec3);" + "uvec4 countTrailingZeros(uvec4);" + + "uint absoluteDifference(int, int);" + "uvec2 absoluteDifference(ivec2, ivec2);" + "uvec3 absoluteDifference(ivec3, ivec3);" + "uvec4 absoluteDifference(ivec4, ivec4);" + + "uint16_t absoluteDifference(int16_t, int16_t);" + "u16vec2 absoluteDifference(i16vec2, i16vec2);" + "u16vec3 absoluteDifference(i16vec3, i16vec3);" + "u16vec4 absoluteDifference(i16vec4, i16vec4);" + + "uint64_t absoluteDifference(int64_t, int64_t);" + "u64vec2 absoluteDifference(i64vec2, i64vec2);" + "u64vec3 absoluteDifference(i64vec3, i64vec3);" + "u64vec4 absoluteDifference(i64vec4, i64vec4);" + + "uint absoluteDifference(uint, uint);" + "uvec2 absoluteDifference(uvec2, uvec2);" + "uvec3 absoluteDifference(uvec3, uvec3);" + "uvec4 absoluteDifference(uvec4, uvec4);" + + "uint16_t absoluteDifference(uint16_t, uint16_t);" + "u16vec2 absoluteDifference(u16vec2, u16vec2);" + "u16vec3 absoluteDifference(u16vec3, u16vec3);" + "u16vec4 absoluteDifference(u16vec4, u16vec4);" + + "uint64_t absoluteDifference(uint64_t, uint64_t);" + "u64vec2 absoluteDifference(u64vec2, u64vec2);" + "u64vec3 absoluteDifference(u64vec3, u64vec3);" + "u64vec4 absoluteDifference(u64vec4, u64vec4);" + + "int addSaturate(int, int);" + "ivec2 addSaturate(ivec2, ivec2);" + "ivec3 addSaturate(ivec3, ivec3);" + "ivec4 addSaturate(ivec4, ivec4);" + + "int16_t addSaturate(int16_t, int16_t);" + "i16vec2 addSaturate(i16vec2, i16vec2);" + "i16vec3 addSaturate(i16vec3, i16vec3);" + "i16vec4 addSaturate(i16vec4, i16vec4);" + + "int64_t addSaturate(int64_t, int64_t);" + "i64vec2 addSaturate(i64vec2, i64vec2);" + "i64vec3 addSaturate(i64vec3, i64vec3);" + "i64vec4 addSaturate(i64vec4, i64vec4);" + + "uint addSaturate(uint, uint);" + "uvec2 addSaturate(uvec2, uvec2);" + "uvec3 addSaturate(uvec3, uvec3);" + "uvec4 addSaturate(uvec4, uvec4);" + + "uint16_t addSaturate(uint16_t, uint16_t);" + "u16vec2 addSaturate(u16vec2, u16vec2);" + "u16vec3 addSaturate(u16vec3, u16vec3);" + "u16vec4 addSaturate(u16vec4, u16vec4);" + + "uint64_t addSaturate(uint64_t, uint64_t);" + "u64vec2 addSaturate(u64vec2, u64vec2);" + "u64vec3 addSaturate(u64vec3, u64vec3);" + "u64vec4 addSaturate(u64vec4, u64vec4);" + + "int subtractSaturate(int, int);" + "ivec2 subtractSaturate(ivec2, ivec2);" + "ivec3 subtractSaturate(ivec3, ivec3);" + "ivec4 subtractSaturate(ivec4, ivec4);" + + "int16_t subtractSaturate(int16_t, int16_t);" + "i16vec2 subtractSaturate(i16vec2, i16vec2);" + "i16vec3 subtractSaturate(i16vec3, i16vec3);" + "i16vec4 subtractSaturate(i16vec4, i16vec4);" + + "int64_t subtractSaturate(int64_t, int64_t);" + "i64vec2 subtractSaturate(i64vec2, i64vec2);" + "i64vec3 subtractSaturate(i64vec3, i64vec3);" + "i64vec4 subtractSaturate(i64vec4, i64vec4);" + + "uint subtractSaturate(uint, uint);" + "uvec2 subtractSaturate(uvec2, uvec2);" + "uvec3 subtractSaturate(uvec3, uvec3);" + "uvec4 subtractSaturate(uvec4, uvec4);" + + "uint16_t subtractSaturate(uint16_t, uint16_t);" + "u16vec2 subtractSaturate(u16vec2, u16vec2);" + "u16vec3 subtractSaturate(u16vec3, u16vec3);" + "u16vec4 subtractSaturate(u16vec4, u16vec4);" + + "uint64_t subtractSaturate(uint64_t, uint64_t);" + "u64vec2 subtractSaturate(u64vec2, u64vec2);" + "u64vec3 subtractSaturate(u64vec3, u64vec3);" + "u64vec4 subtractSaturate(u64vec4, u64vec4);" + + "int average(int, int);" + "ivec2 average(ivec2, ivec2);" + "ivec3 average(ivec3, ivec3);" + "ivec4 average(ivec4, ivec4);" + + "int16_t average(int16_t, int16_t);" + "i16vec2 average(i16vec2, i16vec2);" + "i16vec3 average(i16vec3, i16vec3);" + "i16vec4 average(i16vec4, i16vec4);" + + "int64_t average(int64_t, int64_t);" + "i64vec2 average(i64vec2, i64vec2);" + "i64vec3 average(i64vec3, i64vec3);" + "i64vec4 average(i64vec4, i64vec4);" + + "uint average(uint, uint);" + "uvec2 average(uvec2, uvec2);" + "uvec3 average(uvec3, uvec3);" + "uvec4 average(uvec4, uvec4);" + + "uint16_t average(uint16_t, uint16_t);" + "u16vec2 average(u16vec2, u16vec2);" + "u16vec3 average(u16vec3, u16vec3);" + "u16vec4 average(u16vec4, u16vec4);" + + "uint64_t average(uint64_t, uint64_t);" + "u64vec2 average(u64vec2, u64vec2);" + "u64vec3 average(u64vec3, u64vec3);" + "u64vec4 average(u64vec4, u64vec4);" + + "int averageRounded(int, int);" + "ivec2 averageRounded(ivec2, ivec2);" + "ivec3 averageRounded(ivec3, ivec3);" + "ivec4 averageRounded(ivec4, ivec4);" + + "int16_t averageRounded(int16_t, int16_t);" + "i16vec2 averageRounded(i16vec2, i16vec2);" + "i16vec3 averageRounded(i16vec3, i16vec3);" + "i16vec4 averageRounded(i16vec4, i16vec4);" + + "int64_t averageRounded(int64_t, int64_t);" + "i64vec2 averageRounded(i64vec2, i64vec2);" + "i64vec3 averageRounded(i64vec3, i64vec3);" + "i64vec4 averageRounded(i64vec4, i64vec4);" + + "uint averageRounded(uint, uint);" + "uvec2 averageRounded(uvec2, uvec2);" + "uvec3 averageRounded(uvec3, uvec3);" + "uvec4 averageRounded(uvec4, uvec4);" + + "uint16_t averageRounded(uint16_t, uint16_t);" + "u16vec2 averageRounded(u16vec2, u16vec2);" + "u16vec3 averageRounded(u16vec3, u16vec3);" + "u16vec4 averageRounded(u16vec4, u16vec4);" + + "uint64_t averageRounded(uint64_t, uint64_t);" + "u64vec2 averageRounded(u64vec2, u64vec2);" + "u64vec3 averageRounded(u64vec3, u64vec3);" + "u64vec4 averageRounded(u64vec4, u64vec4);" + + "int multiply32x16(int, int);" + "ivec2 multiply32x16(ivec2, ivec2);" + "ivec3 multiply32x16(ivec3, ivec3);" + "ivec4 multiply32x16(ivec4, ivec4);" + + "uint multiply32x16(uint, uint);" + "uvec2 multiply32x16(uvec2, uvec2);" + "uvec3 multiply32x16(uvec3, uvec3);" + "uvec4 multiply32x16(uvec4, uvec4);" + "\n"); + } + + 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"); + } // GL_AMD_gpu_shader_half_float/Explicit types if (profile != EEsProfile && version >= 450) { @@ -4504,52 +3914,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); stageBuiltins[EShLangFragment].append( - "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);" - "float64_t interpolateAtCentroid(float64_t);" "f64vec2 interpolateAtCentroid(f64vec2);" "f64vec3 interpolateAtCentroid(f64vec3);" @@ -4580,7 +3946,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // // Geometric Functions. // - if (IncludeLegacy(version, profile, spvVersion)) + if (spvVersion.vulkan == 0 && IncludeLegacy(version, profile, spvVersion)) stageBuiltins[EShLangVertex].append("vec4 ftransform();"); // @@ -4662,6 +4028,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void EndPrimitive();" "\n"); } +#endif //============================================================================ // @@ -4677,21 +4044,129 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangCompute].append( "void barrier();" ); + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + stageBuiltins[EShLangMeshNV].append( + "void barrier();" + ); + stageBuiltins[EShLangTaskNV].append( + "void barrier();" + ); + } if ((profile != EEsProfile && version >= 130) || esBarrier) commonBuiltins.append( "void memoryBarrier();" ); if ((profile != EEsProfile && version >= 420) || esBarrier) { commonBuiltins.append( - "void memoryBarrierAtomicCounter();" "void memoryBarrierBuffer();" - "void memoryBarrierImage();" ); stageBuiltins[EShLangCompute].append( "void memoryBarrierShared();" "void groupMemoryBarrier();" ); } +#ifndef GLSLANG_WEB + if ((profile != EEsProfile && version >= 420) || esBarrier) { + commonBuiltins.append( + "void memoryBarrierAtomicCounter();" + "void memoryBarrierImage();" + ); + } + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + stageBuiltins[EShLangMeshNV].append( + "void memoryBarrierShared();" + "void groupMemoryBarrier();" + ); + stageBuiltins[EShLangTaskNV].append( + "void memoryBarrierShared();" + "void groupMemoryBarrier();" + ); + } + + 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" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out icoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatLoadNV(out ucoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatStoreNV(icoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(icoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent int64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent ivec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent ivec4[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n" + "void coopMatStoreNV(ucoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n" + + "icoopmatNV coopMatMulAddNV(icoopmatNV A, icoopmatNV B, icoopmatNV C);\n" + "ucoopmatNV coopMatMulAddNV(ucoopmatNV A, ucoopmatNV B, ucoopmatNV C);\n" + ); + } //============================================================================ // @@ -4735,61 +4210,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\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"); - // 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 @@ -4814,7 +4238,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifdef AMD_EXTENSIONS + stageBuiltins[EShLangFragment].append( + "void beginInvocationInterlockARB(void);" + "void endInvocationInterlockARB(void);"); + + stageBuiltins[EShLangFragment].append( + "bool helperInvocationEXT();" + "\n"); + // GL_AMD_shader_explicit_vertex_parameter if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangFragment].append( @@ -4843,52 +4274,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // GL_AMD_gpu_shader_half_float if (profile != EEsProfile && version >= 450) { + stageBuiltins[EShLangFragment].append(derivativesAndControl16bits); + stageBuiltins[EShLangFragment].append("\n"); + 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);" - "float16_t interpolateAtCentroid(float16_t);" "f16vec2 interpolateAtCentroid(f16vec2);" "f16vec3 interpolateAtCentroid(f16vec3);" @@ -4907,6 +4296,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + // GL_ARB_shader_clock & GL_EXT_shader_realtime_clock + if (profile != EEsProfile && version >= 450) { + commonBuiltins.append( + "uvec2 clock2x32ARB();" + "uint64_t clockARB();" + "uvec2 clockRealtime2x32EXT();" + "uint64_t clockRealtimeEXT();" + "\n"); + } + // GL_AMD_shader_fragment_mask if (profile != EEsProfile && version >= 450 && spvVersion.vulkan > 0) { stageBuiltins[EShLangFragment].append( @@ -4920,6 +4319,50 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + + // 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 + if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) { + 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 //============================================================================ @@ -4942,11 +4385,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "highp float diff;" // f - n ); } else { +#ifndef GLSLANG_WEB commonBuiltins.append( "float near;" // n "float far;" // f "float diff;" // f - n ); +#endif } commonBuiltins.append( @@ -4955,6 +4400,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_WEB if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) { // // Matrix state. p. 31, 32, 37, 39, 40. @@ -5072,6 +4518,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#endif //============================================================================ // @@ -5101,6 +4548,95 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } +#ifndef GLSLANG_WEB + //============================================================================ + // + // Define the interface to the mesh/task shader. + // + //============================================================================ + + 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[];" + ); + + // 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"); + } + } + //============================================================================ // // Define the interface to the vertex shader. @@ -5233,7 +4769,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ); } -#ifdef NV_EXTENSIONS if (version >= 450) stageBuiltins[EShLangVertex].append( "out int gl_ViewportMask[];" // GL_NV_viewport_array2 @@ -5242,8 +4777,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes ); -#endif - } else { // ES profile if (version == 100) { @@ -5258,15 +4791,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp int gl_InstanceID;" // needs qualifier fixed later ); if (spvVersion.vulkan > 0) +#endif stageBuiltins[EShLangVertex].append( "in highp int gl_VertexIndex;" "in highp int gl_InstanceIndex;" ); +#ifndef GLSLANG_WEB if (version < 310) +#endif stageBuiltins[EShLangVertex].append( "highp vec4 gl_Position;" // needs qualifier fixed later "highp float gl_PointSize;" // needs qualifier fixed later ); +#ifndef GLSLANG_WEB else stageBuiltins[EShLangVertex].append( "out gl_PerVertex {" @@ -5318,10 +4855,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if (version >= 450) stageBuiltins[EShLangGeometry].append( "float gl_CullDistance[];" -#ifdef NV_EXTENSIONS "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif ); stageBuiltins[EShLangGeometry].append( "} gl_in[];" @@ -5367,7 +4902,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in int gl_InvocationID;" ); -#ifdef NV_EXTENSIONS if (version >= 450) stageBuiltins[EShLangGeometry].append( "out int gl_ViewportMask[];" // GL_NV_viewport_array2 @@ -5376,7 +4910,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes ); -#endif stageBuiltins[EShLangGeometry].append("\n"); } else if (profile == EEsProfile && version >= 310) { @@ -5441,13 +4974,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if (version >= 450) stageBuiltins[EShLangTessControl].append( "float gl_CullDistance[];" -#ifdef NV_EXTENSIONS "int gl_ViewportMask[];" // GL_NV_viewport_array2 "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif ); stageBuiltins[EShLangTessControl].append( "} gl_out[];" @@ -5481,7 +5012,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "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) || @@ -5539,7 +5077,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out int gl_Layer;" "\n"); -#ifdef NV_EXTENSIONS if (version >= 450) stageBuiltins[EShLangTessEvaluation].append( "out int gl_ViewportMask[];" // GL_NV_viewport_array2 @@ -5548,7 +5085,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes "out int gl_ViewportMaskPerViewNV[];" // GL_NVX_multiview_per_view_attributes ); -#endif } else if (profile == EEsProfile && version >= 310) { // Note: "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below, @@ -5642,19 +5178,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in int gl_PrimitiveID;" ); - if (version >= 400) { + if (version >= 130) { // ARB_sample_shading stageBuiltins[EShLangFragment].append( "flat in int gl_SampleID;" " in vec2 gl_SamplePosition;" - "flat in int gl_SampleMaskIn[];" " out int gl_SampleMask[];" ); - if (spvVersion.spv == 0) + + if (spvVersion.spv == 0) { stageBuiltins[EShLangFragment].append( "uniform int gl_NumSamples;" - ); + ); + } } + if (version >= 400) + stageBuiltins[EShLangFragment].append( + "flat in int gl_SampleMaskIn[];" + ); + if (version >= 430) stageBuiltins[EShLangFragment].append( "flat in int gl_Layer;" @@ -5667,7 +5209,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool gl_HelperInvocation;" // needs qualifier fixed later ); -#ifdef AMD_EXTENSIONS + if (version >= 450) + stageBuiltins[EShLangFragment].append( // GL_EXT_fragment_invocation_density + "flat in ivec2 gl_FragSizeEXT;" + "flat in int gl_FragInvocationCountEXT;" + ); + if (version >= 450) stageBuiltins[EShLangFragment].append( "in vec2 gl_BaryCoordNoPerspAMD;" @@ -5678,14 +5225,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in vec2 gl_BaryCoordSmoothSampleAMD;" "in vec3 gl_BaryCoordPullModelAMD;" ); -#endif -#ifdef NV_EXTENSIONS if (version >= 430) stageBuiltins[EShLangFragment].append( "in bool gl_FragFullyCoveredNV;" ); -#endif + 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;" + ); + } else { // ES profile @@ -5697,6 +5249,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump vec2 gl_PointCoord;" // needs qualifier fixed later ); } +#endif if (version >= 300) { stageBuiltins[EShLangFragment].append( "highp vec4 gl_FragCoord;" // needs qualifier fixed later @@ -5705,6 +5258,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "highp float gl_FragDepth;" // needs qualifier fixed later ); } +#ifndef GLSLANG_WEB if (version >= 310) { stageBuiltins[EShLangFragment].append( "bool gl_HelperInvocation;" // needs qualifier fixed later @@ -5726,15 +5280,35 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV 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;" + ); + 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"); if (version >= 130) add2ndGenerationSamplingImaging(version, profile, spvVersion); +#ifndef GLSLANG_WEB + // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { - const char* ballotDecls = + const char* ballotDecls = "uniform uint gl_SubGroupSizeARB;" "in uint gl_SubGroupInvocationARB;" "in uint64_t gl_SubGroupEqMaskARB;" @@ -5743,7 +5317,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in uint64_t gl_SubGroupLeMaskARB;" "in uint64_t gl_SubGroupLtMaskARB;" "\n"; - const char* fragmentBallotDecls = + const char* fragmentBallotDecls = "uniform uint gl_SubGroupSizeARB;" "flat in uint gl_SubGroupInvocationARB;" "flat in uint64_t gl_SubGroupEqMaskARB;" @@ -5758,6 +5332,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangGeometry] .append(ballotDecls); stageBuiltins[EShLangCompute] .append(ballotDecls); stageBuiltins[EShLangFragment] .append(fragmentBallotDecls); + stageBuiltins[EShLangMeshNV] .append(ballotDecls); + stageBuiltins[EShLangTaskNV] .append(ballotDecls); } if ((profile != EEsProfile && version >= 140) || @@ -5769,8 +5345,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { - const char* ballotDecls = + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + const char* subgroupDecls = "in mediump uint gl_SubgroupSize;" "in mediump uint gl_SubgroupInvocationID;" "in highp uvec4 gl_SubgroupEqMask;" @@ -5778,8 +5355,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp uvec4 gl_SubgroupGtMask;" "in highp uvec4 gl_SubgroupLeMask;" "in highp uvec4 gl_SubgroupLtMask;" + // GL_NV_shader_sm_builtins + "in highp uint gl_WarpsPerSMNV;" + "in highp uint gl_SMCountNV;" + "in highp uint gl_WarpIDNV;" + "in highp uint gl_SMIDNV;" "\n"; - const char* fragmentBallotDecls = + const char* fragmentSubgroupDecls = "flat in mediump uint gl_SubgroupSize;" "flat in mediump uint gl_SubgroupInvocationID;" "flat in highp uvec4 gl_SubgroupEqMask;" @@ -5787,18 +5369,134 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in highp uvec4 gl_SubgroupGtMask;" "flat in highp uvec4 gl_SubgroupLeMask;" "flat in highp uvec4 gl_SubgroupLtMask;" + // GL_NV_shader_sm_builtins + "flat in highp uint gl_WarpsPerSMNV;" + "flat in highp uint gl_SMCountNV;" + "flat in highp uint gl_WarpIDNV;" + "flat in highp uint gl_SMIDNV;" + "\n"; + const char* computeSubgroupDecls = + "in highp uint gl_NumSubgroups;" + "in highp uint gl_SubgroupID;" "\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); - stageBuiltins[EShLangCompute].append( - "highp in uint gl_NumSubgroups;" - "highp in uint gl_SubgroupID;" - "\n"); + stageBuiltins[EShLangVertex] .append(subgroupDecls); + stageBuiltins[EShLangTessControl] .append(subgroupDecls); + stageBuiltins[EShLangTessEvaluation].append(subgroupDecls); + stageBuiltins[EShLangGeometry] .append(subgroupDecls); + stageBuiltins[EShLangCompute] .append(subgroupDecls); + stageBuiltins[EShLangCompute] .append(computeSubgroupDecls); + stageBuiltins[EShLangFragment] .append(fragmentSubgroupDecls); + stageBuiltins[EShLangMeshNV] .append(subgroupDecls); + stageBuiltins[EShLangMeshNV] .append(computeSubgroupDecls); + stageBuiltins[EShLangTaskNV] .append(subgroupDecls); + stageBuiltins[EShLangTaskNV] .append(computeSubgroupDecls); + stageBuiltins[EShLangRayGenNV] .append(subgroupDecls); + stageBuiltins[EShLangIntersectNV] .append(subgroupDecls); + stageBuiltins[EShLangAnyHitNV] .append(subgroupDecls); + stageBuiltins[EShLangClosestHitNV] .append(subgroupDecls); + stageBuiltins[EShLangMissNV] .append(subgroupDecls); + stageBuiltins[EShLangCallableNV] .append(subgroupDecls); + } + + // 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); } if (version >= 300 /* both ES and non-ES */) { @@ -5807,6 +5505,30 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\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_SemanticsVolatile = 0x8000;\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"); + } +#endif + // printf("%s\n", commonBuiltins.c_str()); // printf("%s\n", stageBuiltins[EShLangFragment].c_str()); } @@ -5821,19 +5543,27 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // 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); // enumerate all the types - for (int image = 0; image <= 1; ++image) { // loop over "bool" image vs sampler - +#ifdef GLSLANG_WEB + const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint }; + bool skipBuffer = true; + bool skipCubeArrayed = true; + const int image = 0; +#else + const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 }; + bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); + bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); + for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler +#endif + { for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not - for (int ms = 0; ms <=1; ++ms) { +#ifdef GLSLANG_WEB + const int ms = 0; +#else + for (int ms = 0; ms <= 1; ++ms) // loop over "bool" multisample or not +#endif + { if ((ms || image) && shadow) continue; if (ms && profile != EEsProfile && version < 150) @@ -5844,7 +5574,16 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not - for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, 2D, ..., buffer +#ifdef GLSLANG_WEB + for (int dim = Esd2D; dim <= EsdCube; ++dim) { // 2D, 3D, and Cube +#else + for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, ..., buffer, subpass + if (dim == EsdSubpass && spvVersion.vulkan == 0) + continue; + if (dim == EsdSubpass && (image || shadow || arrayed)) + continue; + if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile) + continue; if (dim == EsdSubpass && spvVersion.vulkan == 0) continue; if (dim == EsdSubpass && (image || shadow || arrayed)) @@ -5853,43 +5592,41 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; if (dim != Esd2D && dim != EsdSubpass && ms) continue; - if ((dim == Esd3D || dim == EsdRect) && arrayed) - continue; - if (dim == Esd3D && shadow) - continue; - if (dim == EsdCube && arrayed && skipCubeArrayed) - continue; if (dim == EsdBuffer && skipBuffer) continue; if (dim == EsdBuffer && (shadow || arrayed || ms)) continue; if (ms && arrayed && profile == EEsProfile && version < 310) continue; -#ifdef AMD_EXTENSIONS - for (int bType = 0; bType < 4; ++bType) { // float, float16, int, uint results +#endif + if (dim == Esd3D && shadow) + continue; + if (dim == EsdCube && arrayed && skipCubeArrayed) + continue; + if ((dim == Esd3D || dim == EsdRect) && arrayed) + continue; - if (shadow && bType > 1) + // Loop over the bTypes + for (size_t bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) { +#ifndef GLSLANG_WEB + if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile || version < 450)) 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) + if (dim == EsdRect && version < 140 && bType > 0) continue; #endif - if (dim == EsdRect && version < 140 && bType > 0) + if (shadow && (bTypes[bType] == EbtInt || bTypes[bType] == EbtUint)) continue; // // Now, make all the function prototypes for the type we just built... // - TSampler sampler; +#ifndef GLSLANG_WEB if (dim == EsdSubpass) { sampler.setSubpass(bTypes[bType], ms ? true : false); - } else if (image) { + } else +#endif + if (image) { sampler.setImage(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, shadow ? true : false, ms ? true : false); @@ -5901,10 +5638,12 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c TString typeName = sampler.getString(); +#ifndef GLSLANG_WEB if (dim == EsdSubpass) { addSubpassSampling(sampler, typeName, version, profile); continue; } +#endif addQueryFunctions(sampler, typeName, version, profile); @@ -5912,18 +5651,23 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c addImageFunctions(sampler, typeName, version, profile); else { addSamplingFunctions(sampler, typeName, version, profile); +#ifndef GLSLANG_WEB 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); } +#endif } } } @@ -5935,7 +5679,6 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // // sparseTexelsResidentARB() // - if (profile != EEsProfile && version >= 450) { commonBuiltins.append("bool sparseTexelsResidentARB(int code);\n"); } @@ -5949,14 +5692,25 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { - if (sampler.image && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) - return; - // // textureSize() and imageSize() // int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); + +#ifdef GLSLANG_WEB + commonBuiltins.append("highp "); + commonBuiltins.append("ivec"); + commonBuiltins.append(postfixes[sizeDims]); + commonBuiltins.append(" textureSize("); + commonBuiltins.append(typeName); + commonBuiltins.append(",int);\n"); + return; +#endif + + if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 430))) + return; + if (profile == EEsProfile) commonBuiltins.append("highp "); if (sizeDims == 1) @@ -5965,12 +5719,12 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append("ivec"); commonBuiltins.append(postfixes[sizeDims]); } - if (sampler.image) + if (sampler.isImage()) commonBuiltins.append(" imageSize(readonly writeonly volatile coherent "); else commonBuiltins.append(" textureSize("); commonBuiltins.append(typeName); - if (! sampler.image && sampler.dim != EsdRect && sampler.dim != EsdBuffer && ! sampler.ms) + if (! sampler.isImage() && ! sampler.isRect() && ! sampler.isBuffer() && ! sampler.isMultiSample()) commonBuiltins.append(",int);\n"); else commonBuiltins.append(");\n"); @@ -5981,9 +5735,9 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // GL_ARB_shader_texture_image_samples // TODO: spec issue? there are no memory qualifiers; how to query a writeonly/readonly image, etc? - if (profile != EEsProfile && version >= 430 && sampler.ms) { + if (profile != EEsProfile && version >= 430 && sampler.isMultiSample()) { commonBuiltins.append("int "); - if (sampler.image) + if (sampler.isImage()) commonBuiltins.append("imageSamples(readonly writeonly volatile coherent "); else commonBuiltins.append("textureSamples("); @@ -5995,45 +5749,45 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int // textureQueryLod(), fragment stage only // - if (profile != EEsProfile && version >= 400 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { -#ifdef AMD_EXTENSIONS + if (profile != EEsProfile && version >= 400 && sampler.isCombined() && sampler.dim != EsdRect && + ! sampler.isMultiSample() && ! sampler.isBuffer()) { 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 + + stageBuiltins[EShLangCompute].append("vec2 textureQueryLod("); + stageBuiltins[EShLangCompute].append(typeName); + if (dimMap[sampler.dim] == 1) + stageBuiltins[EShLangCompute].append(", float"); + else { + stageBuiltins[EShLangCompute].append(", vec"); + stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]); + } + stageBuiltins[EShLangCompute].append(");\n"); } // // textureQueryLevels() // - if (profile != EEsProfile && version >= 430 && ! sampler.image && sampler.dim != EsdRect && ! sampler.ms && sampler.dim != EsdBuffer) { + if (profile != EEsProfile && version >= 430 && ! sampler.isImage() && sampler.dim != EsdRect && + ! sampler.isMultiSample() && ! sampler.isBuffer()) { commonBuiltins.append("int textureQueryLevels("); commonBuiltins.append(typeName); commonBuiltins.append(");\n"); @@ -6060,7 +5814,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int imageParams.append(", ivec"); imageParams.append(postfixes[dims]); } - if (sampler.ms) + if (sampler.isMultiSample()) imageParams.append(", int"); if (profile == EEsProfile) @@ -6076,7 +5830,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append("vec4);\n"); - if (sampler.dim != Esd1D && sampler.dim != EsdBuffer && profile != EEsProfile && version >= 450) { + if (! sampler.is1D() && ! sampler.isBuffer() && profile != EEsProfile && version >= 450) { commonBuiltins.append("int sparseImageLoadARB(readonly volatile coherent "); commonBuiltins.append(imageParams); commonBuiltins.append(", out "); @@ -6102,23 +5856,44 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int " 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 @@ -6132,8 +5907,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int } } -#ifdef AMD_EXTENSIONS - if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.ms) + if (sampler.dim == EsdRect || sampler.dim == EsdBuffer || sampler.shadow || sampler.isMultiSample()) return; if (profile == EEsProfile || version < 450) @@ -6159,7 +5933,7 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append(prefixes[sampler.type]); commonBuiltins.append("vec4);\n"); - if (sampler.dim != Esd1D) { + if (! sampler.is1D()) { commonBuiltins.append("int sparseImageLoadLodAMD(readonly volatile coherent "); commonBuiltins.append(imageLodParams); commonBuiltins.append(", out "); @@ -6167,7 +5941,6 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int commonBuiltins.append("vec4"); commonBuiltins.append(");\n"); } -#endif } // @@ -6182,7 +5955,7 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in stageBuiltins[EShLangFragment].append("vec4 subpassLoad"); stageBuiltins[EShLangFragment].append("("); stageBuiltins[EShLangFragment].append(typeName.c_str()); - if (sampler.ms) + if (sampler.isMultiSample()) stageBuiltins[EShLangFragment].append(", int"); stageBuiltins[EShLangFragment].append(");\n"); } @@ -6195,17 +5968,23 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in // void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#endif + // // texturing // 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.isBuffer() || sampler.arrayed || sampler.isMultiSample() + || !sampler.isCombined())) continue; for (int lod = 0; lod <= 1; ++lod) { - if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms)) + if (lod && (sampler.isBuffer() || sampler.isRect() || sampler.isMultiSample() || !sampler.isCombined())) continue; if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow) continue; @@ -6214,18 +5993,18 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, for (int bias = 0; bias <= 1; ++bias) { - if (bias && (lod || sampler.ms)) + if (bias && (lod || sampler.isMultiSample() || !sampler.isCombined())) continue; if (bias && (sampler.dim == Esd2D || sampler.dim == EsdCube) && sampler.shadow && sampler.arrayed) continue; - if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer)) + if (bias && (sampler.isRect() || sampler.isBuffer())) continue; for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not if (proj + offset + bias + lod > 3) continue; - if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms)) + if (offset && (sampler.dim == EsdCube || sampler.isBuffer() || sampler.isMultiSample())) continue; for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not @@ -6236,14 +6015,15 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; if (fetch && (sampler.shadow || sampler.dim == EsdCube)) continue; - if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer)) + if (fetch == 0 && (sampler.isMultiSample() || sampler.isBuffer() + || !sampler.isCombined())) 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.isMultiSample() || !sampler.isCombined())) continue; - if (grad && sampler.dim == EsdBuffer) + if (grad && sampler.isBuffer()) continue; if (proj + offset + fetch + grad + bias + lod > 3) continue; @@ -6263,31 +6043,46 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, if (extraProj && ! proj) continue; - if (extraProj && (sampler.dim == Esd3D || sampler.shadow)) + if (extraProj && (sampler.dim == Esd3D || sampler.shadow || !sampler.isCombined())) continue; -#ifdef AMD_EXTENSIONS - for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing + // loop over 16-bit floating-point texel addressing +#ifdef GLSLANG_WEB + const int f16TexAddr = 0; +#else + for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) +#endif + { if (f16TexAddr && sampler.type != EbtFloat16) continue; if (f16TexAddr && sampler.shadow && ! compare) { compare = true; // compare argument is always present totalDims--; } + // loop over "bool" lod clamp +#ifdef GLSLANG_WEB + const int lodClamp = 0; +#else + for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) #endif - for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) { // loop over "bool" lod clamp - + { if (lodClamp && (profile == EEsProfile || version < 450)) continue; if (lodClamp && (proj || lod || fetch)) continue; - for (int sparse = 0; sparse <= 1; ++sparse) { // loop over "bool" sparse or not - + // loop over "bool" sparse or not +#ifdef GLSLANG_WEB + const int sparse = 0; +#else + for (int sparse = 0; sparse <= 1; ++sparse) +#endif + { 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)) + // Sparse sampling is not for 1D/1D array texture, buffer texture, and + // projective texture + if (sparse && (sampler.is1D() || sampler.isBuffer() || proj)) continue; TString s; @@ -6297,14 +6092,10 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append("int "); else { 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 "); @@ -6342,7 +6133,6 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, // sampler type s.append(typeName); -#ifdef AMD_EXTENSIONS // P coordinate if (extraProj) { if (f16TexAddr) @@ -6360,31 +6150,15 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, s.append(postfixes[totalDims]); } } -#else - // P coordinate - if (extraProj) - s.append(",vec4"); - else { - 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]); - } - } -#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)) + if ((fetch && !sampler.isBuffer() && + !sampler.isRect() && !sampler.isMultiSample()) + || (sampler.isMultiSample() && fetch)) s.append(",int"); -#ifdef AMD_EXTENSIONS // non-optional lod if (lod) { if (f16TexAddr) @@ -6413,23 +6187,6 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, 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) @@ -6440,7 +6197,6 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, } } -#ifdef AMD_EXTENSIONS // lod clamp if (lodClamp) { if (f16TexAddr) @@ -6448,29 +6204,19 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, 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) @@ -6478,24 +6224,18 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, 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) + if (bias || lodClamp) { stageBuiltins[EShLangFragment].append(s); - else + stageBuiltins[EShLangCompute].append(s); + } else commonBuiltins.append(s); } } -#ifdef AMD_EXTENSIONS } -#endif } } } @@ -6513,6 +6253,11 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, // void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#endif + switch (sampler.dim) { case Esd2D: case EsdRect: @@ -6522,18 +6267,16 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in return; } - if (sampler.ms) + if (sampler.isMultiSample()) return; if (version < 140 && sampler.dim == EsdRect && sampler.type != EbtFloat) return; -#ifdef AMD_EXTENSIONS for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) { // loop over 16-bit floating-point texel addressing 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 for (int comp = 0; comp < 2; ++comp) { // loop over presence of comp argument @@ -6581,14 +6324,10 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in 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]); @@ -6616,14 +6355,11 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in s.append(");\n"); commonBuiltins.append(s); -#ifdef AMD_EXTENSIONS } -#endif } } } -#ifdef AMD_EXTENSIONS if (sampler.dim == EsdRect || sampler.shadow) return; @@ -6749,7 +6485,6 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in } } } -#endif } // @@ -6761,6 +6496,11 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in // void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language) { +#ifdef GLSLANG_WEB + version = 310; + profile = EEsProfile; +#endif + // // Initialize the context-dependent (resource-dependent) built-in strings for parsing. // @@ -6772,7 +6512,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf //============================================================================ TString& s = commonBuiltins; - const int maxSize = 80; + const int maxSize = 200; char builtInConstant[maxSize]; // @@ -6818,6 +6558,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } +#ifndef GLSLANG_WEB if (version >= 310) { // geometry @@ -6876,10 +6617,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf "in gl_PerVertex {" "highp vec4 gl_Position;" "highp float gl_PointSize;" -#ifdef NV_EXTENSIONS "highp vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "highp vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif "} gl_in[gl_MaxPatchVertices];" "\n"); } @@ -6888,6 +6627,14 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf } else { // non-ES profile + if (version > 400) { + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformVectors = %d;", resources.maxVertexUniformVectors); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors); + s.append(builtInConstant); + } + snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); s.append(builtInConstant); @@ -7066,10 +6813,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf if (profile != EEsProfile && version >= 450) s.append( "float gl_CullDistance[];" -#ifdef NV_EXTENSIONS "vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering "vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes -#endif ); s.append( "} gl_in[gl_MaxPatchVertices];" @@ -7103,8 +6848,29 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents); s.append(builtInConstant); } +#endif } + // compute + if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX, + resources.maxComputeWorkGroupCountY, + resources.maxComputeWorkGroupCountZ); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX, + resources.maxComputeWorkGroupSizeY, + resources.maxComputeWorkGroupSizeZ); + s.append(builtInConstant); + + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits); + s.append(builtInConstant); + + s.append("\n"); + } + +#ifndef GLSLANG_WEB // images (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 130)) { @@ -7120,6 +6886,18 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } + // compute + if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters); + s.append(builtInConstant); + snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers); + s.append(builtInConstant); + + s.append("\n"); + } + // atomic counters (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { @@ -7157,31 +6935,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } - // compute - if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { - snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupCount = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupCountX, - resources.maxComputeWorkGroupCountY, - resources.maxComputeWorkGroupCountZ); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const ivec3 gl_MaxComputeWorkGroupSize = ivec3(%d,%d,%d);", resources.maxComputeWorkGroupSizeX, - resources.maxComputeWorkGroupSizeY, - resources.maxComputeWorkGroupSizeZ); - s.append(builtInConstant); - - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeUniformComponents = %d;", resources.maxComputeUniformComponents); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeTextureImageUnits = %d;", resources.maxComputeTextureImageUnits); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeImageUniforms = %d;", resources.maxComputeImageUniforms); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounters = %d;", resources.maxComputeAtomicCounters); - s.append(builtInConstant); - snprintf(builtInConstant, maxSize, "const int gl_MaxComputeAtomicCounterBuffers = %d;", resources.maxComputeAtomicCounterBuffers); - s.append(builtInConstant); - - s.append("\n"); - } - // GL_ARB_cull_distance if (profile != EEsProfile && version >= 450) { snprintf(builtInConstant, maxSize, "const int gl_MaxCullDistances = %d;", resources.maxCullDistances); @@ -7197,11 +6950,27 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } -#ifdef AMD_EXTENSIONS - // GL_AMD_gcn_shader - if (profile != EEsProfile && version >= 450) { - snprintf(builtInConstant, maxSize, "const int gl_SIMDGroupSizeAMD = 64;"); + // 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 @@ -7224,11 +6993,12 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf 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; } // @@ -7244,7 +7014,7 @@ static void SpecialQualifier(const char* name, TStorageQualifier qualifier, TBui 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(); @@ -7261,7 +7031,7 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT 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(); @@ -7283,6 +7053,11 @@ static void BuiltInVariable(const char* blockName, const char* name, TBuiltInVar // void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) { +#ifdef GLSLANG_WEB + version = 310; + profile = EEsProfile; +#endif + // // Tag built-in variables and functions with additional qualifier and extension information // that cannot be declared with the text strings. @@ -7297,6 +7072,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion switch(language) { case EShLangVertex: + if (spvVersion.vulkan > 0) { + BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); + BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); + } + +#ifndef GLSLANG_WEB + if (spvVersion.vulkan == 0) { + SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); + SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); + } + if (profile != EEsProfile) { if (version >= 440) { symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); @@ -7323,19 +7109,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("readInvocationARB", 1, &E_GL_ARB_shader_ballot); symbolTable.setFunctionExtensions("readFirstInvocationARB", 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); - if (version >= 430) { symbolTable.setFunctionExtensions("anyInvocationARB", 1, &E_GL_ARB_shader_group_vote); symbolTable.setFunctionExtensions("allInvocationsARB", 1, &E_GL_ARB_shader_group_vote); @@ -7343,7 +7116,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } } -#ifdef AMD_EXTENSIONS + if (profile != EEsProfile) { symbolTable.setFunctionExtensions("minInvocationsAMD", 1, &E_GL_AMD_shader_ballot); symbolTable.setFunctionExtensions("maxInvocationsAMD", 1, &E_GL_AMD_shader_ballot); @@ -7377,6 +7150,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_SIMDGroupSizeAMD", 1, &E_GL_AMD_gcn_shader); + SpecialQualifier("gl_SIMDGroupSizeAMD", EvqVaryingIn, EbvSubGroupSize, symbolTable); + symbolTable.setFunctionExtensions("cubeFaceIndexAMD", 1, &E_GL_AMD_gcn_shader); symbolTable.setFunctionExtensions("cubeFaceCoordAMD", 1, &E_GL_AMD_gcn_shader); symbolTable.setFunctionExtensions("timeAMD", 1, &E_GL_AMD_gcn_shader); @@ -7386,8 +7162,21 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("fragmentMaskFetchAMD", 1, &E_GL_AMD_shader_fragment_mask); symbolTable.setFunctionExtensions("fragmentFetchAMD", 1, &E_GL_AMD_shader_fragment_mask); } -#endif + symbolTable.setFunctionExtensions("countLeadingZeros", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("countTrailingZeros", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("absoluteDifference", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("addSaturate", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("subtractSaturate", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("average", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("averageRounded", 1, &E_GL_INTEL_shader_integer_functions2); + symbolTable.setFunctionExtensions("multiply32x16", 1, &E_GL_INTEL_shader_integer_functions2); + + 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); // Compatibility variables, vertex only if (spvVersion.spv == 0) { BuiltInVariable("gl_Color", EbvColor, symbolTable); @@ -7428,16 +7217,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); } - if (spvVersion.vulkan == 0) { - SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); - SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); - } - - if (spvVersion.vulkan > 0) { - BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); - BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); - } - if (version >= 300 /* both ES and non-ES */) { symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs); BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable); @@ -7447,32 +7226,41 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); } - // Fall through 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 case EShLangTessEvaluation: case EShLangGeometry: +#endif SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); - SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable); BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable); - BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); - BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable); BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable); + +#ifndef GLSLANG_WEB + SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); + + BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable); + BuiltInVariable("gl_out", "gl_ClipDistance", EbvClipDistance, symbolTable); BuiltInVariable("gl_out", "gl_CullDistance", EbvCullDistance, symbolTable); @@ -7484,19 +7272,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_Layer", EbvLayer, symbolTable); BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable); -#ifdef NV_EXTENSIONS if (language != EShLangGeometry) { symbolTable.setVariableExtensions("gl_Layer", Num_viewportEXTs, viewportEXTs); symbolTable.setVariableExtensions("gl_ViewportIndex", Num_viewportEXTs, viewportEXTs); } -#else - if (language != EShLangGeometry && version >= 410) { - symbolTable.setVariableExtensions("gl_Layer", 1, &E_GL_ARB_shader_viewport_layer_array); - symbolTable.setVariableExtensions("gl_ViewportIndex", 1, &E_GL_ARB_shader_viewport_layer_array); - } -#endif - -#ifdef NV_EXTENSIONS symbolTable.setVariableExtensions("gl_ViewportMask", 1, &E_GL_NV_viewport_array2); symbolTable.setVariableExtensions("gl_SecondaryPositionNV", 1, &E_GL_NV_stereo_view_rendering); symbolTable.setVariableExtensions("gl_SecondaryViewportMaskNV", 1, &E_GL_NV_stereo_view_rendering); @@ -7509,16 +7288,24 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); BuiltInVariable("gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); - if (language != EShLangVertex) { + if (language == EShLangVertex || language == EShLangGeometry) { + 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); BuiltInVariable("gl_out", "gl_PositionPerViewNV", EbvPositionPerViewNV, symbolTable); BuiltInVariable("gl_out", "gl_ViewportMaskPerViewNV", EbvViewportMaskPerViewNV, symbolTable); -#endif BuiltInVariable("gl_PatchVerticesIn", EbvPatchVertices, symbolTable); BuiltInVariable("gl_TessLevelOuter", EbvTessLevelOuter, symbolTable); @@ -7556,15 +7343,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion // 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)) { @@ -7573,9 +7361,25 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); } - + + if (profile != EEsProfile) { + 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 (spvVersion.vulkan > 0) { + 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); @@ -7591,8 +7395,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubgroupGtMask", EbvSubgroupGtMask2, symbolTable); BuiltInVariable("gl_SubgroupLeMask", EbvSubgroupLeMask2, symbolTable); BuiltInVariable("gl_SubgroupLtMask", EbvSubgroupLtMask2, symbolTable); - } + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + } +#endif break; case EShLangFragment: @@ -7609,6 +7423,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } } SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable); +#ifndef GLSLANG_WEB SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable); SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable); @@ -7621,18 +7436,29 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_FragStencilRefARB", EbvFragStencilRef, symbolTable); } - if ((profile != EEsProfile && version >= 400) || + if ((profile != EEsProfile && version >= 130) || (profile == EEsProfile && version >= 310)) { - BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); - BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable); - BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable); - BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable); - if (profile == EEsProfile && version < 320) { - symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_SampleMaskIn", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_OES_sample_variables); - symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables); + BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable); + BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable); + BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable); + + if (profile != EEsProfile && version < 400) { + BuiltInVariable("gl_NumSamples", EbvSampleMask, symbolTable); + + symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_ARB_sample_shading); + symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_ARB_sample_shading); + symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_ARB_sample_shading); + symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_ARB_sample_shading); + } else { + BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable); + + if (profile == EEsProfile && version < 320) { + symbolTable.setVariableExtensions("gl_SampleID", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SamplePosition", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SampleMaskIn", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_SampleMask", 1, &E_GL_OES_sample_variables); + symbolTable.setVariableExtensions("gl_NumSamples", 1, &E_GL_OES_sample_variables); + } } } @@ -7763,7 +7589,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("textureGradOffsetClampARB", 1, &E_GL_ARB_sparse_texture_clamp); } -#ifdef AMD_EXTENSIONS // E_GL_AMD_shader_explicit_vertex_parameter if (profile != EEsProfile) { symbolTable.setVariableExtensions("gl_BaryCoordNoPerspAMD", 1, &E_GL_AMD_shader_explicit_vertex_parameter); @@ -7801,17 +7626,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("imageStoreLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); symbolTable.setFunctionExtensions("sparseImageLoadLodAMD", 1, &E_GL_AMD_shader_image_load_store_lod); } -#endif - -#ifdef NV_EXTENSIONS if (profile != EEsProfile && version >= 430) { symbolTable.setVariableExtensions("gl_FragFullyCoveredNV", 1, &E_GL_NV_conservative_raster_underestimation); BuiltInVariable("gl_FragFullyCoveredNV", EbvFragFullyCoveredNV, symbolTable); } -#endif + 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 >= 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); + symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock); + symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock); + + symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock); + symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock); + if (profile == EEsProfile && version < 320) { symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader); symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader); @@ -7862,7 +7708,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + 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); @@ -7933,8 +7780,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion 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); @@ -7957,14 +7802,46 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion 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 + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); } 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_SemanticsVolatile", 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); + } + + symbolTable.setFunctionExtensions("helperInvocationEXT", 1, &E_GL_EXT_demote_to_helper_invocation); +#endif break; case EShLangCompute: @@ -7974,6 +7851,15 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); + BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); + BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + +#ifndef GLSLANG_WEB + if ((profile != EEsProfile && version >= 140) || + (profile == EEsProfile && version >= 310)) { + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); + symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); + } if (profile != EEsProfile && version < 430) { symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_ARB_compute_shader); @@ -7999,6 +7885,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion 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); @@ -8023,8 +7911,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); } - // GL_ARB_shader_ballot - if (spvVersion.vulkan > 0) { + // 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); @@ -8040,18 +7929,21 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion 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); - BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); - symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); - BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + 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); @@ -8060,8 +7952,373 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic); } + + { + const char *coopExt[2] = { E_GL_NV_cooperative_matrix, E_GL_NV_integer_cooperative_matrix }; + symbolTable.setFunctionExtensions("coopMatLoadNV", 2, coopExt); + symbolTable.setFunctionExtensions("coopMatStoreNV", 2, coopExt); + symbolTable.setFunctionExtensions("coopMatMulAddNV", 2, coopExt); + } + + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + 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 break; +#ifndef GLSLANG_WEB + 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); + + // 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 + 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); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, 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); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + } + 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); + + // GL_NV_shader_sm_builtins + symbolTable.setVariableExtensions("gl_WarpsPerSMNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMCountNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_WarpIDNV", 1, &E_GL_NV_shader_sm_builtins); + symbolTable.setVariableExtensions("gl_SMIDNV", 1, &E_GL_NV_shader_sm_builtins); + BuiltInVariable("gl_WarpsPerSMNV", EbvWarpsPerSM, symbolTable); + BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); + BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); + BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + } + break; +#endif + default: assert(false && "Language not supported"); break; @@ -8073,74 +8330,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion // expected to be resolved through a library of functions, versus as // operations. // - symbolTable.relateToOperator("not", EOpVectorLogicalNot); - symbolTable.relateToOperator("matrixCompMult", EOpMul); - // 120 and 150 are correct for both ES and desktop - if (version >= 120) { - symbolTable.relateToOperator("outerProduct", EOpOuterProduct); - symbolTable.relateToOperator("transpose", EOpTranspose); - if (version >= 150) { - symbolTable.relateToOperator("determinant", EOpDeterminant); - symbolTable.relateToOperator("inverse", EOpMatrixInverse); - } - } + relateTabledBuiltins(version, profile, spvVersion, language, symbolTable); - symbolTable.relateToOperator("mod", EOpMod); - symbolTable.relateToOperator("modf", EOpModf); - - symbolTable.relateToOperator("equal", EOpVectorEqual); - symbolTable.relateToOperator("notEqual", EOpVectorNotEqual); - symbolTable.relateToOperator("lessThan", EOpLessThan); - symbolTable.relateToOperator("greaterThan", EOpGreaterThan); - symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual); - symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual); - - symbolTable.relateToOperator("radians", EOpRadians); - symbolTable.relateToOperator("degrees", EOpDegrees); - symbolTable.relateToOperator("sin", EOpSin); - symbolTable.relateToOperator("cos", EOpCos); - symbolTable.relateToOperator("tan", EOpTan); - symbolTable.relateToOperator("asin", EOpAsin); - symbolTable.relateToOperator("acos", EOpAcos); - symbolTable.relateToOperator("atan", EOpAtan); - symbolTable.relateToOperator("sinh", EOpSinh); - symbolTable.relateToOperator("cosh", EOpCosh); - symbolTable.relateToOperator("tanh", EOpTanh); - symbolTable.relateToOperator("asinh", EOpAsinh); - symbolTable.relateToOperator("acosh", EOpAcosh); - symbolTable.relateToOperator("atanh", EOpAtanh); - - symbolTable.relateToOperator("pow", EOpPow); - symbolTable.relateToOperator("exp2", EOpExp2); - symbolTable.relateToOperator("log", EOpLog); - symbolTable.relateToOperator("exp", EOpExp); - symbolTable.relateToOperator("log2", EOpLog2); - symbolTable.relateToOperator("sqrt", EOpSqrt); - symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt); - - symbolTable.relateToOperator("abs", EOpAbs); - symbolTable.relateToOperator("sign", EOpSign); - symbolTable.relateToOperator("floor", EOpFloor); - symbolTable.relateToOperator("trunc", EOpTrunc); - symbolTable.relateToOperator("round", EOpRound); - symbolTable.relateToOperator("roundEven", EOpRoundEven); - symbolTable.relateToOperator("ceil", EOpCeil); - symbolTable.relateToOperator("fract", EOpFract); - symbolTable.relateToOperator("min", EOpMin); - symbolTable.relateToOperator("max", EOpMax); - symbolTable.relateToOperator("clamp", EOpClamp); - symbolTable.relateToOperator("mix", EOpMix); - symbolTable.relateToOperator("step", EOpStep); - symbolTable.relateToOperator("smoothstep", EOpSmoothStep); - - symbolTable.relateToOperator("isnan", EOpIsNan); - symbolTable.relateToOperator("isinf", EOpIsInf); - - symbolTable.relateToOperator("floatBitsToInt", EOpFloatBitsToInt); - symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint); - symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat); - symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat); +#ifndef GLSLANG_WEB symbolTable.relateToOperator("doubleBitsToInt64", EOpDoubleBitsToInt64); symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64); symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble); @@ -8155,11 +8348,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("int16BitsToHalf", EOpInt16BitsToFloat16); symbolTable.relateToOperator("uint16BitsToHalf", EOpUint16BitsToFloat16); - symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16); - symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16); - symbolTable.relateToOperator("packUnorm2x16", EOpPackUnorm2x16); - symbolTable.relateToOperator("unpackUnorm2x16", EOpUnpackUnorm2x16); - symbolTable.relateToOperator("packSnorm4x8", EOpPackSnorm4x8); symbolTable.relateToOperator("unpackSnorm4x8", EOpUnpackSnorm4x8); symbolTable.relateToOperator("packUnorm4x8", EOpPackUnorm4x8); @@ -8168,9 +8356,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("packDouble2x32", EOpPackDouble2x32); symbolTable.relateToOperator("unpackDouble2x32", EOpUnpackDouble2x32); - symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16); - symbolTable.relateToOperator("unpackHalf2x16", EOpUnpackHalf2x16); - symbolTable.relateToOperator("packInt2x32", EOpPackInt2x32); symbolTable.relateToOperator("unpackInt2x32", EOpUnpackInt2x32); symbolTable.relateToOperator("packUint2x32", EOpPackUint2x32); @@ -8196,37 +8381,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("unpack16", EOpUnpack16); symbolTable.relateToOperator("unpack8", EOpUnpack8); - symbolTable.relateToOperator("length", EOpLength); - symbolTable.relateToOperator("distance", EOpDistance); - symbolTable.relateToOperator("dot", EOpDot); - symbolTable.relateToOperator("cross", EOpCross); - symbolTable.relateToOperator("normalize", EOpNormalize); - symbolTable.relateToOperator("faceforward", EOpFaceForward); - symbolTable.relateToOperator("reflect", EOpReflect); - symbolTable.relateToOperator("refract", EOpRefract); - - symbolTable.relateToOperator("any", EOpAny); - symbolTable.relateToOperator("all", EOpAll); - - symbolTable.relateToOperator("barrier", EOpBarrier); - symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier); + symbolTable.relateToOperator("controlBarrier", EOpBarrier); symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter); - symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer); symbolTable.relateToOperator("memoryBarrierImage", EOpMemoryBarrierImage); - symbolTable.relateToOperator("atomicAdd", EOpAtomicAdd); - symbolTable.relateToOperator("atomicMin", EOpAtomicMin); - symbolTable.relateToOperator("atomicMax", EOpAtomicMax); - symbolTable.relateToOperator("atomicAnd", EOpAtomicAnd); - symbolTable.relateToOperator("atomicOr", EOpAtomicOr); - 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); symbolTable.relateToOperator("atomicCounter", EOpAtomicCounter); + symbolTable.relateToOperator("clockARB", EOpReadClockSubgroupKHR); + symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR); + + symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR); + symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR); + if (profile != EEsProfile && version >= 460) { symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd); symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract); @@ -8253,6 +8424,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("findLSB", EOpFindLSB); symbolTable.relateToOperator("findMSB", EOpFindMSB); + symbolTable.relateToOperator("helperInvocationEXT", EOpIsHelperInvocation); + + symbolTable.relateToOperator("countLeadingZeros", EOpCountLeadingZeros); + symbolTable.relateToOperator("countTrailingZeros", EOpCountTrailingZeros); + symbolTable.relateToOperator("absoluteDifference", EOpAbsDifference); + symbolTable.relateToOperator("addSaturate", EOpAddSaturate); + symbolTable.relateToOperator("subtractSaturate", EOpSubSaturate); + symbolTable.relateToOperator("average", EOpAverage); + symbolTable.relateToOperator("averageRounded", EOpAverageRounded); + symbolTable.relateToOperator("multiply32x16", EOpMul32x16); + if (PureOperatorBuiltins) { symbolTable.relateToOperator("imageSize", EOpImageQuerySize); symbolTable.relateToOperator("imageSamples", EOpImageQuerySamples); @@ -8266,28 +8448,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion 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); - symbolTable.relateToOperator("textureSize", EOpTextureQuerySize); - symbolTable.relateToOperator("textureQueryLod", EOpTextureQueryLod); - symbolTable.relateToOperator("textureQueryLevels", EOpTextureQueryLevels); - symbolTable.relateToOperator("textureSamples", EOpTextureQuerySamples); - symbolTable.relateToOperator("texture", EOpTexture); - symbolTable.relateToOperator("textureProj", EOpTextureProj); - symbolTable.relateToOperator("textureLod", EOpTextureLod); - symbolTable.relateToOperator("textureOffset", EOpTextureOffset); - symbolTable.relateToOperator("texelFetch", EOpTextureFetch); - symbolTable.relateToOperator("texelFetchOffset", EOpTextureFetchOffset); - symbolTable.relateToOperator("textureProjOffset", EOpTextureProjOffset); - symbolTable.relateToOperator("textureLodOffset", EOpTextureLodOffset); - symbolTable.relateToOperator("textureProjLod", EOpTextureProjLod); - symbolTable.relateToOperator("textureProjLodOffset", EOpTextureProjLodOffset); - symbolTable.relateToOperator("textureGrad", EOpTextureGrad); - symbolTable.relateToOperator("textureGradOffset", EOpTextureGradOffset); - symbolTable.relateToOperator("textureProjGrad", EOpTextureProjGrad); - symbolTable.relateToOperator("textureProjGradOffset", EOpTextureProjGradOffset); symbolTable.relateToOperator("textureGather", EOpTextureGather); symbolTable.relateToOperator("textureGatherOffset", EOpTextureGatherOffset); symbolTable.relateToOperator("textureGatherOffsets", EOpTextureGatherOffsets); @@ -8297,9 +8463,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("noise3", EOpNoise); symbolTable.relateToOperator("noise4", EOpNoise); + symbolTable.relateToOperator("textureFootprintNV", EOpImageSampleFootprintNV); + symbolTable.relateToOperator("textureFootprintClampNV", EOpImageSampleFootprintClampNV); + symbolTable.relateToOperator("textureFootprintLodNV", EOpImageSampleFootprintLodNV); + symbolTable.relateToOperator("textureFootprintGradNV", EOpImageSampleFootprintGradNV); + symbolTable.relateToOperator("textureFootprintGradClampNV", EOpImageSampleFootprintGradClampNV); + + if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) + symbolTable.relateToOperator("ftransform", EOpFtransform); + if (spvVersion.spv == 0 && (IncludeLegacy(version, profile, spvVersion) || (profile == EEsProfile && version == 100))) { - symbolTable.relateToOperator("ftransform", EOpFtransform); symbolTable.relateToOperator("texture1D", EOpTexture); symbolTable.relateToOperator("texture1DGradARB", EOpTextureGrad); @@ -8391,7 +8565,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("allInvocations", EOpAllInvocations); symbolTable.relateToOperator("allInvocationsEqual", EOpAllInvocationsEqual); } -#ifdef AMD_EXTENSIONS symbolTable.relateToOperator("minInvocationsAMD", EOpMinInvocations); symbolTable.relateToOperator("maxInvocationsAMD", EOpMaxInvocations); symbolTable.relateToOperator("addInvocationsAMD", EOpAddInvocations); @@ -8436,11 +8609,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("fragmentMaskFetchAMD", EOpFragmentMaskFetch); symbolTable.relateToOperator("fragmentFetchAMD", EOpFragmentFetch); -#endif } // GL_KHR_shader_subgroup - if (spvVersion.vulkan > 0) { + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { symbolTable.relateToOperator("subgroupBarrier", EOpSubgroupBarrier); symbolTable.relateToOperator("subgroupMemoryBarrier", EOpSubgroupMemoryBarrier); symbolTable.relateToOperator("subgroupMemoryBarrierBuffer", EOpSubgroupMemoryBarrierBuffer); @@ -8496,7 +8669,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("subgroupQuadSwapVertical", EOpSubgroupQuadSwapVertical); symbolTable.relateToOperator("subgroupQuadSwapDiagonal", EOpSubgroupQuadSwapDiagonal); -#ifdef NV_EXTENSIONS symbolTable.relateToOperator("subgroupPartitionNV", EOpSubgroupPartition); symbolTable.relateToOperator("subgroupPartitionedAddNV", EOpSubgroupPartitionedAdd); symbolTable.relateToOperator("subgroupPartitionedMulNV", EOpSubgroupPartitionedMul); @@ -8519,7 +8691,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("subgroupPartitionedExclusiveAndNV", EOpSubgroupPartitionedExclusiveAnd); symbolTable.relateToOperator("subgroupPartitionedExclusiveOrNV", EOpSubgroupPartitionedExclusiveOr); symbolTable.relateToOperator("subgroupPartitionedExclusiveXorNV", EOpSubgroupPartitionedExclusiveXor); -#endif } if (profile == EEsProfile) { @@ -8544,9 +8715,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion break; case EShLangFragment: - symbolTable.relateToOperator("dFdx", EOpDPdx); - symbolTable.relateToOperator("dFdy", EOpDPdy); - symbolTable.relateToOperator("fwidth", EOpFwidth); if (profile != EEsProfile && version >= 400) { symbolTable.relateToOperator("dFdxFine", EOpDPdxFine); symbolTable.relateToOperator("dFdyFine", EOpDPdyFine); @@ -8559,21 +8727,73 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("interpolateAtSample", EOpInterpolateAtSample); symbolTable.relateToOperator("interpolateAtOffset", EOpInterpolateAtOffset); -#ifdef AMD_EXTENSIONS if (profile != EEsProfile) symbolTable.relateToOperator("interpolateAtVertexAMD", EOpInterpolateAtVertex); -#endif + + symbolTable.relateToOperator("beginInvocationInterlockARB", EOpBeginInvocationInterlock); + symbolTable.relateToOperator("endInvocationInterlockARB", EOpEndInvocationInterlock); + break; case EShLangCompute: - symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); - symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); + 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); + } + symbolTable.relateToOperator("coopMatLoadNV", EOpCooperativeMatrixLoad); + symbolTable.relateToOperator("coopMatStoreNV", EOpCooperativeMatrixStore); + symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAdd); + break; + + 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); + symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); + } break; default: assert(false && "Language not supported"); } +#endif } // @@ -8587,6 +8807,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion // void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) { +#ifndef GLSLANG_WEB if (profile != EEsProfile && version >= 430 && version < 440) { symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts); symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts); @@ -8631,11 +8852,24 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable); BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable); BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable); + + 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); + + // extension requirements + if (profile == EEsProfile) { + symbolTable.setVariableExtensions("gl_in", "gl_PointSize", Num_AEP_tessellation_point_size, AEP_tessellation_point_size); + } + break; default: break; } +#endif } } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/Initialize.h b/Externals/glslang/glslang/MachineIndependent/Initialize.h index b5de324233..ac8ec33e99 100644 --- a/Externals/glslang/glslang/MachineIndependent/Initialize.h +++ b/Externals/glslang/glslang/MachineIndependent/Initialize.h @@ -91,6 +91,8 @@ public: void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources); protected: + void addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion); + void relateTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage, TSymbolTable&); void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion); void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile); void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile); diff --git a/Externals/glslang/glslang/MachineIndependent/Intermediate.cpp b/Externals/glslang/glslang/MachineIndependent/Intermediate.cpp old mode 100644 new mode 100755 index de722179c7..d0f86e6389 --- a/Externals/glslang/glslang/MachineIndependent/Intermediate.cpp +++ b/Externals/glslang/glslang/MachineIndependent/Intermediate.cpp @@ -1,7 +1,7 @@ // // 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. @@ -119,6 +119,62 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) return nullptr; + // 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->isReference() && left->getType().getReferentType()->containsUnsizedArray()) || + (right->isReference() && right->getType().getReferentType()->containsUnsizedArray())) { + return nullptr; + } + + if (left->isReference() && 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->isReference() && 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->isReference() && right->isReference()) { + 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->isReference() || right->isReference()) { + return nullptr; + } + } + // Try converting the children's base types to compatible types. auto children = addConversion(op, left, right); left = std::get<0>(children); @@ -160,7 +216,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn node->getWritableType().getQualifier().makeSpecConstant(); // If must propagate nonuniform, make a nonuniform. - if ((node->getLeft()->getQualifier().nonUniform || node->getRight()->getQualifier().nonUniform) && + if ((node->getLeft()->getQualifier().isNonUniform() || node->getRight()->getQualifier().isNonUniform()) && isNonuniformPropagating(node->getOp())) node->getWritableType().getQualifier().nonUniform = true; @@ -231,6 +287,26 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm 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->isReference() && + 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. @@ -283,7 +359,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo switch (op) { case EOpLogicalNot: - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { break; // HLSL can promote logical not } @@ -307,18 +383,20 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo // 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; case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; + case EOpConstructInt: newType = EbtInt; break; + case EOpConstructUint: newType = EbtUint; break; +#ifndef GLSLANG_WEB + case EOpConstructInt8: newType = EbtInt8; break; + case EOpConstructUint8: newType = EbtUint8; break; + case EOpConstructInt16: newType = EbtInt16; break; + case EOpConstructUint16: newType = EbtUint16; break; + case EOpConstructInt64: newType = EbtInt64; break; + case EOpConstructUint64: newType = EbtUint64; break; case EOpConstructDouble: newType = EbtDouble; break; case EOpConstructFloat16: newType = EbtFloat16; break; +#endif default: break; // some compilers want this } @@ -373,7 +451,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo node->getWritableType().getQualifier().makeSpecConstant(); // If must propagate nonuniform, make a nonuniform. - if (node->getOperand()->getQualifier().nonUniform && isNonuniformPropagating(node->getOp())) + if (node->getOperand()->getQualifier().isNonUniform() && isNonuniformPropagating(node->getOp())) node->getWritableType().getQualifier().nonUniform = true; return node; @@ -410,7 +488,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOper // // 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. // @@ -460,12 +538,13 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const return false; case EbtAtomicUint: case EbtSampler: + case EbtAccStructNV: // opaque types can be passed to functions if (op == EOpFunction) break; // HLSL can assign samplers directly (no constructor) - if (source == EShSourceHlsl && node->getBasicType() == EbtSampler) + if (getSource() == EShSourceHlsl && node->getBasicType() == EbtSampler) break; // samplers can get assigned via a sampler constructor @@ -483,55 +562,50 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const 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. -TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped* node) const +bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const { - // - // Add a new newNode for the conversion. - // - TIntermUnary* newNode = nullptr; - - TOperator newOp = EOpNull; - - switch (convertTo) { + switch (dst) { +#ifndef GLSLANG_WEB case EbtDouble: - switch (node->getBasicType()) { + switch (src) { + case EbtUint: newOp = EOpConvUintToDouble; break; + case EbtBool: newOp = EOpConvBoolToDouble; break; + case EbtFloat: newOp = EOpConvFloatToDouble; break; + case EbtInt: newOp = EOpConvIntToDouble; break; 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; case EbtInt64: newOp = EOpConvInt64ToDouble; break; case EbtUint64: newOp = EOpConvUint64ToDouble; break; default: - return nullptr; + return false; } break; +#endif case EbtFloat: - switch (node->getBasicType()) { + switch (src) { + case EbtInt: newOp = EOpConvIntToFloat; break; + case EbtUint: newOp = EOpConvUintToFloat; break; + case EbtBool: newOp = EOpConvBoolToFloat; break; +#ifndef GLSLANG_WEB + case EbtDouble: newOp = EOpConvDoubleToFloat; break; 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; case EbtInt64: newOp = EOpConvInt64ToFloat; break; case EbtUint64: newOp = EOpConvUint64ToFloat; break; +#endif default: - return nullptr; + return false; } break; +#ifndef GLSLANG_WEB case EbtFloat16: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToFloat16; break; case EbtUint8: newOp = EOpConvUint8ToFloat16; break; case EbtInt16: newOp = EOpConvInt16ToFloat16; break; @@ -544,28 +618,32 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtInt64: newOp = EOpConvInt64ToFloat16; break; case EbtUint64: newOp = EOpConvUint64ToFloat16; break; default: - return nullptr; + return false; } break; +#endif case EbtBool: - switch (node->getBasicType()) { + switch (src) { + case EbtInt: newOp = EOpConvIntToBool; break; + case EbtUint: newOp = EOpConvUintToBool; break; + case EbtFloat: newOp = EOpConvFloatToBool; break; +#ifndef GLSLANG_WEB + case EbtDouble: newOp = EOpConvDoubleToBool; break; 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; case EbtInt64: newOp = EOpConvInt64ToBool; break; case EbtUint64: newOp = EOpConvUint64ToBool; break; +#endif default: - return nullptr; + return false; } break; +#ifndef GLSLANG_WEB case EbtInt8: - switch (node->getBasicType()) { + switch (src) { case EbtUint8: newOp = EOpConvUint8ToInt8; break; case EbtInt16: newOp = EOpConvInt16ToInt8; break; case EbtUint16: newOp = EOpConvUint16ToInt8; break; @@ -578,11 +656,11 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToInt8; break; case EbtFloat16: newOp = EOpConvFloat16ToInt8; break; default: - return nullptr; + return false; } break; case EbtUint8: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToUint8; break; case EbtInt16: newOp = EOpConvInt16ToUint8; break; case EbtUint16: newOp = EOpConvUint16ToUint8; break; @@ -595,12 +673,12 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToUint8; break; case EbtFloat16: newOp = EOpConvFloat16ToUint8; break; default: - return nullptr; + return false; } break; case EbtInt16: - switch (node->getBasicType()) { + switch (src) { case EbtUint8: newOp = EOpConvUint8ToInt16; break; case EbtInt8: newOp = EOpConvInt8ToInt16; break; case EbtUint16: newOp = EOpConvUint16ToInt16; break; @@ -613,11 +691,11 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToInt16; break; case EbtFloat16: newOp = EOpConvFloat16ToInt16; break; default: - return nullptr; + return false; } break; case EbtUint16: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToUint16; break; case EbtUint8: newOp = EOpConvUint8ToUint16; break; case EbtInt16: newOp = EOpConvInt16ToUint16; break; @@ -630,46 +708,52 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtDouble: newOp = EOpConvDoubleToUint16; break; case EbtFloat16: newOp = EOpConvFloat16ToUint16; break; default: - return nullptr; + return false; } break; +#endif case EbtInt: - switch (node->getBasicType()) { + switch (src) { + case EbtUint: newOp = EOpConvUintToInt; break; + case EbtBool: newOp = EOpConvBoolToInt; break; + case EbtFloat: newOp = EOpConvFloatToInt; break; +#ifndef GLSLANG_WEB 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; +#endif default: - return nullptr; + return false; } break; case EbtUint: - switch (node->getBasicType()) { + switch (src) { + case EbtInt: newOp = EOpConvIntToUint; break; + case EbtBool: newOp = EOpConvBoolToUint; break; + case EbtFloat: newOp = EOpConvFloatToUint; break; +#ifndef GLSLANG_WEB 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; +#endif default: - return nullptr; + return false; } break; +#ifndef GLSLANG_WEB case EbtInt64: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToInt64; break; case EbtUint8: newOp = EOpConvUint8ToInt64; break; case EbtInt16: newOp = EOpConvInt16ToInt64; break; @@ -682,11 +766,11 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtFloat16: newOp = EOpConvFloat16ToInt64; break; case EbtUint64: newOp = EOpConvUint64ToInt64; break; default: - return nullptr; + return false; } break; case EbtUint64: - switch (node->getBasicType()) { + switch (src) { case EbtInt8: newOp = EOpConvInt8ToUint64; break; case EbtUint8: newOp = EOpConvUint8ToUint64; break; case EbtInt16: newOp = EOpConvInt16ToUint64; break; @@ -699,17 +783,84 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped case EbtFloat16: newOp = EOpConvFloat16ToUint64; break; case EbtInt64: newOp = EOpConvInt64ToUint64; break; default: - return nullptr; + return false; } break; +#endif default: + return false; + } + 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 +{ + // + // Add a new newNode for the conversion. + // + +#ifndef GLSLANG_WEB + bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 || + convertTo == EbtInt16 || convertTo == EbtUint16 || + convertTo == EbtInt || convertTo == EbtUint || + convertTo == EbtInt64 || convertTo == EbtUint64); + + 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); + + bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble); + + bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 || + node->getBasicType() == EbtFloat || + node->getBasicType() == EbtDouble); + + if (! getArithemeticInt8Enabled()) { + if (((convertTo == EbtInt8 || convertTo == EbtUint8) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt8 || node->getBasicType() == EbtUint8) && ! convertToIntTypes)) + return nullptr; + } + + if (! getArithemeticInt16Enabled()) { + if (((convertTo == EbtInt16 || convertTo == EbtUint16) && ! convertFromIntTypes) || + ((node->getBasicType() == EbtInt16 || node->getBasicType() == EbtUint16) && ! convertToIntTypes)) + return nullptr; + } + + if (! getArithemeticFloat16Enabled()) { + if ((convertTo == EbtFloat16 && ! convertFromFloatTypes) || + (node->getBasicType() == EbtFloat16 && ! convertToFloatTypes)) + return nullptr; + } +#endif + + TIntermUnary* newNode = nullptr; + TOperator newOp = EOpNull; + if (!buildConvertOp(convertTo, node->getBasicType(), newOp)) { return nullptr; } 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()) { +#ifndef GLSLANG_WEB + // 8/16-bit storage extensions don't support 8/16-bit constants, so don't fold conversions + // to those types + if ((getArithemeticInt8Enabled() || !(convertTo == EbtInt8 || convertTo == EbtUint8)) && + (getArithemeticInt16Enabled() || !(convertTo == EbtInt16 || convertTo == EbtUint16)) && + (getArithemeticFloat16Enabled() || !(convertTo == EbtFloat16))) +#endif + { + TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType); + if (folded) + return folded; + } + } // Propagate specialization-constant-ness, if allowed if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode)) @@ -718,6 +869,11 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped 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 @@ -731,7 +887,7 @@ TIntermUnary* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped // Returns the converted pair of nodes. // Returns when there is no conversion. std::tuple -TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) const +TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) { if (!isConversionAllowed(op, node0) || !isConversionAllowed(op, node1)) return std::make_tuple(nullptr, nullptr); @@ -744,6 +900,10 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no // 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); @@ -789,7 +949,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no case EOpLogicalAnd: case EOpLogicalOr: case EOpLogicalXor: - if (source == EShSourceHlsl) + if (getSource() == EShSourceHlsl) promoteTo = std::make_tuple(EbtBool, EbtBool); else return std::make_tuple(node0, node1); @@ -800,7 +960,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no // HLSL can promote bools to ints to make this work. case EOpLeftShift: case EOpRightShift: - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { TBasicType node0BasicType = node0->getBasicType(); if (node0BasicType == EbtBool) node0BasicType = EbtInt; @@ -860,7 +1020,7 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no // // Return nullptr if a conversion can't be done. // -TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const +TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) { if (!isConversionAllowed(op, node)) return nullptr; @@ -881,6 +1041,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt // 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) { // @@ -892,36 +1055,48 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpConstructFloat: promoteTo = EbtFloat; break; - case EOpConstructDouble: - promoteTo = EbtDouble; - break; - case EOpConstructFloat16: - promoteTo = EbtFloat16; - break; - case EOpConstructInt8: - promoteTo = EbtInt8; - break; - case EOpConstructUint8: - promoteTo = EbtUint8; - break; - case EOpConstructInt16: - promoteTo = EbtInt16; - break; - case EOpConstructUint16: - promoteTo = EbtUint16; - break; case EOpConstructInt: promoteTo = EbtInt; break; case EOpConstructUint: promoteTo = EbtUint; break; +#ifndef GLSLANG_WEB + 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 EOpConstructInt64: promoteTo = EbtInt64; break; case EOpConstructUint64: promoteTo = EbtUint64; break; +#endif case EOpLogicalNot: @@ -954,6 +1129,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpLit: case EOpMax: case EOpMin: + case EOpMod: case EOpModf: case EOpPow: case EOpReflect: @@ -963,6 +1139,15 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpSequence: case EOpConstructStruct: + case EOpConstructCooperativeMatrix: + + if (type.isReference() || node->getType().isReference()) { + // types must match to assign a reference + if (type == node->getType()) + return node; + else + return nullptr; + } if (type.getBasicType() == node->getType().getBasicType()) return node; @@ -970,7 +1155,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt if (canImplicitlyPromote(node->getBasicType(), type.getBasicType(), op)) promoteTo = type.getBasicType(); else - return nullptr; + return nullptr; break; // For GLSL, there are no conversions needed; the shift amount just needs to be an @@ -979,7 +1164,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpLeftShiftAssign: case EOpRightShiftAssign: { - if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) + if (getSource() == EShSourceHlsl && node->getType().getBasicType() == EbtBool) promoteTo = type.getBasicType(); else { if (isTypeInt(type.getBasicType()) && isTypeInt(node->getBasicType())) @@ -999,13 +1184,13 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt return nullptr; } - if (node->getAsConstantUnion()) + if (canPromoteConstant && node->getAsConstantUnion()) return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); // // Add a new newNode for the conversion. // - TIntermUnary* newNode = createConversion(promoteTo, node); + TIntermTyped* newNode = createConversion(promoteTo, node); return newNode; } @@ -1025,7 +1210,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node) { // some source languages don't do this - switch (source) { + switch (getSource()) { case EShSourceHlsl: break; case EShSourceGlsl: @@ -1078,7 +1263,7 @@ TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& ty void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode) { // some source languages don't do this - switch (source) { + switch (getSource()) { case EShSourceHlsl: break; case EShSourceGlsl: @@ -1103,9 +1288,12 @@ void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, T 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. @@ -1178,9 +1366,19 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* // 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()) { + if (getSource() == EShSourceHlsl) { + // 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 @@ -1188,7 +1386,7 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* // 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); @@ -1196,12 +1394,44 @@ TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* 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()); } + + // 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 @@ -1249,7 +1479,31 @@ bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const { +#ifdef GLSLANG_WEB + return false; +#endif + switch (from) { + case EbtInt: + switch(to) { + case EbtUint: + return version >= 400 || getSource() == EShSourceHlsl; + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; + case EbtUint: + switch(to) { + case EbtInt64: + case EbtUint64: + return true; + default: + break; + } + break; case EbtInt8: switch (to) { case EbtUint8: @@ -1296,26 +1550,6 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const 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; @@ -1329,6 +1563,10 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const { +#ifdef GLSLANG_WEB + return false; +#endif + if (to == EbtFloat && from == EbtFloat16) { return true; } else { @@ -1339,6 +1577,17 @@ bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const { switch (from) { + case EbtInt: + case EbtUint: + switch(to) { + case EbtFloat: + case EbtDouble: + return true; + default: + break; + } + break; +#ifndef GLSLANG_WEB case EbtInt8: case EbtUint8: case EbtInt16: @@ -1352,23 +1601,13 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const 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; - +#endif default: break; } @@ -1381,7 +1620,7 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const // bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const { - if (profile == EEsProfile || version == 110) + if (isEsProfile() || version == 110) return false; if (from == to) @@ -1389,7 +1628,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat // TODO: Move more policies into language-specific handlers. // Some languages allow more general (or potentially, more specific) conversions under some conditions. - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool); const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool); @@ -1420,14 +1659,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat } } - bool explicitTypesEnabled = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int8) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int16) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int32) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int64) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float16) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float32) || - extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float64); + 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 @@ -1456,7 +1695,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat } // hlsl supported conversions - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat)) return true; } @@ -1468,16 +1707,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtUint: case EbtInt64: case EbtUint64: -#ifdef AMD_EXTENSIONS + case EbtFloat: + case EbtDouble: + return true; case EbtInt16: case EbtUint16: -#endif - case EbtFloat: - case EbtDouble: -#ifdef AMD_EXTENSIONS - case EbtFloat16: -#endif - return true; + return extensionRequested(E_GL_AMD_gpu_shader_int16); + case EbtFloat16: + return extensionRequested(E_GL_AMD_gpu_shader_half_float); default: return false; } @@ -1485,44 +1722,42 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat switch (from) { case EbtInt: case EbtUint: -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: -#endif case EbtFloat: -#ifdef AMD_EXTENSIONS - case EbtFloat16: -#endif return true; case EbtBool: - return (source == EShSourceHlsl); + return getSource() == EShSourceHlsl; + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); + case EbtFloat16: + return + extensionRequested(E_GL_AMD_gpu_shader_half_float) || + getSource() == EShSourceHlsl; default: return false; } case EbtUint: switch (from) { case EbtInt: - return version >= 400 || (source == EShSourceHlsl); + return version >= 400 || getSource() == EShSourceHlsl; case EbtUint: -#ifdef AMD_EXTENSIONS - case EbtInt16: - case EbtUint16: -#endif return true; case EbtBool: - return (source == EShSourceHlsl); + return getSource() == EShSourceHlsl; + case EbtInt16: + case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); default: return false; } case EbtInt: switch (from) { case EbtInt: -#ifdef AMD_EXTENSIONS - case EbtInt16: -#endif return true; case EbtBool: - return (source == EShSourceHlsl); + return getSource() == EShSourceHlsl; + case EbtInt16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); default: return false; } @@ -1532,11 +1767,10 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtUint: case EbtInt64: case EbtUint64: -#ifdef AMD_EXTENSIONS + return true; case EbtInt16: case EbtUint16: -#endif - return true; + return extensionRequested(E_GL_AMD_gpu_shader_int16); default: return false; } @@ -1544,32 +1778,32 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat switch (from) { case EbtInt: case EbtInt64: -#ifdef AMD_EXTENSIONS - case EbtInt16: -#endif return true; + case EbtInt16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); default: return false; } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch (from) { case EbtInt16: case EbtUint16: + return extensionRequested(E_GL_AMD_gpu_shader_int16); case EbtFloat16: - return true; + return extensionRequested(E_GL_AMD_gpu_shader_half_float); default: - return false; - } + break; + } + return false; case EbtUint16: switch (from) { case EbtInt16: case EbtUint16: - return true; + return extensionRequested(E_GL_AMD_gpu_shader_int16); default: - return false; - } -#endif + break; + } + return false; default: return false; } @@ -1578,7 +1812,12 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat return false; } -static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType) { +static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType) +{ +#ifdef GLSLANG_WEB + return false; +#endif + switch(sintType) { case EbtInt8: switch(uintType) { @@ -1637,7 +1876,13 @@ static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBas } -static TBasicType getCorrespondingUnsignedType(TBasicType type) { +static TBasicType getCorrespondingUnsignedType(TBasicType type) +{ +#ifdef GLSLANG_WEB + assert(type == EbtInt); + return EbtUint; +#endif + switch(type) { case EbtInt8: return EbtUint8; @@ -1686,10 +1931,10 @@ std::tuple TIntermediate::getConversionDestinatonType(TB TBasicType res0 = EbtNumTypes; TBasicType res1 = EbtNumTypes; - if (profile == EEsProfile || version == 110) - return std::make_tuple(res0, res1);; + if (isEsProfile() || version == 110) + return std::make_tuple(res0, res1); - if (source == EShSourceHlsl) { + if (getSource() == EShSourceHlsl) { if (canImplicitlyPromote(type1, type0, op)) { res0 = type0; res1 = type0; @@ -1758,15 +2003,18 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const { TOperator op = EOpNull; - if (type.getQualifier().nonUniform) + if (type.getQualifier().isNonUniform()) return EOpConstructNonuniform; + if (type.isCoopMat()) + return EOpConstructCooperativeMatrix; + switch (type.getBasicType()) { case EbtStruct: op = EOpConstructStruct; break; case EbtSampler: - if (type.getSampler().combined) + if (type.getSampler().isCombined()) op = EOpConstructTextureSampler; break; case EbtFloat: @@ -1808,6 +2056,121 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const } } break; + case EbtInt: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat2x2; break; + case 3: op = EOpConstructIMat2x3; break; + case 4: op = EOpConstructIMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat3x2; break; + case 3: op = EOpConstructIMat3x3; break; + case 4: op = EOpConstructIMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructIMat4x2; break; + case 3: op = EOpConstructIMat4x3; break; + case 4: op = EOpConstructIMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructInt; break; + case 2: op = EOpConstructIVec2; break; + case 3: op = EOpConstructIVec3; break; + case 4: op = EOpConstructIVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtUint: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat2x2; break; + case 3: op = EOpConstructUMat2x3; break; + case 4: op = EOpConstructUMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat3x2; break; + case 3: op = EOpConstructUMat3x3; break; + case 4: op = EOpConstructUMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructUMat4x2; break; + case 3: op = EOpConstructUMat4x3; break; + case 4: op = EOpConstructUMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructUint; break; + case 2: op = EOpConstructUVec2; break; + case 3: op = EOpConstructUVec3; break; + case 4: op = EOpConstructUVec4; break; + default: break; // some compilers want this + } + } + break; + case EbtBool: + if (type.getMatrixCols()) { + switch (type.getMatrixCols()) { + case 2: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat2x2; break; + case 3: op = EOpConstructBMat2x3; break; + case 4: op = EOpConstructBMat2x4; break; + default: break; // some compilers want this + } + break; + case 3: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat3x2; break; + case 3: op = EOpConstructBMat3x3; break; + case 4: op = EOpConstructBMat3x4; break; + default: break; // some compilers want this + } + break; + case 4: + switch (type.getMatrixRows()) { + case 2: op = EOpConstructBMat4x2; break; + case 3: op = EOpConstructBMat4x3; break; + case 4: op = EOpConstructBMat4x4; break; + default: break; // some compilers want this + } + break; + } + } else { + switch(type.getVectorSize()) { + case 1: op = EOpConstructBool; break; + case 2: op = EOpConstructBVec2; break; + case 3: op = EOpConstructBVec3; break; + case 4: op = EOpConstructBVec4; break; + default: break; // some compilers want this + } + } + break; +#ifndef GLSLANG_WEB case EbtDouble: if (type.getMatrixCols()) { switch (type.getMatrixCols()) { @@ -1921,82 +2284,6 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const default: break; // some compilers want this } break; - case EbtInt: - if (type.getMatrixCols()) { - switch (type.getMatrixCols()) { - case 2: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructIMat2x2; break; - case 3: op = EOpConstructIMat2x3; break; - case 4: op = EOpConstructIMat2x4; break; - default: break; // some compilers want this - } - break; - case 3: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructIMat3x2; break; - case 3: op = EOpConstructIMat3x3; break; - case 4: op = EOpConstructIMat3x4; break; - default: break; // some compilers want this - } - break; - case 4: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructIMat4x2; break; - case 3: op = EOpConstructIMat4x3; break; - case 4: op = EOpConstructIMat4x4; break; - default: break; // some compilers want this - } - break; - } - } else { - switch(type.getVectorSize()) { - case 1: op = EOpConstructInt; break; - case 2: op = EOpConstructIVec2; break; - case 3: op = EOpConstructIVec3; break; - case 4: op = EOpConstructIVec4; break; - default: break; // some compilers want this - } - } - break; - case EbtUint: - if (type.getMatrixCols()) { - switch (type.getMatrixCols()) { - case 2: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructUMat2x2; break; - case 3: op = EOpConstructUMat2x3; break; - case 4: op = EOpConstructUMat2x4; break; - default: break; // some compilers want this - } - break; - case 3: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructUMat3x2; break; - case 3: op = EOpConstructUMat3x3; break; - case 4: op = EOpConstructUMat3x4; break; - default: break; // some compilers want this - } - break; - case 4: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructUMat4x2; break; - case 3: op = EOpConstructUMat4x3; break; - case 4: op = EOpConstructUMat4x4; break; - default: break; // some compilers want this - } - break; - } - } else { - switch(type.getVectorSize()) { - case 1: op = EOpConstructUint; break; - case 2: op = EOpConstructUVec2; break; - case 3: op = EOpConstructUVec3; break; - case 4: op = EOpConstructUVec4; break; - default: break; // some compilers want this - } - } - break; case EbtInt64: switch(type.getVectorSize()) { case 1: op = EOpConstructInt64; break; @@ -2015,44 +2302,10 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const default: break; // some compilers want this } break; - case EbtBool: - if (type.getMatrixCols()) { - switch (type.getMatrixCols()) { - case 2: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructBMat2x2; break; - case 3: op = EOpConstructBMat2x3; break; - case 4: op = EOpConstructBMat2x4; break; - default: break; // some compilers want this - } - break; - case 3: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructBMat3x2; break; - case 3: op = EOpConstructBMat3x3; break; - case 4: op = EOpConstructBMat3x4; break; - default: break; // some compilers want this - } - break; - case 4: - switch (type.getMatrixRows()) { - case 2: op = EOpConstructBMat4x2; break; - case 3: op = EOpConstructBMat4x3; break; - case 4: op = EOpConstructBMat4x4; break; - default: break; // some compilers want this - } - break; - } - } else { - switch(type.getVectorSize()) { - case 1: op = EOpConstructBool; break; - case 2: op = EOpConstructBVec2; break; - case 3: op = EOpConstructBVec3; break; - case 4: op = EOpConstructBVec4; break; - default: break; // some compilers want this - } - } + case EbtReference: + op = EOpConstructReference; break; +#endif default: break; } @@ -2511,6 +2764,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); +#ifndef GLSLANG_WEB // Propagate 'noContraction' label in backward from 'precise' variables. glslang::PropagateNoContraction(*this); @@ -2521,6 +2775,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) performTextureUpgradeAndSamplerRemovalTransformation(root); break; } +#endif return true; } @@ -3230,6 +3485,40 @@ bool TIntermediate::promoteBinary(TIntermBinary& node) 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; @@ -3524,217 +3813,54 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC TConstUnionArray leftUnionArray(size); for (int i=0; i < size; i++) { - switch (promoteTo) { - case EbtFloat: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i] = rightUnionArray[i]; - break; - default: - return node; - } - break; - case EbtDouble: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i] = rightUnionArray[i]; - break; - default: - return node; - } - break; - case EbtFloat16: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setDConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i] = rightUnionArray[i]; - break; - default: - return node; - } - break; - case EbtInt: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtUint: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setIConst(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - case EbtUint: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtInt64: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setUConst(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - case EbtBool: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0); - break; - case EbtUint: - leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0); - break; - case EbtInt64: - leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0); - break; - case EbtUint64: - leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0); - break; - case EbtBool: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); - break; - default: - return node; - } - break; - case EbtInt64: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtUint64: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getU64Const())); - break; - case EbtBool: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setI64Const(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - case EbtUint64: - switch (node->getType().getBasicType()) { - case EbtInt: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getIConst())); - break; - case EbtUint: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getUConst())); - break; - case EbtInt64: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getI64Const())); - break; - case EbtUint64: - leftUnionArray[i] = rightUnionArray[i]; - break; - case EbtBool: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getBConst())); - break; - case EbtFloat: - case EbtDouble: - case EbtFloat16: - leftUnionArray[i].setU64Const(static_cast(rightUnionArray[i].getDConst())); - break; - default: - return node; - } - break; - default: - return node; + +#define PROMOTE(Set, CType, Get) leftUnionArray[i].Set(static_cast(rightUnionArray[i].Get())) +#define PROMOTE_TO_BOOL(Get) leftUnionArray[i].setBConst(rightUnionArray[i].Get() != 0) + +#ifdef GLSLANG_WEB +#define TO_ALL(Get) \ + switch (promoteTo) { \ + case EbtFloat: PROMOTE(setDConst, double, Get); break; \ + case EbtInt: PROMOTE(setIConst, int, Get); break; \ + case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \ + case EbtBool: PROMOTE_TO_BOOL(Get); break; \ + default: return node; \ + } +#else +#define TO_ALL(Get) \ + switch (promoteTo) { \ + case EbtFloat16: PROMOTE(setDConst, double, Get); break; \ + case EbtFloat: PROMOTE(setDConst, double, Get); break; \ + case EbtDouble: PROMOTE(setDConst, double, Get); break; \ + case EbtInt8: PROMOTE(setI8Const, char, Get); break; \ + case EbtInt16: PROMOTE(setI16Const, short, Get); break; \ + case EbtInt: PROMOTE(setIConst, int, Get); break; \ + case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \ + case EbtUint8: PROMOTE(setU8Const, unsigned char, Get); break; \ + case EbtUint16: PROMOTE(setU16Const, unsigned short, Get); break; \ + case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \ + case EbtUint64: PROMOTE(setU64Const, unsigned long long, Get); break; \ + case EbtBool: PROMOTE_TO_BOOL(Get); break; \ + default: return node; \ + } +#endif + + switch (node->getType().getBasicType()) { + case EbtFloat: TO_ALL(getDConst); break; + case EbtInt: TO_ALL(getIConst); break; + case EbtUint: TO_ALL(getUConst); break; + case EbtBool: TO_ALL(getBConst); break; +#ifndef GLSLANG_WEB + case EbtFloat16: TO_ALL(getDConst); break; + case EbtDouble: TO_ALL(getDConst); break; + case EbtInt8: TO_ALL(getI8Const); break; + case EbtInt16: TO_ALL(getI16Const); break; + case EbtInt64: TO_ALL(getI64Const); break; + case EbtUint8: TO_ALL(getU8Const); break; + case EbtUint16: TO_ALL(getU16Const); break; + case EbtUint64: TO_ALL(getU64Const); break; +#endif + default: return node; } } @@ -3763,7 +3889,7 @@ bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TInt struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { void visitSymbol(TIntermSymbol* symbol) override { if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) { - symbol->getWritableType().getSampler().combined = true; + symbol->getWritableType().getSampler().setCombined(true); } } bool visitAggregate(TVisit, TIntermAggregate* ag) override { diff --git a/Externals/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/Externals/glslang/glslang/MachineIndependent/ParseContextBase.cpp index bfa9de4dff..282ecca0e0 100644 --- a/Externals/glslang/glslang/MachineIndependent/ParseContextBase.cpp +++ b/Externals/glslang/glslang/MachineIndependent/ParseContextBase.cpp @@ -67,6 +67,8 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso } } +#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL) + void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) { @@ -113,6 +115,8 @@ void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReaso va_end(args); } +#endif + // // Both test and if necessary, spit out an error, to see if the node is really // an l-value that can be operated on this way. @@ -149,10 +153,18 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EvqConst: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break; case EvqUniform: message = "can't modify a uniform"; break; +#ifndef GLSLANG_WEB case EvqBuffer: - if (node->getQualifier().readonly) + if (node->getQualifier().isReadOnly()) message = "can't modify a readonly buffer"; + if (node->getQualifier().isShaderRecordNV()) + message = "can't modify a shaderrecordnv qualified buffer"; break; + case EvqHitAttrNV: + if (language != EShLangIntersectNV) + message = "cannot modify hitAttributeNV in this stage"; + break; +#endif default: // @@ -162,12 +174,17 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EbtSampler: message = "can't modify a sampler"; break; - case EbtAtomicUint: - message = "can't modify an atomic_uint"; - break; case EbtVoid: message = "can't modify void"; break; +#ifndef GLSLANG_WEB + case EbtAtomicUint: + message = "can't modify an atomic_uint"; + break; + case EbtAccStructNV: + message = "can't modify accelerationStructureNV"; + break; +#endif default: break; } @@ -219,7 +236,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, } TIntermSymbol* symNode = node->getAsSymbolNode(); - if (symNode && symNode->getQualifier().writeonly) + if (symNode && symNode->getQualifier().isWriteOnly()) error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); } @@ -239,11 +256,17 @@ void TParseContextBase::trackLinkage(TSymbol& symbol) // Give an error if not. void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index) { + const auto sizeIsSpecializationExpression = [&type]() { + return type.containsSpecializationSize() && + type.getArraySizes()->getOuterNode() != nullptr && + type.getArraySizes()->getOuterNode()->getAsSymbolNode() == nullptr; }; + if (index < 0) { error(loc, "", "[", "index out of range '%d'", index); index = 0; } else if (type.isArray()) { - if (type.isSizedArray() && index >= type.getOuterArraySize()) { + if (type.isSizedArray() && !sizeIsSpecializationExpression() && + index >= type.getOuterArraySize()) { error(loc, "", "[", "array index out of range '%d'", index); index = type.getOuterArraySize() - 1; } @@ -553,6 +576,7 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin selector.push_back(0); } +#ifdef ENABLE_HLSL // // Make the passed-in variable information become a member of the // global uniform block. If this doesn't exist yet, make it. @@ -597,6 +621,7 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem ++firstNewMember; } +#endif void TParseContextBase::finish() { diff --git a/Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp b/Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp old mode 100755 new mode 100644 index 828e49651f..a2224e1609 --- a/Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -1,8 +1,8 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. // Copyright (C) 2012-2015 LunarG, Inc. -// Copyright (C) 2015-2016 Google, Inc. -// Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. +// Copyright (C) 2017, 2019 ARM Limited. // // All rights reserved. // @@ -56,13 +56,16 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b infoSink, forwardCompatible, messages, entryPoint), inMain(false), blockName(nullptr), - limits(resources.limits), + limits(resources.limits) +#ifndef GLSLANG_WEB + , atomicUintOffsets(nullptr), anyIndexLimits(false) +#endif { // decide whether precision qualifiers should be ignored or respected - if (profile == EEsProfile || spvVersion.vulkan > 0) { + if (isEsProfile() || spvVersion.vulkan > 0) { precisionManager.respectPrecisionQualifiers(); - if (! parsingBuiltins && language == EShLangFragment && profile != EEsProfile && spvVersion.vulkan > 0) + if (! parsingBuiltins && language == EShLangFragment && !isEsProfile() && spvVersion.vulkan > 0) precisionManager.warnAboutDefaults(); } @@ -76,9 +79,14 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b 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(); +#ifndef GLSLANG_WEB // "Shaders in the transform // feedback capturing mode have an initial global default of // layout(xfb_buffer = 0) out;" @@ -90,6 +98,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b if (language == EShLangGeometry) globalOutputDefaults.layoutStream = 0; +#endif if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main") infoSink.info.message(EPrefixError, "Source entry point must be \"main\""); @@ -97,7 +106,9 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b TParseContext::~TParseContext() { +#ifndef GLSLANG_WEB delete [] atomicUintOffsets; +#endif } // Set up all default precisions as needed by the current environment. @@ -117,7 +128,7 @@ void TParseContext::setPrecisionDefaults() // replace with real precision defaults for those that have them if (obeyPrecisionQualifiers()) { - if (profile == EEsProfile) { + if (isEsProfile()) { // Most don't have defaults, a few default to lowp. TSampler sampler; sampler.set(EbtFloat, Esd2D); @@ -125,7 +136,7 @@ void TParseContext::setPrecisionDefaults() sampler.set(EbtFloat, EsdCube); defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; sampler.set(EbtFloat, Esd2D); - sampler.external = true; + sampler.setExternal(true); defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; } @@ -134,7 +145,7 @@ void TParseContext::setPrecisionDefaults() // is used to resolve the precision from the supplied arguments/operands instead. // So, we don't actually want to replace EpqNone with a default precision for built-ins. if (! parsingBuiltins) { - if (profile == EEsProfile && language == EShLangFragment) { + if (isEsProfile() && language == EShLangFragment) { defaultPrecision[EbtInt] = EpqMedium; defaultPrecision[EbtUint] = EpqMedium; } else { @@ -143,7 +154,7 @@ void TParseContext::setPrecisionDefaults() defaultPrecision[EbtFloat] = EpqHigh; } - if (profile != EEsProfile) { + if (!isEsProfile()) { // Non-ES profile // All sampler precisions default to highp. for (int type = 0; type < maxSamplerIndex; ++type) @@ -159,7 +170,9 @@ void TParseContext::setPrecisionDefaults() void TParseContext::setLimits(const TBuiltInResource& r) { resources = r; + intermediate.setLimits(r); +#ifndef GLSLANG_WEB anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing || ! limits.generalConstantMatrixVectorIndexing || ! limits.generalSamplerIndexing || @@ -167,7 +180,6 @@ void TParseContext::setLimits(const TBuiltInResource& r) ! limits.generalVariableIndexing || ! limits.generalVaryingIndexing; - intermediate.setLimits(resources); // "Each binding point tracks its own current default offset for // inheritance of subsequent variables using the same binding. The initial state of compilation is that all @@ -175,6 +187,7 @@ void TParseContext::setLimits(const TBuiltInResource& r) atomicUintOffsets = new int[resources.maxAtomicCounterBindings]; for (int b = 0; b < resources.maxAtomicCounterBindings; ++b) atomicUintOffsets[b] = 0; +#endif } // @@ -209,6 +222,7 @@ void TParseContext::parserError(const char* s) void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& tokens) { +#ifndef GLSLANG_WEB if (pragmaCallback) pragmaCallback(loc.line, tokens); @@ -267,10 +281,21 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& 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(); +#endif } // @@ -284,6 +309,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb if (symbol && symbol->getNumExtensions()) requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str()); +#ifndef GLSLANG_WEB if (symbol && symbol->isReadOnly()) { // All shared things containing an unsized array must be copied up // on first use, so that all future references will share its array structure, @@ -293,20 +319,23 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // 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 unsized array. - if (symbol->getType().containsUnsizedArray() || - (symbol->getAsAnonMember() && - symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) - makeEditable(symbol); + // + // This check is being done before the block-name check further down, so guard + // for that too. + if (!symbol->getType().isUnusableName()) { + if (symbol->getType().containsUnsizedArray() || + (symbol->getAsAnonMember() && + symbol->getAsAnonMember()->getAnonContainer().getType().containsUnsizedArray())) + makeEditable(symbol); + } } +#endif const TVariable* variable; const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr; 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); @@ -323,8 +352,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // See if it was a variable. variable = symbol ? symbol->getAsVariable() : nullptr; if (variable) { - if ((variable->getType().getBasicType() == EbtBlock || - variable->getType().getBasicType() == EbtStruct) && variable->getType().getStruct() == nullptr) { + if (variable->getType().isUnusableName()) { error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), ""); variable = nullptr; } @@ -346,6 +374,11 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb if (variable->getType().getQualifier().isIo()) intermediate.addIoAccessed(*string); + if (variable->getType().isReference() && + variable->getType().getQualifier().bufferReferenceNeedsVulkanMemoryModel()) { + intermediate.setUseVulkanMemoryModel(); + } + return node; } @@ -354,99 +387,140 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb // 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->isReference()) { 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().contains16BitFloat()) + 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 (index->getQualifier().isFrontEndConstant()) + // at least one of base and index is not a front-end constant variable... + TIntermTyped* result = nullptr; + +#ifndef GLSLANG_WEB + if (base->isReference() && ! 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 (base->getAsSymbolNode() && isIoResizeArray(base->getType())) + handleIoResizeArrayAccess(loc, base); +#endif + + if (index->getQualifier().isFrontEndConstant()) + checkIndex(loc, base->getType(), indexValue); + + if (index->getQualifier().isFrontEndConstant()) { +#ifndef GLSLANG_WEB + if (base->getType().isUnsizedArray()) { + base->getWritableType().updateImplicitArraySize(indexValue + 1); + // 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)); + } + } + } else +#endif 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); - else - checkIndex(loc, base->getType(), indexValue); - result = intermediate.addIndex(EOpIndexDirect, base, index, loc); - } else { - 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); - } - base->getWritableType().setArrayVariablyIndexed(); - } - 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); - } - } - - if (result == nullptr) { - // Insert dummy error-recovery result - result = intermediate.addConstantUnion(0.0, EbtFloat, loc); + 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(); +#ifndef GLSLANG_WEB + 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(); + } +#endif + 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't be variably 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->setType(newType); - // Propagate nonuniform - if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform()) - result->getWritableType().getQualifier().nonUniform = true; - - if (anyIndexLimits) - handleIndexLimits(loc, base, index); + result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); } + // Insert valid dereferenced result type + TType newType(base->getType(), 0); + 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().storage = EvqTemporary; + newType.getQualifier().specConstant = false; + } + result->setType(newType); + +#ifndef GLSLANG_WEB + inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); + + // Propagate nonuniform + if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform()) + result->getWritableType().getQualifier().nonUniform = true; + + if (anyIndexLimits) + handleIndexLimits(loc, base, index); +#endif + return result; } +#ifndef GLSLANG_WEB + // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index) { @@ -477,12 +551,18 @@ void TParseContext::makeEditable(TSymbol*& symbol) 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) || + (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && + type.getQualifier().pervertexNV) || + (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && + !type.getQualifier().perTaskNV)); } // If an array is not isIoResizeArray() but is an io array, make sure it has the right size @@ -511,11 +591,7 @@ void TParseContext::fixIoArraySize(const TSourceLoc& loc, TType& type) void TParseContext::ioArrayCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (! type.isArray() && ! symbolTable.atBuiltInLevel()) { - if (type.getQualifier().isArrayedIo(language) -#ifdef NV_EXTENSIONS - && !type.getQualifier().layoutPassthrough -#endif - ) + if (type.getQualifier().isArrayedIo(language) && !type.getQualifier().layoutPassthrough) error(loc, "type must be an array:", type.getStorageQualifierString(), identifier.c_str()); } } @@ -532,7 +608,7 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm // fix array size, if it can be fixed and needs to be fixed (will allow variable indexing) if (symbolNode->getType().isUnsizedArray()) { - int newSize = getIoArrayImplicitSize(); + int newSize = getIoArrayImplicitSize(symbolNode->getType().getQualifier()); if (newSize > 0) symbolNode->getWritableType().changeOuterArraySize(newSize); } @@ -546,37 +622,71 @@ void TParseContext::handleIoResizeArrayAccess(const TSourceLoc& /*loc*/, TInterm // 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(); - for (size_t i = 0; i < ioArraySymbolResizeList.size(); ++i) - checkIoArrayConsistency(loc, requiredSize, feature, ioArraySymbolResizeList[i]->getWritableType(), ioArraySymbolResizeList[i]->getName()); + // 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 || (language == EShLangMeshNV)) { + requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString); + if (requiredSize == 0) + break; + firstIteration = false; + } + + 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"; + } 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"; + } + } + if (featureString) + *featureString = str; + return expectedSize; } void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredSize, const char* feature, TType& type, const TString& name) @@ -588,11 +698,19 @@ void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredS 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()); + 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()); else assert(0); } } +#endif // GLSLANG_WEB + // Handle seeing a binary node with a math operation. // Returns nullptr if not semantically allowed. TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right) @@ -615,6 +733,12 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* break; } + if (((left->getType().contains16BitFloat() || right->getType().contains16BitFloat()) && !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); @@ -630,7 +754,16 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* { rValueErrorCheck(loc, str, childNode); - TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc); + bool allowed = true; + if ((childNode->getType().contains16BitFloat() && !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; @@ -660,7 +793,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm 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; @@ -677,6 +810,11 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm 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. @@ -692,6 +830,13 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm TSwizzleSelectors selectors; parseSwizzleSelector(loc, field, base->getVectorSize(), selectors); + if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitFloat()) + 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; @@ -720,8 +865,10 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm 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->isStruct() || base->isReference()) { + const TTypeList* fields = base->isReference() ? + base->getType().getReferentType()->getStruct() : + base->getType().getStruct(); bool fieldFound = false; int member; for (member = 0; member < (int)fields->size(); ++member) { @@ -734,19 +881,22 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm 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); } + inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); } else error(loc, "no such field in structure", field.c_str(), ""); } else error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str()); // Propagate noContraction up the dereference chain - if (base->getQualifier().noContraction) - result->getWritableType().getQualifier().noContraction = true; + if (base->getQualifier().isNoContraction()) + result->getWritableType().getQualifier().setNoContraction(); // Propagate nonuniform if (base->getQualifier().isNonUniform()) @@ -755,14 +905,30 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm 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()); } // @@ -970,6 +1136,13 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (builtIn && fnCandidate->getNumExtensions()) requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str()); + if (builtIn && fnCandidate->getType().contains16BitFloat()) + 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(); @@ -983,18 +1156,46 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped())) error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); } - TQualifier& argQualifier = arg->getAsTyped()->getQualifier(); - if (argQualifier.isMemory()) { + const TType& argType = arg->getAsTyped()->getType(); + const TQualifier& argQualifier = argType.getQualifier(); + if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) { const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; +#ifndef GLSLANG_WEB 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", ""); + // Don't check 'restrict', it is different than the rest: + // "...but only restrict can be taken away from a calling argument, by a formal parameter that + // lacks the restrict qualifier..." +#endif } + if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) { + // we have mismatched formats, which should only be allowed if writeonly + // and at least one format is unknown + if (!formalQualifier.isWriteOnly() || (formalQualifier.getFormat() != ElfNone && + argQualifier.getFormat() != ElfNone)) + error(arguments->getLoc(), "image formats must match", "format", ""); + } + if (builtIn && arg->getAsTyped()->getType().contains16BitFloat()) + 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 @@ -1028,9 +1229,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); } +#ifndef GLSLANG_WEB if (builtIn) nonOpBuiltInCheck(loc, *fnCandidate, *call); else +#endif userFunctionCallCheck(loc, *call); } @@ -1045,6 +1248,13 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction } 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()); + } } } @@ -1152,13 +1362,9 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction operationPrecision = std::max(operationPrecision, function[arg].type->getQualifier().precision); } // compute the result precision -#ifdef AMD_EXTENSIONS if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore || agg->getOp() == EOpImageLoadLod || agg->getOp() == EOpImageStoreLod) -#else - if (agg->isSampling() || agg->getOp() == EOpImageLoad || agg->getOp() == EOpImageStore) -#endif resultPrecision = sequence[0]->getAsTyped()->getQualifier().precision; else if (function.getType().getBasicType() != EbtBool) resultPrecision = function.getType().getQualifier().precision == EpqNone ? @@ -1179,6 +1385,10 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value) { +#ifndef GLSLANG_WEB + storage16BitAssignmentCheck(loc, value->getType(), "return"); +#endif + functionReturnsValue = true; if (currentFunctionType->getBasicType() == EbtVoid) { error(loc, "void function cannot return a value", "return", ""); @@ -1202,6 +1412,7 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType // See if the operation is being done in an illegal location. void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) { +#ifndef GLSLANG_WEB switch (op) { case EOpBarrier: if (language == EShLangTessControl) { @@ -1213,9 +1424,48 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) error(loc, "tessellation control barrier() cannot be placed after a return from main()", "", ""); } break; + case EOpBeginInvocationInterlock: + if (language != EShLangFragment) + error(loc, "beginInvocationInterlockARB() must be in a fragment shader", "", ""); + if (! inMain) + error(loc, "beginInvocationInterlockARB() must be in main()", "", ""); + else if (postEntryPointReturn) + error(loc, "beginInvocationInterlockARB() cannot be placed after a return from main()", "", ""); + if (controlFlowNestingLevel > 0) + error(loc, "beginInvocationInterlockARB() cannot be placed within flow control", "", ""); + + if (beginInvocationInterlockCount > 0) + error(loc, "beginInvocationInterlockARB() must only be called once", "", ""); + if (endInvocationInterlockCount > 0) + error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", ""); + + beginInvocationInterlockCount++; + + // default to pixel_interlock_ordered + if (intermediate.getInterlockOrdering() == EioNone) + intermediate.setInterlockOrdering(EioPixelInterlockOrdered); + break; + case EOpEndInvocationInterlock: + if (language != EShLangFragment) + error(loc, "endInvocationInterlockARB() must be in a fragment shader", "", ""); + if (! inMain) + error(loc, "endInvocationInterlockARB() must be in main()", "", ""); + else if (postEntryPointReturn) + error(loc, "endInvocationInterlockARB() cannot be placed after a return from main()", "", ""); + if (controlFlowNestingLevel > 0) + error(loc, "endInvocationInterlockARB() cannot be placed within flow control", "", ""); + + if (endInvocationInterlockCount > 0) + error(loc, "endInvocationInterlockARB() must only be called once", "", ""); + if (beginInvocationInterlockCount == 0) + error(loc, "beginInvocationInterlockARB() must be called before endInvocationInterlockARB()", "", ""); + + endInvocationInterlockCount++; + break; default: break; } +#endif } // Finish processing object.length(). This started earlier in handleDotDereference(), where @@ -1233,22 +1483,28 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction const TType& type = intermNode->getAsTyped()->getType(); if (type.isArray()) { if (type.isUnsizedArray()) { +#ifndef GLSLANG_WEB 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" || name == "gl_MeshVerticesNV" || + name == "gl_MeshPrimitivesNV") { + length = getIoArrayImplicitSize(type.getQualifier()); + } } +#endif if (length == 0) { +#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier"); 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 +#endif error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); } } else if (type.getOuterArrayNode()) { @@ -1262,6 +1518,8 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction 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()", ""); @@ -1279,6 +1537,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction // void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const { +#ifndef GLSLANG_WEB TIntermAggregate* aggregate = arguments->getAsAggregate(); // Process each argument's conversion @@ -1288,7 +1547,8 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte // 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); @@ -1305,6 +1565,7 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte } } } +#endif } // @@ -1316,6 +1577,9 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte // TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const { +#ifdef GLSLANG_WEB + return &intermNode; +#else TIntermSequence& arguments = intermNode.getSequence(); // Will there be any output conversions? @@ -1356,7 +1620,14 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct 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()); @@ -1376,6 +1647,172 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc()); return conversionTree; +#endif +} + +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_SemanticsVolatile = 0x8000; + + //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 | + gl_SemanticsVolatile))) { + 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(), ""); + } + if ((semantics & gl_SemanticsVolatile) && + (callNode.getOp() == EOpMemoryBarrier || callNode.getOp() == EOpBarrier)) { + error(loc, "gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier", + fnCandidate.getName().c_str(), ""); + } + if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) && + ((semantics ^ semantics2) & gl_SemanticsVolatile)) { + error(loc, "semEqual and semUnequal must either both include gl_SemanticsVolatile or neither", + fnCandidate.getName().c_str(), ""); + } } // @@ -1405,6 +1842,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan TString featureString; const char* feature = nullptr; switch (callNode.getOp()) { +#ifndef GLSLANG_WEB case EOpTextureGather: case EOpTextureGatherOffset: case EOpTextureGatherOffsets: @@ -1461,7 +1899,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan error(loc, "must be a compile-time constant:", feature, "component argument"); } -#ifdef AMD_EXTENSIONS bool bias = false; if (callNode.getOp() == EOpTextureGather) bias = fnCandidate.getParamCount() > 3; @@ -1476,12 +1913,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan profileRequires(loc, ~EEsProfile, 450, nullptr, feature); requireExtensions(loc, 1, &E_GL_AMD_texture_gather_bias_lod, feature); } -#endif - break; } - -#ifdef AMD_EXTENSIONS case EOpSparseTextureGather: case EOpSparseTextureGatherOffset: case EOpSparseTextureGatherOffsets: @@ -1559,7 +1992,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan int arg = -1; switch (callNode.getOp()) { case EOpTextureOffset: arg = 2; break; - case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().dim != EsdRect) ? 3 : 2; break; + case EOpTextureFetchOffset: arg = (arg0->getType().getSampler().isRect()) ? 2 : 3; break; case EOpTextureProjOffset: arg = 2; break; case EOpTextureLodOffset: arg = 3; break; case EOpTextureProjLodOffset: arg = 3; break; @@ -1572,7 +2005,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (arg > 0) { -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow; if (f16ShadowCompare) ++arg; @@ -1592,6 +2025,16 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan break; } +#ifndef GLSLANG_WEB + 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; + case EOpTextureQuerySamples: case EOpImageQuerySamples: // GL_ARB_shader_texture_image_samples @@ -1606,23 +2049,30 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan 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(); if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { - if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui) error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); } else { if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); - else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile) + else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile()) 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: @@ -1631,20 +2081,24 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan 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) { + 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()); + } 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. @@ -1654,13 +2108,12 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan // // ES and desktop 4.3 and earlier: swizzles may not be used // desktop 4.4 and later: swizzles may be used - bool swizzleOkay = (profile != EEsProfile) && (version >= 440); + bool swizzleOkay = (!isEsProfile()) && (version >= 440); const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay); 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", ""); @@ -1674,8 +2127,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } } } -#endif - break; case EOpEmitStreamVertex: @@ -1690,6 +2141,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan 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 { @@ -1701,17 +2156,86 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } break; + case EOpSubgroupBroadcast: + case EOpSubgroupQuadBroadcast: + if (spvVersion.spv < EShTargetSpv_1_5) { + // 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; +#endif + default: break; } - if (callNode.getOp() > EOpSubgroupGuardStart && callNode.getOp() < EOpSubgroupGuardStop) { + // 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.isBuffer(); + 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.isSubgroup()) { // these require SPIR-V 1.3 if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_3) error(loc, "requires SPIR-V 1.3", "subgroup op", ""); + + // Check that if extended types are being used that the correct extensions are enabled. + if (arg0 != nullptr) { + const TType& type = arg0->getType(); + switch (type.getBasicType()) { + default: + break; + case EbtInt8: + case EbtUint8: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str()); + break; + case EbtInt16: + case EbtUint16: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str()); + break; + case EbtInt64: + case EbtUint64: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str()); + break; + case EbtFloat16: + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str()); + break; + } + } } } +#ifndef GLSLANG_WEB + extern bool PureOperatorBuiltins; // Deprecated! Use PureOperatorBuiltins == true instead, in which case this @@ -1827,17 +2351,19 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn if (fnCandidate.getName().compare(0, 11, "imageAtomic") == 0) { const TType& imageType = callNode.getSequence()[0]->getAsTyped()->getType(); if (imageType.getSampler().type == EbtInt || imageType.getSampler().type == EbtUint) { - if (imageType.getQualifier().layoutFormat != ElfR32i && imageType.getQualifier().layoutFormat != ElfR32ui) + if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui) error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); } else { if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); - else if (imageType.getQualifier().layoutFormat != ElfR32f && profile == EEsProfile) + else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile()) error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); } } } +#endif + // // Do any extra checking for a user function call. // @@ -1985,6 +2511,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt bool errorReturn = false; switch(binaryNode->getOp()) { +#ifndef GLSLANG_WEB case EOpIndexDirect: case EOpIndexIndirect: // ... tessellation control shader ... @@ -2000,10 +2527,8 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", ""); } } - - break; // left node is checked by base class - case EOpIndexDirectStruct: break; // left node is checked by base class +#endif case EOpVectorSwizzle: errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); if (!errorReturn) { @@ -2035,6 +2560,9 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt } } + if (binaryNode && binaryNode->getOp() == EOpIndexDirectStruct && binaryNode->getLeft()->isReference()) + return false; + // Let the base class check errors if (TParseContextBase::lValueErrorCheck(loc, op, node)) return true; @@ -2055,7 +2583,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt case EvqFragDepth: intermediate.setDepthReplacing(); // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader." - if (profile == EEsProfile && intermediate.getEarlyFragmentTests()) + if (isEsProfile() && intermediate.getEarlyFragmentTests()) message = "can't modify gl_FragDepth if using early_fragment_tests"; break; @@ -2092,12 +2620,10 @@ void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TInt // Let the base class check errors TParseContextBase::rValueErrorCheck(loc, op, node); -#ifdef AMD_EXTENSIONS TIntermSymbol* symNode = node->getAsSymbolNode(); - if (!(symNode && symNode->getQualifier().writeonly)) // base class checks - if (symNode && symNode->getQualifier().explicitInterp) + if (!(symNode && symNode->getQualifier().isWriteOnly())) // base class checks + if (symNode && symNode->getQualifier().isExplicitInterpolation()) error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str()); -#endif } // @@ -2143,14 +2669,14 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide if (builtInName(identifier)) error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), ""); - // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: + // "__" are not supposed to be an error. ES 300 (and desktop) added the clarification: // "In addition, all identifiers containing two consecutive underscores (__) are // reserved; using such a name does not itself result in an error, but may result // in undefined behavior." // however, before that, ES tests required an error. if (identifier.find("__") != TString::npos) { - if (profile == EEsProfile && version <= 300) - error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version <= 300", identifier.c_str(), ""); + if (isEsProfile() && version < 300) + error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version < 300", identifier.c_str(), ""); else warn(loc, "identifiers containing consecutive underscores (\"__\") are reserved", identifier.c_str(), ""); } @@ -2162,7 +2688,7 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide // void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* identifier, const char* op) { - // "__" are not supposed to be an error. ES 310 (and desktop) added the clarification: + // "__" are not supposed to be an error. ES 300 (and desktop) added the clarification: // "All macro names containing two consecutive underscores ( __ ) are reserved; // defining such a name does not itself result in an error, but may result in // undefined behavior. All macro names prefixed with "GL_" ("GL" followed by a @@ -2174,14 +2700,14 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden else if (strncmp(identifier, "defined", 8) == 0) ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); else if (strstr(identifier, "__") != 0) { - if (profile == EEsProfile && version >= 300 && + if (isEsProfile() && version >= 300 && (strcmp(identifier, "__LINE__") == 0 || strcmp(identifier, "__FILE__") == 0 || strcmp(identifier, "__VERSION__") == 0)) ppError(loc, "predefined names can't be (un)defined:", op, identifier); else { - if (profile == EEsProfile && version <= 300) - ppError(loc, "names containing consecutive underscores are reserved, and an error if version <= 300:", op, identifier); + if (isEsProfile() && version < 300) + ppError(loc, "names containing consecutive underscores are reserved, and an error if version < 300:", op, identifier); else ppWarn(loc, "names containing consecutive underscores are reserved:", op, identifier); } @@ -2195,10 +2721,14 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden // bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment) { +#ifdef GLSLANG_WEB + return true; +#endif + const char* message = "line continuation"; - bool lineContinuationAllowed = (profile == EEsProfile && version >= 300) || - (profile != EEsProfile && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack))); + bool lineContinuationAllowed = (isEsProfile() && version >= 300) || + (!isEsProfile() && (version >= 420 || extensionTurnedOn(E_GL_ARB_shading_language_420pack))); if (endOfComment) { if (lineContinuationAllowed) @@ -2247,10 +2777,27 @@ bool TParseContext::builtInName(const TString& identifier) // bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function, TOperator op, TType& type) { - type.shallowCopy(function.getType()); + // See if the constructor does not establish the main type, only requalifies + // it, in which case the type comes from the argument instead of from the + // constructor function. + switch (op) { +#ifndef GLSLANG_WEB + case EOpConstructNonuniform: + if (node != nullptr && node->getAsTyped() != nullptr) { + type.shallowCopy(node->getAsTyped()->getType()); + type.getQualifier().makeTemporary(); + type.getQualifier().nonUniform = true; + } + break; +#endif + default: + type.shallowCopy(function.getType()); + break; + } + // See if it's a matrix bool constructingMatrix = false; - switch(op) { + switch (op) { case EOpConstructTextureSampler: return constructorTextureSamplerError(loc, function); case EOpConstructMat2x2: @@ -2262,6 +2809,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructMat4x2: case EOpConstructMat4x3: case EOpConstructMat4x4: +#ifndef GLSLANG_WEB case EOpConstructDMat2x2: case EOpConstructDMat2x3: case EOpConstructDMat2x4: @@ -2280,6 +2828,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructF16Mat4x2: case EOpConstructF16Mat4x3: case EOpConstructF16Mat4x4: +#endif constructingMatrix = true; break; default: @@ -2328,7 +2877,62 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T specConstType = true; if (function[arg].type->isFloatingDomain()) floatArgument = true; + if (type.isStruct()) { + if (function[arg].type->contains16BitFloat()) { + requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + } + if (function[arg].type->contains16BitInt()) { + requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + } + if (function[arg].type->contains8BitInt()) { + requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type"); + } + } } + if (op == EOpConstructNonuniform) + constType = false; + +#ifndef GLSLANG_WEB + 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; + } +#endif // inherit constness from children if (constType) { @@ -2337,17 +2941,24 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T if (specConstType) { switch (op) { case EOpConstructInt8: - case EOpConstructUint8: - case EOpConstructInt16: - case EOpConstructUint16: case EOpConstructInt: case EOpConstructUint: - case EOpConstructInt64: - case EOpConstructUint64: case EOpConstructBool: case EOpConstructBVec2: case EOpConstructBVec3: case EOpConstructBVec4: + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructUVec2: + case EOpConstructUVec3: + case EOpConstructUVec4: +#ifndef GLSLANG_WEB + case EOpConstructUint8: + case EOpConstructInt16: + case EOpConstructUint16: + case EOpConstructInt64: + case EOpConstructUint64: case EOpConstructI8Vec2: case EOpConstructI8Vec3: case EOpConstructI8Vec4: @@ -2360,18 +2971,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructU16Vec2: case EOpConstructU16Vec3: case EOpConstructU16Vec4: - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - case EOpConstructUVec2: - case EOpConstructUVec3: - case EOpConstructUVec4: case EOpConstructI64Vec2: case EOpConstructI64Vec3: case EOpConstructI64Vec4: case EOpConstructU64Vec2: case EOpConstructU64Vec3: case EOpConstructU64Vec4: +#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(); @@ -2462,6 +3068,16 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T 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", ""); @@ -2471,7 +3087,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T error(loc, "cannot convert a sampler", "constructor", ""); return true; } - if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) { + if (op != EOpConstructStruct && typed->isAtomic()) { error(loc, "cannot convert an atomic_uint", "constructor", ""); return true; } @@ -2517,7 +3133,7 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const } // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=() TSampler texture = function.getType().getSampler(); - texture.combined = false; + texture.setCombined(false); texture.shadow = false; if (texture != function[0].type->getSampler()) { error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); @@ -2527,18 +3143,12 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const // 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; } @@ -2575,13 +3185,16 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const { // Check that the appropriate extension is enabled if external sampler is used. // There are two extensions. The correct one must be used based on GLSL version. - if (type.getBasicType() == EbtSampler && type.getSampler().external) { + if (type.getBasicType() == EbtSampler && type.getSampler().isExternal()) { if (version < 300) { requireExtensions(loc, 1, &E_GL_OES_EGL_image_external, "samplerExternalOES"); } else { requireExtensions(loc, 1, &E_GL_OES_EGL_image_external_essl3, "samplerExternalOES"); } } + if (type.getSampler().isYuv()) { + requireExtensions(loc, 1, &E_GL_EXT_YUV_target, "__samplerExternal2DY2YEXT"); + } if (type.getQualifier().storage == EvqUniform) return; @@ -2596,6 +3209,8 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const } } +#ifndef GLSLANG_WEB + void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (type.getQualifier().storage == EvqUniform) @@ -2607,6 +3222,21 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); } +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 // GLSLANG_WEB + void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (parsingBuiltins) @@ -2670,7 +3300,7 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q break; } - if (!nonuniformOkay && qualifier.nonUniform) + if (!nonuniformOkay && qualifier.isNonUniform()) error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", ""); invariantCheck(loc, qualifier); @@ -2684,16 +3314,23 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali 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->isReference())) { + 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.hasBufferReference()) error(loc, "buffers can be declared only as blocks", "buffer", ""); if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut) return; - if (publicType.shaderQualifiers.blendEquation) + if (publicType.shaderQualifiers.hasBlendEquation()) error(loc, "can only be applied to a standalone 'out'", "blend equation", ""); // now, knowing it is a shader in/out, do all the in/out semantic checks @@ -2706,22 +3343,15 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble) profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output"); -#ifdef AMD_EXTENSIONS - if (! qualifier.flat && ! qualifier.explicitInterp) { -#else - if (!qualifier.flat) { -#endif + if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV()) { if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble || - (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) || - publicType.userDef->containsBasicType(EbtDouble)))) { + (publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt) + || publicType.userDef->containsBasicType(EbtUint) + || publicType.userDef->contains16BitInt() + || publicType.userDef->contains8BitInt() + || publicType.userDef->contains64BitInt() + || publicType.userDef->containsDouble()))) { if (qualifier.storage == EvqVaryingIn && language == EShLangFragment) error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage)); else if (qualifier.storage == EvqVaryingOut && language == EShLangVertex && version == 300) @@ -2729,9 +3359,12 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali } } - if (qualifier.patch && qualifier.isInterpolation()) + if (qualifier.isPatch() && qualifier.isInterpolation()) error(loc, "cannot use interpolation qualifiers with patch", "patch", ""); + if (qualifier.isTaskMemory() && publicType.basicType != EbtBlock) + error(loc, "taskNV variables can be declared only as blocks", "taskNV", ""); + if (qualifier.storage == EvqVaryingIn) { switch (language) { case EShLangVertex: @@ -2748,18 +3381,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant) error(loc, "vertex input cannot be further qualified", "", ""); break; - - case EShLangTessControl: - if (qualifier.patch) - error(loc, "can only use on output in tessellation-control shader", "patch", ""); - break; - - case EShLangTessEvaluation: - break; - - case EShLangGeometry: - break; - case EShLangFragment: if (publicType.userDef) { profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input"); @@ -2770,12 +3391,16 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array"); } break; - - case EShLangCompute: + case EShLangCompute: if (! symbolTable.atBuiltInLevel()) error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); break; - +#ifndef GLSLANG_WEB + case EShLangTessControl: + if (qualifier.patch) + error(loc, "can only use on output in tessellation-control shader", "patch", ""); + break; +#endif default: break; } @@ -2793,18 +3418,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali } break; - - case EShLangTessControl: - break; - - case EShLangTessEvaluation: - if (qualifier.patch) - error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); - break; - - case EShLangGeometry: - break; - case EShLangFragment: profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output"); if (publicType.basicType == EbtStruct) { @@ -2826,7 +3439,12 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali case EShLangCompute: error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); break; - +#ifndef GLSLANG_WEB + case EShLangTessEvaluation: + if (qualifier.patch) + error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); + break; +#endif default: break; } @@ -2850,18 +3468,14 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons // Multiple interpolation qualifiers (mostly done later by 'individual qualifiers') if (src.isInterpolation() && dst.isInterpolation()) -#ifdef AMD_EXTENSIONS error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective, __explicitInterpAMD)", "", ""); -#else - error(loc, "can only have one interpolation qualifier (flat, smooth, noperspective)", "", ""); -#endif // Ordering - if (! force && ((profile != EEsProfile && version < 420) || - (profile == EEsProfile && version < 310)) + if (! force && ((!isEsProfile() && version < 420) || + (isEsProfile() && version < 310)) && ! extensionTurnedOn(E_GL_ARB_shading_language_420pack)) { // non-function parameters - if (src.noContraction && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) + if (src.isNoContraction() && (dst.invariant || dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) error(loc, "precise qualifier must appear first", "", ""); if (src.invariant && (dst.isInterpolation() || dst.isAuxiliary() || dst.storage != EvqTemporary || dst.precision != EpqNone)) error(loc, "invariant qualifier must appear before interpolation, storage, and precision qualifiers ", "", ""); @@ -2873,7 +3487,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons error(loc, "precision qualifier must appear as last qualifier", "", ""); // function parameters - if (src.noContraction && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut)) + if (src.isNoContraction() && (dst.storage == EvqConst || dst.storage == EvqIn || dst.storage == EvqOut)) error(loc, "precise qualifier must appear first", "", ""); if (src.storage == EvqConst && (dst.storage == EvqIn || dst.storage == EvqOut)) error(loc, "in/out must appear before const", "", ""); @@ -2898,6 +3512,15 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons if (dst.precision == EpqNone || (force && src.precision != EpqNone)) dst.precision = src.precision; +#ifndef GLSLANG_WEB + 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), ""); + } +#endif // Layout qualifiers mergeObjectLayoutQualifiers(dst, src, false); @@ -2905,23 +3528,31 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons bool repeated = false; #define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field; MERGE_SINGLETON(invariant); - MERGE_SINGLETON(noContraction); MERGE_SINGLETON(centroid); MERGE_SINGLETON(smooth); MERGE_SINGLETON(flat); + MERGE_SINGLETON(specConstant); +#ifndef GLSLANG_WEB + MERGE_SINGLETON(noContraction); MERGE_SINGLETON(nopersp); -#ifdef AMD_EXTENSIONS MERGE_SINGLETON(explicitInterp); -#endif + MERGE_SINGLETON(perPrimitiveNV); + MERGE_SINGLETON(perViewNV); + MERGE_SINGLETON(perTaskNV); 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); +#endif if (repeated) error(loc, "replicated qualifiers", "", ""); @@ -2964,11 +3595,11 @@ void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publ // correlates with the declaration of defaultSamplerPrecision[] int TParseContext::computeSamplerTypeIndex(TSampler& sampler) { - int arrayIndex = sampler.arrayed ? 1 : 0; - int shadowIndex = sampler.shadow ? 1 : 0; - int externalIndex = sampler.external? 1 : 0; - int imageIndex = sampler.image ? 1 : 0; - int msIndex = sampler.ms ? 1 : 0; + int arrayIndex = sampler.arrayed ? 1 : 0; + int shadowIndex = sampler.shadow ? 1 : 0; + int externalIndex = sampler.isExternal() ? 1 : 0; + int imageIndex = sampler.isImageClass() ? 1 : 0; + int msIndex = sampler.isMultiSample() ? 1 : 0; int flattened = EsdNumDims * (EbtNumTypes * (2 * (2 * (2 * (2 * arrayIndex + msIndex) + imageIndex) + shadowIndex) + externalIndex) + sampler.type) + sampler.dim; @@ -2992,8 +3623,10 @@ void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType ba if (! obeyPrecisionQualifiers() || parsingBuiltins) return; +#ifndef GLSLANG_WEB if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh) error(loc, "atomic counters can only be highp", "atomic_uint", ""); +#endif if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) { if (qualifier.precision == EpqNone) { @@ -3012,6 +3645,12 @@ void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque()) error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), ""); + if (!parsingBuiltins && type.contains16BitFloat()) + 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) @@ -3033,7 +3672,7 @@ bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType bas // // 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; @@ -3053,18 +3692,24 @@ void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TA 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; } } @@ -3122,7 +3767,7 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type) // void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes) { - if (arraySizes.hasUnsized()) + if (!parsingBuiltins && arraySizes.hasUnsized()) error(loc, "array size required", "", ""); } @@ -3159,46 +3804,57 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua 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", "[]", ""); +#ifndef GLSLANG_WEB + // desktop always allows outer-dimension-unsized variable arrays, - if (profile != EEsProfile) + if (!isEsProfile()) return; // for ES, if size isn't coming from an initializer, it has to be explicitly declared now, // with very few exceptions - // last member of ssbo block exception: - if (qualifier.storage == EvqBuffer && lastMember) - return; - // implicitly-sized io exceptions: switch (language) { case EShLangGeometry: if (qualifier.storage == EvqVaryingIn) - if ((profile == EEsProfile && version >= 320) || + if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_geometry_shader, AEP_geometry_shader)) return; break; case EShLangTessControl: if ( qualifier.storage == EvqVaryingIn || - (qualifier.storage == EvqVaryingOut && ! qualifier.patch)) - if ((profile == EEsProfile && version >= 320) || + (qualifier.storage == EvqVaryingOut && ! qualifier.isPatch())) + if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; case EShLangTessEvaluation: - if ((qualifier.storage == EvqVaryingIn && ! qualifier.patch) || + if ((qualifier.storage == EvqVaryingIn && ! qualifier.isPatch()) || qualifier.storage == EvqVaryingOut) - if ((profile == EEsProfile && version >= 320) || + if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; + case EShLangMeshNV: + if (qualifier.storage == EvqVaryingOut) + if ((isEsProfile() && version >= 320) || + extensionTurnedOn(E_GL_NV_mesh_shader)) + return; + break; default: break; } +#endif + + // last member of ssbo block exception: + if (qualifier.storage == EvqBuffer && lastMember) + return; + arraySizeRequiredCheck(loc, *arraySizes); } @@ -3239,6 +3895,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie if (symbolTable.atGlobalLevel()) trackLinkage(*symbol); +#ifndef GLSLANG_WEB if (! symbolTable.atBuiltInLevel()) { if (isIoResizeArray(type)) { ioArraySymbolResizeList.push_back(symbol); @@ -3246,6 +3903,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie } else fixIoArraySize(loc, symbol->getWritableType()); } +#endif return; } @@ -3283,6 +3941,7 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie return; } +#ifndef GLSLANG_WEB 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())) @@ -3296,8 +3955,11 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie if (isIoResizeArray(type)) checkIoArraysConsistency(loc); +#endif } +#ifndef GLSLANG_WEB + // Policy and error check for needing a runtime sized array. void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base) { @@ -3305,9 +3967,24 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType if (isRuntimeLength(base)) return; + // 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()->isReference()) { + + const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + const int memberCount = (int)binary->getLeft()->getType().getReferentType()->getStruct()->size(); + if (index == memberCount - 1) + return; + } + } + // check for additional things allowed by GL_EXT_nonuniform_qualifier - if (base.getBasicType() == EbtSampler || - (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) + if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStructNV || + (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"); @@ -3322,6 +3999,10 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) { // is it the last member? const int index = binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + + if (binary->getLeft()->isReference()) + return false; + const int memberCount = (int)binary->getLeft()->getType().getStruct()->size(); if (index == memberCount - 1) return true; @@ -3331,6 +4012,35 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const return false; } +// Check if mesh perviewNV attributes have a view dimension +// and resize it to gl_MaxMeshViewCountNV when implicitly sized. +void TParseContext::checkAndResizeMeshViewDim(const TSourceLoc& loc, TType& type, bool isBlockMember) +{ + // see if member is a per-view attribute + if (!type.getQualifier().isPerView()) + return; + + if ((isBlockMember && type.isArray()) || (!isBlockMember && type.isArrayOfArrays())) { + // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value. + int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV; + // For block members, outermost array dimension is the view dimension. + // For non-block members, outermost array dimension is the vertex/primitive dimension + // and 2nd outermost is the view dimension. + int viewDim = isBlockMember ? 0 : 1; + int viewDimSize = type.getArraySizes()->getDimSize(viewDim); + + if (viewDimSize != UnsizedArraySize && viewDimSize != maxViewCount) + error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", ""); + else if (viewDimSize == UnsizedArraySize) + type.getArraySizes()->setDimSize(viewDim, maxViewCount); + } + else { + error(loc, "requires a view array dimension", "perviewNV", ""); + } +} + +#endif // GLSLANG_WEB + // Returns true if the first argument to the #line directive is the line number for the next line. // // Desktop, pre-version 3.30: "After processing this directive @@ -3342,7 +4052,7 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const // source string number source-string-number. bool TParseContext::lineDirectiveShouldSetNextLine() const { - return profile == EEsProfile || version >= 330; + return isEsProfile() || version >= 330; } // @@ -3373,18 +4083,19 @@ void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType) { +#ifndef GLSLANG_WEB if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel()) return nullptr; - bool nonEsRedecls = (profile != EEsProfile && (version >= 130 || identifier == "gl_TexCoord")); - bool esRedecls = (profile == EEsProfile && + bool nonEsRedecls = (!isEsProfile() && (version >= 130 || identifier == "gl_TexCoord")); + bool esRedecls = (isEsProfile() && (version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks))); if (! esRedecls && ! nonEsRedecls) return nullptr; // Special case when using GL_ARB_separate_shader_objects bool ssoPre150 = false; // means the only reason this variable is redeclared is due to this combination - if (profile != EEsProfile && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) { + if (!isEsProfile() && version <= 140 && extensionTurnedOn(E_GL_ARB_separate_shader_objects)) { if (identifier == "gl_Position" || identifier == "gl_PointSize" || identifier == "gl_ClipVertex" || @@ -3405,10 +4116,11 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS identifier == "gl_BackSecondaryColor" || identifier == "gl_SecondaryColor" || (identifier == "gl_Color" && language == EShLangFragment) || -#ifdef NV_EXTENSIONS + (identifier == "gl_FragStencilRefARB" && (nonEsRedecls && version >= 140) + && language == EShLangFragment) || identifier == "gl_SampleMask" || identifier == "gl_Layer" || -#endif + identifier == "gl_PrimitiveIndicesNV" || identifier == "gl_TexCoord") { // Find the existing symbol, if any. @@ -3487,7 +4199,14 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str()); } } -#ifdef NV_EXTENSIONS + else if ( + identifier == "gl_PrimitiveIndicesNV" || + 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()); + } else if (identifier == "gl_SampleMask") { if (!publicType.layoutOverrideCoverage) { error(loc, "redeclaration only allowed for override_coverage layout", "redeclaration", symbol->getName().c_str()); @@ -3500,12 +4219,12 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative; symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset; } -#endif // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above return symbol; } +#endif return nullptr; } @@ -3517,11 +4236,13 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes) { +#ifndef GLSLANG_WEB 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" && + blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV") { error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str()); return; } @@ -3569,7 +4290,9 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) { if (!currentBlockQualifier.hasXfbBuffer()) currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; - fixBlockXfbOffsets(currentBlockQualifier, newTypeList); + if (!currentBlockQualifier.hasStream()) + currentBlockQualifier.layoutStream = globalOutputDefaults.layoutStream; + fixXfbOffsets(currentBlockQualifier, newTypeList); } // Edit and error check the container against the redeclaration @@ -3578,7 +4301,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT TType& type = block->getWritableType(); -#ifdef NV_EXTENSIONS // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position" // for passthrough purpose, the redeclared block should have the same qualifers as // the current one @@ -3588,7 +4310,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT type.getQualifier().layoutStream = currentBlockQualifier.layoutStream; type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; } -#endif TTypeList::iterator member = type.getWritableStruct()->begin(); size_t numOriginalMembersFound = 0; @@ -3617,10 +4338,29 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT 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.isSizedArray()) + 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()); + 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(), ""); if (newType.getQualifier().isMemory()) error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); if (newType.getQualifier().hasNonXfbLayout()) @@ -3630,6 +4370,9 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT 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; @@ -3641,8 +4384,8 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT oldType.getQualifier().layoutXfbBuffer = newType.getQualifier().layoutXfbBuffer; oldType.getQualifier().layoutXfbStride = newType.getQualifier().layoutXfbStride; if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) { - // if any member as 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 + // 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; oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; } @@ -3667,6 +4410,11 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT } } + 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) || @@ -3703,6 +4451,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT // Save it in the AST for linker use. trackLinkage(*block); +#endif // GLSLANG_WEB } void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type) @@ -3730,13 +4479,20 @@ void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQu void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type) { +#ifndef GLSLANG_WEB 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; } +#endif if (qualifier.isAuxiliary() || qualifier.isInterpolation()) @@ -3745,9 +4501,9 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali error(loc, "cannot use layout qualifiers on a function parameter", "", ""); if (qualifier.invariant) error(loc, "cannot use invariant qualifier on a function parameter", "", ""); - if (qualifier.noContraction) { + if (qualifier.isNoContraction()) { if (qualifier.isParamOutput()) - type.getQualifier().noContraction = true; + type.getQualifier().setNoContraction(); else warn(loc, "qualifier has no effect on non-output parameters", "precise", ""); } @@ -3786,6 +4542,49 @@ void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const error(loc, "can't use with samplers or structs containing samplers", op, ""); } +void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ +#ifndef GLSLANG_WEB + if (containsFieldWithBasicType(type, EbtReference)) + error(loc, "can't use with reference types", op, ""); +#endif +} + +void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op) +{ +#ifndef GLSLANG_WEB + 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"); +#endif +} + void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op) { if (type.containsSpecializationSize()) @@ -3835,6 +4634,7 @@ void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publ // void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop) { +#ifndef GLSLANG_WEB // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration bool badInit = false; if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1) @@ -3930,8 +4730,10 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, // the body inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable); +#endif } +#ifndef GLSLANG_WEB // Do limit checks for built-in arrays. void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size) { @@ -3941,7 +4743,12 @@ void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identi 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"); + 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 // GLSLANG_WEB // See if the provided value is less than or equal to the symbol indicated by limit, // which should be a constant in the symbol table. @@ -3955,6 +4762,8 @@ void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* lim error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst()); } +#ifndef GLSLANG_WEB + // // Do any additional error checking, etc., once we know the parsing is done. // @@ -3976,32 +4785,37 @@ void TParseContext::finish() // about the stage itself. switch (language) { case EShLangGeometry: - if (profile == EEsProfile && version == 310) + if (isEsProfile() && version == 310) requireExtensions(getCurrentLoc(), Num_AEP_geometry_shader, AEP_geometry_shader, "geometry shaders"); break; case EShLangTessControl: case EShLangTessEvaluation: - if (profile == EEsProfile && version == 310) + if (isEsProfile() && version == 310) requireExtensions(getCurrentLoc(), Num_AEP_tessellation_shader, AEP_tessellation_shader, "tessellation shaders"); - else if (profile != EEsProfile && version < 400) + else if (!isEsProfile() && version < 400) requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_tessellation_shader, "tessellation shaders"); break; case EShLangCompute: - if (profile != EEsProfile && version < 430) + if (!isEsProfile() && version < 430) requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders"); break; + 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; 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(ElgTriangles); break; + case ElgTriangles: intermediate.setOutputPrimitive(ElgTriangleStrip); break; default: break; } } @@ -4014,8 +4828,8 @@ void TParseContext::finish() } } } -#endif } +#endif // GLSLANG_WEB // // Layout qualifier stuff. @@ -4051,6 +4865,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutPacking = ElpStd140; return; } +#ifndef GLSLANG_WEB if (id == TQualifier::getLayoutPackingString(ElpStd430)) { requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430"); @@ -4058,6 +4873,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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)) { @@ -4076,44 +4897,52 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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 || language == EShLangMeshNV) { if (id == TQualifier::getGeometryString(ElgTriangles)) { publicType.shaderQualifiers.geometry = ElgTriangles; return; } - if (language == EShLangGeometry) { + if (language == EShLangGeometry || language == EShLangMeshNV) { 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 (language == EShLangGeometry) { + 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; + } + if (id == "passthrough") { + requireExtensions(loc, 1, &E_SPV_NV_geometry_shader_passthrough, "geometry shader passthrough"); + publicType.qualifier.layoutPassthrough = true; + intermediate.setGeoPassthroughEXT(); + 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); @@ -4195,6 +5024,17 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } } + for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) { + if (id == TQualifier::getInterlockOrderingString(order)) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 450, nullptr, "fragment shader interlock layout qualifier"); + requireExtensions(loc, 1, &E_GL_ARB_fragment_shader_interlock, TQualifier::getInterlockOrderingString(order)); + if (order == EioShadingRateInterlockOrdered || order == EioShadingRateInterlockUnordered) + requireExtensions(loc, 1, &E_GL_NV_shading_rate_image, TQualifier::getInterlockOrderingString(order)); + publicType.shaderQualifiers.interlockOrdering = order; + return; + } + } if (id.compare(0, 13, "blend_support") == 0) { bool found = false; for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) { @@ -4211,7 +5051,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "unknown blend equation", "blend_support", ""); return; } -#ifdef NV_EXTENSIONS if (id == "override_coverage") { requireExtensions(loc, 1, &E_GL_NV_sample_mask_override_coverage, "sample mask override coverage"); publicType.shaderQualifiers.layoutOverrideCoverage = true; @@ -4227,10 +5066,30 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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; + } + } } -#else + 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; + } + } } #endif + error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); } @@ -4244,6 +5103,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi integerCheck(node, feature); const TIntermConstantUnion* constUnion = node->getAsConstantUnion(); int value; + bool nonLiteral = false; if (constUnion) { value = constUnion->getConstArray()[0].getIConst(); if (! constUnion->isLiteral()) { @@ -4253,6 +5113,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } else { // grammar should have give out the error message value = 0; + nonLiteral = true; } if (value < 0) { @@ -4274,6 +5135,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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"; @@ -4286,15 +5149,20 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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"); - const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + // GL_ARB_explicit_uniform_location requires 330 or GL_ARB_explicit_attrib_location we do not need to add it here profileRequires(loc, ~EEsProfile, 330, 2, exts, "location"); if ((unsigned int)value >= TQualifier::layoutLocationEnd) 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) @@ -4303,24 +5171,49 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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") { +#ifndef GLSLANG_WEB profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); profileRequires(loc, EEsProfile, 310, nullptr, "binding"); +#endif if ((unsigned int)value >= TQualifier::layoutBindingEnd) 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") { + } + if (id == "constant_id") { + requireSpv(loc, "constant_id"); + if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { + error(loc, "specialization-constant id is too large", id.c_str(), ""); + } else { + publicType.qualifier.layoutSpecConstantId = value; + publicType.qualifier.specConstant = true; + 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; + } +#ifndef GLSLANG_WEB + if (id == "component") { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component"); if ((unsigned)value >= TQualifier::layoutComponentEnd) 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) { + } + if (id.compare(0, 4, "xfb_") == 0) { // "Any shader making any static use (after preprocessing) of any of these // *xfb_* qualifiers will cause the shader to be in a transform feedback // capturing mode and hence responsible for describing the transform feedback @@ -4339,53 +5232,50 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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; } } - if (id == "input_attachment_index") { requireVulkan(loc, "input_attachment_index"); if (value >= (int)TQualifier::layoutAttachmentEnd) error(loc, "attachment index is too large", id.c_str(), ""); else publicType.qualifier.layoutAttachment = value; - return; - } - if (id == "constant_id") { - requireSpv(loc, "constant_id"); - if (value >= (int)TQualifier::layoutSpecConstantIdEnd) { - error(loc, "specialization-constant id is too large", id.c_str(), ""); - } else { - publicType.qualifier.layoutSpecConstantId = value; - publicType.qualifier.specConstant = true; - if (! intermediate.addUsedConstantId(value)) - error(loc, "specialization-constant id already used", id.c_str(), ""); - } + if (nonLiteral) + error(loc, "needs a literal integer", "input_attachment_index", ""); 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; } - -#if NV_EXTENSIONS if (language == EShLangVertex || language == EShLangTessControl || language == EShLangTessEvaluation || @@ -4393,28 +5283,38 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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; } } + + 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; + } #endif switch (language) { - case EShLangVertex: - break; - +#ifndef GLSLANG_WEB case EShLangTessControl: if (id == "vertices") { if (value == 0) error(loc, "must be greater than 0", "vertices", ""); else publicType.shaderQualifiers.vertices = value; + if (nonLiteral) + error(loc, "needs a literal integer", "vertices", ""); return; } break; - case EShLangTessEvaluation: - break; - case EShLangGeometry: if (id == "invocations") { profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, nullptr, "invocations"); @@ -4422,12 +5322,16 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi 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") { @@ -4435,6 +5339,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutStream = value; if (value > 0) intermediate.setMultiStream(); + if (nonLiteral) + error(loc, "needs a literal integer", "stream", ""); return; } break; @@ -4452,28 +5358,65 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } publicType.qualifier.layoutIndex = value; + if (nonLiteral) + error(loc, "needs a literal integer", "index", ""); return; } break; + 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"); +#ifndef GLSLANG_WEB + if (language == EShLangMeshNV || language == EShLangTaskNV) { + requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize"); + } else { + profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); + profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); + } +#endif + 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; } if (id == "local_size_x") { publicType.shaderQualifiers.localSize[0] = value; + publicType.shaderQualifiers.localSizeNotDefault[0] = true; return; } if (id == "local_size_y") { publicType.shaderQualifiers.localSize[1] = value; + publicType.shaderQualifiers.localSizeNotDefault[1] = true; return; } if (id == "local_size_z") { publicType.shaderQualifiers.localSize[2] = value; + publicType.shaderQualifiers.localSizeNotDefault[2] = true; return; } if (spvVersion.spv != 0) { @@ -4521,14 +5464,16 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie if (src.hasPacking()) dst.layoutPacking = src.layoutPacking; +#ifndef GLSLANG_WEB if (src.hasStream()) dst.layoutStream = src.layoutStream; - if (src.hasFormat()) dst.layoutFormat = src.layoutFormat; - if (src.hasXfbBuffer()) dst.layoutXfbBuffer = src.layoutXfbBuffer; + if (src.hasBufferReferenceAlign()) + dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign; +#endif if (src.hasAlign()) dst.layoutAlign = src.layoutAlign; @@ -4536,38 +5481,43 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie if (! inheritOnly) { if (src.hasLocation()) dst.layoutLocation = src.layoutLocation; - if (src.hasComponent()) - dst.layoutComponent = src.layoutComponent; - if (src.hasIndex()) - dst.layoutIndex = src.layoutIndex; - if (src.hasOffset()) dst.layoutOffset = src.layoutOffset; - if (src.hasSet()) dst.layoutSet = src.layoutSet; if (src.layoutBinding != TQualifier::layoutBindingEnd) dst.layoutBinding = src.layoutBinding; + if (src.hasSpecConstantId()) + dst.layoutSpecConstantId = src.layoutSpecConstantId; + +#ifndef GLSLANG_WEB + if (src.hasComponent()) + dst.layoutComponent = src.layoutComponent; + if (src.hasIndex()) + dst.layoutIndex = src.layoutIndex; if (src.hasXfbStride()) dst.layoutXfbStride = src.layoutXfbStride; if (src.hasXfbOffset()) dst.layoutXfbOffset = src.layoutXfbOffset; if (src.hasAttachment()) dst.layoutAttachment = src.layoutAttachment; - if (src.hasSpecConstantId()) - dst.layoutSpecConstantId = src.layoutSpecConstantId; - if (src.layoutPushConstant) dst.layoutPushConstant = true; -#ifdef NV_EXTENSIONS + if (src.layoutBufferReference) + dst.layoutBufferReference = true; + if (src.layoutPassthrough) dst.layoutPassthrough = true; if (src.layoutViewportRelative) dst.layoutViewportRelative = true; if (src.layoutSecondaryViewportRelativeOffset != -2048) dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset; + if (src.layoutShaderRecordNV) + dst.layoutShaderRecordNV = true; + if (src.pervertexNV) + dst.pervertexNV = true; #endif } } @@ -4604,9 +5554,10 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb 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: @@ -4625,13 +5576,15 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb if (qualifier.hasPacking()) error(loc, "cannot specify packing on a variable declaration", "layout", ""); // "The offset qualifier can only be used on block members of blocks..." - if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint) + if (qualifier.hasOffset() && !type.isAtomic()) error(loc, "cannot specify on a variable declaration", "offset", ""); // "The align qualifier can only be used on blocks or block members..." if (qualifier.hasAlign()) error(loc, "cannot specify on a variable declaration", "align", ""); - if (qualifier.layoutPushConstant) + if (qualifier.isPushConstant()) error(loc, "can only specify on a uniform block", "push_constant", ""); + if (qualifier.isShaderRecordNV()) + error(loc, "can only specify on a buffer block", "shaderRecordNV", ""); } break; default: @@ -4695,12 +5648,22 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) case EvqVaryingOut: if (type.getBasicType() == EbtBlock) profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "location qualifier on in/out block"); + if (type.getQualifier().isTaskMemory()) + error(loc, "cannot apply to taskNV in/out blocks", "location", ""); break; case EvqUniform: case EvqBuffer: if (type.getBasicType() == EbtBlock) error(loc, "cannot apply to uniform or buffer block", "location", ""); break; +#ifndef GLSLANG_WEB + 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; @@ -4716,6 +5679,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated); } +#ifndef GLSLANG_WEB if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) { int repeated = intermediate.addXfbBufferOffset(type); if (repeated >= 0) @@ -4723,20 +5687,24 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // "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", ""); - // ..., 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", ""); - else if (! IsMultipleOfPow2(qualifier.layoutXfbOffset, 4)) + // 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", ""); + 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.contains16BitFloat() || 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", ""); } - if (qualifier.hasXfbStride() && qualifier.hasXfbBuffer()) { if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride)) error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); } +#endif if (qualifier.hasBinding()) { // Binding checking, from the spec: @@ -4759,15 +5727,19 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) lastBinding += type.getCumulativeArraySize(); else { lastBinding += 1; +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0) warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", ""); +#endif } } } +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); +#endif } - if (type.getBasicType() == EbtAtomicUint) { + if (type.isAtomic()) { if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", ""); return; @@ -4777,14 +5749,16 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // some types require bindings // atomic_uint - if (type.getBasicType() == EbtAtomicUint) + if (type.isAtomic()) error(loc, "layout(binding=X) is required", "atomic_uint", ""); // SPIR-V if (spvVersion.spv > 0) { if (qualifier.isUniformOrBuffer()) { - if (type.getBasicType() == EbtBlock && !qualifier.layoutPushConstant && - !qualifier.layoutAttachment) + if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() && + !qualifier.isShaderRecordNV() && + !qualifier.hasAttachment() && + !qualifier.hasBufferReference()) 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", ""); @@ -4809,33 +5783,39 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // Image format if (qualifier.hasFormat()) { if (! type.isImage()) - error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); else { - if (type.getSampler().type == EbtFloat && qualifier.layoutFormat > ElfFloatGuard) - error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); - if (type.getSampler().type == EbtInt && (qualifier.layoutFormat < ElfFloatGuard || qualifier.layoutFormat > ElfIntGuard)) - error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); - if (type.getSampler().type == EbtUint && qualifier.layoutFormat < ElfIntGuard) - error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard) + error(loc, "does not apply to floating point images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); + if (type.getSampler().type == EbtInt && (qualifier.getFormat() < ElfFloatGuard || qualifier.getFormat() > ElfIntGuard)) + error(loc, "does not apply to signed integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); + if (type.getSampler().type == EbtUint && qualifier.getFormat() < ElfIntGuard) + error(loc, "does not apply to unsigned integer images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); - if (profile == EEsProfile) { + if (isEsProfile()) { // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must // specify either memory qualifier readonly or the memory qualifier writeonly." - if (! (qualifier.layoutFormat == ElfR32f || qualifier.layoutFormat == ElfR32i || qualifier.layoutFormat == ElfR32ui)) { - if (! qualifier.readonly && ! qualifier.writeonly) - error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.layoutFormat), ""); + if (! (qualifier.getFormat() == ElfR32f || qualifier.getFormat() == ElfR32i || qualifier.getFormat() == ElfR32ui)) { + if (! qualifier.isReadOnly() && ! qualifier.isWriteOnly()) + error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); } } } - } else if (type.isImage() && ! qualifier.writeonly) { + } else if (type.isImage() && ! qualifier.isWriteOnly()) { const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier"; requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation); } - if (qualifier.layoutPushConstant && type.getBasicType() != EbtBlock) + if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "push_constant", ""); + if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock) + error(loc, "can only be used with a block", "buffer_reference", ""); + + if (qualifier.isShaderRecordNV() && type.getBasicType() != EbtBlock) + error(loc, "can only be used with a block", "shaderRecordNV", ""); + // input attachment if (type.isSubpass()) { if (! qualifier.hasAttachment()) @@ -4891,10 +5871,11 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier // output block declarations, and output block member declarations." switch (qualifier.storage) { +#ifndef GLSLANG_WEB case EvqVaryingIn: { const char* feature = "location qualifier on input"; - if (profile == EEsProfile && version < 310) + if (isEsProfile() && version < 310) requireStage(loc, EShLangVertex, feature); else requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); @@ -4911,7 +5892,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier case EvqVaryingOut: { const char* feature = "location qualifier on output"; - if (profile == EEsProfile && version < 310) + if (isEsProfile() && version < 310) requireStage(loc, EShLangFragment, feature); else requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature); @@ -4925,12 +5906,14 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier } break; } +#endif case EvqUniform: case EvqBuffer: { const char* feature = "location qualifier on uniform or buffer"; - requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, feature); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, feature); + requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile | ENoProfile, feature); + profileRequires(loc, ~EEsProfile, 330, E_GL_ARB_explicit_attrib_location, feature); + profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_explicit_uniform_location, feature); profileRequires(loc, EEsProfile, 310, nullptr, feature); break; } @@ -4946,7 +5929,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier } if (qualifier.hasBinding()) { - if (! qualifier.isUniformOrBuffer()) + if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) error(loc, "requires uniform or buffer storage qualifier", "binding", ""); } if (qualifier.hasStream()) { @@ -4958,24 +5941,41 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier 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()) error(loc, "offset/align can only be used on a uniform or buffer", "layout", ""); } } - if (qualifier.layoutPushConstant) { + if (qualifier.isPushConstant()) { if (qualifier.storage != EvqUniform) error(loc, "can only be used with a uniform", "push_constant", ""); if (qualifier.hasSet()) error(loc, "cannot be used with push_constant", "set", ""); } + if (qualifier.hasBufferReference()) { + if (qualifier.storage != EvqBuffer) + error(loc, "can only be used with buffer", "buffer_reference", ""); + } + if (qualifier.isShaderRecordNV()) { + 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", ""); + } } // For places that can't have shader-level layout qualifiers void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers) { +#ifndef GLSLANG_WEB const char* message = "can only apply to a standalone qualifier"; if (shaderQualifiers.geometry != ElgNone) @@ -4988,10 +5988,6 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "point_mode", ""); if (shaderQualifiers.invocations != TQualifier::layoutNotSet) error(loc, message, "invocations", ""); - if (shaderQualifiers.earlyFragmentTests) - error(loc, message, "early_fragment_tests", ""); - if (shaderQualifiers.postDepthCoverage) - error(loc, message, "post_depth_coverage", ""); for (int i = 0; i < 3; ++i) { if (shaderQualifiers.localSize[i] > 1) error(loc, message, "local_size", ""); @@ -4999,24 +5995,38 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "local_size id", ""); } if (shaderQualifiers.vertices != TQualifier::layoutNotSet) { - if (language == EShLangGeometry) + if (language == EShLangGeometry || language == EShLangMeshNV) error(loc, message, "max_vertices", ""); else if (language == EShLangTessControl) error(loc, message, "vertices", ""); else assert(0); } - if (shaderQualifiers.blendEquation) + if (shaderQualifiers.earlyFragmentTests) + error(loc, message, "early_fragment_tests", ""); + if (shaderQualifiers.postDepthCoverage) + error(loc, message, "post_depth_coverage", ""); + if (shaderQualifiers.primitives != TQualifier::layoutNotSet) { + if (language == EShLangMeshNV) + error(loc, message, "max_primitives", ""); + else + assert(0); + } + if (shaderQualifiers.hasBlendEquation()) error(loc, message, "blend equation", ""); if (shaderQualifiers.numViews != TQualifier::layoutNotSet) error(loc, message, "num_views", ""); + if (shaderQualifiers.interlockOrdering != EioNone) + error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), ""); +#endif } // Correct and/or advance an object's offset layout qualifier. void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) { const TQualifier& qualifier = symbol.getType().getQualifier(); - if (symbol.getType().getBasicType() == EbtAtomicUint) { +#ifndef GLSLANG_WEB + if (symbol.getType().isAtomic()) { if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) { // Set the offset @@ -5025,6 +6035,10 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) offset = qualifier.layoutOffset; else offset = atomicUintOffsets[qualifier.layoutBinding]; + + if (offset % 4 != 0) + error(loc, "atomic counters offset should align based on 4:", "offset", "%d", offset); + symbol.getWritableType().getQualifier().layoutOffset = offset; // Check for overlap @@ -5045,6 +6059,7 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets; } } +#endif } // @@ -5054,26 +6069,29 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) // const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunction& call, bool& builtIn) { - const TFunction* function = nullptr; - if (symbolTable.isFunctionNameVariable(call.getName())) { error(loc, "can't use function syntax on variable", call.getName().c_str(), ""); return nullptr; } - bool explicitTypesEnabled = extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int8) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int16) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int32) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int64) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float32) || - extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float64); +#ifdef GLSLANG_WEB + return findFunctionExact(loc, call, builtIn); +#endif - if (profile == EEsProfile || version < 120) + const TFunction* function = 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 (isEsProfile() || version < 120) function = findFunctionExact(loc, call, builtIn); else if (version < 400) - function = findFunction120(loc, call, builtIn); + function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn); else if (explicitTypesEnabled) function = findFunctionExplicitTypes(loc, call, builtIn); else @@ -5218,11 +6236,22 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu 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; + if (from.isCoopMat() && to.isCoopMat()) + return from.sameCoopMatBaseType(to); return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); }; @@ -5283,11 +6312,22 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, 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; + if (from.isCoopMat() && to.isCoopMat()) + return from.sameCoopMatBaseType(to); return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType()); }; @@ -5339,21 +6379,26 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc, return bestMatch; } -// When a declaration includes a type, but not a variable name, it can be +// When a declaration includes a type, but not a variable name, it can be used // to establish defaults. void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType) { - if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding() && publicType.qualifier.hasOffset()) { +#ifndef GLSLANG_WEB + if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding()) { if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large", "binding", ""); return; } - atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset; + + if(publicType.qualifier.hasOffset()) { + atomicUintOffsets[publicType.qualifier.layoutBinding] = publicType.qualifier.layoutOffset; + } return; } - if (publicType.qualifier.hasLayout()) + if (publicType.qualifier.hasLayout() && !publicType.qualifier.hasBufferReference()) warn(loc, "useless application of layout qualifier", "layout", ""); +#endif } // @@ -5377,6 +6422,33 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden 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) { + if (isTypeFloat(publicType.basicType) && + 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(), ""); + } + if (isTypeInt(publicType.basicType) && + publicType.typeParameters->getDimSize(0) != 8 && + publicType.typeParameters->getDimSize(0) != 32) { + error(loc, "expected 8 or 32 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())) return nullptr; @@ -5386,12 +6458,31 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden nonInitConstCheck(loc, identifier, type); samplerCheck(loc, type, identifier, initializer); - atomicUintCheck(loc, type, identifier); transparentOpaqueCheck(loc, type, identifier); +#ifndef GLSLANG_WEB + atomicUintCheck(loc, type, identifier); + accStructNVCheck(loc, type, identifier); + checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false); +#endif + if (type.getQualifier().storage == EvqConst && type.containsReference()) { + error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", ""); + } + + if (type.getQualifier().storage != EvqUniform && type.getQualifier().storage != EvqBuffer) { + if (type.contains16BitFloat()) + 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", ""); - if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone) + if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone) error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", ""); // Check for redeclaration of built-ins and/or attempting to declare a reserved name @@ -5447,12 +6538,14 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden // Pick up global defaults from the provide global defaults into dst. void TParseContext::inheritGlobalDefaults(TQualifier& dst) const { +#ifndef GLSLANG_WEB if (dst.storage == EvqVaryingOut) { if (! dst.hasStream() && language == EShLangGeometry) dst.layoutStream = globalOutputDefaults.layoutStream; if (! dst.hasXfbBuffer()) dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; } +#endif } // @@ -5481,7 +6574,9 @@ TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& // make a new variable TVariable* variable = new TVariable(&identifier, type); +#ifndef GLSLANG_WEB ioArrayCheck(loc, type, identifier); +#endif // add variable to symbol table if (symbolTable.insert(*variable)) { @@ -5508,7 +6603,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // TStorageQualifier qualifier = variable->getType().getQualifier().storage; if (! (qualifier == EvqTemporary || qualifier == EvqGlobal || qualifier == EvqConst || - (qualifier == EvqUniform && profile != EEsProfile && version >= 120))) { + (qualifier == EvqUniform && !isEsProfile() && version >= 120))) { error(loc, " cannot initialize this type of qualifier ", variable->getType().getStorageQualifierString(), ""); return nullptr; } @@ -5526,7 +6621,9 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp TType skeletalType; skeletalType.shallowCopy(variable->getType()); skeletalType.getQualifier().makeTemporary(); +#ifndef GLSLANG_WEB initializer = convertInitializerList(loc, skeletalType, initializer); +#endif if (! initializer) { // error recovery; don't leave const without constant values if (qualifier == EvqConst) @@ -5580,7 +6677,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // qualifier any initializer must be a constant expression." if (symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { const char* initFeature = "non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)"; - if (profile == EEsProfile) { + if (isEsProfile()) { if (relaxedErrors() && ! extensionTurnedOn(E_GL_EXT_shader_non_constant_global_initializers)) warn(loc, "not allowed in this version", initFeature, ""); else @@ -5740,8 +6837,14 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* // 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) @@ -5825,7 +6928,7 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T // 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. + // the recursive call work, and avoids the most egregious 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()); @@ -5856,6 +6959,35 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T basicOp = EOpConstructFloat; break; + case EOpConstructIVec2: + case EOpConstructIVec3: + case EOpConstructIVec4: + case EOpConstructInt: + basicOp = EOpConstructInt; + break; + + case EOpConstructUVec2: + if (node->getType().getBasicType() == EbtReference) { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "reference conversion to uvec2"); + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node, + type); + return newNode; + } + case EOpConstructUVec3: + case EOpConstructUVec4: + case EOpConstructUint: + basicOp = EOpConstructUint; + break; + + case EOpConstructBVec2: + case EOpConstructBVec3: + case EOpConstructBVec4: + case EOpConstructBool: + basicOp = EOpConstructBool; + break; + +#ifndef GLSLANG_WEB + case EOpConstructDVec2: case EOpConstructDVec3: case EOpConstructDVec4: @@ -5886,6 +7018,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructF16Mat4x4: case EOpConstructFloat16: basicOp = EOpConstructFloat16; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticFloat16Enabled()) { + TType tempType(EbtFloat, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructFloat16) + aggregateOp = EOpConstructFloat; + else + aggregateOp = (TOperator)(EOpConstructVec2 + op - EOpConstructF16Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtFloat16, newNode); + return newNode; + } break; case EOpConstructI8Vec2: @@ -5893,6 +7041,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructI8Vec4: case EOpConstructInt8: basicOp = EOpConstructInt8; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt8Enabled()) { + TType tempType(EbtInt, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructInt8) + aggregateOp = EOpConstructInt; + else + aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI8Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtInt8, newNode); + return newNode; + } break; case EOpConstructU8Vec2: @@ -5900,6 +7064,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructU8Vec4: case EOpConstructUint8: basicOp = EOpConstructUint8; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt8Enabled()) { + TType tempType(EbtUint, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructUint8) + aggregateOp = EOpConstructUint; + else + aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU8Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtUint8, newNode); + return newNode; + } break; case EOpConstructI16Vec2: @@ -5907,6 +7087,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructI16Vec4: case EOpConstructInt16: basicOp = EOpConstructInt16; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt16Enabled()) { + TType tempType(EbtInt, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructInt16) + aggregateOp = EOpConstructInt; + else + aggregateOp = (TOperator)(EOpConstructIVec2 + op - EOpConstructI16Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtInt16, newNode); + return newNode; + } break; case EOpConstructU16Vec2: @@ -5914,20 +7110,22 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructU16Vec4: case EOpConstructUint16: basicOp = EOpConstructUint16; - break; - - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - case EOpConstructInt: - basicOp = EOpConstructInt; - break; - - case EOpConstructUVec2: - case EOpConstructUVec3: - case EOpConstructUVec4: - case EOpConstructUint: - basicOp = EOpConstructUint; + // 8/16-bit storage extensions don't support constructing composites of 8/16-bit types, + // so construct a 32-bit type and convert + if (!intermediate.getArithemeticInt16Enabled()) { + TType tempType(EbtUint, EvqTemporary, type.getVectorSize()); + newNode = node; + if (tempType != newNode->getType()) { + TOperator aggregateOp; + if (op == EOpConstructUint16) + aggregateOp = EOpConstructUint; + else + aggregateOp = (TOperator)(EOpConstructUVec2 + op - EOpConstructU16Vec2); + newNode = intermediate.setAggregateOperator(newNode, aggregateOp, tempType, node->getLoc()); + } + newNode = intermediate.addConversion(EbtUint16, newNode); + return newNode; + } break; case EOpConstructI64Vec2: @@ -5937,24 +7135,128 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T basicOp = EOpConstructInt64; break; + case EOpConstructUint64: + if (type.isScalar() && node->getType().isReference()) { + 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; - case EOpConstructBVec2: - case EOpConstructBVec3: - case EOpConstructBVec4: - case EOpConstructBool: - basicOp = EOpConstructBool; - break; - case EOpConstructNonuniform: - node->getWritableType().getQualifier().nonUniform = true; + // Make a nonuniform copy of node + newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpCopyObject, true, node, type); + return newNode; + + case EOpConstructReference: + // construct reference from reference + if (node->getType().isReference()) { + 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; + // construct reference from uvec2 + } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint && + node->getVectorSize() == 2) { + requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "uvec2 conversion to reference"); + TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToPtr, 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 { + TOperator op = EOpNull; + switch (type.getBasicType()) { + default: + assert(0); + break; + case EbtInt: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToInt; break; + case EbtFloat16: op = EOpConvFloat16ToInt; break; + case EbtUint8: op = EOpConvUint8ToInt; break; + case EbtInt8: op = EOpConvInt8ToInt; break; + case EbtUint: op = EOpConvUintToInt; break; + default: assert(0); + } + break; + case EbtUint: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToUint; break; + case EbtFloat16: op = EOpConvFloat16ToUint; break; + case EbtUint8: op = EOpConvUint8ToUint; break; + case EbtInt8: op = EOpConvInt8ToUint; break; + case EbtInt: op = EOpConvIntToUint; break; + case EbtUint: op = EOpConvUintToInt8; break; + default: assert(0); + } + break; + case EbtInt8: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToInt8; break; + case EbtFloat16: op = EOpConvFloat16ToInt8; break; + case EbtUint8: op = EOpConvUint8ToInt8; break; + case EbtInt: op = EOpConvIntToInt8; break; + case EbtUint: op = EOpConvUintToInt8; break; + default: assert(0); + } + break; + case EbtUint8: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToUint8; break; + case EbtFloat16: op = EOpConvFloat16ToUint8; break; + case EbtInt8: op = EOpConvInt8ToUint8; break; + case EbtInt: op = EOpConvIntToUint8; break; + case EbtUint: op = EOpConvUintToUint8; break; + default: assert(0); + } + break; + case EbtFloat: + switch (node->getType().getBasicType()) { + case EbtFloat16: op = EOpConvFloat16ToFloat; break; + case EbtInt8: op = EOpConvInt8ToFloat; break; + case EbtUint8: op = EOpConvUint8ToFloat; break; + case EbtInt: op = EOpConvIntToFloat; break; + case EbtUint: op = EOpConvUintToFloat; break; + default: assert(0); + } + break; + case EbtFloat16: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToFloat16; break; + case EbtInt8: op = EOpConvInt8ToFloat16; break; + case EbtUint8: op = EOpConvUint8ToFloat16; break; + case EbtInt: op = EOpConvIntToFloat16; break; + case EbtUint: op = EOpConvUintToFloat16; break; + default: assert(0); + } + break; + } + + node = intermediate.addUnaryNode(op, node, node->getLoc(), type); + // 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; - break; + +#endif // GLSLANG_WEB default: error(loc, "unsupported construction", "", ""); @@ -5997,6 +7299,23 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& return converted; } +// If a memory qualifier is present in 'to', also make it present in 'from'. +void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to) +{ +#ifndef GLSLANG_WEB + if (from.isReadOnly()) + to.readonly = from.readonly; + if (from.isWriteOnly()) + to.writeonly = from.writeonly; + if (from.coherent) + to.coherent = from.coherent; + if (from.volatil) + to.volatil = from.volatil; + if (from.restrict) + to.restrict = from.restrict; +#endif +} + // // Do everything needed to add an interface block. // @@ -6012,7 +7331,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con requireProfile(loc, ~EEsProfile, "array-of-array of block"); } - // fix and check for member storage qualifiers and types that don't belong within a block + // Inherit and check member storage qualifiers WRT to the block-level qualifier. for (unsigned int member = 0; member < typeList.size(); ++member) { TType& memberType = *typeList[member].type; TQualifier& memberQualifier = memberType.getQualifier(); @@ -6021,6 +7340,15 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con 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; +#ifndef GLSLANG_WEB + inheritMemoryQualifiers(currentBlockQualifier, memberQualifier); + 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()) @@ -6034,6 +7362,9 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con 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 @@ -6063,7 +7394,12 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // 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.isPushConstant() && !currentBlockQualifier.hasPacking()) || + (currentBlockQualifier.isShaderRecordNV() && !currentBlockQualifier.hasPacking())) + currentBlockQualifier.layoutPacking = ElpStd430; + + // Special case for "taskNV in/out", which has a default of std430, + if (currentBlockQualifier.isTaskMemory() && !currentBlockQualifier.hasPacking()) currentBlockQualifier.layoutPacking = ElpStd430; // fix and check for member layout qualifiers @@ -6072,17 +7408,21 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // "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; + bool memberWithPerViewQualifier = false; for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier& memberQualifier = typeList[member].type->getQualifier(); const TSourceLoc& memberLoc = typeList[member].loc; +#ifndef GLSLANG_WEB if (memberQualifier.hasStream()) { if (defaultQualification.layoutStream != memberQualifier.layoutStream) error(memberLoc, "member cannot contradict block", "stream", ""); @@ -6096,12 +7436,14 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer) error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); } +#endif if (memberQualifier.hasPacking()) error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), ""); if (memberQualifier.hasLocation()) { const char* feature = "location on block member"; switch (currentBlockQualifier.storage) { +#ifndef GLSLANG_WEB case EvqVaryingIn: case EvqVaryingOut: requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature); @@ -6109,6 +7451,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); memberWithLocation = true; break; +#endif default: error(memberLoc, "can only use in an in/out block", feature, ""); break; @@ -6119,8 +7462,14 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // "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", ""); + } + + if (memberQualifier.isPerView()) { + memberWithPerViewQualifier = true; } TQualifier newMemberQualification = defaultQualification; @@ -6130,13 +7479,33 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes); +#ifndef GLSLANG_WEB + // 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; + } +#endif + // 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); +#ifndef GLSLANG_WEB + if (memberWithPerViewQualifier) { + for (unsigned int member = 0; member < typeList.size(); ++member) { + checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true); + } + } +#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); @@ -6148,34 +7517,63 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con TType blockType(&typeList, *blockName, currentBlockQualifier); 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()); +#ifndef GLSLANG_WEB + if (arraySizes == nullptr) + ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); + if (currentBlockQualifier.hasBufferReference()) { + + 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().isReference() && + 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(), ""); + } + } + if (!instanceName) { + return; + } + } else +#endif + { + // + // 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; } - } else { - error(loc, "block name cannot redefine a non-block name", blockName->c_str(), ""); - return; } } @@ -6197,12 +7595,14 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // Check for general layout qualifier errors layoutObjectCheck(loc, variable); +#ifndef GLSLANG_WEB // fix up if (isIoResizeArray(blockType)) { ioArraySymbolResizeList.push_back(&variable); checkIoArraysConsistency(loc, true); } else fixIoArraySize(loc, variable.getWritableType()); +#endif // Save it in the AST for linker use. trackLinkage(variable); @@ -6215,9 +7615,9 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q switch (qualifier.storage) { case EvqUniform: 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", ""); + profileRequires(loc, ENoProfile, 140, E_GL_ARB_uniform_buffer_object, "uniform block"); + if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant()) + 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"); @@ -6228,17 +7628,52 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q 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|EShLangMeshNVMask), "input block"); + if (language == EShLangFragment) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); + } else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { + error(loc, "input blocks cannot be used in a mesh shader", "out", ""); + } 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|EShLangMeshNVMask|EShLangTaskNVMask), "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"); + } 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", ""); + } break; +#ifndef GLSLANG_WEB + 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; @@ -6269,12 +7704,16 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier& error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", ""); if (qualifier.centroid) error(loc, "cannot use centroid qualifier on an interface block", "centroid", ""); - if (qualifier.sample) + if (qualifier.isSample()) error(loc, "cannot use sample qualifier on an interface block", "sample", ""); if (qualifier.invariant) error(loc, "cannot use invariant qualifier on an interface block", "invariant", ""); - if (qualifier.layoutPushConstant) + if (qualifier.isPushConstant()) intermediate.addPushConstantCount(); + if (qualifier.isShaderRecordNV()) + intermediate.addShaderRecordNVCount(); + if (qualifier.isTaskMemory()) + intermediate.addTaskNVCount(); } // @@ -6321,8 +7760,9 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi } } -void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList) +void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) { +#ifndef GLSLANG_WEB // "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 // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer @@ -6334,13 +7774,19 @@ void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeLis 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; + bool contains32BitType = false; + bool contains16BitType = false; + int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType); // 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); + else if (contains32BitType) + RoundToPow2(nextOffset, 4); + else if (contains16BitType) + RoundToPow2(nextOffset, 2); memberQualifier.layoutXfbOffset = nextOffset; } else nextOffset = memberQualifier.layoutXfbOffset; @@ -6350,6 +7796,7 @@ void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeLis // The above gave all block members an offset, so we can take it off the block now, // which will avoid double counting the offset usage. qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd; +#endif } // Calculate and save the offset of each block member, using the recursively @@ -6360,9 +7807,9 @@ void TParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeLis // 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; @@ -6376,8 +7823,8 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ // 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." @@ -6421,6 +7868,22 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ 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.hasBufferReference()) { + 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; @@ -6450,10 +7913,10 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua error(loc, "cannot change qualification after use", "invariant", ""); symbol->getWritableType().getQualifier().invariant = true; invariantCheck(loc, symbol->getType().getQualifier()); - } else if (qualifier.noContraction) { + } else if (qualifier.isNoContraction()) { if (intermediate.inIoAccessed(identifier)) error(loc, "cannot change qualification after use", "precise", ""); - symbol->getWritableType().getQualifier().noContraction = true; + symbol->getWritableType().getQualifier().setNoContraction(); } else if (qualifier.specConstant) { symbol->getWritableType().getQualifier().makeSpecConstant(); if (qualifier.hasSpecConstantId()) @@ -6476,7 +7939,7 @@ void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qual bool pipeOut = qualifier.isPipeOutput(); bool pipeIn = qualifier.isPipeInput(); - if (version >= 300 || (profile != EEsProfile && version >= 420)) { + if (version >= 300 || (!isEsProfile() && version >= 420)) { if (! pipeOut) error(loc, "can only apply to an output", "invariant", ""); } else { @@ -6491,8 +7954,9 @@ void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qual // void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType) { +#ifndef GLSLANG_WEB if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) { - assert(language == EShLangTessControl || language == EShLangGeometry); + assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV); const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; if (publicType.qualifier.storage != EvqVaryingOut) @@ -6503,6 +7967,15 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (language == EShLangTessControl) checkIoArraysConsistency(loc); } + 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, ""); + } if (publicType.shaderQualifiers.invocations != TQualifier::layoutNotSet) { if (publicType.qualifier.storage != EvqVaryingIn) error(loc, "can only apply to 'in'", "invocations", ""); @@ -6519,6 +7992,10 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con case ElgTrianglesAdjacency: case ElgQuads: case ElgIsolines: + if (language == EShLangMeshNV) { + error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + break; + } if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry)) { if (language == EShLangGeometry) checkIoArraysConsistency(loc); @@ -6530,6 +8007,13 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con } } else if (publicType.qualifier.storage == EvqVaryingOut) { switch (publicType.shaderQualifiers.geometry) { + case ElgLines: + case ElgTriangles: + if (language != EShLangMeshNV) { + error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); + break; + } + // Fall through case ElgPoints: case ElgLineStrip: case ElgTriangleStrip: @@ -6562,21 +8046,48 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con else error(loc, "can only apply to 'in'", "point_mode", ""); } +#endif for (int i = 0; i < 3; ++i) { - if (publicType.shaderQualifiers.localSize[i] > 1) { + if (publicType.shaderQualifiers.localSizeNotDefault[i]) { if (publicType.qualifier.storage == EvqVaryingIn) { if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i])) 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", ""); + } +#ifndef GLSLANG_WEB + 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"); @@ -6598,6 +8109,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con workGroupSize->getWritableType().getQualifier().specConstant = true; } } + +#ifndef GLSLANG_WEB if (publicType.shaderQualifiers.earlyFragmentTests) { if (publicType.qualifier.storage == EvqVaryingIn) intermediate.setEarlyFragmentTests(); @@ -6610,11 +8123,56 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con else error(loc, "can only apply to 'in'", "post_coverage_coverage", ""); } - if (publicType.shaderQualifiers.blendEquation) { + if (publicType.shaderQualifiers.hasBlendEquation()) { if (publicType.qualifier.storage != EvqVaryingOut) error(loc, "can only apply to 'out'", "blend equation", ""); } + if (publicType.shaderQualifiers.interlockOrdering) { + if (publicType.qualifier.storage == EvqVaryingIn) { + if (!intermediate.setInterlockOrdering(publicType.shaderQualifiers.interlockOrdering)) + error(loc, "cannot change previously set fragment shader interlock ordering", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), ""); + } + else + error(loc, "can only apply to 'in'", TQualifier::getInterlockOrderingString(publicType.shaderQualifiers.interlockOrdering), ""); + } + 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() || @@ -6622,6 +8180,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con qualifier.isInterpolation() || qualifier.precision != EpqNone) error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "qualifier", ""); + // "The offset qualifier can only be used on block members of blocks..." // "The align qualifier can only be used on blocks or block members..." if (qualifier.hasOffset() || @@ -6646,6 +8205,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con case EvqVaryingIn: break; case EvqVaryingOut: +#ifndef GLSLANG_WEB if (qualifier.hasStream()) globalOutputDefaults.layoutStream = qualifier.layoutStream; if (qualifier.hasXfbBuffer()) @@ -6654,6 +8214,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride)) error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); } +#endif break; default: error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", ""); @@ -6666,10 +8227,14 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con error(loc, "cannot declare a default, use a full declaration", "location/component/index", ""); if (qualifier.hasXfbOffset()) error(loc, "cannot declare a default, use a full declaration", "xfb_offset", ""); - if (qualifier.layoutPushConstant) + if (qualifier.isPushConstant()) error(loc, "cannot declare a default, can only be used on a block", "push_constant", ""); + if (qualifier.hasBufferReference()) + 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", ""); + if (qualifier.isShaderRecordNV()) + error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", ""); } // @@ -6736,7 +8301,7 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre // "it is an error to have no statement between a label and the end of the switch statement." // The specifications were updated to remove this (being ill-defined what a "statement" was), // so, this became a warning. However, 3.0 tests still check for the error. - if (profile == EEsProfile && version <= 300 && ! relaxedErrors()) + if (isEsProfile() && version <= 300 && ! relaxedErrors()) error(loc, "last case/default label not followed by statements", "switch", ""); else warn(loc, "last case/default label not followed by statements", "switch", ""); @@ -6758,3 +8323,4 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre } } // end namespace glslang + diff --git a/Externals/glslang/glslang/MachineIndependent/ParseHelper.h b/Externals/glslang/glslang/MachineIndependent/ParseHelper.h index dd8e30d20e..39363f1a2a 100644 --- a/Externals/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/Externals/glslang/glslang/MachineIndependent/ParseHelper.h @@ -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. // @@ -84,6 +85,7 @@ public: statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), postEntryPointReturn(false), contextPragma(true, false), + beginInvocationInterlockCount(0), endInvocationInterlockCount(0), parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr), limits(resources.limits), globalUniformBlock(nullptr), @@ -95,6 +97,7 @@ public: } virtual ~TParseContextBase() { } +#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL) virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...); virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, @@ -103,6 +106,7 @@ public: const char* szExtraInfoFormat, ...); virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...); +#endif virtual void setLimits(const TBuiltInResource&) = 0; @@ -148,8 +152,10 @@ public: extensionCallback(line, extension, behavior); } +#ifdef ENABLE_HLSL // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); +#endif // Potentially rename shader entry point function void renameShaderFunction(TString*& name) const @@ -181,6 +187,8 @@ public: // the statementNestingLevel the current switch statement is at, which must match the level of its case statements TList switchLevel; struct TPragma contextPragma; + int beginInvocationInterlockCount; + int endInvocationInterlockCount; protected: TParseContextBase(TParseContextBase&); @@ -275,7 +283,7 @@ public: const TString* entryPoint = nullptr); virtual ~TParseContext(); - bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }; + bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); } void setPrecisionDefaults(); void setLimits(const TBuiltInResource&) override; @@ -293,19 +301,21 @@ public: TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); +#ifndef GLSLANG_WEB void makeEditable(TSymbol*&) override; + void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); +#endif bool isIoResizeArray(const TType&) const; void fixIoArraySize(const TSourceLoc&, TType&); - 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*); @@ -323,6 +333,7 @@ public: 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); @@ -335,7 +346,7 @@ public: 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&); @@ -347,6 +358,7 @@ public: 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&); @@ -367,6 +379,8 @@ public: 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); @@ -396,11 +410,12 @@ public: TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&); TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset); + void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to); void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0); 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&); @@ -409,6 +424,7 @@ public: void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); +#ifndef GLSLANG_WEB TAttributeType attributeFromName(const TString& name) const; TAttributes* makeAttributes(const TString& identifier) const; TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const; @@ -417,9 +433,11 @@ public: // 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*); +#endif + + void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember); protected: void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); @@ -431,7 +449,9 @@ protected: bool isRuntimeLength(const TIntermTyped&) const; TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); +#ifndef GLSLANG_WEB void finish() override; +#endif public: // @@ -457,10 +477,11 @@ protected: TQualifier globalUniformDefaults; TQualifier globalInputDefaults; TQualifier globalOutputDefaults; - int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point TString currentCaller; // name of last function body entered (not valid when at global scope) - TIdSetType inductiveLoopIds; +#ifndef GLSLANG_WEB + int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point bool anyIndexLimits; + TIdSetType inductiveLoopIds; TVector needsIndexLimitationChecking; // @@ -496,6 +517,7 @@ protected: // array-sizing declarations // TVector ioArraySymbolResizeList; +#endif }; } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/Scan.cpp b/Externals/glslang/glslang/MachineIndependent/Scan.cpp index 7232baeb29..fd18fd4d7d 100644 --- a/Externals/glslang/glslang/MachineIndependent/Scan.cpp +++ b/Externals/glslang/glslang/MachineIndependent/Scan.cpp @@ -324,7 +324,9 @@ struct str_hash // A single global usable by all threads, by all versions, by all languages. // After a single process-level initialization, this is read only and thread safe std::unordered_map* KeywordMap = nullptr; +#ifndef GLSLANG_WEB std::unordered_set* ReservedSet = nullptr; +#endif }; @@ -341,9 +343,15 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["const"] = CONST; (*KeywordMap)["uniform"] = UNIFORM; - (*KeywordMap)["nonuniformEXT"] = NONUNIFORM; + (*KeywordMap)["buffer"] = BUFFER; (*KeywordMap)["in"] = IN; (*KeywordMap)["out"] = OUT; + (*KeywordMap)["smooth"] = SMOOTH; + (*KeywordMap)["flat"] = FLAT; + (*KeywordMap)["centroid"] = CENTROID; + (*KeywordMap)["invariant"] = INVARIANT; + (*KeywordMap)["packed"] = PACKED; + (*KeywordMap)["resource"] = RESOURCE; (*KeywordMap)["inout"] = INOUT; (*KeywordMap)["struct"] = STRUCT; (*KeywordMap)["break"] = BREAK; @@ -376,23 +384,12 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["mat4"] = MAT4; (*KeywordMap)["true"] = BOOLCONSTANT; (*KeywordMap)["false"] = BOOLCONSTANT; - (*KeywordMap)["attribute"] = ATTRIBUTE; - (*KeywordMap)["varying"] = VARYING; - (*KeywordMap)["buffer"] = BUFFER; - (*KeywordMap)["coherent"] = COHERENT; - (*KeywordMap)["restrict"] = RESTRICT; - (*KeywordMap)["readonly"] = READONLY; - (*KeywordMap)["writeonly"] = WRITEONLY; - (*KeywordMap)["atomic_uint"] = ATOMIC_UINT; - (*KeywordMap)["volatile"] = VOLATILE; (*KeywordMap)["layout"] = LAYOUT; (*KeywordMap)["shared"] = SHARED; - (*KeywordMap)["patch"] = PATCH; - (*KeywordMap)["sample"] = SAMPLE; - (*KeywordMap)["subroutine"] = SUBROUTINE; (*KeywordMap)["highp"] = HIGH_PRECISION; (*KeywordMap)["mediump"] = MEDIUM_PRECISION; (*KeywordMap)["lowp"] = LOW_PRECISION; + (*KeywordMap)["superp"] = SUPERP; (*KeywordMap)["precision"] = PRECISION; (*KeywordMap)["mat2x2"] = MAT2X2; (*KeywordMap)["mat2x3"] = MAT2X3; @@ -403,6 +400,31 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["mat4x2"] = MAT4X2; (*KeywordMap)["mat4x3"] = MAT4X3; (*KeywordMap)["mat4x4"] = MAT4X4; + (*KeywordMap)["uint"] = UINT; + (*KeywordMap)["uvec2"] = UVEC2; + (*KeywordMap)["uvec3"] = UVEC3; + (*KeywordMap)["uvec4"] = UVEC4; + +#ifndef GLSLANG_WEB + (*KeywordMap)["nonuniformEXT"] = NONUNIFORM; + (*KeywordMap)["demote"] = DEMOTE; + (*KeywordMap)["attribute"] = ATTRIBUTE; + (*KeywordMap)["varying"] = VARYING; + (*KeywordMap)["noperspective"] = NOPERSPECTIVE; + (*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; + (*KeywordMap)["atomic_uint"] = ATOMIC_UINT; + (*KeywordMap)["volatile"] = VOLATILE; + (*KeywordMap)["patch"] = PATCH; + (*KeywordMap)["sample"] = SAMPLE; + (*KeywordMap)["subroutine"] = SUBROUTINE; (*KeywordMap)["dmat2"] = DMAT2; (*KeywordMap)["dmat3"] = DMAT3; (*KeywordMap)["dmat4"] = DMAT4; @@ -452,11 +474,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["dvec2"] = DVEC2; (*KeywordMap)["dvec3"] = DVEC3; (*KeywordMap)["dvec4"] = DVEC4; - (*KeywordMap)["uint"] = UINT; - (*KeywordMap)["uvec2"] = UVEC2; - (*KeywordMap)["uvec3"] = UVEC3; - (*KeywordMap)["uvec4"] = UVEC4; - (*KeywordMap)["int64_t"] = INT64_T; (*KeywordMap)["uint64_t"] = UINT64_T; (*KeywordMap)["i64vec2"] = I64VEC2; @@ -466,7 +483,7 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["u64vec3"] = U64VEC3; (*KeywordMap)["u64vec4"] = U64VEC4; - // GL_KHX_shader_explicit_arithmetic_types + // GL_EXT_shader_explicit_arithmetic_types (*KeywordMap)["int8_t"] = INT8_T; (*KeywordMap)["i8vec2"] = I8VEC2; (*KeywordMap)["i8vec3"] = I8VEC3; @@ -543,19 +560,10 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["f64mat4x2"] = F64MAT4X2; (*KeywordMap)["f64mat4x3"] = F64MAT4X3; (*KeywordMap)["f64mat4x4"] = F64MAT4X4; +#endif (*KeywordMap)["sampler2D"] = SAMPLER2D; (*KeywordMap)["samplerCube"] = SAMPLERCUBE; - (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; - (*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW; - (*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY; - (*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY; - (*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW; - (*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY; - (*KeywordMap)["usampler1D"] = USAMPLER1D; - (*KeywordMap)["isampler1D"] = ISAMPLER1D; - (*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY; - (*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER; (*KeywordMap)["samplerCubeShadow"] = SAMPLERCUBESHADOW; (*KeywordMap)["sampler2DArray"] = SAMPLER2DARRAY; (*KeywordMap)["sampler2DArrayShadow"] = SAMPLER2DARRAYSHADOW; @@ -567,6 +575,39 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["usampler3D"] = USAMPLER3D; (*KeywordMap)["usamplerCube"] = USAMPLERCUBE; (*KeywordMap)["usampler2DArray"] = USAMPLER2DARRAY; + (*KeywordMap)["sampler3D"] = SAMPLER3D; + (*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW; + + (*KeywordMap)["texture2D"] = TEXTURE2D; + (*KeywordMap)["textureCube"] = TEXTURECUBE; + (*KeywordMap)["texture2DArray"] = TEXTURE2DARRAY; + (*KeywordMap)["itexture2D"] = ITEXTURE2D; + (*KeywordMap)["itexture3D"] = ITEXTURE3D; + (*KeywordMap)["itextureCube"] = ITEXTURECUBE; + (*KeywordMap)["itexture2DArray"] = ITEXTURE2DARRAY; + (*KeywordMap)["utexture2D"] = UTEXTURE2D; + (*KeywordMap)["utexture3D"] = UTEXTURE3D; + (*KeywordMap)["utextureCube"] = UTEXTURECUBE; + (*KeywordMap)["utexture2DArray"] = UTEXTURE2DARRAY; + (*KeywordMap)["texture3D"] = TEXTURE3D; + + (*KeywordMap)["sampler"] = SAMPLER; + (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; + +#ifndef GLSLANG_WEB + (*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY; + (*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY; + (*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY; + (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; + (*KeywordMap)["samplerCubeArrayShadow"] = SAMPLERCUBEARRAYSHADOW; + (*KeywordMap)["isamplerCubeArray"] = ISAMPLERCUBEARRAY; + (*KeywordMap)["usamplerCubeArray"] = USAMPLERCUBEARRAY; + (*KeywordMap)["sampler1DArrayShadow"] = SAMPLER1DARRAYSHADOW; + (*KeywordMap)["isampler1DArray"] = ISAMPLER1DARRAY; + (*KeywordMap)["usampler1D"] = USAMPLER1D; + (*KeywordMap)["isampler1D"] = ISAMPLER1D; + (*KeywordMap)["usampler1DArray"] = USAMPLER1DARRAY; + (*KeywordMap)["samplerBuffer"] = SAMPLERBUFFER; (*KeywordMap)["isampler2DRect"] = ISAMPLER2DRECT; (*KeywordMap)["usampler2DRect"] = USAMPLER2DRECT; (*KeywordMap)["isamplerBuffer"] = ISAMPLERBUFFER; @@ -579,36 +620,19 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["usampler2DMSArray"] = USAMPLER2DMSARRAY; (*KeywordMap)["sampler1D"] = SAMPLER1D; (*KeywordMap)["sampler1DShadow"] = SAMPLER1DSHADOW; - (*KeywordMap)["sampler3D"] = SAMPLER3D; - (*KeywordMap)["sampler2DShadow"] = SAMPLER2DSHADOW; (*KeywordMap)["sampler2DRect"] = SAMPLER2DRECT; (*KeywordMap)["sampler2DRectShadow"] = SAMPLER2DRECTSHADOW; (*KeywordMap)["sampler1DArray"] = SAMPLER1DARRAY; (*KeywordMap)["samplerExternalOES"] = SAMPLEREXTERNALOES; // GL_OES_EGL_image_external - (*KeywordMap)["sampler"] = SAMPLER; - (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; + (*KeywordMap)["__samplerExternal2DY2YEXT"] = SAMPLEREXTERNAL2DY2YEXT; // GL_EXT_YUV_target - (*KeywordMap)["texture2D"] = TEXTURE2D; - (*KeywordMap)["textureCube"] = TEXTURECUBE; - (*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY; - (*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY; - (*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY; (*KeywordMap)["itexture1DArray"] = ITEXTURE1DARRAY; (*KeywordMap)["utexture1D"] = UTEXTURE1D; (*KeywordMap)["itexture1D"] = ITEXTURE1D; (*KeywordMap)["utexture1DArray"] = UTEXTURE1DARRAY; (*KeywordMap)["textureBuffer"] = TEXTUREBUFFER; - (*KeywordMap)["texture2DArray"] = TEXTURE2DARRAY; - (*KeywordMap)["itexture2D"] = ITEXTURE2D; - (*KeywordMap)["itexture3D"] = ITEXTURE3D; - (*KeywordMap)["itextureCube"] = ITEXTURECUBE; - (*KeywordMap)["itexture2DArray"] = ITEXTURE2DARRAY; - (*KeywordMap)["utexture2D"] = UTEXTURE2D; - (*KeywordMap)["utexture3D"] = UTEXTURE3D; - (*KeywordMap)["utextureCube"] = UTEXTURECUBE; - (*KeywordMap)["utexture2DArray"] = UTEXTURE2DARRAY; (*KeywordMap)["itexture2DRect"] = ITEXTURE2DRECT; (*KeywordMap)["utexture2DRect"] = UTEXTURE2DRECT; (*KeywordMap)["itextureBuffer"] = ITEXTUREBUFFER; @@ -620,7 +644,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["itexture2DMSArray"] = ITEXTURE2DMSARRAY; (*KeywordMap)["utexture2DMSArray"] = UTEXTURE2DMSARRAY; (*KeywordMap)["texture1D"] = TEXTURE1D; - (*KeywordMap)["texture3D"] = TEXTURE3D; (*KeywordMap)["texture2DRect"] = TEXTURE2DRECT; (*KeywordMap)["texture1DArray"] = TEXTURE1DARRAY; @@ -631,7 +654,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["usubpassInput"] = USUBPASSINPUT; (*KeywordMap)["usubpassInputMS"] = USUBPASSINPUTMS; -#ifdef AMD_EXTENSIONS (*KeywordMap)["f16sampler1D"] = F16SAMPLER1D; (*KeywordMap)["f16sampler2D"] = F16SAMPLER2D; (*KeywordMap)["f16sampler3D"] = F16SAMPLER3D; @@ -677,20 +699,23 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["f16subpassInput"] = F16SUBPASSINPUT; (*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS; -#endif - - (*KeywordMap)["noperspective"] = NOPERSPECTIVE; - (*KeywordMap)["smooth"] = SMOOTH; - (*KeywordMap)["flat"] = FLAT; -#ifdef AMD_EXTENSIONS - (*KeywordMap)["__explicitInterpAMD"] = __EXPLICITINTERPAMD; -#endif - (*KeywordMap)["centroid"] = CENTROID; + (*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD; + (*KeywordMap)["pervertexNV"] = PERVERTEXNV; (*KeywordMap)["precise"] = PRECISE; - (*KeywordMap)["invariant"] = INVARIANT; - (*KeywordMap)["packed"] = PACKED; - (*KeywordMap)["resource"] = RESOURCE; - (*KeywordMap)["superp"] = SUPERP; + + (*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; + + (*KeywordMap)["fcoopmatNV"] = FCOOPMATNV; + (*KeywordMap)["icoopmatNV"] = ICOOPMATNV; + (*KeywordMap)["ucoopmatNV"] = UCOOPMATNV; ReservedSet = new std::unordered_set; @@ -731,14 +756,17 @@ void TScanContext::fillInKeywordMap() ReservedSet->insert("cast"); ReservedSet->insert("namespace"); ReservedSet->insert("using"); +#endif } void TScanContext::deleteKeywordMap() { delete KeywordMap; KeywordMap = nullptr; +#ifndef GLSLANG_WEB delete ReservedSet; ReservedSet = nullptr; +#endif } // Called by yylex to get the next token. @@ -756,7 +784,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) 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; @@ -778,7 +806,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) 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", "\\", ""); @@ -817,13 +845,15 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; + case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; +#ifndef GLSLANG_WEB 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; +#endif case PpAtomIdentifier: { int token = tokenizeIdentifier(); @@ -845,8 +875,10 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) int TScanContext::tokenizeIdentifier() { +#ifndef GLSLANG_WEB if (ReservedSet->find(tokenText) != ReservedSet->end()) return reservedWord(); +#endif auto it = KeywordMap->find(tokenText); if (it == KeywordMap->end()) { @@ -861,7 +893,6 @@ int TScanContext::tokenizeIdentifier() case IN: case OUT: case INOUT: - case STRUCT: case BREAK: case CONTINUE: case DO: @@ -874,16 +905,21 @@ int TScanContext::tokenizeIdentifier() case CASE: return keyword; - case NONUNIFORM: - if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) - return keyword; - else + case BUFFER: + afterBuffer = true; + if ((parseContext.isEsProfile() && parseContext.version < 310) || + (!parseContext.isEsProfile() && parseContext.version < 430)) return identifierOrType(); + return keyword; + + case STRUCT: + afterStruct = true; + return keyword; case SWITCH: case DEFAULT: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 130)) + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 130)) reservedWord(); return keyword; @@ -915,75 +951,129 @@ int TScanContext::tokenizeIdentifier() parserToken->sType.lex.b = false; return keyword; - case ATTRIBUTE: - case VARYING: - if (parseContext.profile == EEsProfile && parseContext.version >= 300) - reservedWord(); - return keyword; - - case BUFFER: - if ((parseContext.profile == EEsProfile && parseContext.version < 310) || - (parseContext.profile != EEsProfile && parseContext.version < 430)) + case SMOOTH: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 130)) return identifierOrType(); return keyword; + case FLAT: + if (parseContext.isEsProfile() && parseContext.version < 300) + reservedWord(); + else if (!parseContext.isEsProfile() && parseContext.version < 130) + return identifierOrType(); + return keyword; + case CENTROID: + if (parseContext.version < 120) + return identifierOrType(); + return keyword; + case INVARIANT: + if (!parseContext.isEsProfile() && parseContext.version < 120) + return identifierOrType(); + return keyword; + case PACKED: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 330)) + return reservedWord(); + return identifierOrType(); + case RESOURCE: + { + bool reserved = (parseContext.isEsProfile() && parseContext.version >= 300) || + (!parseContext.isEsProfile() && parseContext.version >= 420); + return identifierOrReserved(reserved); + } + case SUPERP: + { + bool reserved = parseContext.isEsProfile() || parseContext.version >= 130; + return identifierOrReserved(reserved); + } + +#ifndef GLSLANG_WEB + case NOPERSPECTIVE: + if (parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation)) + return keyword; + return es30ReservedFromGLSL(130); + + case NONUNIFORM: + if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier)) + return keyword; + else + return identifierOrType(); + case ATTRIBUTE: + case VARYING: + if (parseContext.isEsProfile() && parseContext.version >= 300) + reservedWord(); + return keyword; + case PAYLOADNV: + case PAYLOADINNV: + case HITATTRNV: + case CALLDATANV: + case CALLDATAINNV: + case ACCSTRUCTNV: + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_NV_ray_tracing)) + return keyword; + return identifierOrType(); case ATOMIC_UINT: - if ((parseContext.profile == EEsProfile && parseContext.version >= 310) || + if ((parseContext.isEsProfile() && parseContext.version >= 310) || parseContext.extensionTurnedOn(E_GL_ARB_shader_atomic_counters)) return keyword; return es30ReservedFromGLSL(420); case COHERENT: + case DEVICECOHERENT: + case QUEUEFAMILYCOHERENT: + case WORKGROUPCOHERENT: + case SUBGROUPCOHERENT: + case NONPRIVATE: case RESTRICT: case READONLY: case WRITEONLY: - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.isEsProfile() && parseContext.version >= 310) return keyword; return es30ReservedFromGLSL(parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store) ? 130 : 420); - case VOLATILE: - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.isEsProfile() && parseContext.version >= 310) return keyword; - if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || + if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.isEsProfile() || (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) reservedWord(); return keyword; - - case LAYOUT: - { - const int numLayoutExts = 2; - const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack, - E_GL_ARB_explicit_attrib_location }; - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 140 && - ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts))) - return identifierOrType(); - return keyword; - } - case SHARED: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 140)) - return identifierOrType(); - return keyword; - case PATCH: if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile == EEsProfile && + (parseContext.isEsProfile() && (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) || - (parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader))) + (!parseContext.isEsProfile() && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader))) return keyword; return es30ReservedFromGLSL(400); case SAMPLE: - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation)) return keyword; return es30ReservedFromGLSL(400); case SUBROUTINE: return es30ReservedFromGLSL(400); +#endif + case SHARED: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 140)) + return identifierOrType(); + return keyword; + case LAYOUT: + { + const int numLayoutExts = 2; + const char* layoutExts[numLayoutExts] = { E_GL_ARB_shading_language_420pack, + E_GL_ARB_explicit_attrib_location }; + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 140 && + ! parseContext.extensionsTurnedOn(numLayoutExts, layoutExts))) + return identifierOrType(); + return keyword; + } case HIGH_PRECISION: case MEDIUM_PRECISION: @@ -1002,6 +1092,7 @@ int TScanContext::tokenizeIdentifier() case MAT4X4: return matNxM(); +#ifndef GLSLANG_WEB case DMAT2: case DMAT3: case DMAT4: @@ -1032,7 +1123,7 @@ int TScanContext::tokenizeIdentifier() case IIMAGEBUFFER: case UIMAGEBUFFER: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) return keyword; return firstGenerationImage(false); @@ -1056,7 +1147,7 @@ int TScanContext::tokenizeIdentifier() case IIMAGECUBEARRAY: case UIMAGECUBEARRAY: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) return keyword; return secondGenerationImage(); @@ -1075,7 +1166,10 @@ int TScanContext::tokenizeIdentifier() case DVEC3: case DVEC4: afterType = true; - if (parseContext.profile == EEsProfile || parseContext.version < 400) + if (parseContext.isEsProfile() || parseContext.version < 150 || + (!parseContext.symbolTable.atBuiltInLevel() && + parseContext.version < 400 && + !parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64))) reservedWord(); return keyword; @@ -1089,10 +1183,9 @@ int TScanContext::tokenizeIdentifier() case U64VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 450 && - (parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int64)))) + 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(); @@ -1106,9 +1199,9 @@ int TScanContext::tokenizeIdentifier() case U8VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int8)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + 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)) return keyword; return identifierOrType(); @@ -1122,13 +1215,10 @@ int TScanContext::tokenizeIdentifier() case U16VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && parseContext.version >= 450 && - ( -#ifdef AMD_EXTENSIONS - parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) || -#endif - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int16)))) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) || + 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: @@ -1141,9 +1231,8 @@ int TScanContext::tokenizeIdentifier() case U32VEC4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int32)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) return keyword; return identifierOrType(); case FLOAT32_T: @@ -1164,9 +1253,8 @@ int TScanContext::tokenizeIdentifier() case F32MAT4X4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float32)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) return keyword; return identifierOrType(); @@ -1188,9 +1276,8 @@ int TScanContext::tokenizeIdentifier() case F64MAT4X4: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - ((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float64)) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) return keyword; return identifierOrType(); @@ -1198,6 +1285,16 @@ int TScanContext::tokenizeIdentifier() case F16VEC2: case F16VEC3: case F16VEC4: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || + 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: @@ -1212,13 +1309,9 @@ int TScanContext::tokenizeIdentifier() case F16MAT4X4: 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_KHX_shader_explicit_arithmetic_types) || - parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16)))) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) || + parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)) return keyword; return identifierOrType(); @@ -1228,20 +1321,21 @@ int TScanContext::tokenizeIdentifier() case ISAMPLERCUBEARRAY: case USAMPLERCUBEARRAY: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) return keyword; - if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array))) + if (parseContext.isEsProfile() || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array))) reservedWord(); return keyword; - case ISAMPLER1D: - case ISAMPLER1DARRAY: - case SAMPLER1DARRAYSHADOW: - case USAMPLER1D: - case USAMPLER1DARRAY: - afterType = true; - return es30ReservedFromGLSL(130); + case TEXTURECUBEARRAY: + case ITEXTURECUBEARRAY: + case UTEXTURECUBEARRAY: + if (parseContext.spvVersion.vulkan > 0) + return keyword; + else + return identifierOrType(); +#endif case UINT: case UVEC2: @@ -1261,6 +1355,49 @@ int TScanContext::tokenizeIdentifier() afterType = true; return nonreservedKeyword(300, 130); + case SAMPLER3D: + afterType = true; + if (parseContext.isEsProfile() && parseContext.version < 300) { + if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) + reservedWord(); + } + return keyword; + + case SAMPLER2DSHADOW: + afterType = true; + if (parseContext.isEsProfile() && parseContext.version < 300) { + if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers)) + reservedWord(); + } + return keyword; + + case TEXTURE2D: + case TEXTURECUBE: + case TEXTURE2DARRAY: + case ITEXTURE2D: + case ITEXTURE3D: + case ITEXTURECUBE: + case ITEXTURE2DARRAY: + case UTEXTURE2D: + case UTEXTURE3D: + case UTEXTURECUBE: + case UTEXTURE2DARRAY: + case TEXTURE3D: + case SAMPLER: + case SAMPLERSHADOW: + if (parseContext.spvVersion.vulkan > 0) + return keyword; + else + return identifierOrType(); + +#ifndef GLSLANG_WEB + case ISAMPLER1D: + case ISAMPLER1DARRAY: + case SAMPLER1DARRAYSHADOW: + case USAMPLER1D: + case USAMPLER1DARRAY: + afterType = true; + return es30ReservedFromGLSL(130); case ISAMPLER2DRECT: case USAMPLER2DRECT: afterType = true; @@ -1268,7 +1405,7 @@ int TScanContext::tokenizeIdentifier() case SAMPLERBUFFER: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) return keyword; return es30ReservedFromGLSL(130); @@ -1276,7 +1413,7 @@ int TScanContext::tokenizeIdentifier() case ISAMPLERBUFFER: case USAMPLERBUFFER: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer)) return keyword; return es30ReservedFromGLSL(140); @@ -1285,7 +1422,10 @@ int TScanContext::tokenizeIdentifier() case ISAMPLER2DMS: case USAMPLER2DMS: afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version >= 310) + if (parseContext.isEsProfile() && parseContext.version >= 310) + return keyword; + if (!parseContext.isEsProfile() && (parseContext.version > 140 || + (parseContext.version == 140 && parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_multisample)))) return keyword; return es30ReservedFromGLSL(150); @@ -1293,38 +1433,25 @@ int TScanContext::tokenizeIdentifier() case ISAMPLER2DMSARRAY: case USAMPLER2DMSARRAY: afterType = true; - if ((parseContext.profile == EEsProfile && parseContext.version >= 320) || + if ((parseContext.isEsProfile() && parseContext.version >= 320) || parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array)) return keyword; + if (!parseContext.isEsProfile() && (parseContext.version > 140 || + (parseContext.version == 140 && parseContext.extensionsTurnedOn(1, &E_GL_ARB_texture_multisample)))) + return keyword; return es30ReservedFromGLSL(150); case SAMPLER1D: case SAMPLER1DSHADOW: afterType = true; - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) reservedWord(); return keyword; - case SAMPLER3D: - afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version < 300) { - if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D)) - reservedWord(); - } - return keyword; - - case SAMPLER2DSHADOW: - afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version < 300) { - if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers)) - reservedWord(); - } - return keyword; - case SAMPLER2DRECT: case SAMPLER2DRECTSHADOW: afterType = true; - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) reservedWord(); else if (parseContext.version < 140 && ! parseContext.symbolTable.atBuiltInLevel() && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_rectangle)) { if (parseContext.relaxedErrors()) @@ -1336,10 +1463,10 @@ int TScanContext::tokenizeIdentifier() case SAMPLER1DARRAY: afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version == 300) + if (parseContext.isEsProfile() && parseContext.version == 300) reservedWord(); - else if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 130)) + else if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 130)) return identifierOrType(); return keyword; @@ -1351,25 +1478,18 @@ int TScanContext::tokenizeIdentifier() return keyword; return identifierOrType(); - case TEXTURE2D: - case TEXTURECUBE: - case TEXTURECUBEARRAY: - case ITEXTURECUBEARRAY: - case UTEXTURECUBEARRAY: + case SAMPLEREXTERNAL2DY2YEXT: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_YUV_target)) + return keyword; + return identifierOrType(); + case ITEXTURE1DARRAY: case UTEXTURE1D: case ITEXTURE1D: case UTEXTURE1DARRAY: case TEXTUREBUFFER: - case TEXTURE2DARRAY: - case ITEXTURE2D: - case ITEXTURE3D: - case ITEXTURECUBE: - case ITEXTURE2DARRAY: - case UTEXTURE2D: - case UTEXTURE3D: - case UTEXTURECUBE: - case UTEXTURE2DARRAY: case ITEXTURE2DRECT: case UTEXTURE2DRECT: case ITEXTUREBUFFER: @@ -1381,11 +1501,8 @@ int TScanContext::tokenizeIdentifier() case ITEXTURE2DMSARRAY: case UTEXTURE2DMSARRAY: case TEXTURE1D: - case TEXTURE3D: case TEXTURE2DRECT: case TEXTURE1DARRAY: - case SAMPLER: - case SAMPLERSHADOW: if (parseContext.spvVersion.vulkan > 0) return keyword; else @@ -1402,7 +1519,6 @@ int TScanContext::tokenizeIdentifier() else return identifierOrType(); -#ifdef AMD_EXTENSIONS case F16SAMPLER1D: case F16SAMPLER2D: case F16SAMPLER3D: @@ -1450,79 +1566,62 @@ int TScanContext::tokenizeIdentifier() case F16SUBPASSINPUTMS: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) && - parseContext.profile != EEsProfile && parseContext.version >= 450)) + parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch)) 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: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 130)) - return identifierOrType(); - return keyword; - -#ifdef AMD_EXTENSIONS - case __EXPLICITINTERPAMD: - if (parseContext.profile != EEsProfile && parseContext.version >= 450 && - parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) + case EXPLICITINTERPAMD: + if (parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter)) return keyword; return identifierOrType(); -#endif - case FLAT: - if (parseContext.profile == EEsProfile && parseContext.version < 300) - reservedWord(); - else if (parseContext.profile != EEsProfile && parseContext.version < 130) - return identifierOrType(); - return keyword; - - case CENTROID: - if (parseContext.version < 120) - return identifierOrType(); - return keyword; + case PERVERTEXNV: + if ((!parseContext.isEsProfile() && parseContext.version >= 450) || + parseContext.extensionTurnedOn(E_GL_NV_fragment_shader_barycentric)) + return keyword; + return identifierOrType(); case PRECISE: - if ((parseContext.profile == EEsProfile && + if ((parseContext.isEsProfile() && (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) || - (parseContext.profile != EEsProfile && parseContext.version >= 400)) + (!parseContext.isEsProfile() && parseContext.version >= 400)) return keyword; - if (parseContext.profile == EEsProfile && parseContext.version == 310) { + if (parseContext.isEsProfile() && parseContext.version == 310) { reservedWord(); return keyword; } return identifierOrType(); - case INVARIANT: - if (parseContext.profile != EEsProfile && parseContext.version < 120) - return identifierOrType(); - return keyword; - - case PACKED: - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < 330)) - return reservedWord(); + case PERPRIMITIVENV: + case PERVIEWNV: + case PERTASKNV: + if ((!parseContext.isEsProfile() && parseContext.version >= 450) || + (parseContext.isEsProfile() && parseContext.version >= 320) || + parseContext.extensionTurnedOn(E_GL_NV_mesh_shader)) + return keyword; return identifierOrType(); - case RESOURCE: - { - bool reserved = (parseContext.profile == EEsProfile && parseContext.version >= 300) || - (parseContext.profile != EEsProfile && parseContext.version >= 420); - return identifierOrReserved(reserved); - } - case SUPERP: - { - bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130; - return identifierOrReserved(reserved); - } + case FCOOPMATNV: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix)) + return keyword; + return identifierOrType(); + + case UCOOPMATNV: + case ICOOPMATNV: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_NV_integer_cooperative_matrix)) + return keyword; + return identifierOrType(); + + case DEMOTE: + if (parseContext.extensionTurnedOn(E_GL_EXT_demote_to_helper_invocation)) + return keyword; + else + return identifierOrType(); +#endif default: parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); @@ -1537,9 +1636,11 @@ int TScanContext::identifierOrType() 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().isReference() && afterBuffer)) { afterType = true; return TYPE_NAME; @@ -1569,7 +1670,7 @@ int TScanContext::identifierOrReserved(bool reserved) return 0; } - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future reserved keyword", tokenText, ""); return identifierOrType(); @@ -1582,13 +1683,13 @@ int TScanContext::es30ReservedFromGLSL(int version) if (parseContext.symbolTable.atBuiltInLevel()) return keyword; - if ((parseContext.profile == EEsProfile && parseContext.version < 300) || - (parseContext.profile != EEsProfile && parseContext.version < version)) { - if (parseContext.forwardCompatible) + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < version)) { + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, ""); return identifierOrType(); - } else if (parseContext.profile == EEsProfile && parseContext.version >= 300) + } else if (parseContext.isEsProfile() && parseContext.version >= 300) reservedWord(); return keyword; @@ -1598,9 +1699,9 @@ int TScanContext::es30ReservedFromGLSL(int version) // showed up, both in an es version and a non-ES version. int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) { - if ((parseContext.profile == EEsProfile && parseContext.version < esVersion) || - (parseContext.profile != EEsProfile && parseContext.version < nonEsVersion)) { - if (parseContext.forwardCompatible) + if ((parseContext.isEsProfile() && parseContext.version < esVersion) || + (!parseContext.isEsProfile() && parseContext.version < nonEsVersion)) { + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future keyword", tokenText, ""); return identifierOrType(); @@ -1611,10 +1712,10 @@ int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) int TScanContext::precisionKeyword() { - if (parseContext.profile == EEsProfile || parseContext.version >= 130) + if (parseContext.isEsProfile() || parseContext.version >= 130) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, ""); return identifierOrType(); @@ -1627,7 +1728,7 @@ int TScanContext::matNxM() if (parseContext.version > 110) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, ""); return identifierOrType(); @@ -1637,16 +1738,18 @@ int TScanContext::dMat() { afterType = true; - if (parseContext.profile == EEsProfile && parseContext.version >= 300) { + if (parseContext.isEsProfile() && parseContext.version >= 300) { reservedWord(); return keyword; } - if (parseContext.profile != EEsProfile && parseContext.version >= 400) + if (!parseContext.isEsProfile() && (parseContext.version >= 400 || + parseContext.symbolTable.atBuiltInLevel() || + (parseContext.version >= 150 && parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)))) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); @@ -1655,19 +1758,19 @@ int TScanContext::dMat() int TScanContext::firstGenerationImage(bool inEs310) { if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && (parseContext.version >= 420 || + (!parseContext.isEsProfile() && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) || - (inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310)) + (inEs310 && parseContext.isEsProfile() && parseContext.version >= 310)) return keyword; - if ((parseContext.profile == EEsProfile && parseContext.version >= 300) || - (parseContext.profile != EEsProfile && parseContext.version >= 130)) { + if ((parseContext.isEsProfile() && parseContext.version >= 300) || + (!parseContext.isEsProfile() && parseContext.version >= 130)) { reservedWord(); return keyword; } - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); @@ -1675,17 +1778,17 @@ int TScanContext::firstGenerationImage(bool inEs310) int TScanContext::secondGenerationImage() { - if (parseContext.profile == EEsProfile && parseContext.version >= 310) { + if (parseContext.isEsProfile() && parseContext.version >= 310) { reservedWord(); return keyword; } if (parseContext.symbolTable.atBuiltInLevel() || - (parseContext.profile != EEsProfile && + (!parseContext.isEsProfile() && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); diff --git a/Externals/glslang/glslang/MachineIndependent/Scan.h b/Externals/glslang/glslang/MachineIndependent/Scan.h index 2c26c2efd4..24b75cf7ca 100644 --- a/Externals/glslang/glslang/MachineIndependent/Scan.h +++ b/Externals/glslang/glslang/MachineIndependent/Scan.h @@ -65,7 +65,7 @@ public: } 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 @@ public: // 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 --git a/Externals/glslang/glslang/MachineIndependent/ScanContext.h b/Externals/glslang/glslang/MachineIndependent/ScanContext.h index 608ae067e0..74b2b3c746 100644 --- a/Externals/glslang/glslang/MachineIndependent/ScanContext.h +++ b/Externals/glslang/glslang/MachineIndependent/ScanContext.h @@ -50,7 +50,10 @@ class TParserToken; 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 @@ protected: 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 --git a/Externals/glslang/glslang/MachineIndependent/ShaderLang.cpp b/Externals/glslang/glslang/MachineIndependent/ShaderLang.cpp index 4f39f3453e..44ce1c19d1 100644 --- a/Externals/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/Externals/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -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 @@ -283,6 +288,11 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#endif + (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]); InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source, infoSink, *symbolTables[language]); @@ -299,6 +309,11 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi // bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source) { +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#endif + std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); if (builtInParseables == nullptr) @@ -321,6 +336,7 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source, infoSink, commonTable, symbolTables); +#ifndef GLSLANG_WEB // check for tessellation if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { @@ -335,6 +351,7 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS (profile == EEsProfile && version >= 310)) InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source, infoSink, commonTable, symbolTables); +#endif // check for compute if ((profile != EEsProfile && version >= 420) || @@ -342,6 +359,34 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, infoSink, commonTable, symbolTables); + // 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); + return true; } @@ -439,6 +484,18 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp glslang::ReleaseGlobalLock(); } +// Function to Print all builtins +void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) +{ +#ifndef GLSLANG_WEB + infoSink.debug << "BuiltinSymbolTable {\n"; + + symbolTable.dump(infoSink, true); + + infoSink.debug << "}\n"; +#endif +} + // 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) @@ -534,6 +591,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } +#ifndef GLSLANG_WEB // Correct for stage type... switch (stage) { case EShLangGeometry: @@ -565,6 +623,26 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo version = profile == EEsProfile ? 310 : 420; } break; + 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; + } default: break; } @@ -577,15 +655,10 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo // Check for SPIR-V compatibility if (spvVersion.spv != 0) { switch (profile) { - case EEsProfile: - if (spvVersion.vulkan > 0 && version < 310) { + case EEsProfile: + if (version < 310) { correct = false; - infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher"); - version = 310; - } - if (spvVersion.openGl >= 100) { - correct = false; - infoSink.info.message(EPrefixError, "#version: ES shaders for OpenGL SPIR-V are not supported"); + infoSink.info.message(EPrefixError, "#version: ES shaders for SPIR-V require version 310 or higher"); version = 310; } break; @@ -606,6 +679,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } } +#endif return correct; } @@ -764,13 +838,17 @@ bool ProcessDeferred( // Get all the stages, languages, clients, and other environment // stuff sorted out. - EShSource source = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl; + EShSource sourceGuess = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl; SpvVersion spvVersion; EShLanguage stage = compiler->getLanguage(); - TranslateEnvironment(environment, messages, source, stage, spvVersion); + TranslateEnvironment(environment, messages, sourceGuess, stage, spvVersion); +#ifdef ENABLE_HLSL + EShSource source = sourceGuess; if (environment != nullptr && environment->target.hlslFunctionality1) intermediate.setHlslFunctionality1(); - +#else + const EShSource source = EShSourceGlsl; +#endif // 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 // outlined above, just the user shader, after the system and user preambles. @@ -783,6 +861,7 @@ bool ProcessDeferred( : userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { +#ifndef GLSLANG_WEB if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && (version != defaultVersion || profile != defaultProfile)) { compiler->infoSink.info << "Warning, (version, profile) forced to be (" @@ -790,7 +869,7 @@ bool ProcessDeferred( << "), while in source code it is (" << version << ", " << ProfileName(profile) << ")\n"; } - +#endif if (versionNotFound) { versionNotFirstToken = false; versionNotFirst = false; @@ -802,7 +881,13 @@ bool ProcessDeferred( bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, versionNotFirst, defaultVersion, source, version, profile, spvVersion); +#ifdef GLSLANG_WEB + profile = EEsProfile; + version = 310; +#endif + bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); +#ifndef GLSLANG_WEB bool warnVersionNotFirst = false; if (! versionWillBeError && versionNotFirstToken) { if (messages & EShMsgRelaxedErrors) @@ -810,6 +895,7 @@ bool ProcessDeferred( else versionWillBeError = true; } +#endif intermediate.setSource(source); intermediate.setVersion(version); @@ -818,12 +904,17 @@ bool ProcessDeferred( RecordProcesses(intermediate, messages, sourceEntryPointName); if (spvVersion.vulkan > 0) intermediate.setOriginUpperLeft(); +#ifdef ENABLE_HLSL if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl) intermediate.setHlslOffsets(); +#endif 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); @@ -845,6 +936,9 @@ bool ProcessDeferred( return false; } + if (messages & EShMsgBuiltinSymbolTable) + DumpBuiltinSymbolTable(compiler->infoSink, *symbolTable); + // // Now we can process the full shader under proper symbols and rules. // @@ -863,11 +957,13 @@ bool ProcessDeferred( parseContext->setLimits(*resources); if (! goodVersion) parseContext->addError(); +#ifndef GLSLANG_WEB if (warnVersionNotFirst) { TSourceLoc loc; loc.init(); parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", ""); } +#endif parseContext->initializeExtensionBehavior(); @@ -898,6 +994,8 @@ bool ProcessDeferred( return success; } +#ifndef GLSLANG_WEB + // Responsible for keeping track of the most recent source string and line in // the preprocessor and outputting newlines appropriately if the source string // or line changes. @@ -965,6 +1063,8 @@ private: // 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, @@ -1072,7 +1172,11 @@ struct DoPreprocessing { outputBuffer += ' '; } lastToken = token; + if (token == PpAtomConstString) + outputBuffer += "\""; outputBuffer += ppToken.name; + if (token == PpAtomConstString) + outputBuffer += "\""; } while (true); outputBuffer += '\n'; *outputString = std::move(outputBuffer); @@ -1088,6 +1192,8 @@ struct DoPreprocessing { std::string* outputString; }; +#endif + // DoFullParse is a valid ProcessingConext template argument for fully // parsing the shader. It populates the "intermediate" with the AST. struct DoFullParse{ @@ -1118,10 +1224,14 @@ struct DoFullParse{ } }; +#ifndef GLSLANG_WEB // Take a single compilation unit, and run the preprocessor on it. // 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[], @@ -1147,6 +1257,7 @@ bool PreprocessDeferred( forwardCompatible, messages, intermediate, parser, false, includer); } +#endif // // do a partial compile on the given strings for a single compilation unit @@ -1266,7 +1377,7 @@ void ShDestruct(ShHandle handle) // // Cleanup symbol tables // -int __fastcall ShFinalize() +int ShFinalize() { glslang::GetGlobalLock(); --NumberOfClients; @@ -1665,6 +1776,11 @@ void TShader::addProcesses(const std::vector& p) intermediate->addProcesses(p); } +void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } +void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } + +#ifndef GLSLANG_WEB + // Set binding base for given resource type void TShader::setShiftBinding(TResourceType res, unsigned int base) { intermediate->setShiftBinding(res, base); @@ -1692,15 +1808,27 @@ void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSs // Enables binding automapping using TIoMapper void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } // Enables position.Y output negation in vertex shader -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); } -// See comment above TDefaultHlslIoMapper in iomapper.cpp: -void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } -void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } +void TShader::addUniformLocationOverride(const char* name, int loc) +{ + intermediate->addUniformLocationOverride(name, loc); +} +void TShader::setUniformLocationBase(int base) +{ + intermediate->setUniformLocationBase(base); +} void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } +#endif + +#ifdef ENABLE_HLSL +// See comment above TDefaultHlslIoMapper in iomapper.cpp: +void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } +void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } +#endif // // Turn the shader strings into a parse tree in the TIntermediate. @@ -1724,8 +1852,12 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion &environment); } +#ifndef GLSLANG_WEB // 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, @@ -1745,6 +1877,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, message, includer, *intermediate, output_string); } +#endif const char* TShader::getInfoLog() { @@ -1756,7 +1889,11 @@ const char* TShader::getInfoDebugLog() return infoSink->debug.c_str(); } -TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false) +TProgram::TProgram() : +#ifndef GLSLANG_WEB + reflection(0), +#endif + linked(false) { pool = new TPoolAllocator; infoSink = new TInfoSink; @@ -1768,9 +1905,10 @@ TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false) TProgram::~TProgram() { - delete ioMapper; delete infoSink; +#ifndef GLSLANG_WEB delete reflection; +#endif for (int s = 0; s < EShLangCount; ++s) if (newedIntermediate[s]) @@ -1815,6 +1953,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) if (stages[stage].size() == 0) return true; +#ifndef GLSLANG_WEB int numEsShaders = 0, numNonEsShaders = 0; for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) { if ((*it)->intermediate->getProfile() == EEsProfile) { @@ -1863,7 +2002,9 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) for (it = stages[stage].begin(); it != stages[stage].end(); ++it) intermediate[stage]->merge(*infoSink, *(*it)->intermediate); } - +#else + intermediate[stage] = stages[stage].front()->intermediate; +#endif intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0); if (messages & EShMsgAST) @@ -1882,16 +2023,33 @@ const char* TProgram::getInfoDebugLog() return infoSink->debug.c_str(); } +#ifndef GLSLANG_WEB + // // Reflection implementation. // -bool TProgram::buildReflection() +bool TProgram::buildReflection(int opts) { - if (! linked || reflection) + if (! linked || reflection != nullptr) 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]) { @@ -1903,47 +2061,50 @@ bool TProgram::buildReflection() 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::getUniformBlockBinding(int index) const { return reflection->getUniformBlock(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::getReflectionPipeIOIndex(const char* name, const bool inOrOut) const + { return reflection->getPipeIOIndex(name, inOrOut); } -void TProgram::dumpReflection() { reflection->dump(); } +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() { if (reflection != nullptr) reflection->dump(); } // // I/O mapping implementation. // -bool TProgram::mapIO(TIoMapResolver* resolver) +bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) { - if (! linked || ioMapper) + if (! linked) return false; - - ioMapper = new TIoMapper; - + TIoMapper* ioMapper = nullptr; + TIoMapper defaultIOMapper; + if (pIoMapper == nullptr) + ioMapper = &defaultIOMapper; + else + ioMapper = pIoMapper; for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { - if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver)) + if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver)) return false; } } - return true; + return ioMapper->doMap(pResolver, *infoSink); } +#endif // GLSLANG_WEB + } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/SymbolTable.cpp b/Externals/glslang/glslang/MachineIndependent/SymbolTable.cpp index db46e1075d..44682379f7 100644 --- a/Externals/glslang/glslang/MachineIndependent/SymbolTable.cpp +++ b/Externals/glslang/glslang/MachineIndependent/SymbolTable.cpp @@ -2,6 +2,7 @@ // 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,58 +61,66 @@ void TType::buildMangledName(TString& mangledName) const switch (basicType) { case EbtFloat: mangledName += 'f'; break; - case EbtDouble: mangledName += 'd'; break; - case EbtFloat16: mangledName += "f16"; break; case EbtInt: mangledName += 'i'; break; case EbtUint: mangledName += 'u'; break; + case EbtBool: mangledName += 'b'; break; +#ifndef GLSLANG_WEB + case EbtDouble: mangledName += 'd'; break; + case EbtFloat16: mangledName += "f16"; break; case EbtInt8: mangledName += "i8"; break; case EbtUint8: mangledName += "u8"; break; case EbtInt16: mangledName += "i16"; break; case EbtUint16: mangledName += "u16"; break; case EbtInt64: mangledName += "i64"; break; case EbtUint64: mangledName += "u64"; break; - case EbtBool: mangledName += 'b'; break; case EbtAtomicUint: mangledName += "au"; break; + case EbtAccStructNV: mangledName += "asnv"; break; +#endif case EbtSampler: switch (sampler.type) { -#ifdef AMD_EXTENSIONS +#ifndef GLSLANG_WEB case EbtFloat16: mangledName += "f16"; break; #endif case EbtInt: mangledName += "i"; break; case EbtUint: mangledName += "u"; break; default: break; // some compilers want this } - if (sampler.image) - mangledName += "I"; // a normal image - else if (sampler.sampler) + if (sampler.isImageClass()) + mangledName += "I"; // a normal image or subpass + else if (sampler.isPureSampler()) mangledName += "p"; // a "pure" sampler - else if (!sampler.combined) + else if (!sampler.isCombined()) mangledName += "t"; // a "pure" texture else mangledName += "s"; // traditional combined sampler - if (sampler.arrayed) + if (sampler.isArrayed()) mangledName += "A"; - if (sampler.shadow) + if (sampler.isShadow()) mangledName += "S"; - if (sampler.external) + if (sampler.isExternal()) mangledName += "E"; + if (sampler.isYuv()) + mangledName += "Y"; switch (sampler.dim) { - case Esd1D: mangledName += "1"; break; case Esd2D: mangledName += "2"; break; case Esd3D: mangledName += "3"; break; case EsdCube: mangledName += "C"; break; +#ifndef GLSLANG_WEB + case Esd1D: mangledName += "1"; break; case EsdRect: mangledName += "R2"; break; case EsdBuffer: mangledName += "B"; break; case EsdSubpass: mangledName += "P"; break; +#endif default: break; // some compilers want this } +#ifdef ENABLE_HLSL if (sampler.hasReturnStruct()) { // Name mangle for sampler return struct uses struct table index. mangledName += "-tx-struct"; char text[16]; // plenty enough space for the small integers. - snprintf(text, sizeof(text), "%d-", sampler.structReturnIndex); + snprintf(text, sizeof(text), "%d-", sampler.getStructReturnIndex()); mangledName += text; } else { switch (sampler.getVectorSize()) { @@ -121,8 +130,9 @@ void TType::buildMangledName(TString& mangledName) const case 4: break; // default to prior name mangle behavior } } +#endif - if (sampler.ms) + if (sampler.isMultiSample()) mangledName += "M"; break; case EbtStruct: @@ -166,44 +176,88 @@ void TType::buildMangledName(TString& mangledName) const } } +#ifndef GLSLANG_WEB + // // Dump functions. // -void TVariable::dump(TInfoSink& infoSink) const +void TSymbol::dumpExtensions(TInfoSink& infoSink) const { - infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString(); - if (type.isArray()) { - infoSink.debug << "[0]"; + 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 +{ + 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) 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); } } +#endif + // // Functions have buried pointers to delete. // @@ -283,19 +337,25 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf) { 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 @@ -313,10 +373,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) 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; @@ -355,12 +414,12 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const 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 --git a/Externals/glslang/glslang/MachineIndependent/SymbolTable.h b/Externals/glslang/glslang/MachineIndependent/SymbolTable.h index f928b7aedf..40ca3da532 100644 --- a/Externals/glslang/glslang/MachineIndependent/SymbolTable.h +++ b/Externals/glslang/glslang/MachineIndependent/SymbolTable.h @@ -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 TVariable; 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,21 @@ public: 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]; + assert(numExts > 0); + extensions = NewPoolObject(extensions); + for (int e = 0; e < numExts; ++e) + extensions->push_back(exts[e]); } - virtual int getNumExtensions() const { return numExtensions; } - virtual const char** getExtensions() const { return extensions; } - virtual void dump(TInfoSink &infoSink) const = 0; + virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } + virtual const char** getExtensions() const { return extensions->data(); } + +#ifndef GLSLANG_WEB + virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; + void dumpExtensions(TInfoSink& infoSink) const; +#endif virtual bool isReadOnly() const { return ! writable; } virtual void makeReadOnly() { writable = false; } @@ -128,8 +134,7 @@ protected: // 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 +159,9 @@ public: : 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 +178,27 @@ public: 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(); } + +#ifndef GLSLANG_WEB + virtual void dump(TInfoSink& infoSink, bool complete = false) const; +#endif protected: explicit TVariable(const TVariable&); @@ -179,15 +206,14 @@ protected: 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 +319,9 @@ public: 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; +#ifndef GLSLANG_WEB + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; +#endif protected: explicit TFunction(const TFunction&); @@ -324,35 +352,44 @@ protected: // 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; +#ifndef GLSLANG_WEB + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; +#endif protected: explicit TAnonMember(const TAnonMember&); TAnonMember& operator=(const TAnonMember&); - const TVariable& anonContainer; + TVariable& anonContainer; unsigned int memberNumber; int anonId; }; @@ -514,7 +551,9 @@ public: void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); - void dump(TInfoSink &infoSink) const; +#ifndef GLSLANG_WEB + void dump(TInfoSink& infoSink, bool complete = false) const; +#endif TSymbolTableLevel* clone() const; void readOnly(); @@ -788,15 +827,36 @@ public: 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; +#ifndef GLSLANG_WEB + void dump(TInfoSink& infoSink, bool complete = false) const; +#endif void copyTable(const TSymbolTable& copyOf); void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } diff --git a/Externals/glslang/glslang/MachineIndependent/Versions.cpp b/Externals/glslang/glslang/MachineIndependent/Versions.cpp old mode 100755 new mode 100644 index 51b6430853..e549074df8 --- a/Externals/glslang/glslang/MachineIndependent/Versions.cpp +++ b/Externals/glslang/glslang/MachineIndependent/Versions.cpp @@ -2,6 +2,7 @@ // 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. // @@ -144,6 +145,8 @@ namespace glslang { +#ifndef GLSLANG_WEB + // // Initialize all extensions, almost always to 'disable', as once their features // are incorporated into a core version, their features are supported through allowing that @@ -156,6 +159,7 @@ void TParseVersions::initializeExtensionBehavior() 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_shadow_samplers] = EBhDisable; extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable; @@ -168,8 +172,10 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_tessellation_shader] = EBhDisable; extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable; extensionBehavior[E_GL_ARB_texture_cube_map_array] = EBhDisable; + extensionBehavior[E_GL_ARB_texture_multisample] = EBhDisable; extensionBehavior[E_GL_ARB_shader_texture_lod] = EBhDisable; extensionBehavior[E_GL_ARB_explicit_attrib_location] = EBhDisable; + extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable; extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable; extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable; extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable; @@ -178,6 +184,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable; extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable; extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable; + extensionBehavior[E_GL_ARB_gpu_shader_fp64] = EBhDisable; extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable; @@ -185,6 +192,10 @@ void TParseVersions::initializeExtensionBehavior() // extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable; extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable; + extensionBehavior[E_GL_ARB_fragment_shader_interlock] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_clock] = EBhDisable; + extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable; + extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable; @@ -194,18 +205,30 @@ void TParseVersions::initializeExtensionBehavior() 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_buffer_reference_uvec2] = EBhDisable; + extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = 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; extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable; -#ifdef AMD_EXTENSIONS extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable; extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable; extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable; @@ -216,9 +239,9 @@ void TParseVersions::initializeExtensionBehavior() 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 + extensionBehavior[E_GL_INTEL_shader_integer_functions2] = EBhDisable; + extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable; extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable; extensionBehavior[E_GL_NV_viewport_array2] = EBhDisable; @@ -228,7 +251,16 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable; extensionBehavior[E_GL_NV_shader_noperspective_interpolation] = EBhDisable; extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable; -#endif + 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; + + extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable; + extensionBehavior[E_GL_NV_shader_sm_builtins] = EBhDisable; + extensionBehavior[E_GL_NV_integer_cooperative_matrix] = EBhDisable; // AEP extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable; @@ -261,41 +293,52 @@ void TParseVersions::initializeExtensionBehavior() // EXT extensions extensionBehavior[E_GL_EXT_device_group] = EBhDisable; extensionBehavior[E_GL_EXT_multiview] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; extensionBehavior[E_GL_OVR_multiview2] = EBhDisable; // explicit types - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int8] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int16] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int32] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int64] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float16] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float32] = EBhDisable; - extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float64] = EBhDisable; + 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; + + // subgroup extended types + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int8] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable; } +#endif // GLSLANG_WEB // Get code that is not part of a shared symbol table, is specific to this shader, // or needed by the preprocessor (which does not use a shared symbol table). void TParseVersions::getPreamble(std::string& preamble) { - if (profile == EEsProfile) { + if (isEsProfile()) { preamble = "#define GL_ES 1\n" "#define GL_FRAGMENT_PRECISION_HIGH 1\n" +#ifdef GLSLANG_WEB + ; +#else "#define GL_OES_texture_3D 1\n" "#define GL_OES_standard_derivatives 1\n" "#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" // AEP "#define GL_ANDROID_extension_pack_es31a 1\n" - "#define GL_KHR_blend_equation_advanced 1\n" "#define GL_OES_sample_variables 1\n" "#define GL_OES_shader_image_atomic 1\n" "#define GL_OES_shader_multisample_interpolation 1\n" @@ -323,11 +366,9 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_non_constant_global_initializers 1\n" ; -#ifdef NV_EXTENSIONS - if (profile == EEsProfile && version >= 300) { + if (isEsProfile() && version >= 300) { preamble += "#define GL_NV_shader_noperspective_interpolation 1\n"; } -#endif } else { preamble = @@ -341,8 +382,10 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_tessellation_shader 1\n" "#define GL_ARB_enhanced_layouts 1\n" "#define GL_ARB_texture_cube_map_array 1\n" + "#define GL_ARB_texture_multisample 1\n" "#define GL_ARB_shader_texture_lod 1\n" "#define GL_ARB_explicit_attrib_location 1\n" + "#define GL_ARB_explicit_uniform_location 1\n" "#define GL_ARB_shader_image_load_store 1\n" "#define GL_ARB_shader_atomic_counters 1\n" "#define GL_ARB_shader_draw_parameters 1\n" @@ -351,17 +394,30 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_shader_texture_image_samples 1\n" "#define GL_ARB_viewport_array 1\n" "#define GL_ARB_gpu_shader_int64 1\n" + "#define GL_ARB_gpu_shader_fp64 1\n" "#define GL_ARB_shader_ballot 1\n" "#define GL_ARB_sparse_texture2 1\n" "#define GL_ARB_sparse_texture_clamp 1\n" "#define GL_ARB_shader_stencil_export 1\n" + "#define GL_ARB_sample_shading 1\n" // "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members "#define GL_ARB_post_depth_coverage 1\n" + "#define GL_ARB_fragment_shader_interlock 1\n" + "#define GL_ARB_uniform_buffer_object 1\n" "#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" + "#define GL_EXT_buffer_reference_uvec2 1\n" + "#define GL_EXT_demote_to_helper_invocation 1\n" // GL_KHR_shader_subgroup "#define GL_KHR_shader_subgroup_basic 1\n" @@ -373,7 +429,9 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_KHR_shader_subgroup_clustered 1\n" "#define GL_KHR_shader_subgroup_quad 1\n" -#ifdef AMD_EXTENSIONS + "#define E_GL_EXT_shader_atomic_int64 1\n" + "#define E_GL_EXT_shader_realtime_clock 1\n" + "#define GL_AMD_shader_ballot 1\n" "#define GL_AMD_shader_trinary_minmax 1\n" "#define GL_AMD_shader_explicit_vertex_parameter 1\n" @@ -384,24 +442,37 @@ void TParseVersions::getPreamble(std::string& preamble) "#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 + "#define GL_INTEL_shader_integer_functions2 1\n" + "#define GL_NV_sample_mask_override_coverage 1\n" "#define GL_NV_geometry_shader_passthrough 1\n" "#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" -#endif - "#define GL_KHX_shader_explicit_arithmetic_types 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_int8 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_int16 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_int32 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_int64 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_float16 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_float32 1\n" - "#define GL_KHX_shader_explicit_arithmetic_types_float64 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" + "#define GL_NV_cooperative_matrix 1\n" + "#define GL_NV_integer_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" + + "#define GL_EXT_shader_subgroup_extended_types_int8 1\n" + "#define GL_EXT_shader_subgroup_extended_types_int16 1\n" + "#define GL_EXT_shader_subgroup_extended_types_int64 1\n" + "#define GL_EXT_shader_subgroup_extended_types_float16 1\n" ; if (version >= 150) { @@ -411,13 +482,16 @@ void TParseVersions::getPreamble(std::string& preamble) if (profile == ECompatibilityProfile) preamble += "#define GL_compatibility_profile 1\n"; } +#endif // GLSLANG_WEB } - if ((profile != EEsProfile && version >= 140) || - (profile == EEsProfile && version >= 310)) { +#ifndef GLSLANG_WEB + if ((!isEsProfile() && version >= 140) || + (isEsProfile() && version >= 310)) { preamble += "#define GL_EXT_device_group 1\n" "#define GL_EXT_multiview 1\n" + "#define GL_NV_shader_sm_builtins 1\n" ; } @@ -432,7 +506,9 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += "#define GL_GOOGLE_cpp_style_line_directive 1\n" "#define GL_GOOGLE_include_directive 1\n" + "#define GL_KHR_blend_equation_advanced 1\n" ; +#endif // #define VULKAN XXXX const int numberBufSize = 12; @@ -443,6 +519,8 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += numberBuf; preamble += "\n"; } + +#ifndef GLSLANG_WEB // #define GL_SPIRV XXXX if (spvVersion.openGl > 0) { preamble += "#define GL_SPIRV "; @@ -450,22 +528,7 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += numberBuf; preamble += "\n"; } - -} - -// -// When to use requireProfile(): -// -// Use if only some profiles support a feature. However, if within a profile the feature -// is version or extension specific, follow this call with calls to profileRequires(). -// -// Operation: If the current profile is not one of the profileMask, -// give an error message. -// -void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) -{ - if (! (profile & profileMask)) - error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); +#endif } // @@ -475,62 +538,25 @@ const char* StageName(EShLanguage stage) { switch(stage) { case EShLangVertex: return "vertex"; + case EShLangFragment: return "fragment"; + case EShLangCompute: return "compute"; +#ifndef GLSLANG_WEB case EShLangTessControl: return "tessellation control"; case EShLangTessEvaluation: return "tessellation evaluation"; case EShLangGeometry: return "geometry"; - case EShLangFragment: return "fragment"; - case EShLangCompute: return "compute"; + 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"; } } -// -// When to use profileRequires(): -// -// If a set of profiles have the same requirements for what version or extensions -// are needed to support a feature. -// -// It must be called for each profile that needs protection. Use requireProfile() first -// to reduce that set of profiles. -// -// Operation: Will issue warnings/errors based on the current profile, version, and extension -// behaviors. It only checks extensions when the current profile is one of the profileMask. -// -// A minVersion of 0 means no version of the profileMask support this in core, -// the extension must be present. -// - -// entry point that takes multiple extensions -void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc) -{ - if (profile & profileMask) { - bool okay = false; - if (minVersion > 0 && version >= minVersion) - okay = true; - for (int i = 0; i < numExtensions; ++i) { - switch (getExtensionBehavior(extensions[i])) { - case EBhWarn: - infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); - // fall through - case EBhRequire: - case EBhEnable: - okay = true; - break; - default: break; // some compilers want this - } - } - - if (! okay) - error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); - } -} - -// entry point for the above that takes a single extension -void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc) -{ - profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); -} - // // When to use requireStage() // @@ -551,6 +577,75 @@ void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, cons requireStage(loc, static_cast(1 << stage), featureDesc); } +#ifndef GLSLANG_WEB +// +// When to use requireProfile(): +// +// Use if only some profiles support a feature. However, if within a profile the feature +// is version or extension specific, follow this call with calls to profileRequires(). +// +// Operation: If the current profile is not one of the profileMask, +// give an error message. +// +void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) +{ + if (! (profile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); +} + +// +// When to use profileRequires(): +// +// If a set of profiles have the same requirements for what version or extensions +// are needed to support a feature. +// +// It must be called for each profile that needs protection. Use requireProfile() first +// to reduce that set of profiles. +// +// Operation: Will issue warnings/errors based on the current profile, version, and extension +// behaviors. It only checks extensions when the current profile is one of the profileMask. +// +// A minVersion of 0 means no version of the profileMask support this in core, +// the extension must be present. +// + +// entry point that takes multiple extensions +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc) +{ + if (profile & profileMask) { + bool okay = minVersion > 0 && version >= minVersion; +#ifndef GLSLANG_WEB + for (int i = 0; i < numExtensions; ++i) { + switch (getExtensionBehavior(extensions[i])) { + case EBhWarn: + infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc); + // fall through + case EBhRequire: + case EBhEnable: + okay = true; + break; + default: break; // some compilers want this + } + } +#endif + if (! okay) + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); + } +} + +// entry point for the above that takes a single extension +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc) +{ + profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); +} + +void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc) +{ + error(loc, "feature not yet implemented", featureDesc, ""); +} + // // Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether // a future compatibility context is being use. @@ -584,11 +679,6 @@ void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, i } } -void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc) -{ - error(loc, "feature not yet implemented", featureDesc, ""); -} - // Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false. // Warns appropriately if the requested behavior of an extension is "warn". bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc) @@ -708,6 +798,9 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co return; } + // check if extension is used with correct shader stage + checkExtensionStage(getCurrentLoc(), extension); + // update the requested extension updateExtensionBehavior(extension, behavior); @@ -754,10 +847,22 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co 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 || + strcmp(extension, "GL_EXT_buffer_reference_uvec2") == 0) + updateExtensionBehavior(line, "GL_EXT_buffer_reference", behaviorString); + else if (strcmp(extension, "GL_NV_integer_cooperative_matrix") == 0) + updateExtensionBehavior(line, "GL_NV_cooperative_matrix", behaviorString); + // subgroup extended types to explicit types + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int8") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int8", behaviorString); + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int16") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int16", behaviorString); + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int64") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int64", behaviorString); + else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_float16") == 0) + updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_float16", behaviorString); } void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior) @@ -800,6 +905,18 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe } } +// Check if extension is used with correct shader stage. +void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension) +{ + // 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"); + } +} + // Call for any operation needing full GLSL integer data-type support. void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) { @@ -810,28 +927,98 @@ void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) // Call for any operation needing GLSL double data-type support. 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); + //requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op); } // Call for any operation needing GLSL float16 data-type support. void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (!builtIn) { -#if AMD_EXTENSIONS - const char* const extensions[3] = {E_GL_AMD_gpu_shader_half_float, - E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_float16}; + const char* const extensions[] = { + E_GL_AMD_gpu_shader_half_float, + E_GL_EXT_shader_explicit_arithmetic_types, + E_GL_EXT_shader_explicit_arithmetic_types_float16}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} -#else - const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_float16}; -#endif - requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types"); - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); +bool TParseVersions::float16Arithmetic() +{ + const char* const extensions[] = { + E_GL_AMD_gpu_shader_half_float, + 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[] = { + E_GL_AMD_gpu_shader_int16, + 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[] = { + E_GL_AMD_gpu_shader_half_float, + 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[] = { + E_GL_AMD_gpu_shader_int16, + 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[] = { + E_GL_AMD_gpu_shader_half_float, + 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); } } @@ -839,12 +1026,9 @@ void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool bu void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (!builtIn) { - const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_float32}; - requireExtensions(loc, 2, extensions, "explicit types"); - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + 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); } } @@ -852,12 +1036,11 @@ void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (!builtIn) { - const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_float64}; - requireExtensions(loc, 2, extensions, "explicit types"); + 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, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op); } } @@ -865,44 +1048,54 @@ void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { - const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_int8}; - requireExtensions(loc, 2, extensions, "explicit types"); - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + 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 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_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 explicit int16 data-type support. void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { -#if AMD_EXTENSIONS - const char* const extensions[3] = {E_GL_AMD_gpu_shader_int16, - E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_int16}; -#else - const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_int16}; -#endif - requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types"); - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + const char* const extensions[] = { + E_GL_AMD_gpu_shader_int16, + 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[] = { + E_GL_AMD_gpu_shader_int16, + 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); } } @@ -910,12 +1103,9 @@ void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, b void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn) { if (! builtIn) { - const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_int32}; - requireExtensions(loc, 2, extensions, "explicit types"); - requireProfile(loc, ECoreProfile | ECompatibilityProfile, op); - profileRequires(loc, ECoreProfile, 450, nullptr, op); - profileRequires(loc, ECompatibilityProfile, 450, nullptr, op); + 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); } } @@ -924,15 +1114,30 @@ void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool buil { if (! builtIn) { const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64, - E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_int64}; - requireExtensions(loc, 3, extensions, "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); + } +} + +void TParseVersions::intcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = {E_GL_NV_integer_cooperative_matrix}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} +#endif // GLSLANG_WEB // Call for any operation removed because SPIR-V is in use. void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) { @@ -950,15 +1155,19 @@ void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) // Call for any operation that requires Vulkan. void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op) { +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0) error(loc, "only allowed when using GLSL for Vulkan", op, ""); +#endif } // Call for any operation that requires SPIR-V. void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op) { +#ifndef GLSLANG_WEB if (spvVersion.spv == 0) error(loc, "only allowed when generating SPIR-V", op, ""); +#endif } } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/Versions.h b/Externals/glslang/glslang/MachineIndependent/Versions.h old mode 100755 new mode 100644 index b297d27b5c..58558e595a --- a/Externals/glslang/glslang/MachineIndependent/Versions.h +++ b/Externals/glslang/glslang/MachineIndependent/Versions.h @@ -2,6 +2,7 @@ // 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. // @@ -73,7 +74,7 @@ inline const char* ProfileName(EProfile profile) } // -// 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). @@ -109,6 +110,7 @@ const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_deriv 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"; @@ -122,8 +124,10 @@ const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader"; const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts"; const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array"; +const char* const E_GL_ARB_texture_multisample = "GL_ARB_texture_multisample"; const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod"; const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location"; +const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location"; const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters"; const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters"; @@ -132,6 +136,7 @@ const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_con const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples"; const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array"; const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64"; +const char* const E_GL_ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64"; const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot"; const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2"; const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp"; @@ -139,6 +144,10 @@ const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil // const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members 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_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock"; +const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock"; +const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object"; +const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading"; 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"; @@ -148,16 +157,31 @@ const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_sub 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_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_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"; +const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2"; +const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation"; +const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock"; // Arrays of extensions for the above viewportEXTs duplications @@ -175,7 +199,6 @@ const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multi const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive"; const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive"; -#ifdef AMD_EXTENSIONS const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot"; const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax"; const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter"; @@ -186,9 +209,8 @@ const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_sh 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 +const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2"; const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage"; const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough"; @@ -199,12 +221,21 @@ const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_ 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 const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 }; const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]); -#endif + +const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix"; +const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins"; +const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix"; // AEP const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; @@ -234,15 +265,20 @@ const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessel 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_KHX_shader_explicit_arithmetic_types = "GL_KHX_shader_explicit_arithmetic_types"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_int8 = "GL_KHX_shader_explicit_arithmetic_types_int8"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_int16 = "GL_KHX_shader_explicit_arithmetic_types_int16"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_int32 = "GL_KHX_shader_explicit_arithmetic_types_int32"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_int64 = "GL_KHX_shader_explicit_arithmetic_types_int64"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_float16 = "GL_KHX_shader_explicit_arithmetic_types_float16"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_float32 = "GL_KHX_shader_explicit_arithmetic_types_float32"; -const char* const E_GL_KHX_shader_explicit_arithmetic_types_float64 = "GL_KHX_shader_explicit_arithmetic_types_float64"; +// EXT +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"; + +const char* const E_GL_EXT_shader_subgroup_extended_types_int8 = "GL_EXT_shader_subgroup_extended_types_int8"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shader_subgroup_extended_types_int16"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64"; +const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16"; // Arrays of extensions for the above AEP duplications diff --git a/Externals/glslang/glslang/MachineIndependent/attribute.cpp b/Externals/glslang/glslang/MachineIndependent/attribute.cpp index 73b665d808..9585518349 100644 --- a/Externals/glslang/glslang/MachineIndependent/attribute.cpp +++ b/Externals/glslang/glslang/MachineIndependent/attribute.cpp @@ -34,6 +34,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #include "attribute.h" #include "../Include/intermediate.h" #include "ParseHelper.h" @@ -52,6 +54,7 @@ bool TAttributeArgs::getInt(int& value, int argNum) const 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 @@ -85,6 +88,9 @@ const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNu 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; @@ -107,6 +113,16 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const 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; } @@ -222,29 +238,101 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN } for (auto it = attributes.begin(); it != attributes.end(); ++it) { - if (it->name != EatDependencyLength && it->size() > 0) { - warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", ""); - continue; - } - int value; + 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: - loop->setUnroll(); + if (noArgument("unroll")) + loop->setUnroll(); break; case EatLoop: - loop->setDontUnroll(); + if (noArgument("dont_unroll")) + loop->setDontUnroll(); break; case EatDependencyInfinite: - loop->setLoopDependency(TIntermLoop::dependencyInfinite); + if (noArgument("dependency_infinite")) + loop->setLoopDependency(TIntermLoop::dependencyInfinite); break; case EatDependencyLength: - if (it->size() == 1 && it->getInt(value)) { - if (value <= 0) - error(node->getLoc(), "must be positive", "dependency_length", ""); + if (positiveSignedArgument("dependency_length", value)) loop->setLoopDependency(value); - } else - warn(node->getLoc(), "expected a single integer argument", "dependency_length", ""); + 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", "", ""); @@ -253,5 +341,6 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN } } - } // end namespace glslang + +#endif // GLSLANG_WEB diff --git a/Externals/glslang/glslang/MachineIndependent/attribute.h b/Externals/glslang/glslang/MachineIndependent/attribute.h index 8d0c5bcafb..38a943d283 100644 --- a/Externals/glslang/glslang/MachineIndependent/attribute.h +++ b/Externals/glslang/glslang/MachineIndependent/attribute.h @@ -71,7 +71,54 @@ namespace glslang { EatPushConstant, EatConstantId, EatDependencyInfinite, - EatDependencyLength + EatDependencyLength, + EatMinIterations, + EatMaxIterations, + EatIterationMultiple, + EatPeelCount, + EatPartialCount, + EatFormatRgba32f, + EatFormatRgba16f, + EatFormatR32f, + EatFormatRgba8, + EatFormatRgba8Snorm, + EatFormatRg32f, + EatFormatRg16f, + EatFormatR11fG11fB10f, + EatFormatR16f, + EatFormatRgba16, + EatFormatRgb10A2, + EatFormatRg16, + EatFormatRg8, + EatFormatR16, + EatFormatR8, + EatFormatRgba16Snorm, + EatFormatRg16Snorm, + EatFormatRg8Snorm, + EatFormatR16Snorm, + EatFormatR8Snorm, + EatFormatRgba32i, + EatFormatRgba16i, + EatFormatRgba8i, + EatFormatR32i, + EatFormatRg32i, + EatFormatRg16i, + EatFormatRg8i, + EatFormatR16i, + EatFormatR8i, + EatFormatRgba32ui, + EatFormatRgba16ui, + EatFormatRgba8ui, + EatFormatR32ui, + EatFormatRgb10a2ui, + EatFormatRg32ui, + EatFormatRg16ui, + EatFormatRg8ui, + EatFormatR16ui, + EatFormatR8ui, + EatFormatUnknown, + EatNonWritable, + EatNonReadable }; class TIntermAggregate; diff --git a/Externals/glslang/glslang/MachineIndependent/gl_types.h b/Externals/glslang/glslang/MachineIndependent/gl_types.h index c9fee9ecce..b6f613bced 100644 --- a/Externals/glslang/glslang/MachineIndependent/gl_types.h +++ b/Externals/glslang/glslang/MachineIndependent/gl_types.h @@ -78,7 +78,6 @@ #define GL_DOUBLE_MAT4x2 0x8F4D #define GL_DOUBLE_MAT4x3 0x8F4E -#ifdef AMD_EXTENSIONS // Those constants are borrowed from extension NV_gpu_shader5 #define GL_FLOAT16_NV 0x8FF8 #define GL_FLOAT16_VEC2_NV 0x8FF9 @@ -94,7 +93,6 @@ #define GL_FLOAT16_MAT3x4_AMD 0x91CB #define GL_FLOAT16_MAT4x2_AMD 0x91CC #define GL_FLOAT16_MAT4x3_AMD 0x91CD -#endif #define GL_SAMPLER_1D 0x8B5D #define GL_SAMPLER_2D 0x8B5E @@ -117,7 +115,6 @@ #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 @@ -149,7 +146,6 @@ #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 diff --git a/Externals/glslang/glslang/MachineIndependent/glslang.m4 b/Externals/glslang/glslang/MachineIndependent/glslang.m4 new file mode 100644 index 0000000000..cd949c2d30 --- /dev/null +++ b/Externals/glslang/glslang/MachineIndependent/glslang.m4 @@ -0,0 +1,3827 @@ +// +// 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. +// +// 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. +// + +// +// Do not edit the .y file, only edit the .m4 file. +// The .y bison file is not a source file, it is a derivative of the .m4 file. +// The m4 file needs to be processed by m4 to generate the .y bison file. +// +// Code sandwiched between a pair: +// +// GLSLANG_WEB_EXCLUDE_ON +// ... +// ... +// ... +// GLSLANG_WEB_EXCLUDE_OFF +// +// Will be excluded from the grammar when m4 is executed as: +// +// m4 -P -DGLSLANG_WEB +// +// It will be included when m4 is executed as: +// +// m4 -P +// + +m4_define(`GLSLANG_WEB_EXCLUDE_ON', `m4_ifdef(`GLSLANG_WEB', `m4_divert(`-1')')') +m4_define(`GLSLANG_WEB_EXCLUDE_OFF', `m4_ifdef(`GLSLANG_WEB', `m4_divert')') + +/** + * This is bison grammar and productions for parsing all versions of the + * GLSL shading languages. + */ +%{ + +/* Based on: +ANSI C Yacc grammar + +In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a +matching Lex specification) for the April 30, 1985 draft version of the +ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that +original, as mentioned in the answer to question 17.25 of the comp.lang.c +FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z. + +I intend to keep this version as close to the current C Standard grammar as +possible; please let me know if you discover discrepancies. + +Jutta Degener, 1995 +*/ + +#include "SymbolTable.h" +#include "ParseHelper.h" +#include "../Public/ShaderLang.h" +#include "attribute.h" + +using namespace glslang; + +%} + +%define parse.error verbose + +%union { + struct { + glslang::TSourceLoc loc; + union { + glslang::TString *string; + int i; + unsigned int u; + long long i64; + unsigned long long u64; + bool b; + double d; + }; + glslang::TSymbol* symbol; + } lex; + struct { + glslang::TSourceLoc loc; + glslang::TOperator op; + union { + TIntermNode* intermNode; + glslang::TIntermNodePair nodePair; + glslang::TIntermTyped* intermTypedNode; + glslang::TAttributes* attributes; + }; + union { + glslang::TPublicType type; + glslang::TFunction* function; + glslang::TParameter param; + glslang::TTypeLoc typeLine; + glslang::TTypeList* typeList; + glslang::TArraySizes* arraySizes; + glslang::TIdentifierList* identifierList; + }; + glslang::TArraySizes* typeParameters; + } interm; +} + +%{ + +/* windows only pragma */ +#ifdef _MSC_VER + #pragma warning(disable : 4065) + #pragma warning(disable : 4127) + #pragma warning(disable : 4244) +#endif + +#define parseContext (*pParseContext) +#define yyerror(context, msg) context->parserError(msg) + +extern int yylex(YYSTYPE*, TParseContext&); + +%} + +%parse-param {glslang::TParseContext* pParseContext} +%lex-param {parseContext} +%pure-parser // enable thread safety +%expect 1 // One shift reduce conflict because of if | else + +%token CONST BOOL INT UINT FLOAT +%token BVEC2 BVEC3 BVEC4 +%token IVEC2 IVEC3 IVEC4 +%token UVEC2 UVEC3 UVEC4 +%token VEC2 VEC3 VEC4 +%token MAT2 MAT3 MAT4 +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 + +// combined image/sampler +%token SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER2DARRAY +%token SAMPLER2DARRAYSHADOW ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER2DARRAY USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER2DARRAY + +// separate image/sampler +%token SAMPLER SAMPLERSHADOW +%token TEXTURE2D TEXTURE3D TEXTURECUBE TEXTURE2DARRAY +%token ITEXTURE2D ITEXTURE3D ITEXTURECUBE ITEXTURE2DARRAY +%token UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY + +GLSLANG_WEB_EXCLUDE_ON + +%token ATTRIBUTE VARYING +%token FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T +%token INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T +%token I64VEC2 I64VEC3 I64VEC4 +%token U64VEC2 U64VEC3 U64VEC4 +%token I32VEC2 I32VEC3 I32VEC4 +%token U32VEC2 U32VEC3 U32VEC4 +%token I16VEC2 I16VEC3 I16VEC4 +%token U16VEC2 U16VEC3 U16VEC4 +%token I8VEC2 I8VEC3 I8VEC4 +%token U8VEC2 U8VEC3 U8VEC4 +%token DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4 +%token F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4 +%token F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4 +%token F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4 +%token DMAT2X2 DMAT2X3 DMAT2X4 +%token DMAT3X2 DMAT3X3 DMAT3X4 +%token DMAT4X2 DMAT4X3 DMAT4X4 +%token F16MAT2X2 F16MAT2X3 F16MAT2X4 +%token F16MAT3X2 F16MAT3X3 F16MAT3X4 +%token F16MAT4X2 F16MAT4X3 F16MAT4X4 +%token F32MAT2X2 F32MAT2X3 F32MAT2X4 +%token F32MAT3X2 F32MAT3X3 F32MAT3X4 +%token F32MAT4X2 F32MAT4X3 F32MAT4X4 +%token F64MAT2X2 F64MAT2X3 F64MAT2X4 +%token F64MAT3X2 F64MAT3X3 F64MAT3X4 +%token F64MAT4X2 F64MAT4X3 F64MAT4X4 +%token ATOMIC_UINT +%token ACCSTRUCTNV +%token FCOOPMATNV ICOOPMATNV UCOOPMATNV + +// combined image/sampler +%token SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW +%token ISAMPLERCUBEARRAY USAMPLERCUBEARRAY +%token SAMPLER1D SAMPLER1DARRAY SAMPLER1DARRAYSHADOW ISAMPLER1D SAMPLER1DSHADOW +%token SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT +%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER +%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS +%token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY +%token SAMPLEREXTERNALOES +%token SAMPLEREXTERNAL2DY2YEXT +%token ISAMPLER1DARRAY USAMPLER1D USAMPLER1DARRAY +%token F16SAMPLER1D F16SAMPLER2D F16SAMPLER3D F16SAMPLER2DRECT F16SAMPLERCUBE +%token F16SAMPLER1DARRAY F16SAMPLER2DARRAY F16SAMPLERCUBEARRAY +%token F16SAMPLERBUFFER F16SAMPLER2DMS F16SAMPLER2DMSARRAY +%token F16SAMPLER1DSHADOW F16SAMPLER2DSHADOW F16SAMPLER1DARRAYSHADOW F16SAMPLER2DARRAYSHADOW +%token F16SAMPLER2DRECTSHADOW F16SAMPLERCUBESHADOW F16SAMPLERCUBEARRAYSHADOW + +// images +%token IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D +%token UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D +%token IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT +%token IMAGECUBE IIMAGECUBE UIMAGECUBE +%token IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER +%token IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY +%token IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY +%token IMAGECUBEARRAY IIMAGECUBEARRAY UIMAGECUBEARRAY +%token IMAGE2DMS IIMAGE2DMS UIMAGE2DMS +%token IMAGE2DMSARRAY IIMAGE2DMSARRAY UIMAGE2DMSARRAY + +%token F16IMAGE1D F16IMAGE2D F16IMAGE3D F16IMAGE2DRECT +%token F16IMAGECUBE F16IMAGE1DARRAY F16IMAGE2DARRAY F16IMAGECUBEARRAY +%token F16IMAGEBUFFER F16IMAGE2DMS F16IMAGE2DMSARRAY + +// texture without sampler +%token TEXTURECUBEARRAY ITEXTURECUBEARRAY UTEXTURECUBEARRAY +%token TEXTURE1D ITEXTURE1D UTEXTURE1D +%token TEXTURE1DARRAY ITEXTURE1DARRAY UTEXTURE1DARRAY +%token TEXTURE2DRECT ITEXTURE2DRECT UTEXTURE2DRECT +%token TEXTUREBUFFER ITEXTUREBUFFER UTEXTUREBUFFER +%token TEXTURE2DMS ITEXTURE2DMS UTEXTURE2DMS +%token TEXTURE2DMSARRAY ITEXTURE2DMSARRAY UTEXTURE2DMSARRAY + +%token F16TEXTURE1D F16TEXTURE2D F16TEXTURE3D F16TEXTURE2DRECT F16TEXTURECUBE +%token F16TEXTURE1DARRAY F16TEXTURE2DARRAY F16TEXTURECUBEARRAY +%token F16TEXTUREBUFFER F16TEXTURE2DMS F16TEXTURE2DMSARRAY + +// input attachments +%token SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS +%token F16SUBPASSINPUT F16SUBPASSINPUTMS + +GLSLANG_WEB_EXCLUDE_OFF + +%token LEFT_OP RIGHT_OP +%token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP +%token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN +%token MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN +%token SUB_ASSIGN + +%token LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT +%token COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT +%token LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION + +%token INVARIANT +%token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION +%token PACKED RESOURCE SUPERP + +%token FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token IDENTIFIER TYPE_NAME +%token CENTROID IN OUT INOUT +%token STRUCT VOID WHILE +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token UNIFORM SHARED BUFFER +%token FLAT SMOOTH LAYOUT + +GLSLANG_WEB_EXCLUDE_ON +%token DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT +%token INT64CONSTANT UINT64CONSTANT +%token SUBROUTINE DEMOTE +%token PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV +%token PATCH SAMPLE NONUNIFORM +%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT +%token SUBGROUPCOHERENT NONPRIVATE +%token NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV +%token PRECISE +GLSLANG_WEB_EXCLUDE_OFF + +%type assignment_operator unary_operator +%type variable_identifier primary_expression postfix_expression +%type expression integer_expression assignment_expression +%type unary_expression multiplicative_expression additive_expression +%type relational_expression equality_expression +%type conditional_expression constant_expression +%type logical_or_expression logical_xor_expression logical_and_expression +%type shift_expression and_expression exclusive_or_expression inclusive_or_expression +%type function_call initializer condition conditionopt + +%type translation_unit function_definition +%type statement simple_statement +%type statement_list switch_statement_list compound_statement +%type declaration_statement selection_statement selection_statement_nonattributed expression_statement +%type switch_statement switch_statement_nonattributed case_label +%type declaration external_declaration +%type for_init_statement compound_statement_no_new_scope +%type selection_rest_statement for_rest_statement +%type iteration_statement iteration_statement_nonattributed jump_statement statement_no_new_scope statement_scoped +%type single_declaration init_declarator_list + +%type parameter_declaration parameter_declarator parameter_type_specifier + +%type array_specifier +%type invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier +%type layout_qualifier layout_qualifier_id_list layout_qualifier_id + +%type type_parameter_specifier +%type type_parameter_specifier_opt +%type type_parameter_specifier_list + +%type type_qualifier fully_specified_type type_specifier +%type single_type_qualifier +%type type_specifier_nonarray +%type struct_specifier +%type struct_declarator +%type struct_declarator_list struct_declaration struct_declaration_list +%type block_structure +%type function_header function_declarator +%type function_header_with_parameters +%type function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype +%type function_call_or_method function_identifier function_call_header + +%type identifier_list + +GLSLANG_WEB_EXCLUDE_ON +%type precise_qualifier non_uniform_qualifier +%type type_name_list +%type attribute attribute_list single_attribute +%type demote_statement +%type initializer_list +GLSLANG_WEB_EXCLUDE_OFF + +%start translation_unit +%% + +variable_identifier + : IDENTIFIER { + $$ = parseContext.handleVariable($1.loc, $1.symbol, $1.string); + } + ; + +primary_expression + : variable_identifier { + $$ = $1; + } + | LEFT_PAREN expression RIGHT_PAREN { + $$ = $2; + if ($$->getAsConstantUnion()) + $$->getAsConstantUnion()->setExpression(); + } + | FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); + } + | INTCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINTCONSTANT { + parseContext.fullIntegerCheck($1.loc, "unsigned literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } +GLSLANG_WEB_EXCLUDE_ON + | INT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } + | INT64CONSTANT { + parseContext.int64Check($1.loc, "64-bit integer literal"); + $$ = parseContext.intermediate.addConstantUnion($1.i64, $1.loc, true); + } + | UINT64CONSTANT { + parseContext.int64Check($1.loc, "64-bit unsigned integer literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u64, $1.loc, true); + } + | INT16CONSTANT { + parseContext.explicitInt16Check($1.loc, "16-bit integer literal"); + $$ = parseContext.intermediate.addConstantUnion((short)$1.i, $1.loc, true); + } + | UINT16CONSTANT { + parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer literal"); + $$ = parseContext.intermediate.addConstantUnion((unsigned short)$1.u, $1.loc, true); + } + | DOUBLECONSTANT { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double literal"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double literal"); + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtDouble, $1.loc, true); + } + | FLOAT16CONSTANT { + parseContext.float16Check($1.loc, "half float literal"); + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat16, $1.loc, true); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +postfix_expression + : primary_expression { + $$ = $1; + } + | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { + $$ = parseContext.handleBracketDereference($2.loc, $1, $3); + } + | function_call { + $$ = $1; + } + | postfix_expression DOT IDENTIFIER { + $$ = parseContext.handleDotDereference($3.loc, $1, *$3.string); + } + | postfix_expression INC_OP { + parseContext.variableCheck($1); + parseContext.lValueErrorCheck($2.loc, "++", $1); + $$ = parseContext.handleUnaryMath($2.loc, "++", EOpPostIncrement, $1); + } + | postfix_expression DEC_OP { + parseContext.variableCheck($1); + parseContext.lValueErrorCheck($2.loc, "--", $1); + $$ = parseContext.handleUnaryMath($2.loc, "--", EOpPostDecrement, $1); + } + ; + +integer_expression + : expression { + parseContext.integerCheck($1, "[]"); + $$ = $1; + } + ; + +function_call + : function_call_or_method { + $$ = parseContext.handleFunctionCall($1.loc, $1.function, $1.intermNode); + delete $1.function; + } + ; + +function_call_or_method + : function_call_generic { + $$ = $1; + } + ; + +function_call_generic + : function_call_header_with_parameters RIGHT_PAREN { + $$ = $1; + $$.loc = $2.loc; + } + | function_call_header_no_parameters RIGHT_PAREN { + $$ = $1; + $$.loc = $2.loc; + } + ; + +function_call_header_no_parameters + : function_call_header VOID { + $$ = $1; + } + | function_call_header { + $$ = $1; + } + ; + +function_call_header_with_parameters + : function_call_header assignment_expression { + TParameter param = { 0, new TType }; + param.type->shallowCopy($2->getType()); + $1.function->addParameter(param); + $$.function = $1.function; + $$.intermNode = $2; + } + | function_call_header_with_parameters COMMA assignment_expression { + TParameter param = { 0, new TType }; + param.type->shallowCopy($3->getType()); + $1.function->addParameter(param); + $$.function = $1.function; + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc); + } + ; + +function_call_header + : function_identifier LEFT_PAREN { + $$ = $1; + } + ; + +// Grammar Note: Constructors look like functions, but are recognized as types. + +function_identifier + : type_specifier { + // Constructor + $$.intermNode = 0; + $$.function = parseContext.handleConstructorCall($1.loc, $1); + } + | postfix_expression { + // + // Should be a method or subroutine call, but we haven't recognized the arguments yet. + // + $$.function = 0; + $$.intermNode = 0; + + TIntermMethod* method = $1->getAsMethodNode(); + if (method) { + $$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength); + $$.intermNode = method->getObject(); + } else { + TIntermSymbol* symbol = $1->getAsSymbolNode(); + if (symbol) { + parseContext.reservedErrorCheck(symbol->getLoc(), symbol->getName()); + TFunction *function = new TFunction(&symbol->getName(), TType(EbtVoid)); + $$.function = function; + } else + parseContext.error($1->getLoc(), "function call, method, or subroutine call expected", "", ""); + } + + if ($$.function == 0) { + // error recover + TString* empty = NewPoolTString(""); + $$.function = new TFunction(empty, TType(EbtVoid), EOpNull); + } + } +GLSLANG_WEB_EXCLUDE_ON + | non_uniform_qualifier { + // Constructor + $$.intermNode = 0; + $$.function = parseContext.handleConstructorCall($1.loc, $1); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +unary_expression + : postfix_expression { + parseContext.variableCheck($1); + $$ = $1; + if (TIntermMethod* method = $1->getAsMethodNode()) + parseContext.error($1->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); + } + | INC_OP unary_expression { + parseContext.lValueErrorCheck($1.loc, "++", $2); + $$ = parseContext.handleUnaryMath($1.loc, "++", EOpPreIncrement, $2); + } + | DEC_OP unary_expression { + parseContext.lValueErrorCheck($1.loc, "--", $2); + $$ = parseContext.handleUnaryMath($1.loc, "--", EOpPreDecrement, $2); + } + | unary_operator unary_expression { + if ($1.op != EOpNull) { + char errorOp[2] = {0, 0}; + switch($1.op) { + case EOpNegative: errorOp[0] = '-'; break; + case EOpLogicalNot: errorOp[0] = '!'; break; + case EOpBitwiseNot: errorOp[0] = '~'; break; + default: break; // some compilers want this + } + $$ = parseContext.handleUnaryMath($1.loc, errorOp, $1.op, $2); + } else { + $$ = $2; + if ($$->getAsConstantUnion()) + $$->getAsConstantUnion()->setExpression(); + } + } + ; +// Grammar Note: No traditional style type casts. + +unary_operator + : PLUS { $$.loc = $1.loc; $$.op = EOpNull; } + | DASH { $$.loc = $1.loc; $$.op = EOpNegative; } + | BANG { $$.loc = $1.loc; $$.op = EOpLogicalNot; } + | TILDE { $$.loc = $1.loc; $$.op = EOpBitwiseNot; + parseContext.fullIntegerCheck($1.loc, "bitwise not"); } + ; +// Grammar Note: No '*' or '&' unary ops. Pointers are not supported. + +multiplicative_expression + : unary_expression { $$ = $1; } + | multiplicative_expression STAR unary_expression { + $$ = parseContext.handleBinaryMath($2.loc, "*", EOpMul, $1, $3); + if ($$ == 0) + $$ = $1; + } + | multiplicative_expression SLASH unary_expression { + $$ = parseContext.handleBinaryMath($2.loc, "/", EOpDiv, $1, $3); + if ($$ == 0) + $$ = $1; + } + | multiplicative_expression PERCENT unary_expression { + parseContext.fullIntegerCheck($2.loc, "%"); + $$ = parseContext.handleBinaryMath($2.loc, "%", EOpMod, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +additive_expression + : multiplicative_expression { $$ = $1; } + | additive_expression PLUS multiplicative_expression { + $$ = parseContext.handleBinaryMath($2.loc, "+", EOpAdd, $1, $3); + if ($$ == 0) + $$ = $1; + } + | additive_expression DASH multiplicative_expression { + $$ = parseContext.handleBinaryMath($2.loc, "-", EOpSub, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +shift_expression + : additive_expression { $$ = $1; } + | shift_expression LEFT_OP additive_expression { + parseContext.fullIntegerCheck($2.loc, "bit shift left"); + $$ = parseContext.handleBinaryMath($2.loc, "<<", EOpLeftShift, $1, $3); + if ($$ == 0) + $$ = $1; + } + | shift_expression RIGHT_OP additive_expression { + parseContext.fullIntegerCheck($2.loc, "bit shift right"); + $$ = parseContext.handleBinaryMath($2.loc, ">>", EOpRightShift, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +relational_expression + : shift_expression { $$ = $1; } + | relational_expression LEFT_ANGLE shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, "<", EOpLessThan, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | relational_expression RIGHT_ANGLE shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, ">", EOpGreaterThan, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | relational_expression LE_OP shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, "<=", EOpLessThanEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | relational_expression GE_OP shift_expression { + $$ = parseContext.handleBinaryMath($2.loc, ">=", EOpGreaterThanEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +equality_expression + : relational_expression { $$ = $1; } + | equality_expression EQ_OP relational_expression { + parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); + parseContext.opaqueCheck($2.loc, $1->getType(), "=="); + parseContext.specializationCheck($2.loc, $1->getType(), "=="); + parseContext.referenceCheck($2.loc, $1->getType(), "=="); + $$ = parseContext.handleBinaryMath($2.loc, "==", EOpEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + | equality_expression NE_OP relational_expression { + parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); + parseContext.opaqueCheck($2.loc, $1->getType(), "!="); + parseContext.specializationCheck($2.loc, $1->getType(), "!="); + parseContext.referenceCheck($2.loc, $1->getType(), "!="); + $$ = parseContext.handleBinaryMath($2.loc, "!=", EOpNotEqual, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +and_expression + : equality_expression { $$ = $1; } + | and_expression AMPERSAND equality_expression { + parseContext.fullIntegerCheck($2.loc, "bitwise and"); + $$ = parseContext.handleBinaryMath($2.loc, "&", EOpAnd, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +exclusive_or_expression + : and_expression { $$ = $1; } + | exclusive_or_expression CARET and_expression { + parseContext.fullIntegerCheck($2.loc, "bitwise exclusive or"); + $$ = parseContext.handleBinaryMath($2.loc, "^", EOpExclusiveOr, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +inclusive_or_expression + : exclusive_or_expression { $$ = $1; } + | inclusive_or_expression VERTICAL_BAR exclusive_or_expression { + parseContext.fullIntegerCheck($2.loc, "bitwise inclusive or"); + $$ = parseContext.handleBinaryMath($2.loc, "|", EOpInclusiveOr, $1, $3); + if ($$ == 0) + $$ = $1; + } + ; + +logical_and_expression + : inclusive_or_expression { $$ = $1; } + | logical_and_expression AND_OP inclusive_or_expression { + $$ = parseContext.handleBinaryMath($2.loc, "&&", EOpLogicalAnd, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +logical_xor_expression + : logical_and_expression { $$ = $1; } + | logical_xor_expression XOR_OP logical_and_expression { + $$ = parseContext.handleBinaryMath($2.loc, "^^", EOpLogicalXor, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +logical_or_expression + : logical_xor_expression { $$ = $1; } + | logical_or_expression OR_OP logical_xor_expression { + $$ = parseContext.handleBinaryMath($2.loc, "||", EOpLogicalOr, $1, $3); + if ($$ == 0) + $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); + } + ; + +conditional_expression + : logical_or_expression { $$ = $1; } + | logical_or_expression QUESTION { + ++parseContext.controlFlowNestingLevel; + } + expression COLON assignment_expression { + --parseContext.controlFlowNestingLevel; + parseContext.boolCheck($2.loc, $1); + parseContext.rValueErrorCheck($2.loc, "?", $1); + parseContext.rValueErrorCheck($5.loc, ":", $4); + parseContext.rValueErrorCheck($5.loc, ":", $6); + $$ = parseContext.intermediate.addSelection($1, $4, $6, $2.loc); + if ($$ == 0) { + parseContext.binaryOpError($2.loc, ":", $4->getCompleteString(), $6->getCompleteString()); + $$ = $6; + } + } + ; + +assignment_expression + : conditional_expression { $$ = $1; } + | unary_expression assignment_operator assignment_expression { + parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment"); + parseContext.opaqueCheck($2.loc, $1->getType(), "="); + parseContext.storage16BitAssignmentCheck($2.loc, $1->getType(), "="); + parseContext.specializationCheck($2.loc, $1->getType(), "="); + parseContext.lValueErrorCheck($2.loc, "assign", $1); + parseContext.rValueErrorCheck($2.loc, "assign", $3); + $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.loc); + if ($$ == 0) { + parseContext.assignError($2.loc, "assign", $1->getCompleteString(), $3->getCompleteString()); + $$ = $1; + } + } + ; + +assignment_operator + : EQUAL { + $$.loc = $1.loc; + $$.op = EOpAssign; + } + | MUL_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpMulAssign; + } + | DIV_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpDivAssign; + } + | MOD_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "%="); + $$.loc = $1.loc; + $$.op = EOpModAssign; + } + | ADD_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpAddAssign; + } + | SUB_ASSIGN { + $$.loc = $1.loc; + $$.op = EOpSubAssign; + } + | LEFT_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bit-shift left assign"); + $$.loc = $1.loc; $$.op = EOpLeftShiftAssign; + } + | RIGHT_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bit-shift right assign"); + $$.loc = $1.loc; $$.op = EOpRightShiftAssign; + } + | AND_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bitwise-and assign"); + $$.loc = $1.loc; $$.op = EOpAndAssign; + } + | XOR_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bitwise-xor assign"); + $$.loc = $1.loc; $$.op = EOpExclusiveOrAssign; + } + | OR_ASSIGN { + parseContext.fullIntegerCheck($1.loc, "bitwise-or assign"); + $$.loc = $1.loc; $$.op = EOpInclusiveOrAssign; + } + ; + +expression + : assignment_expression { + $$ = $1; + } + | expression COMMA assignment_expression { + parseContext.samplerConstructorLocationCheck($2.loc, ",", $3); + $$ = parseContext.intermediate.addComma($1, $3, $2.loc); + if ($$ == 0) { + parseContext.binaryOpError($2.loc, ",", $1->getCompleteString(), $3->getCompleteString()); + $$ = $3; + } + } + ; + +constant_expression + : conditional_expression { + parseContext.constantValueCheck($1, ""); + $$ = $1; + } + ; + +declaration + : function_prototype SEMICOLON { + parseContext.handleFunctionDeclarator($1.loc, *$1.function, true /* prototype */); + $$ = 0; + // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature + } + | init_declarator_list SEMICOLON { + if ($1.intermNode && $1.intermNode->getAsAggregate()) + $1.intermNode->getAsAggregate()->setOperator(EOpSequence); + $$ = $1.intermNode; + } + | PRECISION precision_qualifier type_specifier SEMICOLON { + parseContext.profileRequires($1.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($1.loc, $3, $2.qualifier.precision); + $$ = 0; + } + | block_structure SEMICOLON { + parseContext.declareBlock($1.loc, *$1.typeList); + $$ = 0; + } + | block_structure IDENTIFIER SEMICOLON { + parseContext.declareBlock($1.loc, *$1.typeList, $2.string); + $$ = 0; + } + | block_structure IDENTIFIER array_specifier SEMICOLON { + parseContext.declareBlock($1.loc, *$1.typeList, $2.string, $3.arraySizes); + $$ = 0; + } + | type_qualifier SEMICOLON { + parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); + parseContext.updateStandaloneQualifierDefaults($1.loc, $1); + $$ = 0; + } + | type_qualifier IDENTIFIER SEMICOLON { + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string); + $$ = 0; + } + | type_qualifier IDENTIFIER identifier_list SEMICOLON { + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + $3->push_back($2.string); + parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3); + $$ = 0; + } + ; + +block_structure + : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE { + --parseContext.structNestingLevel; + parseContext.blockName = $2.string; + parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.currentBlockQualifier = $1.qualifier; + $$.loc = $1.loc; + $$.typeList = $5; + } + +identifier_list + : COMMA IDENTIFIER { + $$ = new TIdentifierList; + $$->push_back($2.string); + } + | identifier_list COMMA IDENTIFIER { + $$ = $1; + $$->push_back($3.string); + } + ; + +function_prototype + : function_declarator RIGHT_PAREN { + $$.function = $1; + $$.loc = $2.loc; + } + ; + +function_declarator + : function_header { + $$ = $1; + } + | function_header_with_parameters { + $$ = $1; + } + ; + + +function_header_with_parameters + : function_header parameter_declaration { + // Add the parameter + $$ = $1; + if ($2.param.type->getBasicType() != EbtVoid) + $1->addParameter($2.param); + else + delete $2.param.type; + } + | function_header_with_parameters COMMA parameter_declaration { + // + // Only first parameter of one-parameter functions can be void + // The check for named parameters not being void is done in parameter_declarator + // + if ($3.param.type->getBasicType() == EbtVoid) { + // + // This parameter > first is void + // + parseContext.error($2.loc, "cannot be an argument type except for '(void)'", "void", ""); + delete $3.param.type; + } else { + // Add the parameter + $$ = $1; + $1->addParameter($3.param); + } + } + ; + +function_header + : fully_specified_type IDENTIFIER LEFT_PAREN { + if ($1.qualifier.storage != EvqGlobal && $1.qualifier.storage != EvqTemporary) { + parseContext.error($2.loc, "no qualifiers allowed for function return", + GetStorageQualifierString($1.qualifier.storage), ""); + } + if ($1.arraySizes) + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + + // Add the function as a prototype after parsing it (we do not support recursion) + TFunction *function; + TType type($1); + + // Potentially rename shader entry point function. No-op most of the time. + parseContext.renameShaderFunction($2.string); + + // Make the function + function = new TFunction($2.string, type); + $$ = function; + } + ; + +parameter_declarator + // Type + name + : type_specifier IDENTIFIER { + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + if ($1.basicType == EbtVoid) { + parseContext.error($2.loc, "illegal use of type 'void'", $2.string->c_str(), ""); + } + parseContext.reservedErrorCheck($2.loc, *$2.string); + + TParameter param = {$2.string, new TType($1)}; + $$.loc = $2.loc; + $$.param = param; + } + | type_specifier IDENTIFIER array_specifier { + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + TType* type = new TType($1); + type->transferArraySizes($3.arraySizes); + type->copyArrayInnerSizes($1.arraySizes); + + parseContext.arrayOfArrayVersionCheck($2.loc, type->getArraySizes()); + parseContext.arraySizeRequiredCheck($3.loc, *$3.arraySizes); + parseContext.reservedErrorCheck($2.loc, *$2.string); + + TParameter param = { $2.string, type }; + + $$.loc = $2.loc; + $$.param = param; + } + ; + +parameter_declaration + // + // With name + // + : type_qualifier parameter_declarator { + $$ = $2; + if ($1.qualifier.precision != EpqNone) + $$.param.type->getQualifier().precision = $1.qualifier.precision; + parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheckFix($1.loc, $1.qualifier, *$$.param.type); + + } + | parameter_declarator { + $$ = $1; + + parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type); + parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type); + parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + } + // + // Without name + // + | type_qualifier parameter_type_specifier { + $$ = $2; + if ($1.qualifier.precision != EpqNone) + $$.param.type->getQualifier().precision = $1.qualifier.precision; + parseContext.precisionQualifierCheck($1.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + + parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers); + parseContext.parameterTypeCheck($2.loc, $1.qualifier.storage, *$$.param.type); + parseContext.paramCheckFix($1.loc, $1.qualifier, *$$.param.type); + } + | parameter_type_specifier { + $$ = $1; + + parseContext.parameterTypeCheck($1.loc, EvqIn, *$1.param.type); + parseContext.paramCheckFixStorage($1.loc, EvqTemporary, *$$.param.type); + parseContext.precisionQualifierCheck($$.loc, $$.param.type->getBasicType(), $$.param.type->getQualifier()); + } + ; + +parameter_type_specifier + : type_specifier { + TParameter param = { 0, new TType($1) }; + $$.param = param; + if ($1.arraySizes) + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + ; + +init_declarator_list + : single_declaration { + $$ = $1; + } + | init_declarator_list COMMA IDENTIFIER { + $$ = $1; + parseContext.declareVariable($3.loc, *$3.string, $1.type); + } + | init_declarator_list COMMA IDENTIFIER array_specifier { + $$ = $1; + parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes); + } + | init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer { + $$.type = $1.type; + TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, $4.arraySizes, $6); + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $5.loc); + } + | init_declarator_list COMMA IDENTIFIER EQUAL initializer { + $$.type = $1.type; + TIntermNode* initNode = parseContext.declareVariable($3.loc, *$3.string, $1.type, 0, $5); + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, initNode, $4.loc); + } + ; + +single_declaration + : fully_specified_type { + $$.type = $1; + $$.intermNode = 0; +GLSLANG_WEB_EXCLUDE_ON + parseContext.declareTypeDefaults($$.loc, $$.type); +GLSLANG_WEB_EXCLUDE_OFF + } + | fully_specified_type IDENTIFIER { + $$.type = $1; + $$.intermNode = 0; + parseContext.declareVariable($2.loc, *$2.string, $1); + } + | fully_specified_type IDENTIFIER array_specifier { + $$.type = $1; + $$.intermNode = 0; + parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes); + } + | fully_specified_type IDENTIFIER array_specifier EQUAL initializer { + $$.type = $1; + TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, $3.arraySizes, $5); + $$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $4.loc); + } + | fully_specified_type IDENTIFIER EQUAL initializer { + $$.type = $1; + TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4); + $$.intermNode = parseContext.intermediate.growAggregate(0, initNode, $3.loc); + } + +// Grammar Note: No 'enum', or 'typedef'. + +fully_specified_type + : type_specifier { + $$ = $1; + + parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $$); + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + } + parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier); + } + | type_qualifier type_specifier { + parseContext.globalQualifierFixCheck($1.loc, $1.qualifier); + parseContext.globalQualifierTypeCheck($1.loc, $1.qualifier, $2); + + if ($2.arraySizes) { + parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); + } + + if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier)) + $2.arraySizes = nullptr; + + parseContext.checkNoShaderLayouts($2.loc, $1.shaderQualifiers); + $2.shaderQualifiers.merge($1.shaderQualifiers); + parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); + parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier); + + $$ = $2; + + if (! $$.qualifier.isInterpolation() && + ((parseContext.language == EShLangVertex && $$.qualifier.storage == EvqVaryingOut) || + (parseContext.language == EShLangFragment && $$.qualifier.storage == EvqVaryingIn))) + $$.qualifier.smooth = true; + } + ; + +invariant_qualifier + : INVARIANT { + parseContext.globalCheck($1.loc, "invariant"); + parseContext.profileRequires($$.loc, ENoProfile, 120, 0, "invariant"); + $$.init($1.loc); + $$.qualifier.invariant = true; + } + ; + +interpolation_qualifier + : SMOOTH { + parseContext.globalCheck($1.loc, "smooth"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "smooth"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "smooth"); + $$.init($1.loc); + $$.qualifier.smooth = true; + } + | FLAT { + parseContext.globalCheck($1.loc, "flat"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "flat"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "flat"); + $$.init($1.loc); + $$.qualifier.flat = true; + } +GLSLANG_WEB_EXCLUDE_ON + | NOPERSPECTIVE { + parseContext.globalCheck($1.loc, "noperspective"); + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective"); + $$.init($1.loc); + $$.qualifier.nopersp = true; + } + | EXPLICITINTERPAMD { + parseContext.globalCheck($1.loc, "__explicitInterpAMD"); + parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + parseContext.profileRequires($1.loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); + $$.init($1.loc); + $$.qualifier.explicitInterp = true; + } + | PERVERTEXNV { + parseContext.globalCheck($1.loc, "pervertexNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + $$.init($1.loc); + $$.qualifier.pervertexNV = true; + } + | PERPRIMITIVENV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "perprimitiveNV"); + parseContext.requireStage($1.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($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); + $$.init($1.loc); + $$.qualifier.perPrimitiveNV = true; + } + | PERVIEWNV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "perviewNV"); + parseContext.requireStage($1.loc, EShLangMeshNV, "perviewNV"); + $$.init($1.loc); + $$.qualifier.perViewNV = true; + } + | PERTASKNV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "taskNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); + $$.init($1.loc); + $$.qualifier.perTaskNV = true; + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +layout_qualifier + : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { + $$ = $3; + } + ; + +layout_qualifier_id_list + : layout_qualifier_id { + $$ = $1; + } + | layout_qualifier_id_list COMMA layout_qualifier_id { + $$ = $1; + $$.shaderQualifiers.merge($3.shaderQualifiers); + parseContext.mergeObjectLayoutQualifiers($$.qualifier, $3.qualifier, false); + } + +layout_qualifier_id + : IDENTIFIER { + $$.init($1.loc); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string); + } + | IDENTIFIER EQUAL constant_expression { + $$.init($1.loc); + parseContext.setLayoutQualifier($1.loc, $$, *$1.string, $3); + } + | SHARED { // because "shared" is both an identifier and a keyword + $$.init($1.loc); + TString strShared("shared"); + parseContext.setLayoutQualifier($1.loc, $$, strShared); + } + ; + +GLSLANG_WEB_EXCLUDE_ON +precise_qualifier + : PRECISE { + parseContext.profileRequires($$.loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); + parseContext.profileRequires($1.loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); + $$.init($1.loc); + $$.qualifier.noContraction = true; + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +type_qualifier + : single_type_qualifier { + $$ = $1; + } + | type_qualifier single_type_qualifier { + $$ = $1; + if ($$.basicType == EbtVoid) + $$.basicType = $2.basicType; + + $$.shaderQualifiers.merge($2.shaderQualifiers); + parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false); + } + ; + +single_type_qualifier + : storage_qualifier { + $$ = $1; + } + | layout_qualifier { + $$ = $1; + } + | precision_qualifier { + parseContext.checkPrecisionQualifier($1.loc, $1.qualifier.precision); + $$ = $1; + } + | interpolation_qualifier { + // allow inheritance of storage qualifier from block declaration + $$ = $1; + } + | invariant_qualifier { + // allow inheritance of storage qualifier from block declaration + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | precise_qualifier { + // allow inheritance of storage qualifier from block declaration + $$ = $1; + } + | non_uniform_qualifier { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +storage_qualifier + : CONST { + $$.init($1.loc); + $$.qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant + } + | INOUT { + parseContext.globalCheck($1.loc, "inout"); + $$.init($1.loc); + $$.qualifier.storage = EvqInOut; + } + | IN { + parseContext.globalCheck($1.loc, "in"); + $$.init($1.loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + $$.qualifier.storage = EvqIn; + } + | OUT { + parseContext.globalCheck($1.loc, "out"); + $$.init($1.loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + $$.qualifier.storage = EvqOut; + } + | CENTROID { + parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck($1.loc, "centroid"); + $$.init($1.loc); + $$.qualifier.centroid = true; + } + | UNIFORM { + parseContext.globalCheck($1.loc, "uniform"); + $$.init($1.loc); + $$.qualifier.storage = EvqUniform; + } + | SHARED { + parseContext.globalCheck($1.loc, "shared"); + parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + $$.init($1.loc); + $$.qualifier.storage = EvqShared; + } + | BUFFER { + parseContext.globalCheck($1.loc, "buffer"); + $$.init($1.loc); + $$.qualifier.storage = EvqBuffer; + } +GLSLANG_WEB_EXCLUDE_ON + | ATTRIBUTE { + parseContext.requireStage($1.loc, EShLangVertex, "attribute"); + parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute"); + parseContext.checkDeprecated($1.loc, ENoProfile, 130, "attribute"); + parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "attribute"); + parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "attribute"); + + parseContext.globalCheck($1.loc, "attribute"); + + $$.init($1.loc); + $$.qualifier.storage = EvqVaryingIn; + } + | VARYING { + parseContext.checkDeprecated($1.loc, ENoProfile, 130, "varying"); + parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "varying"); + parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "varying"); + parseContext.requireNotRemoved($1.loc, EEsProfile, 300, "varying"); + + parseContext.globalCheck($1.loc, "varying"); + + $$.init($1.loc); + if (parseContext.language == EShLangVertex) + $$.qualifier.storage = EvqVaryingOut; + else + $$.qualifier.storage = EvqVaryingIn; + } + | PATCH { + parseContext.globalCheck($1.loc, "patch"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); + $$.init($1.loc); + $$.qualifier.patch = true; + } + | SAMPLE { + parseContext.globalCheck($1.loc, "sample"); + $$.init($1.loc); + $$.qualifier.sample = true; + } + | HITATTRNV { + parseContext.globalCheck($1.loc, "hitAttributeNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask + | EShLangAnyHitNVMask), "hitAttributeNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqHitAttrNV; + } + | PAYLOADNV { + parseContext.globalCheck($1.loc, "rayPayloadNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | + EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayloadNV; + } + | PAYLOADINNV { + parseContext.globalCheck($1.loc, "rayPayloadInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitNVMask | + EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqPayloadInNV; + } + | CALLDATANV { + parseContext.globalCheck($1.loc, "callableDataNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | + EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableDataNV; + } + | CALLDATAINNV { + parseContext.globalCheck($1.loc, "callableDataInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableDataInNV; + } + | COHERENT { + $$.init($1.loc); + $$.qualifier.coherent = true; + } + | DEVICECOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); + $$.qualifier.devicecoherent = true; + } + | QUEUEFAMILYCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); + $$.qualifier.queuefamilycoherent = true; + } + | WORKGROUPCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); + $$.qualifier.workgroupcoherent = true; + } + | SUBGROUPCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); + $$.qualifier.subgroupcoherent = true; + } + | NONPRIVATE { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); + $$.qualifier.nonprivate = true; + } + | VOLATILE { + $$.init($1.loc); + $$.qualifier.volatil = true; + } + | RESTRICT { + $$.init($1.loc); + $$.qualifier.restrict = true; + } + | READONLY { + $$.init($1.loc); + $$.qualifier.readonly = true; + } + | WRITEONLY { + $$.init($1.loc); + $$.qualifier.writeonly = true; + } + | SUBROUTINE { + parseContext.spvRemoved($1.loc, "subroutine"); + parseContext.globalCheck($1.loc, "subroutine"); + parseContext.unimplemented($1.loc, "subroutine"); + $$.init($1.loc); + } + | SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN { + parseContext.spvRemoved($1.loc, "subroutine"); + parseContext.globalCheck($1.loc, "subroutine"); + parseContext.unimplemented($1.loc, "subroutine"); + $$.init($1.loc); + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +GLSLANG_WEB_EXCLUDE_ON +non_uniform_qualifier + : NONUNIFORM { + $$.init($1.loc); + $$.qualifier.nonUniform = true; + } + ; + +type_name_list + : IDENTIFIER { + // TODO + } + | type_name_list COMMA IDENTIFIER { + // 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 + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +type_specifier + : type_specifier_nonarray type_parameter_specifier_opt { + $$ = $1; + $$.qualifier.precision = parseContext.getDefaultPrecision($$); + $$.typeParameters = $2; + } + | type_specifier_nonarray type_parameter_specifier_opt array_specifier { + parseContext.arrayOfArrayVersionCheck($3.loc, $3.arraySizes); + $$ = $1; + $$.qualifier.precision = parseContext.getDefaultPrecision($$); + $$.typeParameters = $2; + $$.arraySizes = $3.arraySizes; + } + ; + +array_specifier + : LEFT_BRACKET RIGHT_BRACKET { + $$.loc = $1.loc; + $$.arraySizes = new TArraySizes; + $$.arraySizes->addInnerSize(); + } + | LEFT_BRACKET conditional_expression RIGHT_BRACKET { + $$.loc = $1.loc; + $$.arraySizes = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck($2->getLoc(), $2, size, "array size"); + $$.arraySizes->addInnerSize(size); + } + | array_specifier LEFT_BRACKET RIGHT_BRACKET { + $$ = $1; + $$.arraySizes->addInnerSize(); + } + | array_specifier LEFT_BRACKET conditional_expression RIGHT_BRACKET { + $$ = $1; + + TArraySize size; + parseContext.arraySizeCheck($3->getLoc(), $3, size, "array size"); + $$.arraySizes->addInnerSize(size); + } + ; + +type_parameter_specifier_opt + : type_parameter_specifier { + $$ = $1; + } + | /* May be null */ { + $$ = 0; + } + ; + +type_parameter_specifier + : LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE { + $$ = $2; + } + ; + +type_parameter_specifier_list + : unary_expression { + $$ = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck($1->getLoc(), $1, size, "type parameter"); + $$->addInnerSize(size); + } + | type_parameter_specifier_list COMMA unary_expression { + $$ = $1; + + TArraySize size; + parseContext.arraySizeCheck($3->getLoc(), $3, size, "type parameter"); + $$->addInnerSize(size); + } + ; + +type_specifier_nonarray + : VOID { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtVoid; + } + | FLOAT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + } + | INT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + } + | UINT { + parseContext.fullIntegerCheck($1.loc, "unsigned integer"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + } + | BOOL { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + } + | VEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(2); + } + | VEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(3); + } + | VEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(4); + } + | BVEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(2); + } + | BVEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(3); + } + | BVEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtBool; + $$.setVector(4); + } + | IVEC2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(2); + } + | IVEC3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(3); + } + | IVEC4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(4); + } + | UVEC2 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(2); + } + | UVEC3 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(3); + } + | UVEC4 { + parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(4); + } + | MAT2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | MAT3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | MAT4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | MAT2X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | MAT2X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 3); + } + | MAT2X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 4); + } + | MAT3X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 2); + } + | MAT3X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | MAT3X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 4); + } + | MAT4X2 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 2); + } + | MAT4X3 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 3); + } + | MAT4X4 { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } +GLSLANG_WEB_EXCLUDE_ON + | DOUBLE { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + } + | FLOAT16_T { + parseContext.float16ScalarVectorCheck($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + } + | FLOAT32_T { + parseContext.explicitFloat32Check($1.loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + } + | FLOAT64_T { + parseContext.explicitFloat64Check($1.loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + } + | INT8_T { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + } + | UINT8_T { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + } + | INT16_T { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + } + | UINT16_T { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + } + | INT32_T { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + } + | UINT32_T { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + } + | INT64_T { + parseContext.int64Check($1.loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + } + | UINT64_T { + parseContext.int64Check($1.loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + } + | DVEC2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(2); + } + | DVEC3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(3); + } + | DVEC4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(4); + } + | F16VEC2 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(2); + } + | F16VEC3 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(3); + } + | F16VEC4 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(4); + } + | F32VEC2 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(2); + } + | F32VEC3 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(3); + } + | F32VEC4 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(4); + } + | F64VEC2 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(2); + } + | F64VEC3 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(3); + } + | F64VEC4 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(4); + } + | I8VEC2 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(2); + } + | I8VEC3 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(3); + } + | I8VEC4 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(4); + } + | I16VEC2 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(2); + } + | I16VEC3 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(3); + } + | I16VEC4 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(4); + } + | I32VEC2 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(2); + } + | I32VEC3 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(3); + } + | I32VEC4 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(4); + } + | I64VEC2 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(2); + } + | I64VEC3 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(3); + } + | I64VEC4 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(4); + } + | U8VEC2 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(2); + } + | U8VEC3 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(3); + } + | U8VEC4 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(4); + } + | U16VEC2 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(2); + } + | U16VEC3 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(3); + } + | U16VEC4 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(4); + } + | U32VEC2 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(2); + } + | U32VEC3 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(3); + } + | U32VEC4 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(4); + } + | U64VEC2 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(2); + } + | U64VEC3 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(3); + } + | U64VEC4 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(4); + } + | DMAT2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | DMAT3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | DMAT4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | DMAT2X2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | DMAT2X3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 3); + } + | DMAT2X4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 4); + } + | DMAT3X2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 2); + } + | DMAT3X3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | DMAT3X4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 4); + } + | DMAT4X2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 2); + } + | DMAT4X3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 3); + } + | DMAT4X4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | F16MAT2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 2); + } + | F16MAT3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 3); + } + | F16MAT4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 4); + } + | F16MAT2X2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 2); + } + | F16MAT2X3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 3); + } + | F16MAT2X4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(2, 4); + } + | F16MAT3X2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 2); + } + | F16MAT3X3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 3); + } + | F16MAT3X4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(3, 4); + } + | F16MAT4X2 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 2); + } + | F16MAT4X3 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 3); + } + | F16MAT4X4 { + parseContext.float16Check($1.loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setMatrix(4, 4); + } + | F32MAT2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | F32MAT3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | F32MAT4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | F32MAT2X2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 2); + } + | F32MAT2X3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 3); + } + | F32MAT2X4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(2, 4); + } + | F32MAT3X2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 2); + } + | F32MAT3X3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 3); + } + | F32MAT3X4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(3, 4); + } + | F32MAT4X2 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 2); + } + | F32MAT4X3 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 3); + } + | F32MAT4X4 { + parseContext.explicitFloat32Check($1.loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setMatrix(4, 4); + } + | F64MAT2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | F64MAT3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | F64MAT4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | F64MAT2X2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 2); + } + | F64MAT2X3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 3); + } + | F64MAT2X4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(2, 4); + } + | F64MAT3X2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 2); + } + | F64MAT3X3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 3); + } + | F64MAT3X4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(3, 4); + } + | F64MAT4X2 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 2); + } + | F64MAT4X3 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 3); + } + | F64MAT4X4 { + parseContext.explicitFloat64Check($1.loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setMatrix(4, 4); + } + | ACCSTRUCTNV { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAccStructNV; + } + | ATOMIC_UINT { + parseContext.vulkanRemoved($1.loc, "atomic counter types"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAtomicUint; + } + | SAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D); + } +GLSLANG_WEB_EXCLUDE_OFF + | SAMPLER2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + } + | SAMPLER3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd3D); + } + | SAMPLERCUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube); + } + | SAMPLER2DSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, false, true); + } + | SAMPLERCUBESHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube, false, true); + } + | SAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, true); + } + | SAMPLER2DARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, true, true); + } +GLSLANG_WEB_EXCLUDE_ON + | SAMPLER1DSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, false, true); + } + | SAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true); + } + | SAMPLER1DARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true, true); + } + | SAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube, true); + } + | SAMPLERCUBEARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdCube, true, true); + } + | F16SAMPLER1D { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D); + } + | F16SAMPLER2D { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D); + } + | F16SAMPLER3D { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd3D); + } + | F16SAMPLERCUBE { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube); + } + | F16SAMPLER1DSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D, false, true); + } + | F16SAMPLER2DSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, false, true); + } + | F16SAMPLERCUBESHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube, false, true); + } + | F16SAMPLER1DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D, true); + } + | F16SAMPLER2DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, true); + } + | F16SAMPLER1DARRAYSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd1D, true, true); + } + | F16SAMPLER2DARRAYSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, true, true); + } + | F16SAMPLERCUBEARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube, true); + } + | F16SAMPLERCUBEARRAYSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdCube, true, true); + } + | ISAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd1D); + } +GLSLANG_WEB_EXCLUDE_OFF + | ISAMPLER2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D); + } + | ISAMPLER3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd3D); + } + | ISAMPLERCUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdCube); + } + | ISAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D, true); + } + | USAMPLER2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D); + } + | USAMPLER3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd3D); + } + | USAMPLERCUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdCube); + } +GLSLANG_WEB_EXCLUDE_ON + | ISAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd1D, true); + } + | ISAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdCube, true); + } + | USAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd1D); + } + | USAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd1D, true); + } + | USAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdCube, true); + } + | TEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube, true); + } + | ITEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube, true); + } + | UTEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube, true); + } +GLSLANG_WEB_EXCLUDE_OFF + | USAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, true); + } + | TEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D); + } + | TEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd3D); + } + | TEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, true); + } + | TEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube); + } + | ITEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D); + } + | ITEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd3D); + } + | ITEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube); + } + | ITEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, true); + } + | UTEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D); + } + | UTEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd3D); + } + | UTEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube); + } + | UTEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, true); + } + | SAMPLER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(false); + } + | SAMPLERSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(true); + } +GLSLANG_WEB_EXCLUDE_ON + | SAMPLER2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdRect); + } + | SAMPLER2DRECTSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdRect, false, true); + } + | F16SAMPLER2DRECT { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdRect); + } + | F16SAMPLER2DRECTSHADOW { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdRect, false, true); + } + | ISAMPLER2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdRect); + } + | USAMPLER2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdRect); + } + | SAMPLERBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, EsdBuffer); + } + | F16SAMPLERBUFFER { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, EsdBuffer); + } + | ISAMPLERBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdBuffer); + } + | USAMPLERBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, EsdBuffer); + } + | SAMPLER2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, false, false, true); + } + | F16SAMPLER2DMS { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, false, false, true); + } + | ISAMPLER2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D, false, false, true); + } + | USAMPLER2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, false, false, true); + } + | SAMPLER2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D, true, false, true); + } + | F16SAMPLER2DMSARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat16, Esd2D, true, false, true); + } + | ISAMPLER2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd2D, true, false, true); + } + | USAMPLER2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, true, false, true); + } + | TEXTURE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd1D); + } + | F16TEXTURE1D { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd1D); + } + | F16TEXTURE2D { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D); + } + | F16TEXTURE3D { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd3D); + } + | F16TEXTURECUBE { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdCube); + } + | TEXTURE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd1D, true); + } + | F16TEXTURE1DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd1D, true); + } + | F16TEXTURE2DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D, true); + } + | F16TEXTURECUBEARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdCube, true); + } + | ITEXTURE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd1D); + } + | ITEXTURE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd1D, true); + } + | UTEXTURE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd1D); + } + | UTEXTURE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd1D, true); + } + | TEXTURE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdRect); + } + | F16TEXTURE2DRECT { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdRect); + } + | ITEXTURE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdRect); + } + | UTEXTURE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdRect); + } + | TEXTUREBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdBuffer); + } + | F16TEXTUREBUFFER { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, EsdBuffer); + } + | ITEXTUREBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdBuffer); + } + | UTEXTUREBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdBuffer); + } + | TEXTURE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, false, false, true); + } + | F16TEXTURE2DMS { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D, false, false, true); + } + | ITEXTURE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, false, false, true); + } + | UTEXTURE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, false, false, true); + } + | TEXTURE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, true, false, true); + } + | F16TEXTURE2DMSARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat16, Esd2D, true, false, true); + } + | ITEXTURE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, true, false, true); + } + | UTEXTURE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, true, false, true); + } + | IMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd1D); + } + | F16IMAGE1D { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd1D); + } + | IIMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd1D); + } + | UIMAGE1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd1D); + } + | IMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D); + } + | F16IMAGE2D { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D); + } + | IIMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D); + } + | UIMAGE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D); + } + | IMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd3D); + } + | F16IMAGE3D { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd3D); + } + | IIMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd3D); + } + | UIMAGE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd3D); + } + | IMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdRect); + } + | F16IMAGE2DRECT { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdRect); + } + | IIMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdRect); + } + | UIMAGE2DRECT { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdRect); + } + | IMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdCube); + } + | F16IMAGECUBE { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdCube); + } + | IIMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdCube); + } + | UIMAGECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdCube); + } + | IMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdBuffer); + } + | F16IMAGEBUFFER { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdBuffer); + } + | IIMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdBuffer); + } + | UIMAGEBUFFER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdBuffer); + } + | IMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd1D, true); + } + | F16IMAGE1DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd1D, true); + } + | IIMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd1D, true); + } + | UIMAGE1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd1D, true); + } + | IMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D, true); + } + | F16IMAGE2DARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D, true); + } + | IIMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D, true); + } + | UIMAGE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D, true); + } + | IMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, EsdCube, true); + } + | F16IMAGECUBEARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, EsdCube, true); + } + | IIMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, EsdCube, true); + } + | UIMAGECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, EsdCube, true); + } + | IMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D, false, false, true); + } + | F16IMAGE2DMS { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D, false, false, true); + } + | IIMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D, false, false, true); + } + | UIMAGE2DMS { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D, false, false, true); + } + | IMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat, Esd2D, true, false, true); + } + | F16IMAGE2DMSARRAY { + parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtFloat16, Esd2D, true, false, true); + } + | IIMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtInt, Esd2D, true, false, true); + } + | UIMAGE2DMSARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setImage(EbtUint, Esd2D, true, false, true); + } + | SAMPLEREXTERNALOES { // GL_OES_EGL_image_external + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + $$.sampler.external = true; + } + | SAMPLEREXTERNAL2DY2YEXT { // GL_EXT_YUV_target + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + $$.sampler.yuv = true; + } + | SUBPASSINPUT { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat); + } + | SUBPASSINPUTMS { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat, true); + } + | F16SUBPASSINPUT { + parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat16); + } + | F16SUBPASSINPUTMS { + parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtFloat16, true); + } + | ISUBPASSINPUT { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtInt); + } + | ISUBPASSINPUTMS { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtInt, true); + } + | USUBPASSINPUT { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtUint); + } + | USUBPASSINPUTMS { + parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setSubpass(EbtUint, true); + } + | FCOOPMATNV { + parseContext.fcoopmatCheck($1.loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.coopmat = true; + } + | ICOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.coopmat = true; + } + | UCOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.coopmat = true; + } +GLSLANG_WEB_EXCLUDE_OFF + | struct_specifier { + $$ = $1; + $$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + parseContext.structTypeCheck($$.loc, $$); + } + | TYPE_NAME { + // + // This is for user defined type names. The lexical phase looked up the + // type. + // + if (const TVariable* variable = ($1.symbol)->getAsVariable()) { + const TType& structure = variable->getType(); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtStruct; + $$.userDef = &structure; + } else + parseContext.error($1.loc, "expected type name", $1.string->c_str(), ""); + } + ; + +precision_qualifier + : HIGH_PRECISION { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "highp precision qualifier"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier($1.loc, $$.qualifier, EpqHigh); + } + | MEDIUM_PRECISION { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "mediump precision qualifier"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier($1.loc, $$.qualifier, EpqMedium); + } + | LOW_PRECISION { + parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "lowp precision qualifier"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + parseContext.handlePrecisionQualifier($1.loc, $$.qualifier, EpqLow); + } + ; + +struct_specifier + : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { + TType* structure = new TType($5, *$2.string); + parseContext.structArrayCheck($2.loc, *structure); + TVariable* userTypeDef = new TVariable($2.string, *structure, true); + if (! parseContext.symbolTable.insert(*userTypeDef)) + parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct"); + $$.init($1.loc); + $$.basicType = EbtStruct; + $$.userDef = structure; + --parseContext.structNestingLevel; + } + | STRUCT LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE { + TType* structure = new TType($4, TString("")); + $$.init($1.loc); + $$.basicType = EbtStruct; + $$.userDef = structure; + --parseContext.structNestingLevel; + } + ; + +struct_declaration_list + : struct_declaration { + $$ = $1; + } + | struct_declaration_list struct_declaration { + $$ = $1; + for (unsigned int i = 0; i < $2->size(); ++i) { + for (unsigned int j = 0; j < $$->size(); ++j) { + if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) + parseContext.error((*$2)[i].loc, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str()); + } + $$->push_back((*$2)[i]); + } + } + ; + +struct_declaration + : type_specifier struct_declarator_list SEMICOLON { + if ($1.arraySizes) { + parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); + if (parseContext.isEsProfile()) + parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); + } + + $$ = $2; + + parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1.basicType); + parseContext.precisionQualifierCheck($1.loc, $1.basicType, $1.qualifier); + + for (unsigned int i = 0; i < $$->size(); ++i) { + TType type($1); + type.setFieldName((*$$)[i].type->getFieldName()); + type.transferArraySizes((*$$)[i].type->getArraySizes()); + type.copyArrayInnerSizes($1.arraySizes); + parseContext.arrayOfArrayVersionCheck((*$$)[i].loc, type.getArraySizes()); + (*$$)[i].type->shallowCopy(type); + } + } + | type_qualifier type_specifier struct_declarator_list SEMICOLON { + if ($2.arraySizes) { + parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); + parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); + if (parseContext.isEsProfile()) + parseContext.arraySizeRequiredCheck($2.loc, *$2.arraySizes); + } + + $$ = $3; + + parseContext.memberQualifierCheck($1); + parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType); + parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true); + parseContext.precisionQualifierCheck($2.loc, $2.basicType, $2.qualifier); + + for (unsigned int i = 0; i < $$->size(); ++i) { + TType type($2); + type.setFieldName((*$$)[i].type->getFieldName()); + type.transferArraySizes((*$$)[i].type->getArraySizes()); + type.copyArrayInnerSizes($2.arraySizes); + parseContext.arrayOfArrayVersionCheck((*$$)[i].loc, type.getArraySizes()); + (*$$)[i].type->shallowCopy(type); + } + } + ; + +struct_declarator_list + : struct_declarator { + $$ = new TTypeList; + $$->push_back($1); + } + | struct_declarator_list COMMA struct_declarator { + $$->push_back($3); + } + ; + +struct_declarator + : IDENTIFIER { + $$.type = new TType(EbtVoid); + $$.loc = $1.loc; + $$.type->setFieldName(*$1.string); + } + | IDENTIFIER array_specifier { + parseContext.arrayOfArrayVersionCheck($1.loc, $2.arraySizes); + + $$.type = new TType(EbtVoid); + $$.loc = $1.loc; + $$.type->setFieldName(*$1.string); + $$.type->transferArraySizes($2.arraySizes); + } + ; + +initializer + : assignment_expression { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | LEFT_BRACE initializer_list RIGHT_BRACE { + const char* initFeature = "{ } style initializers"; + parseContext.requireProfile($1.loc, ~EEsProfile, initFeature); + parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + $$ = $2; + } + | LEFT_BRACE initializer_list COMMA RIGHT_BRACE { + const char* initFeature = "{ } style initializers"; + parseContext.requireProfile($1.loc, ~EEsProfile, initFeature); + parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +GLSLANG_WEB_EXCLUDE_ON +initializer_list + : initializer { + $$ = parseContext.intermediate.growAggregate(0, $1, $1->getLoc()); + } + | initializer_list COMMA initializer { + $$ = parseContext.intermediate.growAggregate($1, $3); + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +declaration_statement + : declaration { $$ = $1; } + ; + +statement + : compound_statement { $$ = $1; } + | simple_statement { $$ = $1; } + ; + +// Grammar Note: labeled statements for switch statements only; 'goto' is not supported. + +simple_statement + : declaration_statement { $$ = $1; } + | expression_statement { $$ = $1; } + | selection_statement { $$ = $1; } + | switch_statement { $$ = $1; } + | case_label { $$ = $1; } + | iteration_statement { $$ = $1; } + | jump_statement { $$ = $1; } +GLSLANG_WEB_EXCLUDE_ON + | demote_statement { $$ = $1; } +GLSLANG_WEB_EXCLUDE_OFF + ; + +GLSLANG_WEB_EXCLUDE_ON +demote_statement + : DEMOTE SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "demote"); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); + $$ = parseContext.intermediate.addBranch(EOpDemote, $1.loc); + } + ; +GLSLANG_WEB_EXCLUDE_OFF + +compound_statement + : LEFT_BRACE RIGHT_BRACE { $$ = 0; } + | LEFT_BRACE { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + } + statement_list { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + } + RIGHT_BRACE { + if ($3 && $3->getAsAggregate()) + $3->getAsAggregate()->setOperator(EOpSequence); + $$ = $3; + } + ; + +statement_no_new_scope + : compound_statement_no_new_scope { $$ = $1; } + | simple_statement { $$ = $1; } + ; + +statement_scoped + : { + ++parseContext.controlFlowNestingLevel; + } + compound_statement { + --parseContext.controlFlowNestingLevel; + $$ = $2; + } + | { + parseContext.symbolTable.push(); + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + simple_statement { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + $$ = $2; + } + +compound_statement_no_new_scope + // Statement that doesn't create a new scope, for selection_statement, iteration_statement + : LEFT_BRACE RIGHT_BRACE { + $$ = 0; + } + | LEFT_BRACE statement_list RIGHT_BRACE { + if ($2 && $2->getAsAggregate()) + $2->getAsAggregate()->setOperator(EOpSequence); + $$ = $2; + } + ; + +statement_list + : statement { + $$ = parseContext.intermediate.makeAggregate($1); + if ($1 && $1->getAsBranchNode() && ($1->getAsBranchNode()->getFlowOp() == EOpCase || + $1->getAsBranchNode()->getFlowOp() == EOpDefault)) { + parseContext.wrapupSwitchSubsequence(0, $1); + $$ = 0; // start a fresh subsequence for what's after this case + } + } + | statement_list statement { + if ($2 && $2->getAsBranchNode() && ($2->getAsBranchNode()->getFlowOp() == EOpCase || + $2->getAsBranchNode()->getFlowOp() == EOpDefault)) { + parseContext.wrapupSwitchSubsequence($1 ? $1->getAsAggregate() : 0, $2); + $$ = 0; // start a fresh subsequence for what's after this case + } else + $$ = parseContext.intermediate.growAggregate($1, $2); + } + ; + +expression_statement + : SEMICOLON { $$ = 0; } + | expression SEMICOLON { $$ = static_cast($1); } + ; + +selection_statement + : selection_statement_nonattributed { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | attribute selection_statement_nonattributed { + parseContext.handleSelectionAttributes(*$1, $2); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + +selection_statement_nonattributed + : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { + parseContext.boolCheck($1.loc, $3); + $$ = parseContext.intermediate.addSelection($3, $5, $1.loc); + } + ; + +selection_rest_statement + : statement_scoped ELSE statement_scoped { + $$.node1 = $1; + $$.node2 = $3; + } + | statement_scoped { + $$.node1 = $1; + $$.node2 = 0; + } + ; + +condition + // In 1996 c++ draft, conditions can include single declarations + : expression { + $$ = $1; + parseContext.boolCheck($1->getLoc(), $1); + } + | fully_specified_type IDENTIFIER EQUAL initializer { + parseContext.boolCheck($2.loc, $1); + + TType type($1); + TIntermNode* initNode = parseContext.declareVariable($2.loc, *$2.string, $1, 0, $4); + if (initNode) + $$ = initNode->getAsTyped(); + else + $$ = 0; + } + ; + +switch_statement + : switch_statement_nonattributed { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | attribute switch_statement_nonattributed { + parseContext.handleSwitchAttributes(*$1, $2); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + +switch_statement_nonattributed + : SWITCH LEFT_PAREN expression RIGHT_PAREN { + // start new switch sequence on the switch stack + ++parseContext.controlFlowNestingLevel; + ++parseContext.statementNestingLevel; + parseContext.switchSequenceStack.push_back(new TIntermSequence); + parseContext.switchLevel.push_back(parseContext.statementNestingLevel); + parseContext.symbolTable.push(); + } + LEFT_BRACE switch_statement_list RIGHT_BRACE { + $$ = parseContext.addSwitch($1.loc, $3, $7 ? $7->getAsAggregate() : 0); + delete parseContext.switchSequenceStack.back(); + parseContext.switchSequenceStack.pop_back(); + parseContext.switchLevel.pop_back(); + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + ; + +switch_statement_list + : /* nothing */ { + $$ = 0; + } + | statement_list { + $$ = $1; + } + ; + +case_label + : CASE expression COLON { + $$ = 0; + if (parseContext.switchLevel.size() == 0) + parseContext.error($1.loc, "cannot appear outside switch statement", "case", ""); + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) + parseContext.error($1.loc, "cannot be nested inside control flow", "case", ""); + else { + parseContext.constantValueCheck($2, "case"); + parseContext.integerCheck($2, "case"); + $$ = parseContext.intermediate.addBranch(EOpCase, $2, $1.loc); + } + } + | DEFAULT COLON { + $$ = 0; + if (parseContext.switchLevel.size() == 0) + parseContext.error($1.loc, "cannot appear outside switch statement", "default", ""); + else if (parseContext.switchLevel.back() != parseContext.statementNestingLevel) + parseContext.error($1.loc, "cannot be nested inside control flow", "default", ""); + else + $$ = parseContext.intermediate.addBranch(EOpDefault, $1.loc); + } + ; + +iteration_statement + : iteration_statement_nonattributed { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | attribute iteration_statement_nonattributed { + parseContext.handleLoopAttributes(*$1, $2); + $$ = $2; + } +GLSLANG_WEB_EXCLUDE_OFF + +iteration_statement_nonattributed + : WHILE LEFT_PAREN { + if (! parseContext.limits.whileLoops) + parseContext.error($1.loc, "while loops not available", "limitation", ""); + parseContext.symbolTable.push(); + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + condition RIGHT_PAREN statement_no_new_scope { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.loc); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + | DO { + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { + if (! parseContext.limits.whileLoops) + parseContext.error($1.loc, "do-while loops not available", "limitation", ""); + + parseContext.boolCheck($8.loc, $6); + + $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + | FOR LEFT_PAREN { + parseContext.symbolTable.push(); + ++parseContext.loopNestingLevel; + ++parseContext.statementNestingLevel; + ++parseContext.controlFlowNestingLevel; + } + for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + $$ = parseContext.intermediate.makeAggregate($4, $2.loc); + TIntermLoop* forLoop = parseContext.intermediate.addLoop($7, reinterpret_cast($5.node1), reinterpret_cast($5.node2), true, $1.loc); + if (! parseContext.limits.nonInductiveForLoops) + parseContext.inductiveLoopCheck($1.loc, $4, forLoop); + $$ = parseContext.intermediate.growAggregate($$, forLoop, $1.loc); + $$->getAsAggregate()->setOperator(EOpSequence); + --parseContext.loopNestingLevel; + --parseContext.statementNestingLevel; + --parseContext.controlFlowNestingLevel; + } + ; + +for_init_statement + : expression_statement { + $$ = $1; + } + | declaration_statement { + $$ = $1; + } + ; + +conditionopt + : condition { + $$ = $1; + } + | /* May be null */ { + $$ = 0; + } + ; + +for_rest_statement + : conditionopt SEMICOLON { + $$.node1 = $1; + $$.node2 = 0; + } + | conditionopt SEMICOLON expression { + $$.node1 = $1; + $$.node2 = $3; + } + ; + +jump_statement + : CONTINUE SEMICOLON { + if (parseContext.loopNestingLevel <= 0) + parseContext.error($1.loc, "continue statement only allowed in loops", "", ""); + $$ = parseContext.intermediate.addBranch(EOpContinue, $1.loc); + } + | BREAK SEMICOLON { + if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) + parseContext.error($1.loc, "break statement only allowed in switch and loops", "", ""); + $$ = parseContext.intermediate.addBranch(EOpBreak, $1.loc); + } + | RETURN SEMICOLON { + $$ = parseContext.intermediate.addBranch(EOpReturn, $1.loc); + if (parseContext.currentFunctionType->getBasicType() != EbtVoid) + parseContext.error($1.loc, "non-void function must return a value", "return", ""); + if (parseContext.inMain) + parseContext.postEntryPointReturn = true; + } + | RETURN expression SEMICOLON { + $$ = parseContext.handleReturnValue($1.loc, $2); + } + | DISCARD SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "discard"); + $$ = parseContext.intermediate.addBranch(EOpKill, $1.loc); + } + ; + +// Grammar Note: No 'goto'. Gotos are not supported. + +translation_unit + : external_declaration { + $$ = $1; + parseContext.intermediate.setTreeRoot($$); + } + | translation_unit external_declaration { + if ($2 != nullptr) { + $$ = parseContext.intermediate.growAggregate($1, $2); + parseContext.intermediate.setTreeRoot($$); + } + } + ; + +external_declaration + : function_definition { + $$ = $1; + } + | declaration { + $$ = $1; + } +GLSLANG_WEB_EXCLUDE_ON + | SEMICOLON { + parseContext.requireProfile($1.loc, ~EEsProfile, "extraneous semicolon"); + parseContext.profileRequires($1.loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); + $$ = nullptr; + } +GLSLANG_WEB_EXCLUDE_OFF + ; + +function_definition + : function_prototype { + $1.function = parseContext.handleFunctionDeclarator($1.loc, *$1.function, false /* not prototype */); + $1.intermNode = parseContext.handleFunctionDefinition($1.loc, *$1.function); + } + compound_statement_no_new_scope { + // May be best done as post process phase on intermediate code + if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) + parseContext.error($1.loc, "function does not return a value:", "", $1.function->getName().c_str()); + parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); + $$ = parseContext.intermediate.growAggregate($1.intermNode, $3); + parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getType(), $1.loc); + $$->getAsAggregate()->setName($1.function->getMangledName().c_str()); + + // store the pragma information for debug and optimize and other vendor specific + // information. This information can be queried from the parse tree + $$->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); + $$->getAsAggregate()->setDebug(parseContext.contextPragma.debug); + $$->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); + } + ; + +GLSLANG_WEB_EXCLUDE_ON +attribute + : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET { + $$ = $3; + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute"); + } + +attribute_list + : single_attribute { + $$ = $1; + } + | attribute_list COMMA single_attribute { + $$ = parseContext.mergeAttributes($1, $3); + } + +single_attribute + : IDENTIFIER { + $$ = parseContext.makeAttributes(*$1.string); + } + | IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN { + $$ = parseContext.makeAttributes(*$1.string, $3); + } +GLSLANG_WEB_EXCLUDE_OFF + +%% diff --git a/Externals/glslang/glslang/MachineIndependent/glslang.y b/Externals/glslang/glslang/MachineIndependent/glslang.y index e65483a82e..9f30fdb2ab 100644 --- a/Externals/glslang/glslang/MachineIndependent/glslang.y +++ b/Externals/glslang/glslang/MachineIndependent/glslang.y @@ -2,6 +2,7 @@ // 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. // @@ -35,6 +36,31 @@ // POSSIBILITY OF SUCH DAMAGE. // +// +// Do not edit the .y file, only edit the .m4 file. +// The .y bison file is not a source file, it is a derivative of the .m4 file. +// The m4 file needs to be processed by m4 to generate the .y bison file. +// +// Code sandwiched between a pair: +// +// GLSLANG_WEB_EXCLUDE_ON +// ... +// ... +// ... +// GLSLANG_WEB_EXCLUDE_OFF +// +// Will be excluded from the grammar when m4 is executed as: +// +// m4 -P -DGLSLANG_WEB +// +// It will be included when m4 is executed as: +// +// m4 -P +// + + + + /** * This is bison grammar and productions for parsing all versions of the * GLSL shading languages. @@ -99,6 +125,7 @@ using namespace glslang; glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; } @@ -123,13 +150,34 @@ extern int yylex(YYSTYPE*, TParseContext&); %pure-parser // enable thread safety %expect 1 // One shift reduce conflict because of if | else -%token ATTRIBUTE VARYING -%token FLOAT16_T FLOAT FLOAT32_T DOUBLE FLOAT64_T -%token CONST BOOL INT UINT INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T -%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE +%token CONST BOOL INT UINT FLOAT %token BVEC2 BVEC3 BVEC4 %token IVEC2 IVEC3 IVEC4 %token UVEC2 UVEC3 UVEC4 +%token VEC2 VEC3 VEC4 +%token MAT2 MAT3 MAT4 +%token MAT2X2 MAT2X3 MAT2X4 +%token MAT3X2 MAT3X3 MAT3X4 +%token MAT4X2 MAT4X3 MAT4X4 + +// combined image/sampler +%token SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER2DSHADOW +%token SAMPLERCUBESHADOW SAMPLER2DARRAY +%token SAMPLER2DARRAYSHADOW ISAMPLER2D ISAMPLER3D ISAMPLERCUBE +%token ISAMPLER2DARRAY USAMPLER2D USAMPLER3D +%token USAMPLERCUBE USAMPLER2DARRAY + +// separate image/sampler +%token SAMPLER SAMPLERSHADOW +%token TEXTURE2D TEXTURE3D TEXTURECUBE TEXTURE2DARRAY +%token ITEXTURE2D ITEXTURE3D ITEXTURECUBE ITEXTURE2DARRAY +%token UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY + + + +%token ATTRIBUTE VARYING +%token FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T +%token INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T %token I64VEC2 I64VEC3 I64VEC4 %token U64VEC2 U64VEC3 U64VEC4 %token I32VEC2 I32VEC3 I32VEC4 @@ -138,19 +186,10 @@ extern int yylex(YYSTYPE*, TParseContext&); %token U16VEC2 U16VEC3 U16VEC4 %token I8VEC2 I8VEC3 I8VEC4 %token U8VEC2 U8VEC3 U8VEC4 -%token VEC2 VEC3 VEC4 -%token MAT2 MAT3 MAT4 CENTROID IN OUT INOUT -%token UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM -%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY %token DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4 %token F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4 %token F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4 %token F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4 -%token NOPERSPECTIVE FLAT SMOOTH LAYOUT __EXPLICITINTERPAMD - -%token MAT2X2 MAT2X3 MAT2X4 -%token MAT3X2 MAT3X3 MAT3X4 -%token MAT4X2 MAT4X3 MAT4X4 %token DMAT2X2 DMAT2X3 DMAT2X4 %token DMAT3X2 DMAT3X3 DMAT3X4 %token DMAT4X2 DMAT4X3 DMAT4X4 @@ -164,50 +203,27 @@ extern int yylex(YYSTYPE*, TParseContext&); %token F64MAT3X2 F64MAT3X3 F64MAT3X4 %token F64MAT4X2 F64MAT4X3 F64MAT4X4 %token ATOMIC_UINT +%token ACCSTRUCTNV +%token FCOOPMATNV ICOOPMATNV UCOOPMATNV // combined image/sampler -%token SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW -%token SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW -%token SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE -%token ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D -%token USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY -%token SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT -%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER %token SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW %token ISAMPLERCUBEARRAY USAMPLERCUBEARRAY +%token SAMPLER1D SAMPLER1DARRAY SAMPLER1DARRAYSHADOW ISAMPLER1D SAMPLER1DSHADOW +%token SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT +%token SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER %token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS %token SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY %token SAMPLEREXTERNALOES - +%token SAMPLEREXTERNAL2DY2YEXT +%token ISAMPLER1DARRAY USAMPLER1D USAMPLER1DARRAY %token F16SAMPLER1D F16SAMPLER2D F16SAMPLER3D F16SAMPLER2DRECT F16SAMPLERCUBE %token F16SAMPLER1DARRAY F16SAMPLER2DARRAY F16SAMPLERCUBEARRAY %token F16SAMPLERBUFFER F16SAMPLER2DMS F16SAMPLER2DMSARRAY %token F16SAMPLER1DSHADOW F16SAMPLER2DSHADOW F16SAMPLER1DARRAYSHADOW F16SAMPLER2DARRAYSHADOW %token F16SAMPLER2DRECTSHADOW F16SAMPLERCUBESHADOW F16SAMPLERCUBEARRAYSHADOW -// pure sampler -%token SAMPLER SAMPLERSHADOW - -// texture without sampler -%token TEXTURE1D TEXTURE2D TEXTURE3D TEXTURECUBE -%token TEXTURE1DARRAY TEXTURE2DARRAY -%token ITEXTURE1D ITEXTURE2D ITEXTURE3D ITEXTURECUBE -%token ITEXTURE1DARRAY ITEXTURE2DARRAY UTEXTURE1D UTEXTURE2D UTEXTURE3D -%token UTEXTURECUBE UTEXTURE1DARRAY UTEXTURE2DARRAY -%token TEXTURE2DRECT ITEXTURE2DRECT UTEXTURE2DRECT -%token TEXTUREBUFFER ITEXTUREBUFFER UTEXTUREBUFFER -%token TEXTURECUBEARRAY ITEXTURECUBEARRAY UTEXTURECUBEARRAY -%token TEXTURE2DMS ITEXTURE2DMS UTEXTURE2DMS -%token TEXTURE2DMSARRAY ITEXTURE2DMSARRAY UTEXTURE2DMSARRAY - -%token F16TEXTURE1D F16TEXTURE2D F16TEXTURE3D F16TEXTURE2DRECT F16TEXTURECUBE -%token F16TEXTURE1DARRAY F16TEXTURE2DARRAY F16TEXTURECUBEARRAY -%token F16TEXTUREBUFFER F16TEXTURE2DMS F16TEXTURE2DMSARRAY - -// input attachments -%token SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS -%token F16SUBPASSINPUT F16SUBPASSINPUTMS - +// images %token IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D %token UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D %token IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT @@ -223,10 +239,25 @@ extern int yylex(YYSTYPE*, TParseContext&); %token F16IMAGECUBE F16IMAGE1DARRAY F16IMAGE2DARRAY F16IMAGECUBEARRAY %token F16IMAGEBUFFER F16IMAGE2DMS F16IMAGE2DMSARRAY -%token STRUCT VOID WHILE +// texture without sampler +%token TEXTURECUBEARRAY ITEXTURECUBEARRAY UTEXTURECUBEARRAY +%token TEXTURE1D ITEXTURE1D UTEXTURE1D +%token TEXTURE1DARRAY ITEXTURE1DARRAY UTEXTURE1DARRAY +%token TEXTURE2DRECT ITEXTURE2DRECT UTEXTURE2DRECT +%token TEXTUREBUFFER ITEXTUREBUFFER UTEXTUREBUFFER +%token TEXTURE2DMS ITEXTURE2DMS UTEXTURE2DMS +%token TEXTURE2DMSARRAY ITEXTURE2DMSARRAY UTEXTURE2DMSARRAY + +%token F16TEXTURE1D F16TEXTURE2D F16TEXTURE3D F16TEXTURE2DRECT F16TEXTURECUBE +%token F16TEXTURE1DARRAY F16TEXTURE2DARRAY F16TEXTURECUBEARRAY +%token F16TEXTUREBUFFER F16TEXTURE2DMS F16TEXTURE2DMSARRAY + +// input attachments +%token SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS +%token F16SUBPASSINPUT F16SUBPASSINPUTMS + + -%token IDENTIFIER TYPE_NAME -%token FLOATCONSTANT DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT INT32CONSTANT UINT32CONSTANT INTCONSTANT UINTCONSTANT INT64CONSTANT UINT64CONSTANT BOOLCONSTANT FLOAT16CONSTANT %token LEFT_OP RIGHT_OP %token INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP %token AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN @@ -237,11 +268,30 @@ extern int yylex(YYSTYPE*, TParseContext&); %token COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT %token LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION -%token INVARIANT PRECISE +%token INVARIANT %token HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION - %token PACKED RESOURCE SUPERP +%token FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT +%token IDENTIFIER TYPE_NAME +%token CENTROID IN OUT INOUT +%token STRUCT VOID WHILE +%token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT +%token UNIFORM SHARED BUFFER +%token FLAT SMOOTH LAYOUT + + +%token DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT +%token INT64CONSTANT UINT64CONSTANT +%token SUBROUTINE DEMOTE +%token PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV +%token PATCH SAMPLE NONUNIFORM +%token COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT +%token SUBGROUPCOHERENT NONPRIVATE +%token NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV +%token PRECISE + + %type assignment_operator unary_operator %type variable_identifier primary_expression postfix_expression %type expression integer_expression assignment_expression @@ -250,7 +300,7 @@ extern int yylex(YYSTYPE*, TParseContext&); %type conditional_expression constant_expression %type logical_or_expression logical_xor_expression logical_and_expression %type shift_expression and_expression exclusive_or_expression inclusive_or_expression -%type function_call initializer initializer_list condition conditionopt +%type function_call initializer condition conditionopt %type translation_unit function_definition %type statement simple_statement @@ -266,16 +316,19 @@ extern int yylex(YYSTYPE*, TParseContext&); %type parameter_declaration parameter_declarator parameter_type_specifier %type array_specifier -%type precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier +%type invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier %type layout_qualifier layout_qualifier_id_list layout_qualifier_id -%type non_uniform_qualifier + +%type type_parameter_specifier +%type type_parameter_specifier_opt +%type type_parameter_specifier_list %type type_qualifier fully_specified_type type_specifier %type single_type_qualifier %type type_specifier_nonarray %type struct_specifier %type struct_declarator -%type struct_declarator_list struct_declaration struct_declaration_list type_name_list +%type struct_declarator_list struct_declaration struct_declaration_list %type block_structure %type function_header function_declarator %type function_header_with_parameters @@ -284,7 +337,13 @@ extern int yylex(YYSTYPE*, TParseContext&); %type identifier_list + +%type precise_qualifier non_uniform_qualifier +%type type_name_list %type attribute attribute_list single_attribute +%type demote_statement +%type initializer_list + %start translation_unit %% @@ -299,13 +358,13 @@ primary_expression : variable_identifier { $$ = $1; } - | INT32CONSTANT { - parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); - $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + | LEFT_PAREN expression RIGHT_PAREN { + $$ = $2; + if ($$->getAsConstantUnion()) + $$->getAsConstantUnion()->setExpression(); } - | UINT32CONSTANT { - parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); - $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + | FLOATCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); } | INTCONSTANT { $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); @@ -314,6 +373,18 @@ primary_expression parseContext.fullIntegerCheck($1.loc, "unsigned literal"); $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); } + | BOOLCONSTANT { + $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); + } + + | INT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true); + } + | UINT32CONSTANT { + parseContext.explicitInt32Check($1.loc, "32-bit signed literal"); + $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); + } | INT64CONSTANT { parseContext.int64Check($1.loc, "64-bit integer literal"); $$ = parseContext.intermediate.addConstantUnion($1.i64, $1.loc, true); @@ -330,25 +401,17 @@ primary_expression parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer literal"); $$ = parseContext.intermediate.addConstantUnion((unsigned short)$1.u, $1.loc, true); } - | FLOATCONSTANT { - $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); - } | DOUBLECONSTANT { - parseContext.doubleCheck($1.loc, "double literal"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double literal"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double literal"); $$ = parseContext.intermediate.addConstantUnion($1.d, EbtDouble, $1.loc, true); } | FLOAT16CONSTANT { parseContext.float16Check($1.loc, "half float literal"); $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat16, $1.loc, true); } - | BOOLCONSTANT { - $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true); - } - | LEFT_PAREN expression RIGHT_PAREN { - $$ = $2; - if ($$->getAsConstantUnion()) - $$->getAsConstantUnion()->setExpression(); - } + ; postfix_expression @@ -470,15 +533,17 @@ function_identifier if ($$.function == 0) { // error recover - TString empty(""); - $$.function = new TFunction(&empty, TType(EbtVoid), EOpNull); + TString* empty = NewPoolTString(""); + $$.function = new TFunction(empty, TType(EbtVoid), EOpNull); } } + | non_uniform_qualifier { // Constructor $$.intermNode = 0; $$.function = parseContext.handleConstructorCall($1.loc, $1); } + ; unary_expression @@ -604,6 +669,7 @@ equality_expression parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); parseContext.opaqueCheck($2.loc, $1->getType(), "=="); parseContext.specializationCheck($2.loc, $1->getType(), "=="); + parseContext.referenceCheck($2.loc, $1->getType(), "=="); $$ = parseContext.handleBinaryMath($2.loc, "==", EOpEqual, $1, $3); if ($$ == 0) $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); @@ -612,6 +678,7 @@ equality_expression parseContext.arrayObjectCheck($2.loc, $1->getType(), "array comparison"); parseContext.opaqueCheck($2.loc, $1->getType(), "!="); parseContext.specializationCheck($2.loc, $1->getType(), "!="); + parseContext.referenceCheck($2.loc, $1->getType(), "!="); $$ = parseContext.handleBinaryMath($2.loc, "!=", EOpNotEqual, $1, $3); if ($$ == 0) $$ = parseContext.intermediate.addConstantUnion(false, $2.loc); @@ -699,6 +766,7 @@ assignment_expression | unary_expression assignment_operator assignment_expression { parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment"); parseContext.opaqueCheck($2.loc, $1->getType(), "="); + parseContext.storage16BitAssignmentCheck($2.loc, $1->getType(), "="); parseContext.specializationCheck($2.loc, $1->getType(), "="); parseContext.lValueErrorCheck($2.loc, "assign", $1); parseContext.rValueErrorCheck($2.loc, "assign", $3); @@ -792,7 +860,6 @@ declaration } | PRECISION precision_qualifier type_specifier SEMICOLON { parseContext.profileRequires($1.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($1.loc, $3, $2.qualifier.precision); @@ -1036,7 +1103,9 @@ single_declaration : fully_specified_type { $$.type = $1; $$.intermNode = 0; + parseContext.declareTypeDefaults($$.loc, $$.type); + } | fully_specified_type IDENTIFIER { $$.type = $1; @@ -1070,7 +1139,6 @@ fully_specified_type parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); } - parseContext.precisionQualifierCheck($$.loc, $$.basicType, $$.qualifier); } | type_qualifier type_specifier { @@ -1123,26 +1191,54 @@ interpolation_qualifier $$.init($1.loc); $$.qualifier.flat = true; } + | NOPERSPECTIVE { parseContext.globalCheck($1.loc, "noperspective"); -#ifdef NV_EXTENSIONS parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); -#else - parseContext.requireProfile($1.loc, ~EEsProfile, "noperspective"); -#endif parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective"); $$.init($1.loc); $$.qualifier.nopersp = true; } - | __EXPLICITINTERPAMD { -#ifdef AMD_EXTENSIONS + | EXPLICITINTERPAMD { parseContext.globalCheck($1.loc, "__explicitInterpAMD"); parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); parseContext.profileRequires($1.loc, ECompatibilityProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); $$.init($1.loc); $$.qualifier.explicitInterp = true; -#endif } + | PERVERTEXNV { + parseContext.globalCheck($1.loc, "pervertexNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires($1.loc, ECompatibilityProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); + $$.init($1.loc); + $$.qualifier.pervertexNV = true; + } + | PERPRIMITIVENV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "perprimitiveNV"); + parseContext.requireStage($1.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($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); + $$.init($1.loc); + $$.qualifier.perPrimitiveNV = true; + } + | PERVIEWNV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "perviewNV"); + parseContext.requireStage($1.loc, EShLangMeshNV, "perviewNV"); + $$.init($1.loc); + $$.qualifier.perViewNV = true; + } + | PERTASKNV { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck($1.loc, "taskNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); + $$.init($1.loc); + $$.qualifier.perTaskNV = true; + } + ; layout_qualifier @@ -1177,6 +1273,7 @@ layout_qualifier_id } ; + precise_qualifier : PRECISE { parseContext.profileRequires($$.loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); @@ -1186,6 +1283,7 @@ precise_qualifier } ; + type_qualifier : single_type_qualifier { $$ = $1; @@ -1219,6 +1317,7 @@ single_type_qualifier // allow inheritance of storage qualifier from block declaration $$ = $1; } + | precise_qualifier { // allow inheritance of storage qualifier from block declaration $$ = $1; @@ -1226,6 +1325,7 @@ single_type_qualifier | non_uniform_qualifier { $$ = $1; } + ; storage_qualifier @@ -1233,6 +1333,49 @@ storage_qualifier $$.init($1.loc); $$.qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } + | INOUT { + parseContext.globalCheck($1.loc, "inout"); + $$.init($1.loc); + $$.qualifier.storage = EvqInOut; + } + | IN { + parseContext.globalCheck($1.loc, "in"); + $$.init($1.loc); + // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later + $$.qualifier.storage = EvqIn; + } + | OUT { + parseContext.globalCheck($1.loc, "out"); + $$.init($1.loc); + // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later + $$.qualifier.storage = EvqOut; + } + | CENTROID { + parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); + parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); + parseContext.globalCheck($1.loc, "centroid"); + $$.init($1.loc); + $$.qualifier.centroid = true; + } + | UNIFORM { + parseContext.globalCheck($1.loc, "uniform"); + $$.init($1.loc); + $$.qualifier.storage = EvqUniform; + } + | SHARED { + parseContext.globalCheck($1.loc, "shared"); + parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); + parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + $$.init($1.loc); + $$.qualifier.storage = EvqShared; + } + | BUFFER { + parseContext.globalCheck($1.loc, "buffer"); + $$.init($1.loc); + $$.qualifier.storage = EvqBuffer; + } + | ATTRIBUTE { parseContext.requireStage($1.loc, EShLangVertex, "attribute"); parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute"); @@ -1259,30 +1402,6 @@ storage_qualifier else $$.qualifier.storage = EvqVaryingIn; } - | INOUT { - parseContext.globalCheck($1.loc, "inout"); - $$.init($1.loc); - $$.qualifier.storage = EvqInOut; - } - | IN { - parseContext.globalCheck($1.loc, "in"); - $$.init($1.loc); - // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later - $$.qualifier.storage = EvqIn; - } - | OUT { - parseContext.globalCheck($1.loc, "out"); - $$.init($1.loc); - // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later - $$.qualifier.storage = EvqOut; - } - | CENTROID { - parseContext.profileRequires($1.loc, ENoProfile, 120, 0, "centroid"); - parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "centroid"); - parseContext.globalCheck($1.loc, "centroid"); - $$.init($1.loc); - $$.qualifier.centroid = true; - } | PATCH { parseContext.globalCheck($1.loc, "patch"); parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); @@ -1294,28 +1413,74 @@ storage_qualifier $$.init($1.loc); $$.qualifier.sample = true; } - | UNIFORM { - parseContext.globalCheck($1.loc, "uniform"); + | HITATTRNV { + parseContext.globalCheck($1.loc, "hitAttributeNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangClosestHitNVMask + | EShLangAnyHitNVMask), "hitAttributeNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); $$.init($1.loc); - $$.qualifier.storage = EvqUniform; + $$.qualifier.storage = EvqHitAttrNV; } - | BUFFER { - parseContext.globalCheck($1.loc, "buffer"); + | PAYLOADNV { + parseContext.globalCheck($1.loc, "rayPayloadNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | + EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV"); $$.init($1.loc); - $$.qualifier.storage = EvqBuffer; + $$.qualifier.storage = EvqPayloadNV; } - | SHARED { - parseContext.globalCheck($1.loc, "shared"); - parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); - parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared"); - parseContext.requireStage($1.loc, EShLangCompute, "shared"); + | PAYLOADINNV { + parseContext.globalCheck($1.loc, "rayPayloadInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangClosestHitNVMask | + EShLangAnyHitNVMask | EShLangMissNVMask), "rayPayloadInNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV"); $$.init($1.loc); - $$.qualifier.storage = EvqShared; + $$.qualifier.storage = EvqPayloadInNV; + } + | CALLDATANV { + parseContext.globalCheck($1.loc, "callableDataNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangRayGenNVMask | + EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask), "callableDataNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableDataNV; + } + | CALLDATAINNV { + parseContext.globalCheck($1.loc, "callableDataInNV"); + parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV"); + parseContext.profileRequires($1.loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV"); + $$.init($1.loc); + $$.qualifier.storage = EvqCallableDataInNV; } | COHERENT { $$.init($1.loc); $$.qualifier.coherent = true; } + | DEVICECOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); + $$.qualifier.devicecoherent = true; + } + | QUEUEFAMILYCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); + $$.qualifier.queuefamilycoherent = true; + } + | WORKGROUPCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); + $$.qualifier.workgroupcoherent = true; + } + | SUBGROUPCOHERENT { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); + $$.qualifier.subgroupcoherent = true; + } + | NONPRIVATE { + $$.init($1.loc); + parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); + $$.qualifier.nonprivate = true; + } | VOLATILE { $$.init($1.loc); $$.qualifier.volatil = true; @@ -1344,8 +1509,10 @@ storage_qualifier parseContext.unimplemented($1.loc, "subroutine"); $$.init($1.loc); } + ; + non_uniform_qualifier : NONUNIFORM { $$.init($1.loc); @@ -1364,16 +1531,19 @@ type_name_list } ; + type_specifier - : type_specifier_nonarray { + : type_specifier_nonarray type_parameter_specifier_opt { $$ = $1; $$.qualifier.precision = parseContext.getDefaultPrecision($$); + $$.typeParameters = $2; } - | type_specifier_nonarray array_specifier { - parseContext.arrayOfArrayVersionCheck($2.loc, $2.arraySizes); + | type_specifier_nonarray type_parameter_specifier_opt array_specifier { + parseContext.arrayOfArrayVersionCheck($3.loc, $3.arraySizes); $$ = $1; $$.qualifier.precision = parseContext.getDefaultPrecision($$); - $$.arraySizes = $2.arraySizes; + $$.typeParameters = $2; + $$.arraySizes = $3.arraySizes; } ; @@ -1388,7 +1558,7 @@ array_specifier $$.arraySizes = new TArraySizes; TArraySize size; - parseContext.arraySizeCheck($2->getLoc(), $2, size); + parseContext.arraySizeCheck($2->getLoc(), $2, size, "array size"); $$.arraySizes->addInnerSize(size); } | array_specifier LEFT_BRACKET RIGHT_BRACKET { @@ -1399,11 +1569,43 @@ array_specifier $$ = $1; TArraySize size; - parseContext.arraySizeCheck($3->getLoc(), $3, size); + parseContext.arraySizeCheck($3->getLoc(), $3, size, "array size"); $$.arraySizes->addInnerSize(size); } ; +type_parameter_specifier_opt + : type_parameter_specifier { + $$ = $1; + } + | /* May be null */ { + $$ = 0; + } + ; + +type_parameter_specifier + : LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE { + $$ = $2; + } + ; + +type_parameter_specifier_list + : unary_expression { + $$ = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck($1->getLoc(), $1, size, "type parameter"); + $$->addInnerSize(size); + } + | type_parameter_specifier_list COMMA unary_expression { + $$ = $1; + + TArraySize size; + parseContext.arraySizeCheck($3->getLoc(), $3, size, "type parameter"); + $$->addInnerSize(size); + } + ; + type_specifier_nonarray : VOID { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -1413,26 +1615,6 @@ type_specifier_nonarray $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; } - | DOUBLE { - parseContext.doubleCheck($1.loc, "double"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - } - | FLOAT16_T { - parseContext.float16Check($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat16; - } - | FLOAT32_T { - parseContext.explicitFloat32Check($1.loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - } - | FLOAT64_T { - parseContext.explicitFloat64Check($1.loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - } | INT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtInt; @@ -1442,46 +1624,6 @@ type_specifier_nonarray $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtUint; } - | INT8_T { - parseContext.explicitInt8Check($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt8; - } - | UINT8_T { - parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint8; - } - | INT16_T { - parseContext.explicitInt16Check($1.loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt16; - } - | UINT16_T { - parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint16; - } - | INT32_T { - parseContext.explicitInt32Check($1.loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - } - | UINT32_T { - parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - } - | INT64_T { - parseContext.int64Check($1.loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt64; - } - | UINT64_T { - parseContext.int64Check($1.loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint64; - } | BOOL { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtBool; @@ -1501,78 +1643,6 @@ type_specifier_nonarray $$.basicType = EbtFloat; $$.setVector(4); } - | DVEC2 { - parseContext.doubleCheck($1.loc, "double vector"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - $$.setVector(2); - } - | DVEC3 { - parseContext.doubleCheck($1.loc, "double vector"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - $$.setVector(3); - } - | DVEC4 { - parseContext.doubleCheck($1.loc, "double vector"); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - $$.setVector(4); - } - | F16VEC2 { - parseContext.float16Check($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat16; - $$.setVector(2); - } - | F16VEC3 { - parseContext.float16Check($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat16; - $$.setVector(3); - } - | F16VEC4 { - parseContext.float16Check($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat16; - $$.setVector(4); - } - | F32VEC2 { - parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setVector(2); - } - | F32VEC3 { - parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setVector(3); - } - | F32VEC4 { - parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtFloat; - $$.setVector(4); - } - | F64VEC2 { - parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - $$.setVector(2); - } - | F64VEC3 { - parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - $$.setVector(3); - } - | F64VEC4 { - parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtDouble; - $$.setVector(4); - } | BVEC2 { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtBool; @@ -1603,78 +1673,6 @@ type_specifier_nonarray $$.basicType = EbtInt; $$.setVector(4); } - | I8VEC2 { - parseContext.explicitInt8Check($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt8; - $$.setVector(2); - } - | I8VEC3 { - parseContext.explicitInt8Check($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt8; - $$.setVector(3); - } - | I8VEC4 { - parseContext.explicitInt8Check($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt8; - $$.setVector(4); - } - | I16VEC2 { - parseContext.explicitInt16Check($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt16; - $$.setVector(2); - } - | I16VEC3 { - parseContext.explicitInt16Check($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt16; - $$.setVector(3); - } - | I16VEC4 { - parseContext.explicitInt16Check($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt16; - $$.setVector(4); - } - | I32VEC2 { - parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - $$.setVector(2); - } - | I32VEC3 { - parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - $$.setVector(3); - } - | I32VEC4 { - parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt; - $$.setVector(4); - } - | I64VEC2 { - parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt64; - $$.setVector(2); - } - | I64VEC3 { - parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt64; - $$.setVector(3); - } - | I64VEC4 { - parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt64; - $$.setVector(4); - } | UVEC2 { parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -1693,78 +1691,6 @@ type_specifier_nonarray $$.basicType = EbtUint; $$.setVector(4); } - | U8VEC2 { - parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint8; - $$.setVector(2); - } - | U8VEC3 { - parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtInt8; - $$.setVector(3); - } - | U8VEC4 { - parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint8; - $$.setVector(4); - } - | U16VEC2 { - parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint16; - $$.setVector(2); - } - | U16VEC3 { - parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint16; - $$.setVector(3); - } - | U16VEC4 { - parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint16; - $$.setVector(4); - } - | U32VEC2 { - parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - $$.setVector(2); - } - | U32VEC3 { - parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - $$.setVector(3); - } - | U32VEC4 { - parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint; - $$.setVector(4); - } - | U64VEC2 { - parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint64; - $$.setVector(2); - } - | U64VEC3 { - parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint64; - $$.setVector(3); - } - | U64VEC4 { - parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtUint64; - $$.setVector(4); - } | MAT2 { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtFloat; @@ -1825,74 +1751,383 @@ type_specifier_nonarray $$.basicType = EbtFloat; $$.setMatrix(4, 4); } + + | DOUBLE { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + } + | FLOAT16_T { + parseContext.float16ScalarVectorCheck($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + } + | FLOAT32_T { + parseContext.explicitFloat32Check($1.loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + } + | FLOAT64_T { + parseContext.explicitFloat64Check($1.loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + } + | INT8_T { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + } + | UINT8_T { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + } + | INT16_T { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + } + | UINT16_T { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + } + | INT32_T { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + } + | UINT32_T { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + } + | INT64_T { + parseContext.int64Check($1.loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + } + | UINT64_T { + parseContext.int64Check($1.loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + } + | DVEC2 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(2); + } + | DVEC3 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(3); + } + | DVEC4 { + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double vector"); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(4); + } + | F16VEC2 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(2); + } + | F16VEC3 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(3); + } + | F16VEC4 { + parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat16; + $$.setVector(4); + } + | F32VEC2 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(2); + } + | F32VEC3 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(3); + } + | F32VEC4 { + parseContext.explicitFloat32Check($1.loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.setVector(4); + } + | F64VEC2 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(2); + } + | F64VEC3 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(3); + } + | F64VEC4 { + parseContext.explicitFloat64Check($1.loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtDouble; + $$.setVector(4); + } + | I8VEC2 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(2); + } + | I8VEC3 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(3); + } + | I8VEC4 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt8; + $$.setVector(4); + } + | I16VEC2 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(2); + } + | I16VEC3 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(3); + } + | I16VEC4 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt16; + $$.setVector(4); + } + | I32VEC2 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(2); + } + | I32VEC3 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(3); + } + | I32VEC4 { + parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.setVector(4); + } + | I64VEC2 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(2); + } + | I64VEC3 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(3); + } + | I64VEC4 { + parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt64; + $$.setVector(4); + } + | U8VEC2 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(2); + } + | U8VEC3 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(3); + } + | U8VEC4 { + parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint8; + $$.setVector(4); + } + | U16VEC2 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(2); + } + | U16VEC3 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(3); + } + | U16VEC4 { + parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint16; + $$.setVector(4); + } + | U32VEC2 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(2); + } + | U32VEC3 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(3); + } + | U32VEC4 { + parseContext.explicitInt32Check($1.loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.setVector(4); + } + | U64VEC2 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(2); + } + | U64VEC3 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(3); + } + | U64VEC4 { + parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint64; + $$.setVector(4); + } | DMAT2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 2); } | DMAT3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 3); } | DMAT4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 4); } | DMAT2X2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 2); } | DMAT2X3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 3); } | DMAT2X4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(2, 4); } | DMAT3X2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 2); } | DMAT3X3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 3); } | DMAT3X4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(3, 4); } | DMAT4X2 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 2); } | DMAT4X3 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 3); } | DMAT4X4 { - parseContext.doubleCheck($1.loc, "double matrix"); + parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck($1.loc, "double matrix"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtDouble; $$.setMatrix(4, 4); @@ -2113,6 +2348,10 @@ type_specifier_nonarray $$.basicType = EbtDouble; $$.setMatrix(4, 4); } + | ACCSTRUCTNV { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtAccStructNV; + } | ATOMIC_UINT { parseContext.vulkanRemoved($1.loc, "atomic counter types"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2123,6 +2362,7 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd1D); } + | SAMPLER2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2138,11 +2378,6 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube); } - | SAMPLER1DSHADOW { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtFloat, Esd1D, false, true); - } | SAMPLER2DSHADOW { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2153,26 +2388,32 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, EsdCube, false, true); } - | SAMPLER1DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtFloat, Esd1D, true); - } | SAMPLER2DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true); } - | SAMPLER1DARRAYSHADOW { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtFloat, Esd1D, true, true); - } | SAMPLER2DARRAYSHADOW { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat, Esd2D, true, true); } + + | SAMPLER1DSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, false, true); + } + | SAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true); + } + | SAMPLER1DARRAYSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd1D, true, true); + } | SAMPLERCUBEARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2184,114 +2425,89 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, EsdCube, true, true); } | F16SAMPLER1D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D); -#endif } | F16SAMPLER2D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D); -#endif } | F16SAMPLER3D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd3D); -#endif } | F16SAMPLERCUBE { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube); -#endif } | F16SAMPLER1DSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D, false, true); -#endif } | F16SAMPLER2DSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, false, true); -#endif } | F16SAMPLERCUBESHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube, false, true); -#endif } | F16SAMPLER1DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D, true); -#endif } | F16SAMPLER2DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, true); -#endif } | F16SAMPLER1DARRAYSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd1D, true, true); -#endif } | F16SAMPLER2DARRAYSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, true, true); -#endif } | F16SAMPLERCUBEARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube, true); -#endif } | F16SAMPLERCUBEARRAYSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdCube, true, true); -#endif } | ISAMPLER1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd1D); } + | ISAMPLER2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2307,26 +2523,11 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtInt, EsdCube); } - | ISAMPLER1DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtInt, Esd1D, true); - } | ISAMPLER2DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtInt, Esd2D, true); } - | ISAMPLERCUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtInt, EsdCube, true); - } - | USAMPLER1D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtUint, Esd1D); - } | USAMPLER2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2342,21 +2543,124 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdCube); } + + | ISAMPLER1DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, Esd1D, true); + } + | ISAMPLERCUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtInt, EsdCube, true); + } + | USAMPLER1D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd1D); + } | USAMPLER1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd1D, true); } - | USAMPLER2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.set(EbtUint, Esd2D, true); - } | USAMPLERCUBEARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtUint, EsdCube, true); } + | TEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube, true); + } + | ITEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube, true); + } + | UTEXTURECUBEARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube, true); + } + + | USAMPLER2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtUint, Esd2D, true); + } + | TEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D); + } + | TEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd3D); + } + | TEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, Esd2D, true); + } + | TEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtFloat, EsdCube); + } + | ITEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D); + } + | ITEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd3D); + } + | ITEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, EsdCube); + } + | ITEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtInt, Esd2D, true); + } + | UTEXTURE2D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D); + } + | UTEXTURE3D { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd3D); + } + | UTEXTURECUBE { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, EsdCube); + } + | UTEXTURE2DARRAY { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setTexture(EbtUint, Esd2D, true); + } + | SAMPLER { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(false); + } + | SAMPLERSHADOW { + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.setPureSampler(true); + } + | SAMPLER2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; @@ -2368,20 +2672,16 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, EsdRect, false, true); } | F16SAMPLER2DRECT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdRect); -#endif } | F16SAMPLER2DRECTSHADOW { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdRect, false, true); -#endif } | ISAMPLER2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2399,12 +2699,10 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, EsdBuffer); } | F16SAMPLERBUFFER { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, EsdBuffer); -#endif } | ISAMPLERBUFFER { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2422,12 +2720,10 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, Esd2D, false, false, true); } | F16SAMPLER2DMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, false, false, true); -#endif } | ISAMPLER2DMS { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2445,12 +2741,10 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, Esd2D, true, false, true); } | F16SAMPLER2DMSARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.set(EbtFloat16, Esd2D, true, false, true); -#endif } | ISAMPLER2DMSARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2462,67 +2756,34 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.set(EbtUint, Esd2D, true, false, true); } - | SAMPLER { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setPureSampler(false); - } - | SAMPLERSHADOW { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setPureSampler(true); - } | TEXTURE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat, Esd1D); } | F16TEXTURE1D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd1D); -#endif - } - | TEXTURE2D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, Esd2D); } | F16TEXTURE2D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D); -#endif - } - | TEXTURE3D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, Esd3D); } | F16TEXTURE3D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd3D); -#endif - } - | TEXTURECUBE { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, EsdCube); } | F16TEXTURECUBE { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdCube); -#endif } | TEXTURE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2530,121 +2791,53 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, Esd1D, true); } | F16TEXTURE1DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd1D, true); -#endif - } - | TEXTURE2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, Esd2D, true); } | F16TEXTURE2DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D, true); -#endif - } - | TEXTURECUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtFloat, EsdCube, true); } | F16TEXTURECUBEARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdCube, true); -#endif } | ITEXTURE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtInt, Esd1D); } - | ITEXTURE2D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, Esd2D); - } - | ITEXTURE3D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, Esd3D); - } - | ITEXTURECUBE { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, EsdCube); - } | ITEXTURE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtInt, Esd1D, true); } - | ITEXTURE2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, Esd2D, true); - } - | ITEXTURECUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtInt, EsdCube, true); - } | UTEXTURE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtUint, Esd1D); } - | UTEXTURE2D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, Esd2D); - } - | UTEXTURE3D { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, Esd3D); - } - | UTEXTURECUBE { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, EsdCube); - } | UTEXTURE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtUint, Esd1D, true); } - | UTEXTURE2DARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, Esd2D, true); - } - | UTEXTURECUBEARRAY { - $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); - $$.basicType = EbtSampler; - $$.sampler.setTexture(EbtUint, EsdCube, true); - } | TEXTURE2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat, EsdRect); } | F16TEXTURE2DRECT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdRect); -#endif } | ITEXTURE2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2662,12 +2855,10 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, EsdBuffer); } | F16TEXTUREBUFFER { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, EsdBuffer); -#endif } | ITEXTUREBUFFER { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2685,12 +2876,10 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, Esd2D, false, false, true); } | F16TEXTURE2DMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D, false, false, true); -#endif } | ITEXTURE2DMS { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2708,12 +2897,10 @@ type_specifier_nonarray $$.sampler.setTexture(EbtFloat, Esd2D, true, false, true); } | F16TEXTURE2DMSARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setTexture(EbtFloat16, Esd2D, true, false, true); -#endif } | ITEXTURE2DMSARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2731,12 +2918,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd1D); } | F16IMAGE1D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd1D); -#endif } | IIMAGE1D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2754,12 +2939,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D); } | F16IMAGE2D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D); -#endif } | IIMAGE2D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2777,12 +2960,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd3D); } | F16IMAGE3D { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd3D); -#endif } | IIMAGE3D { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2800,12 +2981,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdRect); } | F16IMAGE2DRECT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdRect); -#endif } | IIMAGE2DRECT { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2823,12 +3002,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdCube); } | F16IMAGECUBE { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdCube); -#endif } | IIMAGECUBE { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2846,12 +3023,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdBuffer); } | F16IMAGEBUFFER { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdBuffer); -#endif } | IIMAGEBUFFER { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2869,12 +3044,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd1D, true); } | F16IMAGE1DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd1D, true); -#endif } | IIMAGE1DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2892,12 +3065,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D, true); } | F16IMAGE2DARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D, true); -#endif } | IIMAGE2DARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2915,12 +3086,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, EsdCube, true); } | F16IMAGECUBEARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, EsdCube, true); -#endif } | IIMAGECUBEARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2938,12 +3107,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D, false, false, true); } | F16IMAGE2DMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D, false, false, true); -#endif } | IIMAGE2DMS { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2961,12 +3128,10 @@ type_specifier_nonarray $$.sampler.setImage(EbtFloat, Esd2D, true, false, true); } | F16IMAGE2DMSARRAY { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setImage(EbtFloat16, Esd2D, true, false, true); -#endif } | IIMAGE2DMSARRAY { $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2984,6 +3149,12 @@ type_specifier_nonarray $$.sampler.set(EbtFloat, Esd2D); $$.sampler.external = true; } + | SAMPLEREXTERNAL2DY2YEXT { // GL_EXT_YUV_target + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtSampler; + $$.sampler.set(EbtFloat, Esd2D); + $$.sampler.yuv = true; + } | SUBPASSINPUT { parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); @@ -2997,22 +3168,18 @@ type_specifier_nonarray $$.sampler.setSubpass(EbtFloat, true); } | F16SUBPASSINPUT { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setSubpass(EbtFloat16); -#endif } | F16SUBPASSINPUTMS { -#ifdef AMD_EXTENSIONS parseContext.float16OpaqueCheck($1.loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.basicType = EbtSampler; $$.sampler.setSubpass(EbtFloat16, true); -#endif } | ISUBPASSINPUT { parseContext.requireStage($1.loc, EShLangFragment, "subpass input"); @@ -3038,6 +3205,25 @@ type_specifier_nonarray $$.basicType = EbtSampler; $$.sampler.setSubpass(EbtUint, true); } + | FCOOPMATNV { + parseContext.fcoopmatCheck($1.loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtFloat; + $$.coopmat = true; + } + | ICOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtInt; + $$.coopmat = true; + } + | UCOOPMATNV { + parseContext.intcoopmatCheck($1.loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + $$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); + $$.basicType = EbtUint; + $$.coopmat = true; + } + | struct_specifier { $$ = $1; $$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; @@ -3118,7 +3304,7 @@ struct_declaration if ($1.arraySizes) { parseContext.profileRequires($1.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($1.loc, EEsProfile, 300, 0, "arrayed type"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck($1.loc, *$1.arraySizes); } @@ -3140,7 +3326,7 @@ struct_declaration if ($2.arraySizes) { parseContext.profileRequires($2.loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires($2.loc, EEsProfile, 300, 0, "arrayed type"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck($2.loc, *$2.arraySizes); } @@ -3192,6 +3378,7 @@ initializer : assignment_expression { $$ = $1; } + | LEFT_BRACE initializer_list RIGHT_BRACE { const char* initFeature = "{ } style initializers"; parseContext.requireProfile($1.loc, ~EEsProfile, initFeature); @@ -3204,8 +3391,10 @@ initializer parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); $$ = $2; } + ; + initializer_list : initializer { $$ = parseContext.intermediate.growAggregate(0, $1, $1->getLoc()); @@ -3215,6 +3404,7 @@ initializer_list } ; + declaration_statement : declaration { $$ = $1; } ; @@ -3234,8 +3424,21 @@ simple_statement | case_label { $$ = $1; } | iteration_statement { $$ = $1; } | jump_statement { $$ = $1; } + + | demote_statement { $$ = $1; } + ; + +demote_statement + : DEMOTE SEMICOLON { + parseContext.requireStage($1.loc, EShLangFragment, "demote"); + parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); + $$ = parseContext.intermediate.addBranch(EOpDemote, $1.loc); + } + ; + + compound_statement : LEFT_BRACE RIGHT_BRACE { $$ = 0; } | LEFT_BRACE { @@ -3318,11 +3521,13 @@ selection_statement : selection_statement_nonattributed { $$ = $1; } + | attribute selection_statement_nonattributed { parseContext.handleSelectionAttributes(*$1, $2); $$ = $2; } + selection_statement_nonattributed : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { parseContext.boolCheck($1.loc, $3); @@ -3363,11 +3568,13 @@ switch_statement : switch_statement_nonattributed { $$ = $1; } + | attribute switch_statement_nonattributed { parseContext.handleSwitchAttributes(*$1, $2); $$ = $2; } + switch_statement_nonattributed : SWITCH LEFT_PAREN expression RIGHT_PAREN { // start new switch sequence on the switch stack @@ -3425,11 +3632,13 @@ iteration_statement : iteration_statement_nonattributed { $$ = $1; } + | attribute iteration_statement_nonattributed { parseContext.handleLoopAttributes(*$1, $2); $$ = $2; } + iteration_statement_nonattributed : WHILE LEFT_PAREN { if (! parseContext.limits.whileLoops) @@ -3560,11 +3769,13 @@ external_declaration | declaration { $$ = $1; } + | SEMICOLON { parseContext.requireProfile($1.loc, ~EEsProfile, "extraneous semicolon"); parseContext.profileRequires($1.loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); $$ = nullptr; } + ; function_definition @@ -3589,6 +3800,7 @@ function_definition } ; + attribute : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET { $$ = $3; @@ -3611,4 +3823,5 @@ single_attribute $$ = parseContext.makeAttributes(*$1.string, $3); } + %% diff --git a/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp b/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp index 38672d67d3..2a47faada4 100644 --- a/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp +++ b/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp @@ -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 42 "MachineIndependent/glslang.y" /* yacc.c:339 */ +#line 68 "MachineIndependent/glslang.y" /* yacc.c:339 */ /* Based on: @@ -90,11 +90,11 @@ using namespace glslang; #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 @@ -123,403 +123,423 @@ extern int yydebug; # define YYTOKENTYPE enum yytokentype { - ATTRIBUTE = 258, - VARYING = 259, - FLOAT16_T = 260, - FLOAT = 261, - FLOAT32_T = 262, - DOUBLE = 263, - 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, - COHERENT = 338, - VOLATILE = 339, - RESTRICT = 340, - READONLY = 341, - WRITEONLY = 342, - DVEC2 = 343, - DVEC3 = 344, - DVEC4 = 345, - DMAT2 = 346, - DMAT3 = 347, - DMAT4 = 348, - F16VEC2 = 349, - F16VEC3 = 350, - F16VEC4 = 351, - F16MAT2 = 352, - F16MAT3 = 353, - F16MAT4 = 354, - F32VEC2 = 355, - F32VEC3 = 356, - F32VEC4 = 357, - F32MAT2 = 358, - F32MAT3 = 359, - F32MAT4 = 360, - F64VEC2 = 361, - F64VEC3 = 362, - F64VEC4 = 363, - F64MAT2 = 364, - F64MAT3 = 365, - F64MAT4 = 366, - NOPERSPECTIVE = 367, - FLAT = 368, - SMOOTH = 369, - LAYOUT = 370, - __EXPLICITINTERPAMD = 371, - MAT2X2 = 372, - MAT2X3 = 373, - MAT2X4 = 374, - MAT3X2 = 375, - MAT3X3 = 376, - MAT3X4 = 377, - MAT4X2 = 378, - MAT4X3 = 379, - MAT4X4 = 380, - DMAT2X2 = 381, - DMAT2X3 = 382, - DMAT2X4 = 383, - DMAT3X2 = 384, - DMAT3X3 = 385, - DMAT3X4 = 386, - DMAT4X2 = 387, - DMAT4X3 = 388, - DMAT4X4 = 389, - F16MAT2X2 = 390, - F16MAT2X3 = 391, - F16MAT2X4 = 392, - F16MAT3X2 = 393, - F16MAT3X3 = 394, - F16MAT3X4 = 395, - F16MAT4X2 = 396, - F16MAT4X3 = 397, - F16MAT4X4 = 398, - F32MAT2X2 = 399, - F32MAT2X3 = 400, - F32MAT2X4 = 401, - F32MAT3X2 = 402, - F32MAT3X3 = 403, - F32MAT3X4 = 404, - F32MAT4X2 = 405, - F32MAT4X3 = 406, - F32MAT4X4 = 407, - F64MAT2X2 = 408, - F64MAT2X3 = 409, - F64MAT2X4 = 410, - F64MAT3X2 = 411, - F64MAT3X3 = 412, - F64MAT3X4 = 413, - F64MAT4X2 = 414, - F64MAT4X3 = 415, - F64MAT4X4 = 416, - ATOMIC_UINT = 417, - SAMPLER1D = 418, - SAMPLER2D = 419, - SAMPLER3D = 420, - SAMPLERCUBE = 421, - SAMPLER1DSHADOW = 422, - SAMPLER2DSHADOW = 423, - SAMPLERCUBESHADOW = 424, - SAMPLER1DARRAY = 425, - SAMPLER2DARRAY = 426, - SAMPLER1DARRAYSHADOW = 427, - SAMPLER2DARRAYSHADOW = 428, - ISAMPLER1D = 429, - ISAMPLER2D = 430, - ISAMPLER3D = 431, - ISAMPLERCUBE = 432, - ISAMPLER1DARRAY = 433, - ISAMPLER2DARRAY = 434, - USAMPLER1D = 435, - USAMPLER2D = 436, - USAMPLER3D = 437, - USAMPLERCUBE = 438, - USAMPLER1DARRAY = 439, - USAMPLER2DARRAY = 440, - SAMPLER2DRECT = 441, - SAMPLER2DRECTSHADOW = 442, - ISAMPLER2DRECT = 443, - USAMPLER2DRECT = 444, - SAMPLERBUFFER = 445, - ISAMPLERBUFFER = 446, - USAMPLERBUFFER = 447, - SAMPLERCUBEARRAY = 448, - SAMPLERCUBEARRAYSHADOW = 449, - ISAMPLERCUBEARRAY = 450, - USAMPLERCUBEARRAY = 451, - SAMPLER2DMS = 452, - ISAMPLER2DMS = 453, - USAMPLER2DMS = 454, - SAMPLER2DMSARRAY = 455, - ISAMPLER2DMSARRAY = 456, - USAMPLER2DMSARRAY = 457, - SAMPLEREXTERNALOES = 458, - F16SAMPLER1D = 459, - F16SAMPLER2D = 460, - F16SAMPLER3D = 461, - F16SAMPLER2DRECT = 462, - F16SAMPLERCUBE = 463, - F16SAMPLER1DARRAY = 464, - F16SAMPLER2DARRAY = 465, - F16SAMPLERCUBEARRAY = 466, - F16SAMPLERBUFFER = 467, - F16SAMPLER2DMS = 468, - F16SAMPLER2DMSARRAY = 469, - F16SAMPLER1DSHADOW = 470, - F16SAMPLER2DSHADOW = 471, - F16SAMPLER1DARRAYSHADOW = 472, - F16SAMPLER2DARRAYSHADOW = 473, - F16SAMPLER2DRECTSHADOW = 474, - F16SAMPLERCUBESHADOW = 475, - F16SAMPLERCUBEARRAYSHADOW = 476, - SAMPLER = 477, - SAMPLERSHADOW = 478, - TEXTURE1D = 479, - TEXTURE2D = 480, - TEXTURE3D = 481, - TEXTURECUBE = 482, - TEXTURE1DARRAY = 483, - TEXTURE2DARRAY = 484, - ITEXTURE1D = 485, - ITEXTURE2D = 486, - ITEXTURE3D = 487, - ITEXTURECUBE = 488, - ITEXTURE1DARRAY = 489, - ITEXTURE2DARRAY = 490, - UTEXTURE1D = 491, - UTEXTURE2D = 492, - UTEXTURE3D = 493, - UTEXTURECUBE = 494, - UTEXTURE1DARRAY = 495, - UTEXTURE2DARRAY = 496, - TEXTURE2DRECT = 497, - ITEXTURE2DRECT = 498, - UTEXTURE2DRECT = 499, - TEXTUREBUFFER = 500, - ITEXTUREBUFFER = 501, - UTEXTUREBUFFER = 502, - TEXTURECUBEARRAY = 503, - ITEXTURECUBEARRAY = 504, - UTEXTURECUBEARRAY = 505, - TEXTURE2DMS = 506, - ITEXTURE2DMS = 507, - UTEXTURE2DMS = 508, - TEXTURE2DMSARRAY = 509, - ITEXTURE2DMSARRAY = 510, - UTEXTURE2DMSARRAY = 511, - F16TEXTURE1D = 512, - F16TEXTURE2D = 513, - F16TEXTURE3D = 514, - F16TEXTURE2DRECT = 515, - F16TEXTURECUBE = 516, - F16TEXTURE1DARRAY = 517, - F16TEXTURE2DARRAY = 518, - F16TEXTURECUBEARRAY = 519, - F16TEXTUREBUFFER = 520, - F16TEXTURE2DMS = 521, - F16TEXTURE2DMSARRAY = 522, - SUBPASSINPUT = 523, - SUBPASSINPUTMS = 524, - ISUBPASSINPUT = 525, - ISUBPASSINPUTMS = 526, - USUBPASSINPUT = 527, - USUBPASSINPUTMS = 528, - F16SUBPASSINPUT = 529, - F16SUBPASSINPUTMS = 530, - IMAGE1D = 531, - IIMAGE1D = 532, - UIMAGE1D = 533, - IMAGE2D = 534, - IIMAGE2D = 535, - UIMAGE2D = 536, - IMAGE3D = 537, - IIMAGE3D = 538, - UIMAGE3D = 539, - IMAGE2DRECT = 540, - IIMAGE2DRECT = 541, - UIMAGE2DRECT = 542, - IMAGECUBE = 543, - IIMAGECUBE = 544, - UIMAGECUBE = 545, - IMAGEBUFFER = 546, - IIMAGEBUFFER = 547, - UIMAGEBUFFER = 548, - IMAGE1DARRAY = 549, - IIMAGE1DARRAY = 550, - UIMAGE1DARRAY = 551, - IMAGE2DARRAY = 552, - IIMAGE2DARRAY = 553, - UIMAGE2DARRAY = 554, - IMAGECUBEARRAY = 555, - IIMAGECUBEARRAY = 556, - UIMAGECUBEARRAY = 557, - IMAGE2DMS = 558, - IIMAGE2DMS = 559, - UIMAGE2DMS = 560, - IMAGE2DMSARRAY = 561, - IIMAGE2DMSARRAY = 562, - UIMAGE2DMSARRAY = 563, - F16IMAGE1D = 564, - F16IMAGE2D = 565, - F16IMAGE3D = 566, - F16IMAGE2DRECT = 567, - F16IMAGECUBE = 568, - F16IMAGE1DARRAY = 569, - F16IMAGE2DARRAY = 570, - F16IMAGECUBEARRAY = 571, - F16IMAGEBUFFER = 572, - F16IMAGE2DMS = 573, - F16IMAGE2DMSARRAY = 574, - STRUCT = 575, - VOID = 576, - WHILE = 577, - IDENTIFIER = 578, - TYPE_NAME = 579, - FLOATCONSTANT = 580, - DOUBLECONSTANT = 581, - INT16CONSTANT = 582, - UINT16CONSTANT = 583, - INT32CONSTANT = 584, - UINT32CONSTANT = 585, - INTCONSTANT = 586, - UINTCONSTANT = 587, - INT64CONSTANT = 588, - UINT64CONSTANT = 589, - BOOLCONSTANT = 590, - FLOAT16CONSTANT = 591, - LEFT_OP = 592, - RIGHT_OP = 593, - INC_OP = 594, - DEC_OP = 595, - LE_OP = 596, - GE_OP = 597, - EQ_OP = 598, - NE_OP = 599, - AND_OP = 600, - OR_OP = 601, - XOR_OP = 602, - MUL_ASSIGN = 603, - DIV_ASSIGN = 604, - ADD_ASSIGN = 605, - MOD_ASSIGN = 606, - LEFT_ASSIGN = 607, - RIGHT_ASSIGN = 608, - AND_ASSIGN = 609, - XOR_ASSIGN = 610, - OR_ASSIGN = 611, - SUB_ASSIGN = 612, - LEFT_PAREN = 613, - RIGHT_PAREN = 614, - LEFT_BRACKET = 615, - RIGHT_BRACKET = 616, - LEFT_BRACE = 617, - RIGHT_BRACE = 618, - DOT = 619, - COMMA = 620, - COLON = 621, - EQUAL = 622, - SEMICOLON = 623, - BANG = 624, - DASH = 625, - TILDE = 626, - PLUS = 627, - STAR = 628, - SLASH = 629, - PERCENT = 630, - LEFT_ANGLE = 631, - RIGHT_ANGLE = 632, - VERTICAL_BAR = 633, - CARET = 634, - AMPERSAND = 635, - QUESTION = 636, - INVARIANT = 637, - PRECISE = 638, - HIGH_PRECISION = 639, - MEDIUM_PRECISION = 640, - LOW_PRECISION = 641, - PRECISION = 642, - PACKED = 643, - RESOURCE = 644, - SUPERP = 645 + CONST = 258, + BOOL = 259, + INT = 260, + UINT = 261, + FLOAT = 262, + BVEC2 = 263, + BVEC3 = 264, + BVEC4 = 265, + IVEC2 = 266, + IVEC3 = 267, + IVEC4 = 268, + UVEC2 = 269, + UVEC3 = 270, + UVEC4 = 271, + VEC2 = 272, + VEC3 = 273, + VEC4 = 274, + MAT2 = 275, + MAT3 = 276, + MAT4 = 277, + MAT2X2 = 278, + MAT2X3 = 279, + MAT2X4 = 280, + MAT3X2 = 281, + MAT3X3 = 282, + MAT3X4 = 283, + MAT4X2 = 284, + MAT4X3 = 285, + MAT4X4 = 286, + SAMPLER2D = 287, + SAMPLER3D = 288, + SAMPLERCUBE = 289, + SAMPLER2DSHADOW = 290, + SAMPLERCUBESHADOW = 291, + SAMPLER2DARRAY = 292, + SAMPLER2DARRAYSHADOW = 293, + ISAMPLER2D = 294, + ISAMPLER3D = 295, + ISAMPLERCUBE = 296, + ISAMPLER2DARRAY = 297, + USAMPLER2D = 298, + USAMPLER3D = 299, + USAMPLERCUBE = 300, + USAMPLER2DARRAY = 301, + SAMPLER = 302, + SAMPLERSHADOW = 303, + TEXTURE2D = 304, + TEXTURE3D = 305, + TEXTURECUBE = 306, + TEXTURE2DARRAY = 307, + ITEXTURE2D = 308, + ITEXTURE3D = 309, + ITEXTURECUBE = 310, + ITEXTURE2DARRAY = 311, + UTEXTURE2D = 312, + UTEXTURE3D = 313, + UTEXTURECUBE = 314, + UTEXTURE2DARRAY = 315, + ATTRIBUTE = 316, + VARYING = 317, + FLOAT16_T = 318, + FLOAT32_T = 319, + DOUBLE = 320, + FLOAT64_T = 321, + INT64_T = 322, + UINT64_T = 323, + INT32_T = 324, + UINT32_T = 325, + INT16_T = 326, + UINT16_T = 327, + INT8_T = 328, + UINT8_T = 329, + I64VEC2 = 330, + I64VEC3 = 331, + I64VEC4 = 332, + U64VEC2 = 333, + U64VEC3 = 334, + U64VEC4 = 335, + I32VEC2 = 336, + I32VEC3 = 337, + I32VEC4 = 338, + U32VEC2 = 339, + U32VEC3 = 340, + U32VEC4 = 341, + I16VEC2 = 342, + I16VEC3 = 343, + I16VEC4 = 344, + U16VEC2 = 345, + U16VEC3 = 346, + U16VEC4 = 347, + I8VEC2 = 348, + I8VEC3 = 349, + I8VEC4 = 350, + U8VEC2 = 351, + U8VEC3 = 352, + U8VEC4 = 353, + DVEC2 = 354, + DVEC3 = 355, + DVEC4 = 356, + DMAT2 = 357, + DMAT3 = 358, + DMAT4 = 359, + F16VEC2 = 360, + F16VEC3 = 361, + F16VEC4 = 362, + F16MAT2 = 363, + F16MAT3 = 364, + F16MAT4 = 365, + F32VEC2 = 366, + F32VEC3 = 367, + F32VEC4 = 368, + F32MAT2 = 369, + F32MAT3 = 370, + F32MAT4 = 371, + F64VEC2 = 372, + F64VEC3 = 373, + F64VEC4 = 374, + F64MAT2 = 375, + F64MAT3 = 376, + F64MAT4 = 377, + DMAT2X2 = 378, + DMAT2X3 = 379, + DMAT2X4 = 380, + DMAT3X2 = 381, + DMAT3X3 = 382, + DMAT3X4 = 383, + DMAT4X2 = 384, + DMAT4X3 = 385, + DMAT4X4 = 386, + F16MAT2X2 = 387, + F16MAT2X3 = 388, + F16MAT2X4 = 389, + F16MAT3X2 = 390, + F16MAT3X3 = 391, + F16MAT3X4 = 392, + F16MAT4X2 = 393, + F16MAT4X3 = 394, + F16MAT4X4 = 395, + F32MAT2X2 = 396, + F32MAT2X3 = 397, + F32MAT2X4 = 398, + F32MAT3X2 = 399, + F32MAT3X3 = 400, + F32MAT3X4 = 401, + F32MAT4X2 = 402, + F32MAT4X3 = 403, + F32MAT4X4 = 404, + F64MAT2X2 = 405, + F64MAT2X3 = 406, + F64MAT2X4 = 407, + F64MAT3X2 = 408, + F64MAT3X3 = 409, + F64MAT3X4 = 410, + F64MAT4X2 = 411, + F64MAT4X3 = 412, + F64MAT4X4 = 413, + ATOMIC_UINT = 414, + ACCSTRUCTNV = 415, + FCOOPMATNV = 416, + ICOOPMATNV = 417, + UCOOPMATNV = 418, + SAMPLERCUBEARRAY = 419, + SAMPLERCUBEARRAYSHADOW = 420, + ISAMPLERCUBEARRAY = 421, + USAMPLERCUBEARRAY = 422, + SAMPLER1D = 423, + SAMPLER1DARRAY = 424, + SAMPLER1DARRAYSHADOW = 425, + ISAMPLER1D = 426, + SAMPLER1DSHADOW = 427, + SAMPLER2DRECT = 428, + SAMPLER2DRECTSHADOW = 429, + ISAMPLER2DRECT = 430, + USAMPLER2DRECT = 431, + SAMPLERBUFFER = 432, + ISAMPLERBUFFER = 433, + USAMPLERBUFFER = 434, + SAMPLER2DMS = 435, + ISAMPLER2DMS = 436, + USAMPLER2DMS = 437, + SAMPLER2DMSARRAY = 438, + ISAMPLER2DMSARRAY = 439, + USAMPLER2DMSARRAY = 440, + SAMPLEREXTERNALOES = 441, + SAMPLEREXTERNAL2DY2YEXT = 442, + ISAMPLER1DARRAY = 443, + USAMPLER1D = 444, + USAMPLER1DARRAY = 445, + F16SAMPLER1D = 446, + F16SAMPLER2D = 447, + F16SAMPLER3D = 448, + F16SAMPLER2DRECT = 449, + F16SAMPLERCUBE = 450, + F16SAMPLER1DARRAY = 451, + F16SAMPLER2DARRAY = 452, + F16SAMPLERCUBEARRAY = 453, + F16SAMPLERBUFFER = 454, + F16SAMPLER2DMS = 455, + F16SAMPLER2DMSARRAY = 456, + F16SAMPLER1DSHADOW = 457, + F16SAMPLER2DSHADOW = 458, + F16SAMPLER1DARRAYSHADOW = 459, + F16SAMPLER2DARRAYSHADOW = 460, + F16SAMPLER2DRECTSHADOW = 461, + F16SAMPLERCUBESHADOW = 462, + F16SAMPLERCUBEARRAYSHADOW = 463, + IMAGE1D = 464, + IIMAGE1D = 465, + UIMAGE1D = 466, + IMAGE2D = 467, + IIMAGE2D = 468, + UIMAGE2D = 469, + IMAGE3D = 470, + IIMAGE3D = 471, + UIMAGE3D = 472, + IMAGE2DRECT = 473, + IIMAGE2DRECT = 474, + UIMAGE2DRECT = 475, + IMAGECUBE = 476, + IIMAGECUBE = 477, + UIMAGECUBE = 478, + IMAGEBUFFER = 479, + IIMAGEBUFFER = 480, + UIMAGEBUFFER = 481, + IMAGE1DARRAY = 482, + IIMAGE1DARRAY = 483, + UIMAGE1DARRAY = 484, + IMAGE2DARRAY = 485, + IIMAGE2DARRAY = 486, + UIMAGE2DARRAY = 487, + IMAGECUBEARRAY = 488, + IIMAGECUBEARRAY = 489, + UIMAGECUBEARRAY = 490, + IMAGE2DMS = 491, + IIMAGE2DMS = 492, + UIMAGE2DMS = 493, + IMAGE2DMSARRAY = 494, + IIMAGE2DMSARRAY = 495, + UIMAGE2DMSARRAY = 496, + F16IMAGE1D = 497, + F16IMAGE2D = 498, + F16IMAGE3D = 499, + F16IMAGE2DRECT = 500, + F16IMAGECUBE = 501, + F16IMAGE1DARRAY = 502, + F16IMAGE2DARRAY = 503, + F16IMAGECUBEARRAY = 504, + F16IMAGEBUFFER = 505, + F16IMAGE2DMS = 506, + F16IMAGE2DMSARRAY = 507, + TEXTURECUBEARRAY = 508, + ITEXTURECUBEARRAY = 509, + UTEXTURECUBEARRAY = 510, + TEXTURE1D = 511, + ITEXTURE1D = 512, + UTEXTURE1D = 513, + TEXTURE1DARRAY = 514, + ITEXTURE1DARRAY = 515, + UTEXTURE1DARRAY = 516, + TEXTURE2DRECT = 517, + ITEXTURE2DRECT = 518, + UTEXTURE2DRECT = 519, + TEXTUREBUFFER = 520, + ITEXTUREBUFFER = 521, + UTEXTUREBUFFER = 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, + LEFT_OP = 548, + RIGHT_OP = 549, + INC_OP = 550, + DEC_OP = 551, + LE_OP = 552, + GE_OP = 553, + EQ_OP = 554, + NE_OP = 555, + AND_OP = 556, + OR_OP = 557, + XOR_OP = 558, + MUL_ASSIGN = 559, + DIV_ASSIGN = 560, + ADD_ASSIGN = 561, + MOD_ASSIGN = 562, + LEFT_ASSIGN = 563, + RIGHT_ASSIGN = 564, + AND_ASSIGN = 565, + XOR_ASSIGN = 566, + OR_ASSIGN = 567, + SUB_ASSIGN = 568, + LEFT_PAREN = 569, + RIGHT_PAREN = 570, + LEFT_BRACKET = 571, + RIGHT_BRACKET = 572, + LEFT_BRACE = 573, + RIGHT_BRACE = 574, + DOT = 575, + COMMA = 576, + COLON = 577, + EQUAL = 578, + SEMICOLON = 579, + BANG = 580, + DASH = 581, + TILDE = 582, + PLUS = 583, + STAR = 584, + SLASH = 585, + PERCENT = 586, + LEFT_ANGLE = 587, + RIGHT_ANGLE = 588, + VERTICAL_BAR = 589, + CARET = 590, + AMPERSAND = 591, + QUESTION = 592, + INVARIANT = 593, + HIGH_PRECISION = 594, + MEDIUM_PRECISION = 595, + LOW_PRECISION = 596, + PRECISION = 597, + PACKED = 598, + RESOURCE = 599, + SUPERP = 600, + FLOATCONSTANT = 601, + INTCONSTANT = 602, + UINTCONSTANT = 603, + BOOLCONSTANT = 604, + IDENTIFIER = 605, + TYPE_NAME = 606, + CENTROID = 607, + IN = 608, + OUT = 609, + INOUT = 610, + STRUCT = 611, + VOID = 612, + WHILE = 613, + BREAK = 614, + CONTINUE = 615, + DO = 616, + ELSE = 617, + FOR = 618, + IF = 619, + DISCARD = 620, + RETURN = 621, + SWITCH = 622, + CASE = 623, + DEFAULT = 624, + UNIFORM = 625, + SHARED = 626, + BUFFER = 627, + FLAT = 628, + SMOOTH = 629, + LAYOUT = 630, + DOUBLECONSTANT = 631, + INT16CONSTANT = 632, + UINT16CONSTANT = 633, + FLOAT16CONSTANT = 634, + INT32CONSTANT = 635, + UINT32CONSTANT = 636, + INT64CONSTANT = 637, + UINT64CONSTANT = 638, + SUBROUTINE = 639, + DEMOTE = 640, + PAYLOADNV = 641, + PAYLOADINNV = 642, + HITATTRNV = 643, + CALLDATANV = 644, + CALLDATAINNV = 645, + PATCH = 646, + SAMPLE = 647, + NONUNIFORM = 648, + COHERENT = 649, + VOLATILE = 650, + RESTRICT = 651, + READONLY = 652, + WRITEONLY = 653, + DEVICECOHERENT = 654, + QUEUEFAMILYCOHERENT = 655, + WORKGROUPCOHERENT = 656, + SUBGROUPCOHERENT = 657, + NONPRIVATE = 658, + NOPERSPECTIVE = 659, + EXPLICITINTERPAMD = 660, + PERVERTEXNV = 661, + PERPRIMITIVENV = 662, + PERVIEWNV = 663, + PERTASKNV = 664, + PRECISE = 665 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; + union YYSTYPE { -#line 70 "MachineIndependent/glslang.y" /* yacc.c:355 */ +#line 96 "MachineIndependent/glslang.y" /* yacc.c:355 */ struct { glslang::TSourceLoc loc; @@ -552,10 +572,13 @@ union YYSTYPE glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; -#line 558 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ +#line 579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:355 */ }; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif @@ -567,7 +590,7 @@ int yyparse (glslang::TParseContext* pParseContext); #endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ /* Copy the second part of user declarations. */ -#line 105 "MachineIndependent/glslang.y" /* yacc.c:358 */ +#line 132 "MachineIndependent/glslang.y" /* yacc.c:358 */ /* windows only pragma */ @@ -583,7 +606,7 @@ int yyparse (glslang::TParseContext* pParseContext); extern int yylex(YYSTYPE*, TParseContext&); -#line 587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ +#line 610 "MachineIndependent/glslang_tab.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -640,11 +663,30 @@ typedef short int yytype_int16; # 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 @@ -804,23 +846,23 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 366 +#define YYFINAL 386 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 8949 +#define YYLAST 9369 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 391 +#define YYNTOKENS 411 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 107 +#define YYNNTS 111 /* YYNRULES -- Number of rules. */ -#define YYNRULES 556 +#define YYNRULES 582 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 697 +#define YYNSTATES 727 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 645 +#define YYMAXUTOK 665 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -893,69 +935,74 @@ static const yytype_uint16 yytranslate[] = 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 + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 293, 293, 299, 302, 306, 310, 313, 317, 321, - 325, 329, 333, 336, 340, 344, 347, 355, 358, 361, - 364, 367, 372, 380, 387, 394, 400, 404, 411, 414, - 420, 427, 437, 445, 450, 477, 485, 491, 495, 499, - 519, 520, 521, 522, 528, 529, 534, 539, 548, 549, - 554, 562, 563, 569, 578, 579, 584, 589, 594, 602, - 603, 611, 622, 623, 632, 633, 642, 643, 652, 653, - 661, 662, 670, 671, 679, 680, 680, 698, 699, 714, - 718, 722, 726, 731, 735, 739, 743, 747, 751, 755, - 762, 765, 776, 783, 788, 793, 801, 805, 809, 813, - 818, 823, 832, 832, 843, 847, 854, 861, 864, 871, - 879, 899, 922, 937, 962, 973, 983, 993, 1003, 1012, - 1015, 1019, 1023, 1028, 1036, 1041, 1046, 1051, 1056, 1065, - 1076, 1103, 1112, 1119, 1126, 1137, 1149, 1155, 1158, 1165, - 1169, 1173, 1181, 1190, 1193, 1204, 1207, 1210, 1214, 1218, - 1222, 1226, 1232, 1236, 1248, 1262, 1267, 1273, 1279, 1286, - 1292, 1297, 1302, 1307, 1315, 1319, 1323, 1327, 1331, 1335, - 1341, 1350, 1357, 1360, 1368, 1372, 1381, 1386, 1394, 1398, - 1408, 1412, 1416, 1421, 1426, 1431, 1436, 1440, 1445, 1450, - 1455, 1460, 1465, 1470, 1475, 1480, 1485, 1489, 1494, 1499, - 1504, 1510, 1516, 1522, 1528, 1534, 1540, 1546, 1552, 1558, - 1564, 1570, 1576, 1581, 1586, 1591, 1596, 1601, 1606, 1612, - 1618, 1624, 1630, 1636, 1642, 1648, 1654, 1660, 1666, 1672, - 1678, 1684, 1690, 1696, 1702, 1708, 1714, 1720, 1726, 1732, - 1738, 1744, 1750, 1756, 1762, 1768, 1773, 1778, 1783, 1788, - 1793, 1798, 1803, 1808, 1813, 1818, 1823, 1828, 1834, 1840, - 1846, 1852, 1858, 1864, 1870, 1876, 1882, 1888, 1894, 1900, - 1906, 1912, 1918, 1924, 1930, 1936, 1942, 1948, 1954, 1960, - 1966, 1972, 1978, 1984, 1990, 1996, 2002, 2008, 2014, 2020, - 2026, 2032, 2038, 2044, 2050, 2056, 2062, 2068, 2074, 2080, - 2086, 2092, 2098, 2104, 2110, 2116, 2121, 2126, 2131, 2136, - 2141, 2146, 2151, 2156, 2161, 2166, 2171, 2176, 2181, 2186, - 2194, 2202, 2210, 2218, 2226, 2234, 2242, 2250, 2258, 2266, - 2274, 2282, 2290, 2295, 2300, 2305, 2310, 2315, 2320, 2325, - 2330, 2335, 2340, 2345, 2350, 2355, 2360, 2365, 2370, 2378, - 2386, 2391, 2396, 2401, 2409, 2414, 2419, 2424, 2432, 2437, - 2442, 2447, 2455, 2460, 2465, 2470, 2475, 2480, 2488, 2493, - 2501, 2506, 2514, 2519, 2527, 2532, 2540, 2545, 2553, 2558, - 2566, 2571, 2576, 2581, 2586, 2591, 2596, 2601, 2606, 2611, - 2616, 2621, 2626, 2631, 2636, 2641, 2649, 2654, 2659, 2664, - 2672, 2677, 2682, 2687, 2695, 2700, 2705, 2710, 2718, 2723, - 2728, 2733, 2741, 2746, 2751, 2756, 2764, 2769, 2774, 2779, - 2787, 2792, 2797, 2802, 2810, 2815, 2820, 2825, 2833, 2838, - 2843, 2848, 2856, 2861, 2866, 2871, 2879, 2884, 2889, 2894, - 2902, 2907, 2912, 2917, 2925, 2930, 2935, 2940, 2948, 2953, - 2958, 2963, 2971, 2976, 2981, 2987, 2993, 2999, 3008, 3017, - 3023, 3029, 3035, 3041, 3046, 3062, 3067, 3072, 3080, 3080, - 3091, 3091, 3101, 3104, 3117, 3139, 3166, 3170, 3176, 3181, - 3192, 3195, 3201, 3210, 3213, 3219, 3223, 3224, 3230, 3231, - 3232, 3233, 3234, 3235, 3236, 3240, 3241, 3245, 3241, 3257, - 3258, 3262, 3262, 3269, 3269, 3283, 3286, 3294, 3302, 3313, - 3314, 3318, 3321, 3327, 3334, 3338, 3346, 3350, 3363, 3366, - 3372, 3372, 3392, 3395, 3401, 3413, 3425, 3428, 3434, 3434, - 3449, 3449, 3465, 3465, 3486, 3489, 3495, 3498, 3504, 3508, - 3515, 3520, 3525, 3532, 3535, 3544, 3548, 3557, 3560, 3563, - 3571, 3571, 3593, 3599, 3602, 3607, 3610 + 0, 352, 352, 358, 361, 366, 369, 372, 376, 380, + 384, 388, 392, 396, 400, 404, 408, 416, 419, 422, + 425, 428, 433, 441, 448, 455, 461, 465, 472, 475, + 481, 488, 498, 506, 511, 539, 548, 554, 558, 562, + 582, 583, 584, 585, 591, 592, 597, 602, 611, 612, + 617, 625, 626, 632, 641, 642, 647, 652, 657, 665, + 666, 675, 687, 688, 697, 698, 707, 708, 717, 718, + 726, 727, 735, 736, 744, 745, 745, 763, 764, 780, + 784, 788, 792, 797, 801, 805, 809, 813, 817, 821, + 828, 831, 842, 849, 854, 859, 866, 870, 874, 878, + 883, 888, 897, 897, 908, 912, 919, 926, 929, 936, + 944, 964, 987, 1002, 1027, 1038, 1048, 1058, 1068, 1077, + 1080, 1084, 1088, 1093, 1101, 1108, 1113, 1118, 1123, 1132, + 1142, 1169, 1178, 1185, 1193, 1200, 1207, 1215, 1225, 1232, + 1243, 1249, 1252, 1259, 1263, 1267, 1276, 1286, 1289, 1300, + 1303, 1306, 1310, 1314, 1319, 1323, 1330, 1334, 1339, 1345, + 1351, 1358, 1363, 1371, 1377, 1389, 1403, 1409, 1414, 1422, + 1430, 1438, 1446, 1453, 1457, 1462, 1467, 1472, 1477, 1482, + 1486, 1490, 1494, 1498, 1504, 1515, 1522, 1525, 1534, 1539, + 1549, 1554, 1562, 1566, 1576, 1579, 1585, 1591, 1598, 1608, + 1612, 1616, 1620, 1625, 1629, 1634, 1639, 1644, 1649, 1654, + 1659, 1664, 1669, 1674, 1680, 1686, 1692, 1697, 1702, 1707, + 1712, 1717, 1722, 1727, 1732, 1737, 1742, 1747, 1753, 1758, + 1763, 1768, 1773, 1778, 1783, 1788, 1793, 1798, 1803, 1808, + 1813, 1819, 1825, 1831, 1837, 1843, 1849, 1855, 1861, 1867, + 1873, 1879, 1885, 1891, 1897, 1903, 1909, 1915, 1921, 1927, + 1933, 1939, 1945, 1951, 1957, 1963, 1969, 1975, 1981, 1987, + 1993, 1999, 2005, 2011, 2017, 2023, 2029, 2035, 2041, 2047, + 2053, 2059, 2065, 2071, 2077, 2083, 2089, 2095, 2101, 2107, + 2113, 2119, 2125, 2131, 2137, 2143, 2149, 2155, 2161, 2167, + 2173, 2179, 2185, 2191, 2197, 2203, 2209, 2215, 2221, 2227, + 2233, 2239, 2245, 2251, 2257, 2263, 2269, 2275, 2281, 2287, + 2293, 2299, 2305, 2311, 2317, 2321, 2326, 2332, 2337, 2342, + 2347, 2352, 2357, 2362, 2368, 2373, 2378, 2383, 2388, 2393, + 2399, 2405, 2411, 2417, 2423, 2429, 2435, 2441, 2447, 2453, + 2459, 2465, 2471, 2477, 2482, 2487, 2492, 2497, 2502, 2507, + 2513, 2518, 2523, 2528, 2533, 2538, 2543, 2548, 2554, 2559, + 2564, 2569, 2574, 2579, 2584, 2589, 2594, 2599, 2604, 2609, + 2614, 2619, 2624, 2630, 2635, 2640, 2646, 2652, 2657, 2662, + 2667, 2673, 2678, 2683, 2688, 2694, 2699, 2704, 2709, 2715, + 2720, 2725, 2730, 2736, 2742, 2748, 2754, 2759, 2765, 2771, + 2777, 2782, 2787, 2792, 2797, 2802, 2808, 2813, 2818, 2823, + 2829, 2834, 2839, 2844, 2850, 2855, 2860, 2865, 2871, 2876, + 2881, 2886, 2892, 2897, 2902, 2907, 2913, 2918, 2923, 2928, + 2934, 2939, 2944, 2949, 2955, 2960, 2965, 2970, 2976, 2981, + 2986, 2991, 2997, 3002, 3007, 3012, 3018, 3023, 3028, 3033, + 3039, 3044, 3049, 3054, 3060, 3065, 3070, 3075, 3081, 3086, + 3091, 3096, 3102, 3107, 3112, 3118, 3124, 3130, 3136, 3143, + 3150, 3156, 3162, 3168, 3174, 3180, 3186, 3193, 3198, 3214, + 3219, 3224, 3232, 3232, 3243, 3243, 3253, 3256, 3269, 3291, + 3318, 3322, 3328, 3333, 3344, 3348, 3354, 3365, 3368, 3375, + 3379, 3380, 3386, 3387, 3388, 3389, 3390, 3391, 3392, 3394, + 3400, 3409, 3410, 3414, 3410, 3426, 3427, 3431, 3431, 3438, + 3438, 3452, 3455, 3463, 3471, 3482, 3483, 3487, 3491, 3498, + 3505, 3509, 3517, 3521, 3534, 3538, 3545, 3545, 3565, 3568, + 3574, 3586, 3598, 3602, 3609, 3609, 3624, 3624, 3640, 3640, + 3661, 3664, 3670, 3673, 3679, 3683, 3690, 3695, 3700, 3707, + 3710, 3719, 3723, 3732, 3735, 3739, 3748, 3748, 3771, 3777, + 3780, 3785, 3788 }; #endif @@ -964,79 +1011,71 @@ static const yytype_uint16 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$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", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", - "WRITEONLY", "DVEC2", "DVEC3", "DVEC4", "DMAT2", "DMAT3", "DMAT4", - "F16VEC2", "F16VEC3", "F16VEC4", "F16MAT2", "F16MAT3", "F16MAT4", - "F32VEC2", "F32VEC3", "F32VEC4", "F32MAT2", "F32MAT3", "F32MAT4", - "F64VEC2", "F64VEC3", "F64VEC4", "F64MAT2", "F64MAT3", "F64MAT4", - "NOPERSPECTIVE", "FLAT", "SMOOTH", "LAYOUT", "__EXPLICITINTERPAMD", - "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", "F32MAT2X2", "F32MAT2X3", - "F32MAT2X4", "F32MAT3X2", "F32MAT3X3", "F32MAT3X4", "F32MAT4X2", - "F32MAT4X3", "F32MAT4X4", "F64MAT2X2", "F64MAT2X3", "F64MAT2X4", - "F64MAT3X2", "F64MAT3X3", "F64MAT3X4", "F64MAT4X2", "F64MAT4X3", - "F64MAT4X4", "ATOMIC_UINT", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", - "SAMPLERCUBE", "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "SAMPLERCUBESHADOW", - "SAMPLER1DARRAY", "SAMPLER2DARRAY", "SAMPLER1DARRAYSHADOW", - "SAMPLER2DARRAYSHADOW", "ISAMPLER1D", "ISAMPLER2D", "ISAMPLER3D", - "ISAMPLERCUBE", "ISAMPLER1DARRAY", "ISAMPLER2DARRAY", "USAMPLER1D", - "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER1DARRAY", - "USAMPLER2DARRAY", "SAMPLER2DRECT", "SAMPLER2DRECTSHADOW", - "ISAMPLER2DRECT", "USAMPLER2DRECT", "SAMPLERBUFFER", "ISAMPLERBUFFER", - "USAMPLERBUFFER", "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", - "ISAMPLERCUBEARRAY", "USAMPLERCUBEARRAY", "SAMPLER2DMS", "ISAMPLER2DMS", - "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", - "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "F16SAMPLER1D", + "$end", "error", "$undefined", "CONST", "BOOL", "INT", "UINT", "FLOAT", + "BVEC2", "BVEC3", "BVEC4", "IVEC2", "IVEC3", "IVEC4", "UVEC2", "UVEC3", + "UVEC4", "VEC2", "VEC3", "VEC4", "MAT2", "MAT3", "MAT4", "MAT2X2", + "MAT2X3", "MAT2X4", "MAT3X2", "MAT3X3", "MAT3X4", "MAT4X2", "MAT4X3", + "MAT4X4", "SAMPLER2D", "SAMPLER3D", "SAMPLERCUBE", "SAMPLER2DSHADOW", + "SAMPLERCUBESHADOW", "SAMPLER2DARRAY", "SAMPLER2DARRAYSHADOW", + "ISAMPLER2D", "ISAMPLER3D", "ISAMPLERCUBE", "ISAMPLER2DARRAY", + "USAMPLER2D", "USAMPLER3D", "USAMPLERCUBE", "USAMPLER2DARRAY", "SAMPLER", + "SAMPLERSHADOW", "TEXTURE2D", "TEXTURE3D", "TEXTURECUBE", + "TEXTURE2DARRAY", "ITEXTURE2D", "ITEXTURE3D", "ITEXTURECUBE", + "ITEXTURE2DARRAY", "UTEXTURE2D", "UTEXTURE3D", "UTEXTURECUBE", + "UTEXTURE2DARRAY", "ATTRIBUTE", "VARYING", "FLOAT16_T", "FLOAT32_T", + "DOUBLE", "FLOAT64_T", "INT64_T", "UINT64_T", "INT32_T", "UINT32_T", + "INT16_T", "UINT16_T", "INT8_T", "UINT8_T", "I64VEC2", "I64VEC3", + "I64VEC4", "U64VEC2", "U64VEC3", "U64VEC4", "I32VEC2", "I32VEC3", + "I32VEC4", "U32VEC2", "U32VEC3", "U32VEC4", "I16VEC2", "I16VEC3", + "I16VEC4", "U16VEC2", "U16VEC3", "U16VEC4", "I8VEC2", "I8VEC3", "I8VEC4", + "U8VEC2", "U8VEC3", "U8VEC4", "DVEC2", "DVEC3", "DVEC4", "DMAT2", + "DMAT3", "DMAT4", "F16VEC2", "F16VEC3", "F16VEC4", "F16MAT2", "F16MAT3", + "F16MAT4", "F32VEC2", "F32VEC3", "F32VEC4", "F32MAT2", "F32MAT3", + "F32MAT4", "F64VEC2", "F64VEC3", "F64VEC4", "F64MAT2", "F64MAT3", + "F64MAT4", "DMAT2X2", "DMAT2X3", "DMAT2X4", "DMAT3X2", "DMAT3X3", + "DMAT3X4", "DMAT4X2", "DMAT4X3", "DMAT4X4", "F16MAT2X2", "F16MAT2X3", + "F16MAT2X4", "F16MAT3X2", "F16MAT3X3", "F16MAT3X4", "F16MAT4X2", + "F16MAT4X3", "F16MAT4X4", "F32MAT2X2", "F32MAT2X3", "F32MAT2X4", + "F32MAT3X2", "F32MAT3X3", "F32MAT3X4", "F32MAT4X2", "F32MAT4X3", + "F32MAT4X4", "F64MAT2X2", "F64MAT2X3", "F64MAT2X4", "F64MAT3X2", + "F64MAT3X3", "F64MAT3X4", "F64MAT4X2", "F64MAT4X3", "F64MAT4X4", + "ATOMIC_UINT", "ACCSTRUCTNV", "FCOOPMATNV", "ICOOPMATNV", "UCOOPMATNV", + "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", + "USAMPLERCUBEARRAY", "SAMPLER1D", "SAMPLER1DARRAY", + "SAMPLER1DARRAYSHADOW", "ISAMPLER1D", "SAMPLER1DSHADOW", "SAMPLER2DRECT", + "SAMPLER2DRECTSHADOW", "ISAMPLER2DRECT", "USAMPLER2DRECT", + "SAMPLERBUFFER", "ISAMPLERBUFFER", "USAMPLERBUFFER", "SAMPLER2DMS", + "ISAMPLER2DMS", "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", + "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", + "ISAMPLER1DARRAY", "USAMPLER1D", "USAMPLER1DARRAY", "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", "UTEXTURE2DARRAY", "TEXTURE2DRECT", "ITEXTURE2DRECT", - "UTEXTURE2DRECT", "TEXTUREBUFFER", "ITEXTUREBUFFER", "UTEXTUREBUFFER", - "TEXTURECUBEARRAY", "ITEXTURECUBEARRAY", "UTEXTURECUBEARRAY", - "TEXTURE2DMS", "ITEXTURE2DMS", "UTEXTURE2DMS", "TEXTURE2DMSARRAY", - "ITEXTURE2DMSARRAY", "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", "UIMAGEBUFFER", "IMAGE1DARRAY", - "IIMAGE1DARRAY", "UIMAGE1DARRAY", "IMAGE2DARRAY", "IIMAGE2DARRAY", - "UIMAGE2DARRAY", "IMAGECUBEARRAY", "IIMAGECUBEARRAY", "UIMAGECUBEARRAY", - "IMAGE2DMS", "IIMAGE2DMS", "UIMAGE2DMS", "IMAGE2DMSARRAY", - "IIMAGE2DMSARRAY", "UIMAGE2DMSARRAY", "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", + "F16SAMPLERCUBESHADOW", "F16SAMPLERCUBEARRAYSHADOW", "IMAGE1D", + "IIMAGE1D", "UIMAGE1D", "IMAGE2D", "IIMAGE2D", "UIMAGE2D", "IMAGE3D", + "IIMAGE3D", "UIMAGE3D", "IMAGE2DRECT", "IIMAGE2DRECT", "UIMAGE2DRECT", + "IMAGECUBE", "IIMAGECUBE", "UIMAGECUBE", "IMAGEBUFFER", "IIMAGEBUFFER", + "UIMAGEBUFFER", "IMAGE1DARRAY", "IIMAGE1DARRAY", "UIMAGE1DARRAY", + "IMAGE2DARRAY", "IIMAGE2DARRAY", "UIMAGE2DARRAY", "IMAGECUBEARRAY", + "IIMAGECUBEARRAY", "UIMAGECUBEARRAY", "IMAGE2DMS", "IIMAGE2DMS", + "UIMAGE2DMS", "IMAGE2DMSARRAY", "IIMAGE2DMSARRAY", "UIMAGE2DMSARRAY", + "F16IMAGE1D", "F16IMAGE2D", "F16IMAGE3D", "F16IMAGE2DRECT", + "F16IMAGECUBE", "F16IMAGE1DARRAY", "F16IMAGE2DARRAY", + "F16IMAGECUBEARRAY", "F16IMAGEBUFFER", "F16IMAGE2DMS", + "F16IMAGE2DMSARRAY", "TEXTURECUBEARRAY", "ITEXTURECUBEARRAY", + "UTEXTURECUBEARRAY", "TEXTURE1D", "ITEXTURE1D", "UTEXTURE1D", + "TEXTURE1DARRAY", "ITEXTURE1DARRAY", "UTEXTURE1DARRAY", "TEXTURE2DRECT", + "ITEXTURE2DRECT", "UTEXTURE2DRECT", "TEXTUREBUFFER", "ITEXTUREBUFFER", + "UTEXTUREBUFFER", "TEXTURE2DMS", "ITEXTURE2DMS", "UTEXTURE2DMS", + "TEXTURE2DMSARRAY", "ITEXTURE2DMSARRAY", "UTEXTURE2DMSARRAY", + "F16TEXTURE1D", "F16TEXTURE2D", "F16TEXTURE3D", "F16TEXTURE2DRECT", + "F16TEXTURECUBE", "F16TEXTURE1DARRAY", "F16TEXTURE2DARRAY", + "F16TEXTURECUBEARRAY", "F16TEXTUREBUFFER", "F16TEXTURE2DMS", + "F16TEXTURE2DMSARRAY", "SUBPASSINPUT", "SUBPASSINPUTMS", "ISUBPASSINPUT", + "ISUBPASSINPUTMS", "USUBPASSINPUT", "USUBPASSINPUTMS", "F16SUBPASSINPUT", + "F16SUBPASSINPUTMS", "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", "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", @@ -1044,11 +1083,24 @@ static const char *const yytname[] = "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", "QUESTION", - "INVARIANT", "PRECISE", "HIGH_PRECISION", "MEDIUM_PRECISION", - "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", "SUPERP", "$accept", - "variable_identifier", "primary_expression", "postfix_expression", - "integer_expression", "function_call", "function_call_or_method", - "function_call_generic", "function_call_header_no_parameters", + "INVARIANT", "HIGH_PRECISION", "MEDIUM_PRECISION", "LOW_PRECISION", + "PRECISION", "PACKED", "RESOURCE", "SUPERP", "FLOATCONSTANT", + "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", "IDENTIFIER", "TYPE_NAME", + "CENTROID", "IN", "OUT", "INOUT", "STRUCT", "VOID", "WHILE", "BREAK", + "CONTINUE", "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "SWITCH", + "CASE", "DEFAULT", "UNIFORM", "SHARED", "BUFFER", "FLAT", "SMOOTH", + "LAYOUT", "DOUBLECONSTANT", "INT16CONSTANT", "UINT16CONSTANT", + "FLOAT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", "INT64CONSTANT", + "UINT64CONSTANT", "SUBROUTINE", "DEMOTE", "PAYLOADNV", "PAYLOADINNV", + "HITATTRNV", "CALLDATANV", "CALLDATAINNV", "PATCH", "SAMPLE", + "NONUNIFORM", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", + "WRITEONLY", "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", + "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", "NOPERSPECTIVE", + "EXPLICITINTERPAMD", "PERVERTEXNV", "PERPRIMITIVENV", "PERVIEWNV", + "PERTASKNV", "PRECISE", "$accept", "variable_identifier", + "primary_expression", "postfix_expression", "integer_expression", + "function_call", "function_call_or_method", "function_call_generic", + "function_call_header_no_parameters", "function_call_header_with_parameters", "function_call_header", "function_identifier", "unary_expression", "unary_operator", "multiplicative_expression", "additive_expression", "shift_expression", @@ -1066,13 +1118,14 @@ static const char *const yytname[] = "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", "precise_qualifier", "type_qualifier", "single_type_qualifier", "storage_qualifier", "non_uniform_qualifier", "type_name_list", - "type_specifier", "array_specifier", "type_specifier_nonarray", - "precision_qualifier", "struct_specifier", "$@3", "$@4", - "struct_declaration_list", "struct_declaration", + "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", + "simple_statement", "demote_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_statement_nonattributed", "selection_rest_statement", @@ -1082,7 +1135,7 @@ static const char *const yytname[] = "for_init_statement", "conditionopt", "for_rest_statement", "jump_statement", "translation_unit", "external_declaration", "function_definition", "$@13", "attribute", "attribute_list", - "single_attribute", YY_NULL + "single_attribute", YY_NULLPTR }; #endif @@ -1130,16 +1183,18 @@ static const yytype_uint16 yytoknum[] = 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 + 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, + 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, + 665 }; # endif -#define YYPACT_NINF -634 +#define YYPACT_NINF -453 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-634))) + (!!((Yystate) == (-453))) -#define YYTABLE_NINF -502 +#define YYTABLE_NINF -528 #define yytable_value_is_error(Yytable_value) \ 0 @@ -1148,76 +1203,79 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 3391, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -311, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -295, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, -634, -301, -634, -634, - -634, -634, -634, -634, -634, -634, -241, -634, -302, -342, - -290, -254, 5696, -300, -634, -210, -634, -634, -634, -634, - 4160, -634, -634, -634, -634, -219, -634, -634, 696, -634, - -634, -189, -69, -207, -634, 8625, -320, -634, -634, -203, - -634, 5696, -634, -634, -634, 5696, -155, -154, -634, -324, - -288, -634, -634, -634, 6417, -190, -634, -634, -634, -292, - -634, -196, -287, -634, -634, 5696, -195, -634, -306, 1081, - -634, -634, -634, -634, -219, -325, -634, 6785, -310, -634, - -151, -634, -277, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, 7889, 7889, 7889, -634, - -634, -634, -634, -634, -634, -634, -309, -634, -634, -634, - -185, -283, 8257, -183, -634, 7889, -227, -263, -299, -318, - -194, -204, -202, -200, -165, -166, -321, -179, -634, -634, - 7153, -634, -140, 7889, -634, -69, 5696, 5696, -139, 4544, - -634, -634, -634, -182, -180, -634, -173, -169, -178, 7521, - -164, 7889, -174, -163, -167, -162, -634, -634, -252, -634, - -634, -237, -634, -342, -161, -158, -634, -634, -634, -634, - 1466, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -19, -190, 6785, -296, 6785, -634, -634, 6785, 5696, -634, - -127, -634, -634, -634, -278, -634, -634, 7889, -121, -634, - -634, 7889, -156, -634, -634, -634, 7889, 7889, 7889, 7889, - 7889, 7889, 7889, 7889, 7889, 7889, 7889, 7889, 7889, 7889, - 7889, 7889, 7889, 7889, 7889, -634, -634, -634, -157, -634, - -634, -634, -634, 4928, -139, -219, -236, -634, -634, -634, - -634, -634, 1851, -634, 7889, -634, -634, -230, 7889, -213, - -634, -634, -118, -634, 1851, -634, -634, -634, -634, -634, - -634, -634, -634, -634, -634, -634, 7889, 7889, -634, -634, - -634, -634, -634, -634, -634, 6785, -634, -270, -634, 5312, - -634, -634, -153, -150, -634, -634, -634, -634, -634, -227, - -227, -263, -263, -299, -299, -299, -299, -318, -318, -194, - -204, -202, -200, -165, -166, 7889, -634, -634, -226, -190, - -139, -634, -113, 3006, -275, -634, -253, -634, 3776, -148, - -282, -634, 1851, -634, -634, -634, -634, 6049, -634, -634, - -208, -634, -634, -147, -634, -634, 3776, -146, -634, -150, - -111, 5696, -145, 7889, -144, -118, -143, -634, -634, 7889, - 7889, -634, -149, -141, 196, -136, 2621, -634, -116, -120, - 2236, -137, -634, -634, -634, -634, -239, 7889, 2236, -146, - -634, -634, 1851, 6785, -634, -634, -634, -634, -119, -150, - -634, -634, 1851, -112, -634, -634, -634 + 3994, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, 97, -453, -453, -453, + -453, -453, 6, -453, -453, -453, -453, -453, -453, -307, + -241, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -3, 95, 36, + 125, 6034, 82, -453, -22, -453, -453, -453, -453, 4402, + -453, -453, -453, -453, 131, -453, -453, 730, -453, -453, + 11, -453, 153, -28, 127, -453, 7, -453, 157, -453, + 6034, -453, -453, -453, 6034, 129, 134, -453, 13, -453, + 73, -453, -453, 8391, 162, -453, -453, -453, 161, 6034, + -453, 163, -453, -309, -453, -453, 27, 6831, -453, 16, + 1138, -453, -453, -453, -453, 162, 23, -453, 7221, 49, + -453, 138, -453, 87, 8391, 8391, 8391, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, 68, -453, -453, -453, + 174, 60, 8781, 176, -453, 8391, -453, -453, -320, 175, + -453, 6034, 142, 4810, -453, 6034, 8391, -453, -28, -453, + 143, -453, -453, 119, 128, 32, 21, 38, 158, 160, + 165, 195, 194, 18, 183, 7611, -453, 185, 184, -453, + -453, 188, 180, 181, -453, 196, 197, 190, 8001, 198, + 8391, 187, 193, 122, -453, -453, 91, -453, 95, 204, + 205, -453, -453, -453, -453, -453, 1546, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -353, 175, 7221, 69, + 7221, -453, -453, 7221, 6034, -453, 170, -453, -453, -453, + 78, -453, -453, 8391, 171, -453, -453, 8391, 207, -453, + -453, -453, 8391, -453, 142, 162, 93, -453, -453, -453, + 5218, -453, -453, -453, -453, 8391, 8391, 8391, 8391, 8391, + 8391, 8391, 8391, 8391, 8391, 8391, 8391, 8391, 8391, 8391, + 8391, 8391, 8391, 8391, -453, -453, -453, 206, 177, -453, + 1954, -453, -453, -453, 1954, -453, 8391, -453, -453, 100, + 8391, 144, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, -453, -453, -453, 8391, 8391, -453, -453, -453, + -453, -453, -453, -453, 7221, -453, 140, -453, 5626, -453, + -453, 209, 208, -453, -453, -453, 123, 175, 142, -453, + -453, -453, -453, -453, 119, 119, 128, 128, 32, 32, + 32, 32, 21, 21, 38, 158, 160, 165, 195, 194, + 8391, -453, 214, 56, -453, 1954, 3586, 172, 3178, 80, + -453, 81, -453, -453, -453, -453, -453, 6441, -453, -453, + -453, -453, 146, 8391, 215, 177, 212, 208, 186, 6034, + 219, 221, -453, -453, 3586, 220, -453, -453, -453, 8391, + 222, -453, -453, -453, 216, 2362, 8391, -453, 217, 227, + 182, 225, 2770, -453, 229, -453, -453, 7221, -453, -453, + -453, 89, 8391, 2362, 220, -453, -453, 1954, -453, 224, + 208, -453, -453, 1954, 226, -453, -453 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1225,108 +1283,113 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 153, 154, 183, 181, 184, 182, 185, 152, 196, - 186, 187, 194, 195, 192, 193, 190, 191, 188, 189, - 169, 212, 213, 214, 215, 216, 217, 230, 231, 232, - 227, 228, 229, 242, 243, 244, 224, 225, 226, 239, - 240, 241, 221, 222, 223, 236, 237, 238, 218, 219, - 220, 233, 234, 235, 197, 198, 199, 245, 246, 247, - 158, 156, 157, 155, 161, 159, 160, 162, 163, 171, - 164, 165, 166, 167, 168, 200, 201, 202, 257, 258, - 259, 203, 204, 205, 269, 270, 271, 206, 207, 208, - 281, 282, 283, 209, 210, 211, 293, 294, 295, 134, - 133, 132, 0, 135, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 332, 333, 334, 335, 336, 337, 339, 340, 341, - 342, 343, 344, 346, 347, 350, 351, 352, 354, 355, - 317, 318, 338, 345, 356, 358, 359, 360, 362, 363, - 454, 319, 320, 321, 348, 322, 326, 327, 330, 353, - 357, 361, 323, 324, 328, 329, 349, 325, 331, 364, - 365, 366, 368, 370, 372, 374, 376, 380, 381, 382, - 383, 384, 385, 387, 388, 389, 390, 391, 392, 394, - 396, 397, 398, 400, 401, 378, 386, 393, 402, 404, - 405, 406, 408, 409, 367, 369, 371, 395, 373, 375, - 377, 379, 399, 403, 407, 455, 456, 459, 460, 461, - 462, 457, 458, 410, 412, 413, 414, 416, 417, 418, - 420, 421, 422, 424, 425, 426, 428, 429, 430, 432, - 433, 434, 436, 437, 438, 440, 441, 442, 444, 445, - 446, 448, 449, 450, 452, 453, 411, 415, 419, 423, - 427, 435, 439, 443, 431, 447, 451, 0, 180, 464, - 549, 131, 142, 465, 466, 467, 0, 548, 0, 550, - 0, 108, 107, 0, 119, 124, 149, 148, 146, 150, - 0, 143, 145, 151, 129, 174, 147, 463, 0, 545, - 547, 0, 0, 0, 470, 0, 0, 96, 93, 0, - 106, 0, 115, 109, 117, 0, 118, 0, 94, 125, - 0, 99, 144, 130, 0, 175, 1, 546, 172, 0, - 141, 139, 0, 137, 468, 0, 0, 97, 0, 0, - 551, 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, 176, - 42, 41, 43, 40, 3, 17, 36, 19, 24, 25, - 0, 0, 29, 0, 44, 0, 48, 51, 54, 59, - 62, 64, 66, 68, 70, 72, 74, 0, 35, 33, - 0, 170, 0, 0, 136, 0, 0, 0, 0, 0, - 472, 95, 98, 0, 0, 530, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 496, 505, 509, 44, 77, - 90, 0, 485, 0, 151, 129, 488, 507, 487, 486, - 0, 489, 490, 511, 491, 518, 492, 493, 526, 494, - 0, 113, 0, 121, 0, 480, 128, 0, 0, 104, - 0, 101, 37, 38, 0, 21, 22, 0, 0, 27, - 26, 0, 180, 30, 32, 39, 0, 0, 0, 0, + 0, 156, 203, 201, 202, 200, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 204, 205, 206, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 327, 328, 329, 330, 331, 332, 333, 353, 354, 355, + 356, 357, 358, 359, 368, 381, 382, 369, 370, 372, + 371, 373, 374, 375, 376, 377, 378, 379, 380, 164, + 165, 229, 230, 228, 231, 238, 239, 236, 237, 234, + 235, 232, 233, 261, 262, 263, 273, 274, 275, 258, + 259, 260, 270, 271, 272, 255, 256, 257, 267, 268, + 269, 252, 253, 254, 264, 265, 266, 240, 241, 242, + 276, 277, 278, 243, 244, 245, 288, 289, 290, 246, + 247, 248, 300, 301, 302, 249, 250, 251, 312, 313, + 314, 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, + 485, 486, 337, 338, 361, 364, 326, 335, 336, 352, + 334, 383, 384, 387, 388, 389, 391, 392, 393, 395, + 396, 397, 399, 400, 474, 475, 360, 362, 363, 339, + 340, 341, 385, 342, 346, 347, 350, 390, 394, 398, + 343, 344, 348, 349, 386, 345, 351, 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, 365, 366, 367, 401, 410, 412, 406, 411, 413, + 414, 416, 417, 418, 420, 421, 422, 424, 425, 426, + 428, 429, 402, 403, 404, 415, 405, 407, 408, 409, + 419, 423, 427, 476, 477, 480, 481, 482, 483, 478, + 479, 575, 131, 489, 490, 491, 0, 488, 160, 158, + 159, 157, 0, 199, 161, 162, 163, 133, 132, 0, + 183, 169, 170, 168, 171, 172, 166, 167, 185, 173, + 179, 180, 181, 182, 174, 175, 176, 177, 178, 134, + 135, 136, 137, 138, 139, 146, 574, 0, 576, 0, + 108, 107, 0, 119, 124, 153, 152, 150, 154, 0, + 147, 149, 155, 129, 195, 151, 487, 0, 571, 573, + 0, 494, 0, 0, 0, 96, 0, 93, 0, 106, + 0, 115, 109, 117, 0, 118, 0, 94, 125, 99, + 0, 148, 130, 0, 188, 194, 1, 572, 0, 0, + 492, 143, 145, 0, 141, 186, 0, 0, 97, 0, + 0, 577, 110, 114, 116, 112, 120, 111, 0, 126, + 102, 0, 100, 0, 0, 0, 0, 42, 41, 43, + 40, 5, 6, 7, 8, 2, 15, 13, 14, 16, + 9, 10, 11, 12, 3, 17, 36, 19, 24, 25, + 0, 0, 29, 0, 197, 0, 35, 33, 0, 189, + 95, 0, 0, 0, 496, 0, 0, 140, 0, 184, + 0, 190, 44, 48, 51, 54, 59, 62, 64, 66, + 68, 70, 72, 74, 0, 0, 98, 0, 522, 531, + 535, 0, 0, 0, 556, 0, 0, 0, 0, 0, + 0, 0, 0, 44, 77, 90, 0, 509, 0, 155, + 129, 512, 533, 511, 519, 510, 0, 513, 514, 537, + 515, 544, 516, 517, 552, 518, 0, 113, 0, 121, + 0, 504, 128, 0, 0, 104, 0, 101, 37, 38, + 0, 21, 22, 0, 0, 27, 26, 0, 199, 30, + 32, 39, 0, 196, 0, 502, 0, 500, 495, 497, + 0, 92, 144, 142, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 75, 177, 178, 0, 173, - 92, 140, 138, 0, 0, 478, 0, 476, 471, 473, - 541, 540, 0, 532, 0, 544, 542, 0, 0, 0, - 525, 528, 0, 495, 0, 80, 81, 83, 82, 85, - 86, 87, 88, 89, 84, 79, 0, 0, 510, 506, - 508, 512, 519, 527, 123, 0, 483, 0, 127, 0, - 105, 16, 0, 23, 20, 31, 45, 46, 47, 50, - 49, 52, 53, 57, 58, 55, 56, 60, 61, 63, - 65, 67, 69, 71, 73, 0, 179, 469, 0, 479, - 0, 474, 0, 0, 0, 543, 0, 524, 0, 555, - 0, 553, 497, 78, 91, 122, 481, 0, 103, 18, - 0, 475, 477, 0, 535, 534, 537, 503, 520, 516, - 0, 0, 0, 0, 0, 0, 0, 482, 484, 0, - 0, 536, 0, 0, 515, 0, 0, 513, 0, 0, - 0, 0, 552, 554, 498, 76, 0, 538, 0, 503, - 502, 504, 522, 0, 500, 529, 499, 556, 0, 539, - 533, 514, 523, 0, 517, 531, 521 + 0, 0, 0, 0, 75, 191, 192, 0, 0, 521, + 0, 554, 567, 566, 0, 558, 0, 570, 568, 0, + 0, 0, 551, 520, 80, 81, 83, 82, 85, 86, + 87, 88, 89, 84, 79, 0, 0, 536, 532, 534, + 538, 545, 553, 123, 0, 507, 0, 127, 0, 105, + 4, 0, 23, 20, 31, 198, 0, 503, 0, 498, + 493, 45, 46, 47, 50, 49, 52, 53, 57, 58, + 55, 56, 60, 61, 63, 65, 67, 69, 71, 73, + 0, 193, 581, 0, 579, 523, 0, 0, 0, 0, + 569, 0, 550, 78, 91, 122, 505, 0, 103, 18, + 499, 501, 0, 0, 0, 0, 0, 542, 0, 0, + 0, 0, 561, 560, 563, 529, 546, 506, 508, 0, + 0, 578, 580, 524, 0, 0, 0, 562, 0, 0, + 541, 0, 0, 539, 0, 76, 582, 0, 526, 555, + 525, 0, 564, 0, 529, 528, 530, 548, 543, 0, + 565, 559, 540, 549, 0, 557, 547 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -634, -634, -634, -634, -634, -634, -634, -634, -634, -634, - -634, -634, -289, -634, -358, -355, -401, -364, -279, -307, - -276, -280, -273, -281, -634, -354, -634, -378, -634, -367, - -397, 1, -634, -634, -634, 2, -634, -634, -634, -98, - -93, -92, -634, -634, -600, -634, -634, -634, -634, -181, - -634, -319, -326, -634, 6, -634, 0, -332, -634, -54, - -634, -634, -634, -428, -433, -272, -353, -477, -634, -357, - -467, -633, -400, -634, -634, -410, -408, -634, -634, -80, - -545, -350, -634, -216, -634, -371, -634, -214, -634, -634, - -634, -634, -212, -634, -634, -634, -634, -634, -634, -634, - -634, -61, -634, -634, -634, -634, -375 + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + -453, -453, 8696, -453, -89, -88, -122, -84, -19, -18, + -17, -16, -20, -15, -453, -85, -453, -98, -453, -110, + -119, 2, -453, -453, -453, 4, -453, -453, -453, 189, + 191, 192, -453, -453, -339, -453, -453, -453, -453, 98, + -453, -37, -44, -453, 9, -453, 0, -71, -453, -453, + -453, -453, 261, -453, -453, -453, -452, -137, 20, -68, + -209, -453, -96, -198, -326, -453, -136, -453, -453, -146, + -144, -453, -453, 200, -265, -87, -453, 57, -453, -112, + -453, 59, -453, -453, -453, -453, 61, -453, -453, -453, + -453, -453, -453, -453, -453, 228, -453, -453, -453, -453, + -99 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 414, 415, 416, 592, 417, 418, 419, 420, 421, - 422, 423, 468, 425, 426, 427, 428, 429, 430, 431, - 432, 433, 434, 435, 436, 469, 615, 470, 576, 471, - 541, 472, 318, 498, 392, 473, 320, 321, 322, 352, - 353, 354, 323, 324, 325, 326, 327, 328, 372, 373, - 329, 330, 331, 332, 438, 369, 439, 365, 335, 336, - 337, 446, 375, 449, 450, 546, 547, 496, 587, 476, - 477, 478, 479, 564, 656, 685, 664, 665, 666, 686, - 480, 481, 482, 483, 667, 652, 484, 485, 668, 693, - 486, 487, 488, 628, 552, 623, 646, 662, 663, 489, - 338, 339, 340, 349, 490, 630, 631 + -1, 434, 435, 436, 621, 437, 438, 439, 440, 441, + 442, 443, 493, 445, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 494, 650, 495, 605, 496, + 552, 497, 337, 524, 413, 498, 339, 340, 341, 371, + 372, 373, 342, 343, 344, 345, 346, 347, 393, 394, + 348, 349, 350, 351, 446, 396, 447, 399, 384, 385, + 448, 354, 355, 356, 455, 389, 453, 454, 546, 547, + 522, 616, 501, 502, 503, 504, 505, 580, 676, 709, + 700, 701, 702, 710, 506, 507, 508, 509, 703, 680, + 510, 511, 704, 724, 512, 513, 514, 656, 584, 658, + 684, 698, 699, 515, 357, 358, 359, 368, 516, 653, + 654 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -1334,430 +1397,14 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 334, 317, 319, 355, 362, 455, 333, 456, 457, 495, - 437, 460, 370, 580, 378, 584, 549, 586, 543, 632, - 588, 346, 343, 523, 524, 534, 348, 388, 650, 362, - 505, 506, 355, 681, 386, 364, 364, 684, 521, 522, - 364, 504, 492, 387, 513, 684, 650, 341, 377, -34, - 440, 507, 491, 493, 440, 508, 447, 497, 525, 526, - 535, 344, 452, 342, 440, 357, 347, 441, 358, 350, - 589, 585, 444, 442, 389, 424, 510, 390, 445, 654, - 391, 591, 511, 655, 647, 622, 538, 577, 500, 540, - 577, 501, 557, 636, 559, 637, 565, 566, 567, 568, - 569, 570, 571, 572, 573, 574, 648, 519, 635, 520, - 549, 351, 577, 359, 495, 575, 495, 502, 503, 495, - 688, 362, 603, 604, 605, 606, 577, 447, 577, 620, - 447, 578, 621, 595, 368, 577, 515, 692, 625, 620, - 593, 364, 641, 313, 314, 315, 516, 517, 518, 527, - 528, 424, 577, 627, 424, 374, 549, 577, 659, 379, - 658, 599, 600, 607, 608, 580, 601, 602, 384, 385, - 440, 443, 499, 451, 509, 514, 529, 530, 531, 447, - 532, 533, 536, 539, 545, 553, 550, 624, 551, 554, - 555, 626, 560, 562, 558, 561, 590, -35, 633, 634, - -33, 563, 594, -28, 616, 629, 694, 495, 639, 643, - 653, 660, 669, 619, 670, 577, -501, 672, 678, 677, - 674, 679, 687, 610, 447, 580, 465, 596, 597, 598, - 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, - 424, 424, 424, 424, 424, 424, 682, 683, 640, 695, - 609, 696, 612, 614, 371, 611, 671, 382, 381, 495, - 613, 649, 345, 383, 542, 680, 644, 642, 690, 380, - 447, 691, 618, 645, 581, 661, 582, 367, 583, 649, - 673, 675, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 676, 0, 0, 0, 0, 0, 540, - 0, 0, 0, 463, 0, 495, 0, 0, 0, 651, - 689, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 356, 0, 0, 362, 0, 651, 333, 0, - 363, 0, 0, 0, 0, 0, 333, 0, 334, 317, - 319, 0, 0, 0, 333, 376, 0, 0, 0, 0, - 0, 356, 0, 0, 0, 356, 0, 333, 0, 0, - 0, 333, 0, 0, 424, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 448, 0, 0, 0, 475, - 0, 333, 0, 0, 0, 474, 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, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 448, 544, 0, 448, - 0, 0, 333, 333, 0, 333, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 475, 0, 0, 0, 0, 0, 474, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 448, 0, - 0, 0, 0, 0, 333, 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, 448, 0, 0, 0, 0, 0, 333, - 0, 0, 475, 0, 0, 0, 0, 0, 474, 0, - 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, - 474, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 448, - 0, 0, 0, 0, 0, 333, 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, 475, 0, 0, 0, 0, 475, 474, - 0, 0, 475, 0, 474, 0, 0, 0, 474, 0, - 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, - 0, 363, 474, 0, 0, 0, 0, 333, 0, 0, - 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, - 475, 0, 474, 0, 0, 0, 474, 0, 475, 0, - 0, 0, 475, 0, 474, 0, 0, 0, 474, 0, - 0, 0, 475, 0, 0, 0, 366, 0, 474, 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, 0, 0, - 309, 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, 310, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 311, 312, - 313, 314, 315, 316, 1, 2, 3, 4, 5, 6, + 353, 542, 336, 550, 338, 481, 457, 363, 484, 352, + 485, 486, 458, 543, 489, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 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, 463, 393, 309, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 0, 0, - 406, 407, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, - 0, 464, 0, 465, 466, 0, 0, 0, 0, 467, - 410, 411, 412, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 311, 312, 313, 314, 315, 316, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 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, 463, 393, - 309, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 0, 0, 406, 407, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 408, 0, 464, 0, 465, 579, - 0, 0, 0, 0, 467, 410, 411, 412, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 311, 312, - 313, 314, 315, 316, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 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, 463, 393, 309, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 0, 0, - 406, 407, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, - 0, 464, 0, 465, 0, 0, 0, 0, 0, 467, - 410, 411, 412, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 311, 312, 313, 314, 315, 316, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 453, 454, - 455, 0, 456, 457, 458, 459, 460, 461, 462, 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, 463, 393, - 309, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 0, 0, 406, 407, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 408, 0, 464, 0, 379, 0, - 0, 0, 0, 0, 467, 410, 411, 412, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 311, 312, - 313, 314, 315, 316, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 453, 454, 455, 0, 456, 457, 458, - 459, 460, 461, 462, 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, 463, 393, 309, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 0, 0, - 406, 407, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, - 0, 464, 0, 0, 0, 0, 0, 0, 0, 467, - 410, 411, 412, 413, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 311, 312, 313, 314, 315, 316, 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, 0, 393, - 309, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 0, 0, 406, 407, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 467, 410, 411, 412, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 311, 312, - 313, 314, 315, 316, 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, 0, 0, 309, 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, 310, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 311, 312, 313, 314, 315, 316, 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, 0, 393, - 309, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 403, 404, 405, 0, 0, 406, 407, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 410, 411, 412, 413, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 311, 312, - 313, 314, 315, 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, + 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, + 57, 58, 618, 364, 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, @@ -1780,994 +1427,53 @@ static const yytype_int16 yytable[] = 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, 0, 360, 309, 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, 361, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 311, 312, 313, 314, 315, 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, 0, 0, 309, 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, 548, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 311, 312, 313, 314, - 315, 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, - 0, 0, 309, 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, 617, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 311, 312, 313, 314, 315, 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, 0, 0, 309, 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, 638, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 311, 312, 313, 314, 315, 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, 0, 0, - 309, 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, 311, 312, - 313, 314, 315, 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, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 0, 0, 0, 0, 0, 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, 0, 393, 309, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 0, 0, 406, 407, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, - 0, 494, 657, 0, 0, 0, 0, 0, 410, 411, - 412, 413, 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, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 0, - 0, 0, 0, 0, 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, 0, - 393, 309, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 0, 0, 406, 407, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 408, 0, 0, 409, 0, - 0, 0, 0, 0, 0, 0, 410, 411, 412, 413, - 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, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 0, 0, 0, - 0, 0, 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, 0, 393, 309, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 404, 405, 0, 0, 406, 407, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 408, 0, 0, 0, 494, 0, 0, - 0, 0, 0, 0, 410, 411, 412, 413, 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, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 0, 0, 0, 0, 0, - 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, 0, 393, 309, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 0, 0, 406, 407, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 408, 0, 0, 537, 0, 0, 0, 0, 0, - 0, 0, 410, 411, 412, 413, 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, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 0, 0, 0, 0, 0, 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, 0, 393, 309, 394, 395, 396, 397, - 398, 399, 400, 401, 402, 403, 404, 405, 0, 0, - 406, 407, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 556, - 410, 411, 412, 413, 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, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 0, 0, 0, 0, 0, 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, 0, 393, 309, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 0, 0, 406, 407, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 410, 411, - 412, 413, 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, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 0, - 0, 0, 0, 0, 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, 512, 0, - 393, 309, 394, 395, 396, 397, 398, 399, 400, 401, - 402, 403, 404, 405, 0, 0, 406, 407, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 408, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 410, 411, 412, 413, - 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, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 0, 0, 0, - 0, 0, 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, 0, 0, 309 -}; - -static const yytype_int16 yycheck[] = -{ - 0, 0, 0, 322, 330, 24, 0, 26, 27, 387, - 364, 30, 81, 480, 346, 492, 449, 494, 446, 564, - 497, 323, 323, 341, 342, 346, 368, 359, 628, 355, - 339, 340, 351, 666, 358, 360, 360, 670, 337, 338, - 360, 408, 367, 367, 422, 678, 646, 358, 368, 358, - 360, 360, 384, 385, 360, 364, 375, 367, 376, 377, - 381, 362, 368, 358, 360, 365, 368, 359, 368, 359, - 498, 367, 359, 365, 362, 364, 359, 365, 365, 361, - 368, 359, 365, 365, 359, 552, 440, 365, 365, 443, - 365, 368, 459, 363, 461, 365, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 359, 370, 585, 372, - 543, 365, 365, 323, 492, 367, 494, 406, 407, 497, - 359, 447, 523, 524, 525, 526, 365, 446, 365, 365, - 449, 368, 368, 511, 323, 365, 425, 682, 368, 365, - 507, 360, 368, 384, 385, 386, 373, 374, 375, 343, - 344, 440, 365, 366, 443, 362, 589, 365, 366, 362, - 637, 519, 520, 527, 528, 632, 521, 522, 323, 323, - 360, 367, 323, 368, 359, 358, 380, 379, 378, 498, - 345, 347, 361, 323, 323, 358, 368, 554, 368, 358, - 368, 558, 366, 360, 358, 358, 323, 358, 576, 577, - 358, 363, 323, 359, 361, 323, 683, 585, 361, 322, - 358, 358, 323, 545, 359, 365, 362, 361, 359, 368, - 363, 25, 359, 530, 543, 692, 362, 516, 517, 518, - 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, - 529, 530, 531, 532, 533, 534, 362, 367, 615, 368, - 529, 363, 532, 534, 323, 531, 653, 355, 351, 637, - 533, 628, 316, 355, 445, 665, 623, 620, 678, 349, - 589, 679, 544, 623, 490, 646, 490, 338, 490, 646, - 655, 659, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 660, -1, -1, -1, -1, -1, 653, - -1, -1, -1, 322, -1, 683, -1, -1, -1, 628, - 677, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 322, -1, -1, 651, -1, 646, 322, -1, - 330, -1, -1, -1, -1, -1, 330, -1, 338, 338, - 338, -1, -1, -1, 338, 345, -1, -1, -1, -1, - -1, 351, -1, -1, -1, 355, -1, 351, -1, -1, - -1, 355, -1, -1, 653, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 375, -1, -1, -1, 379, - -1, 375, -1, -1, -1, 379, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 446, 447, -1, 449, - -1, -1, 446, 447, -1, 449, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 480, -1, -1, -1, -1, -1, 480, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 498, -1, - -1, -1, -1, -1, 498, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 543, -1, -1, -1, -1, -1, 543, - -1, -1, 552, -1, -1, -1, -1, -1, 552, -1, - -1, -1, -1, -1, 564, -1, -1, -1, -1, -1, - 564, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 589, - -1, -1, -1, -1, -1, 589, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 623, -1, -1, -1, -1, 628, 623, - -1, -1, 632, -1, 628, -1, -1, -1, 632, -1, - -1, -1, -1, -1, -1, -1, 646, -1, -1, -1, - -1, 651, 646, -1, -1, -1, -1, 651, -1, -1, - -1, -1, -1, -1, -1, -1, 666, -1, -1, -1, - 670, -1, 666, -1, -1, -1, 670, -1, 678, -1, - -1, -1, 682, -1, 678, -1, -1, -1, 682, -1, - -1, -1, 692, -1, -1, -1, 0, -1, 692, 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, -1, -1, - 324, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 368, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 382, 383, - 384, 385, 386, 387, 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, -1, -1, - 339, 340, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, - -1, 360, -1, 362, 363, -1, -1, -1, -1, 368, - 369, 370, 371, 372, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 382, 383, 384, 385, 386, 387, 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, -1, -1, 339, 340, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 358, -1, 360, -1, 362, 363, - -1, -1, -1, -1, 368, 369, 370, 371, 372, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 382, 383, - 384, 385, 386, 387, 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, -1, -1, - 339, 340, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, - -1, 360, -1, 362, -1, -1, -1, -1, -1, 368, - 369, 370, 371, 372, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 382, 383, 384, 385, 386, 387, 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, -1, -1, 339, 340, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 358, -1, 360, -1, 362, -1, - -1, -1, -1, -1, 368, 369, 370, 371, 372, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 382, 383, - 384, 385, 386, 387, 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, -1, -1, - 339, 340, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, - -1, 360, -1, -1, -1, -1, -1, -1, -1, 368, - 369, 370, 371, 372, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 382, 383, 384, 385, 386, 387, 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, -1, 323, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, -1, -1, 339, 340, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 358, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 368, 369, 370, 371, 372, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 382, 383, - 384, 385, 386, 387, 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, -1, -1, 324, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 382, 383, 384, 385, 386, 387, 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, -1, 323, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, -1, -1, 339, 340, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 358, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 369, 370, 371, 372, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 382, 383, - 384, 385, 386, 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, -1, 323, 324, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 368, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 382, 383, 384, 385, 386, 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, -1, -1, 324, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 363, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 382, 383, 384, 385, - 386, 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, - -1, -1, 324, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 363, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 382, 383, 384, 385, 386, 3, 4, 5, 6, 7, + 287, 288, 289, 290, 374, 381, 530, 409, 609, 613, + 521, 615, 474, 449, 617, 655, 549, 678, 562, 563, + 573, 365, 391, 397, 361, 560, 561, 407, 378, 397, + 381, 398, 475, 374, 517, 519, 408, 566, 567, 397, + 476, 375, 459, 392, 539, 678, 518, 366, 460, 382, + 352, 369, 451, 564, 565, 574, 362, 353, 352, 336, + 388, 338, 297, 531, 532, 475, 352, 302, 303, 708, + 375, 551, 523, 674, 375, 536, 716, 675, 589, 352, + 591, 537, -34, 352, 533, 475, 657, 708, 534, 452, + 577, 410, 614, 620, 411, 685, 686, 412, 352, 606, + 500, 606, 606, 376, 719, 665, 377, 381, 526, 499, + 606, 527, 606, 549, 628, 607, 451, 629, 451, 367, + 521, 606, 521, 622, 660, 521, 594, 595, 596, 597, + 598, 599, 600, 601, 602, 603, 293, 294, 295, 624, + 638, 639, 640, 641, 628, 604, 370, 670, 555, 556, + 557, 544, 723, 452, 558, 452, 559, 609, 688, 666, + 352, 667, 352, 383, 352, 606, 662, 606, 689, 634, + 635, 390, 636, 637, 627, 400, 659, 395, 397, 405, + 661, 549, 642, 643, 406, 450, 456, 451, 525, 535, + 540, 475, 545, 554, 568, 569, 571, 572, 718, 570, + 575, 578, 581, 579, 582, 583, 500, 663, 664, 592, + 585, 586, 590, 451, 587, 499, 521, 593, -35, -33, + 619, 623, -28, 651, 452, 609, 669, 652, 673, 606, + 681, 693, 691, 352, 695, 696, 694, 706, -527, 707, + 672, 712, 713, 478, 714, 726, 677, 717, 725, 644, + 452, 645, 648, 646, 690, 647, 553, 360, 649, 352, + 671, 402, 682, 403, 626, 715, 404, 721, 401, 521, + 722, 683, 697, 610, 677, 611, 692, 612, 0, 0, + 500, 451, 0, 0, 500, 387, 711, 0, 551, 499, + 0, 705, 0, 499, 0, 0, 0, 0, 0, 0, + 0, 0, 720, 0, 0, 0, 0, 0, 0, 521, + 0, 0, 0, 0, 0, 0, 0, 0, 452, 679, + 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, + 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 679, 0, 0, + 0, 0, 0, 0, 0, 500, 500, 0, 500, 0, + 0, 0, 0, 0, 499, 499, 0, 499, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 382, + 0, 0, 0, 0, 500, 0, 0, 0, 352, 0, + 0, 0, 0, 499, 0, 500, 0, 0, 0, 0, + 0, 0, 500, 0, 499, 0, 0, 0, 0, 0, + 0, 499, 0, 500, 0, 0, 0, 500, 0, 0, + 0, 0, 499, 500, 0, 0, 499, 0, 0, 0, + 386, 0, 499, 1, 2, 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, + 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, @@ -2793,19 +1499,103 @@ static const yytype_int16 yycheck[] = 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, -1, -1, 324, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 363, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 382, 383, 384, 385, 386, 3, + 288, 289, 290, 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, 291, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 292, 293, + 294, 295, 296, 0, 0, 0, 0, 0, 0, 0, + 0, 297, 298, 299, 300, 301, 302, 303, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, + 0, 0, 0, 0, 310, 0, 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, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 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, 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, 0, 0, 414, 415, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 416, 0, 477, 0, 478, 479, 0, 0, + 0, 0, 480, 417, 418, 419, 420, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 292, 293, 294, 295, + 296, 0, 0, 0, 421, 422, 423, 424, 425, 297, + 298, 299, 300, 301, 302, 303, 481, 482, 483, 484, + 0, 485, 486, 487, 488, 489, 490, 491, 304, 305, + 306, 307, 308, 309, 426, 427, 428, 429, 430, 431, + 432, 433, 310, 492, 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, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 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, 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, 0, + 0, 414, 415, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 416, 0, 477, 0, 478, 608, 0, 0, 0, 0, + 480, 417, 418, 419, 420, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 292, 293, 294, 295, 296, 0, + 0, 0, 421, 422, 423, 424, 425, 297, 298, 299, + 300, 301, 302, 303, 481, 482, 483, 484, 0, 485, + 486, 487, 488, 489, 490, 491, 304, 305, 306, 307, + 308, 309, 426, 427, 428, 429, 430, 431, 432, 433, + 310, 492, 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, 1, 2, 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, + 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, @@ -2831,135 +1621,438 @@ static const yytype_int16 yycheck[] = 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, -1, -1, - 324, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -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, 382, 383, - 384, 385, 386, 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, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, -1, -1, -1, -1, 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, + 284, 285, 286, 287, 288, 289, 290, 0, 0, 414, + 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, + 477, 0, 478, 0, 0, 0, 0, 0, 480, 417, + 418, 419, 420, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 292, 293, 294, 295, 296, 0, 0, 0, + 421, 422, 423, 424, 425, 297, 298, 299, 300, 301, + 302, 303, 481, 482, 483, 484, 0, 485, 486, 487, + 488, 489, 490, 491, 304, 305, 306, 307, 308, 309, + 426, 427, 428, 429, 430, 431, 432, 433, 310, 492, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, -1, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, -1, -1, 339, 340, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, - -1, 362, 363, -1, -1, -1, -1, -1, 369, 370, - 371, 372, 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, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - -1, -1, -1, -1, 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, -1, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 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, 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, 0, 0, 414, 415, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 416, 0, 477, 0, + 400, 0, 0, 0, 0, 0, 480, 417, 418, 419, + 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 292, 293, 294, 295, 296, 0, 0, 0, 421, 422, + 423, 424, 425, 297, 298, 299, 300, 301, 302, 303, + 481, 482, 483, 484, 0, 485, 486, 487, 488, 489, + 490, 491, 304, 305, 306, 307, 308, 309, 426, 427, + 428, 429, 430, 431, 432, 433, 310, 492, 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, -1, -1, 339, 340, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 358, -1, -1, 361, -1, - -1, -1, -1, -1, -1, -1, 369, 370, 371, 372, - 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, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, -1, -1, - -1, -1, 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, -1, 323, 324, + 333, 334, 335, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 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, + 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, 0, 0, 414, 415, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 416, 0, 477, 0, 0, 0, + 0, 0, 0, 0, 480, 417, 418, 419, 420, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 292, 293, + 294, 295, 296, 0, 0, 0, 421, 422, 423, 424, + 425, 297, 298, 299, 300, 301, 302, 303, 481, 482, + 483, 484, 0, 485, 486, 487, 488, 489, 490, 491, + 304, 305, 306, 307, 308, 309, 426, 427, 428, 429, + 430, 431, 432, 433, 310, 492, 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, -1, -1, 339, 340, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 358, -1, -1, -1, 362, -1, -1, - -1, -1, -1, -1, 369, 370, 371, 372, 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, + 335, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 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, 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, 0, 0, 414, 415, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 480, 417, 418, 419, 420, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 292, 293, 294, 295, + 296, 0, 0, 0, 421, 422, 423, 424, 425, 297, + 298, 299, 300, 301, 302, 303, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, + 306, 307, 308, 309, 426, 427, 428, 429, 430, 431, + 432, 433, 310, 0, 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, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 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, 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, 0, + 0, 414, 415, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 417, 418, 419, 420, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 292, 293, 294, 295, 0, 0, + 0, 0, 421, 422, 423, 424, 425, 297, 298, 299, + 300, 301, 302, 303, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 304, 305, 306, 307, + 308, 309, 426, 427, 428, 429, 430, 431, 432, 433, + 310, 0, 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, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 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, 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, 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, 291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 292, 293, 294, 295, 296, 0, 0, 0, + 0, 0, 0, 0, 0, 297, 298, 299, 300, 301, + 302, 303, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 304, 305, 306, 307, 308, 309, + 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, + 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, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 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, 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, 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, 379, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 292, 293, 294, 295, 0, 0, 0, 0, 0, 0, + 0, 0, 380, 297, 298, 299, 300, 301, 302, 303, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 304, 305, 306, 307, 308, 309, 0, 0, + 0, 0, 0, 0, 0, 0, 310, 0, 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, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 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, + 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, 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, 548, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 292, 293, + 294, 295, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 297, 298, 299, 300, 301, 302, 303, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 304, 305, 306, 307, 308, 309, 0, 0, 0, 0, + 0, 0, 0, 0, 310, 0, 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, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 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, 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, 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, 630, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 292, 293, 294, 295, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, + 298, 299, 300, 301, 302, 303, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, + 306, 307, 308, 309, 0, 0, 0, 0, 0, 0, + 0, 0, 310, 0, 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, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 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, 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, 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, 668, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 292, 293, 294, 295, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 297, 298, 299, + 300, 301, 302, 303, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 304, 305, 306, 307, + 308, 309, 0, 0, 0, 0, 0, 0, 0, 0, + 310, 0, 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, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 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, 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, 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, 292, 293, 294, 295, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 297, 298, 299, 300, 301, + 302, 303, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 304, 305, 306, 307, 308, 309, + 0, 0, 0, 0, 0, 0, 0, 0, 310, 0, + 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, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 82, -1, -1, -1, -1, - -1, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 57, 58, 0, 0, 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, -1, -1, -1, -1, -1, + 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, @@ -2977,26 +2070,287 @@ static const yytype_int16 yycheck[] = 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, -1, 323, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, - -1, -1, 339, 340, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 358, -1, -1, 361, -1, -1, -1, -1, -1, - -1, -1, 369, 370, 371, 372, 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, + 287, 288, 289, 290, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 0, 520, + 687, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, 0, 0, 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, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 461, 0, + 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, 0, 0, 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, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 0, 520, + 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, 0, 0, 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, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 576, 0, + 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, 0, 0, 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, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 588, 417, 418, 419, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, 0, 0, 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, 0, 0, 414, 415, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 303, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 318, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 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, 0, 0, 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, 0, 0, 414, 415, 0, 444, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 462, 0, 416, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 417, 418, 419, 420, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 421, 422, 423, + 424, 425, 297, 0, 0, 0, 0, 302, 538, 0, + 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 462, 0, 0, 0, 0, 426, 427, 428, + 429, 430, 431, 432, 433, 0, 0, 0, 0, 0, + 0, 462, 0, 0, 318, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 625, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 631, 632, 633, 462, 462, 462, 462, 462, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + 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, 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, 0, 0, 0, 462 +}; + +static const yytype_int16 yycheck[] = +{ + 0, 321, 0, 455, 0, 358, 315, 314, 361, 0, + 363, 364, 321, 333, 367, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 82, -1, -1, -1, -1, -1, 88, + 59, 60, 524, 314, 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, -1, -1, -1, -1, -1, 117, 118, + 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, @@ -3014,120 +2368,913 @@ static const yytype_int16 yycheck[] = 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, -1, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 334, 335, 336, -1, -1, - 339, 340, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 358, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 368, - 369, 370, 371, 372, 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, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, -1, -1, -1, -1, -1, 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, -1, 323, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, -1, -1, 339, 340, + 289, 290, 291, 292, 341, 349, 416, 378, 506, 518, + 408, 520, 397, 384, 523, 580, 453, 656, 297, 298, + 302, 324, 350, 316, 318, 293, 294, 314, 350, 316, + 374, 324, 316, 370, 405, 406, 323, 299, 300, 316, + 324, 341, 315, 371, 442, 684, 323, 350, 321, 349, + 341, 315, 389, 332, 333, 337, 350, 357, 349, 357, + 360, 357, 351, 295, 296, 316, 357, 356, 357, 695, + 370, 456, 323, 317, 374, 315, 702, 321, 488, 370, + 490, 321, 314, 374, 316, 316, 584, 713, 320, 389, + 475, 318, 323, 315, 321, 315, 315, 324, 389, 321, + 400, 321, 321, 321, 315, 614, 324, 451, 321, 400, + 321, 324, 321, 550, 321, 324, 453, 324, 455, 324, + 518, 321, 520, 533, 324, 523, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 339, 340, 341, 537, + 562, 563, 564, 565, 321, 323, 321, 324, 329, 330, + 331, 451, 717, 453, 326, 455, 328, 655, 667, 319, + 451, 321, 453, 332, 455, 321, 322, 321, 322, 558, + 559, 318, 560, 561, 545, 318, 586, 350, 316, 350, + 590, 618, 566, 567, 350, 324, 323, 524, 350, 315, + 314, 316, 350, 350, 336, 335, 301, 303, 707, 334, + 317, 316, 314, 319, 324, 324, 506, 605, 606, 322, + 314, 314, 314, 550, 324, 506, 614, 324, 314, 314, + 350, 350, 315, 317, 524, 723, 317, 350, 314, 321, + 358, 319, 317, 524, 315, 314, 350, 315, 318, 323, + 650, 324, 315, 318, 362, 319, 656, 318, 324, 568, + 550, 569, 572, 570, 673, 571, 458, 296, 573, 550, + 628, 370, 658, 374, 544, 701, 374, 713, 368, 667, + 714, 658, 684, 516, 684, 516, 675, 516, -1, -1, + 580, 618, -1, -1, 584, 357, 696, -1, 673, 580, + -1, 689, -1, 584, -1, -1, -1, -1, -1, -1, + -1, -1, 712, -1, -1, -1, -1, -1, -1, 707, + -1, -1, -1, -1, -1, -1, -1, -1, 618, 656, + -1, -1, -1, -1, -1, -1, -1, 618, -1, -1, + -1, -1, -1, -1, -1, 679, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 684, -1, -1, + -1, -1, -1, -1, -1, 655, 656, -1, 658, -1, + -1, -1, -1, -1, 655, 656, -1, 658, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 679, + -1, -1, -1, -1, 684, -1, -1, -1, 679, -1, + -1, -1, -1, 684, -1, 695, -1, -1, -1, -1, + -1, -1, 702, -1, 695, -1, -1, -1, -1, -1, + -1, 702, -1, 713, -1, -1, -1, 717, -1, -1, + -1, -1, 713, 723, -1, -1, 717, -1, -1, -1, + 0, -1, 723, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 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, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 358, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 369, 370, - 371, 372, 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, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, -1, - -1, -1, -1, -1, 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, -1, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, -1, -1, 339, 340, -1, -1, + -1, -1, -1, -1, 324, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 338, 339, + 340, 341, 342, -1, -1, -1, -1, -1, -1, -1, + -1, 351, 352, 353, 354, 355, 356, 357, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 358, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 369, 370, 371, 372, - 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, + 370, 371, 372, 373, 374, 375, -1, -1, -1, -1, + -1, -1, -1, -1, 384, -1, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 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, 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, -1, -1, 295, 296, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, -1, -1, -1, - -1, -1, 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, -1, -1, 324 + -1, -1, 314, -1, 316, -1, 318, 319, -1, -1, + -1, -1, 324, 325, 326, 327, 328, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 338, 339, 340, 341, + 342, -1, -1, -1, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + -1, 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, 408, 409, 410, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 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, 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, -1, + -1, 295, 296, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 314, -1, 316, -1, 318, 319, -1, -1, -1, -1, + 324, 325, 326, 327, 328, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 338, 339, 340, 341, 342, -1, + -1, -1, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, -1, 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, 408, 409, 410, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 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, 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, -1, -1, 295, + 296, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 314, -1, + 316, -1, 318, -1, -1, -1, -1, -1, 324, 325, + 326, 327, 328, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 338, 339, 340, 341, 342, -1, -1, -1, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, -1, 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, 408, 409, 410, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 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, + 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, -1, -1, 295, 296, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 314, -1, 316, -1, + 318, -1, -1, -1, -1, -1, 324, 325, 326, 327, + 328, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 338, 339, 340, 341, 342, -1, -1, -1, 346, 347, + 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, -1, 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, + 408, 409, 410, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 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, 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, -1, -1, 295, 296, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 314, -1, 316, -1, -1, -1, + -1, -1, -1, -1, 324, 325, 326, 327, 328, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 338, 339, + 340, 341, 342, -1, -1, -1, 346, 347, 348, 349, + 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, -1, 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, 408, 409, + 410, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 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, 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, -1, -1, 295, 296, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 314, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 324, 325, 326, 327, 328, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 338, 339, 340, 341, + 342, -1, -1, -1, 346, 347, 348, 349, 350, 351, + 352, 353, 354, 355, 356, 357, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, -1, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, 410, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 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, 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, -1, + -1, 295, 296, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 325, 326, 327, 328, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 338, 339, 340, 341, -1, -1, + -1, -1, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, -1, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 407, 408, 409, 410, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 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, 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, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 324, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 338, 339, 340, 341, 342, -1, -1, -1, + -1, -1, -1, -1, -1, 351, 352, 353, 354, 355, + 356, 357, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 370, 371, 372, 373, 374, 375, + -1, -1, -1, -1, -1, -1, -1, -1, 384, -1, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 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, + 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, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 324, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 338, 339, 340, 341, -1, -1, -1, -1, -1, -1, + -1, -1, 350, 351, 352, 353, 354, 355, 356, 357, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 370, 371, 372, 373, 374, 375, -1, -1, + -1, -1, -1, -1, -1, -1, 384, -1, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 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, 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, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 319, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 338, 339, + 340, 341, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 351, 352, 353, 354, 355, 356, 357, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 370, 371, 372, 373, 374, 375, -1, -1, -1, -1, + -1, -1, -1, -1, 384, -1, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 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, 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, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 319, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 338, 339, 340, 341, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 351, + 352, 353, 354, 355, 356, 357, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 370, 371, + 372, 373, 374, 375, -1, -1, -1, -1, -1, -1, + -1, -1, 384, -1, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, 404, 405, 406, 407, 408, 409, 410, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 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, 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, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 319, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 338, 339, 340, 341, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 351, 352, 353, + 354, 355, 356, 357, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 370, 371, 372, 373, + 374, 375, -1, -1, -1, -1, -1, -1, -1, -1, + 384, -1, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 407, 408, 409, 410, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 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, 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, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 338, 339, 340, 341, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 351, 352, 353, 354, 355, + 356, 357, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 370, 371, 372, 373, 374, 375, + -1, -1, -1, -1, -1, -1, -1, -1, 384, -1, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 314, -1, -1, -1, 318, + 319, -1, -1, -1, -1, -1, 325, 326, 327, 328, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 314, -1, -1, 317, -1, + -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 314, -1, -1, -1, 318, + -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 314, -1, -1, 317, -1, + -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 314, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 324, 325, 326, 327, 328, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 314, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 393, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 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, -1, -1, 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, -1, -1, 295, 296, -1, 383, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 397, -1, 314, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 325, 326, 327, 328, + 414, 415, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 346, 347, 348, + 349, 350, 351, -1, -1, -1, -1, 356, 357, -1, + -1, 445, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 456, -1, -1, -1, -1, 376, 377, 378, + 379, 380, 381, 382, 383, -1, -1, -1, -1, -1, + -1, 475, -1, -1, 393, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 542, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 555, 556, 557, 558, 559, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 673 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -3136,142 +3283,148 @@ 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, 324, - 368, 382, 383, 384, 385, 386, 387, 422, 423, 426, - 427, 428, 429, 433, 434, 435, 436, 437, 438, 441, - 442, 443, 444, 445, 447, 449, 450, 451, 491, 492, - 493, 358, 358, 323, 362, 450, 323, 368, 368, 494, - 359, 365, 430, 431, 432, 442, 447, 365, 368, 323, - 323, 368, 443, 447, 360, 448, 0, 492, 323, 446, - 81, 323, 439, 440, 362, 453, 447, 368, 448, 362, - 470, 431, 430, 432, 323, 323, 358, 367, 448, 362, - 365, 368, 425, 323, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 334, 335, 336, 339, 340, 358, 361, - 369, 370, 371, 372, 392, 393, 394, 396, 397, 398, - 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 445, 447, - 360, 359, 365, 367, 359, 365, 452, 442, 447, 454, - 455, 368, 368, 22, 23, 24, 26, 27, 28, 29, - 30, 31, 32, 322, 360, 362, 363, 368, 403, 416, - 418, 420, 422, 426, 445, 447, 460, 461, 462, 463, - 471, 472, 473, 474, 477, 478, 481, 482, 483, 490, - 495, 448, 367, 448, 362, 418, 458, 367, 424, 323, - 365, 368, 403, 403, 420, 339, 340, 360, 364, 359, - 359, 365, 321, 418, 358, 403, 373, 374, 375, 370, - 372, 337, 338, 341, 342, 376, 377, 343, 344, 380, - 379, 378, 345, 347, 346, 381, 361, 361, 416, 323, - 416, 421, 440, 454, 447, 323, 456, 457, 363, 455, - 368, 368, 485, 358, 358, 368, 368, 420, 358, 420, - 366, 358, 360, 363, 464, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 367, 419, 365, 368, 363, - 461, 474, 478, 483, 458, 367, 458, 459, 458, 454, - 323, 359, 395, 420, 323, 418, 403, 403, 403, 405, - 405, 406, 406, 407, 407, 407, 407, 408, 408, 409, - 410, 411, 412, 413, 414, 417, 361, 363, 456, 448, - 365, 368, 461, 486, 420, 368, 420, 366, 484, 323, - 496, 497, 471, 418, 418, 458, 363, 365, 363, 361, - 420, 368, 457, 322, 460, 472, 487, 359, 359, 420, - 435, 442, 476, 358, 361, 365, 465, 363, 458, 366, - 358, 476, 488, 489, 467, 468, 469, 475, 479, 323, - 359, 421, 361, 497, 363, 418, 420, 368, 359, 25, - 463, 462, 362, 367, 462, 466, 470, 359, 359, 420, - 466, 467, 471, 480, 458, 368, 363 + 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, 324, 338, 339, 340, 341, 342, 351, 352, 353, + 354, 355, 356, 357, 370, 371, 372, 373, 374, 375, + 384, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 442, 443, 446, 447, + 448, 449, 453, 454, 455, 456, 457, 458, 461, 462, + 463, 464, 465, 467, 472, 473, 474, 515, 516, 517, + 473, 318, 350, 314, 314, 324, 350, 324, 518, 315, + 321, 450, 451, 452, 462, 467, 321, 324, 350, 324, + 350, 463, 467, 332, 469, 470, 0, 516, 467, 476, + 318, 350, 371, 459, 460, 350, 466, 316, 324, 468, + 318, 494, 451, 450, 452, 350, 350, 314, 323, 468, + 318, 321, 324, 445, 295, 296, 314, 325, 326, 327, + 328, 346, 347, 348, 349, 350, 376, 377, 378, 379, + 380, 381, 382, 383, 412, 413, 414, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 465, 467, 471, 468, + 324, 462, 467, 477, 478, 475, 323, 315, 321, 315, + 321, 317, 423, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 316, 324, 316, 318, 319, + 324, 358, 359, 360, 361, 363, 364, 365, 366, 367, + 368, 369, 385, 423, 436, 438, 440, 442, 446, 465, + 467, 483, 484, 485, 486, 487, 495, 496, 497, 498, + 501, 502, 505, 506, 507, 514, 519, 468, 323, 468, + 318, 438, 481, 323, 444, 350, 321, 324, 423, 423, + 440, 295, 296, 316, 320, 315, 315, 321, 357, 438, + 314, 423, 321, 333, 467, 350, 479, 480, 319, 478, + 477, 436, 441, 460, 350, 329, 330, 331, 326, 328, + 293, 294, 297, 298, 332, 333, 299, 300, 336, 335, + 334, 301, 303, 302, 337, 317, 317, 436, 316, 319, + 488, 314, 324, 324, 509, 314, 314, 324, 324, 440, + 314, 440, 322, 324, 304, 305, 306, 307, 308, 309, + 310, 311, 312, 313, 323, 439, 321, 324, 319, 484, + 498, 502, 507, 481, 323, 481, 482, 481, 477, 350, + 315, 415, 440, 350, 438, 423, 479, 468, 321, 324, + 319, 423, 423, 423, 425, 425, 426, 426, 427, 427, + 427, 427, 428, 428, 429, 430, 431, 432, 433, 434, + 437, 317, 350, 520, 521, 495, 508, 484, 510, 440, + 324, 440, 322, 438, 438, 481, 319, 321, 319, 317, + 324, 480, 440, 314, 317, 321, 489, 440, 455, 462, + 500, 358, 483, 496, 511, 315, 315, 319, 481, 322, + 441, 317, 521, 319, 350, 315, 314, 500, 512, 513, + 491, 492, 493, 499, 503, 438, 315, 323, 485, 490, + 494, 440, 324, 315, 362, 487, 485, 318, 481, 315, + 440, 490, 491, 495, 504, 324, 319 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 391, 392, 393, 393, 393, 393, 393, 393, 393, - 393, 393, 393, 393, 393, 393, 393, 394, 394, 394, - 394, 394, 394, 395, 396, 397, 398, 398, 399, 399, - 400, 400, 401, 402, 402, 402, 403, 403, 403, 403, - 404, 404, 404, 404, 405, 405, 405, 405, 406, 406, - 406, 407, 407, 407, 408, 408, 408, 408, 408, 409, - 409, 409, 410, 410, 411, 411, 412, 412, 413, 413, - 414, 414, 415, 415, 416, 417, 416, 418, 418, 419, - 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 420, 420, 421, 422, 422, 422, 422, 422, 422, 422, - 422, 422, 424, 423, 425, 425, 426, 427, 427, 428, - 428, 429, 430, 430, 431, 431, 431, 431, 432, 433, - 433, 433, 433, 433, 434, 434, 434, 434, 434, 435, - 435, 436, 437, 437, 437, 437, 438, 439, 439, 440, - 440, 440, 441, 442, 442, 443, 443, 443, 443, 443, - 443, 443, 444, 444, 444, 444, 444, 444, 444, 444, - 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, - 444, 445, 446, 446, 447, 447, 448, 448, 448, 448, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 450, 450, 450, 452, 451, - 453, 451, 454, 454, 455, 455, 456, 456, 457, 457, - 458, 458, 458, 459, 459, 460, 461, 461, 462, 462, - 462, 462, 462, 462, 462, 463, 464, 465, 463, 466, - 466, 468, 467, 469, 467, 470, 470, 471, 471, 472, - 472, 473, 473, 474, 475, 475, 476, 476, 477, 477, - 479, 478, 480, 480, 481, 481, 482, 482, 484, 483, - 485, 483, 486, 483, 487, 487, 488, 488, 489, 489, - 490, 490, 490, 490, 490, 491, 491, 492, 492, 492, - 494, 493, 495, 496, 496, 497, 497 + 0, 411, 412, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 414, 414, 414, + 414, 414, 414, 415, 416, 417, 418, 418, 419, 419, + 420, 420, 421, 422, 422, 422, 423, 423, 423, 423, + 424, 424, 424, 424, 425, 425, 425, 425, 426, 426, + 426, 427, 427, 427, 428, 428, 428, 428, 428, 429, + 429, 429, 430, 430, 431, 431, 432, 432, 433, 433, + 434, 434, 435, 435, 436, 437, 436, 438, 438, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 440, 440, 441, 442, 442, 442, 442, 442, 442, 442, + 442, 442, 444, 443, 445, 445, 446, 447, 447, 448, + 448, 449, 450, 450, 451, 451, 451, 451, 452, 453, + 453, 453, 453, 453, 454, 454, 454, 454, 454, 455, + 455, 456, 457, 457, 457, 457, 457, 457, 457, 457, + 458, 459, 459, 460, 460, 460, 461, 462, 462, 463, + 463, 463, 463, 463, 463, 463, 464, 464, 464, 464, + 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, 464, 464, 464, 464, 465, 466, 466, 467, 467, + 468, 468, 468, 468, 469, 469, 470, 471, 471, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 473, + 473, 473, 475, 474, 476, 474, 477, 477, 478, 478, + 479, 479, 480, 480, 481, 481, 481, 482, 482, 483, + 484, 484, 485, 485, 485, 485, 485, 485, 485, 485, + 486, 487, 488, 489, 487, 490, 490, 492, 491, 493, + 491, 494, 494, 495, 495, 496, 496, 497, 497, 498, + 499, 499, 500, 500, 501, 501, 503, 502, 504, 504, + 505, 505, 506, 506, 508, 507, 509, 507, 510, 507, + 511, 511, 512, 512, 513, 513, 514, 514, 514, 514, + 514, 515, 515, 516, 516, 516, 518, 517, 519, 520, + 520, 521, 521 }; /* 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, + 0, 2, 1, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 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, @@ -3283,11 +3436,13 @@ static const yytype_uint8 yyr2[] = 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, + 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, - 4, 1, 1, 3, 1, 2, 2, 3, 3, 4, + 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, @@ -3316,16 +3471,17 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 + 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, 1, + 2, 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 }; @@ -3610,11 +3766,11 @@ 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 yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULL; + 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 @@ -3671,7 +3827,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, } yyarg[yycount++] = yytname[yyx]; { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; @@ -4008,250 +4164,252 @@ yyreduce: switch (yyn) { case 2: -#line 293 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 352 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); } -#line 4016 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4172 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 3: -#line 299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4024 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 4: -#line 302 "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 4033 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 5: -#line 306 "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 4042 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 6: -#line 310 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); - } -#line 4050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 7: -#line 313 "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 4059 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 8: -#line 317 "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 4068 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 9: -#line 321 "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 4077 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 10: -#line 325 "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 4086 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 11: -#line 329 "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 4095 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 12: -#line 333 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); - } -#line 4103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 13: -#line 336 "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); - } -#line 4112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 14: -#line 340 "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 4121 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 15: -#line 344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); - } -#line 4129 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 16: -#line 347 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } -#line 4139 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4190 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 5: +#line 366 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 4198 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 6: +#line 369 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 4206 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 7: +#line 372 "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 4215 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 8: +#line 376 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 4223 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 9: +#line 380 "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 4232 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 10: +#line 384 "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 4241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 11: +#line 388 "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 4250 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 12: +#line 392 "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 4259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 13: +#line 396 "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 4268 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 14: +#line 400 "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 4277 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 15: +#line 404 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double literal"); + if (! parseContext.symbolTable.atBuiltInLevel()) + 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 4286 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 16: +#line 408 "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 4295 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 17: -#line 355 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 18: -#line 358 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 419 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); } -#line 4155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 19: -#line 361 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 422 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4163 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4319 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 20: -#line 364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 425 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); } -#line 4171 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4327 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 21: -#line 367 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 428 "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)); } -#line 4181 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 22: -#line 372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 433 "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 4191 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4347 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 23: -#line 380 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 441 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4200 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4356 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 24: -#line 387 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 448 "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; } -#line 4209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 25: -#line 394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 455 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 4217 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4373 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 26: -#line 400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 461 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 4226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4382 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 27: -#line 404 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 4235 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 28: -#line 411 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); } -#line 4243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4399 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 29: -#line 414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 4251 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4407 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 30: -#line 420 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 481 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); @@ -4259,11 +4417,11 @@ yyreduce: (yyval.interm).function = (yyvsp[-1].interm).function; (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); } -#line 4263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4419 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 31: -#line 427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 488 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TParameter param = { 0, new TType }; param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); @@ -4271,29 +4429,29 @@ yyreduce: (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 4275 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4431 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 32: -#line 437 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-1].interm); } -#line 4283 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4439 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 33: -#line 445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 506 "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 4293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 34: -#line 450 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 511 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // Should be a method or subroutine call, but we haven't recognized the arguments yet. @@ -4317,54 +4475,54 @@ yyreduce: if ((yyval.interm).function == 0) { // error recover - TString empty(""); - (yyval.interm).function = new TFunction(&empty, TType(EbtVoid), EOpNull); + TString* empty = NewPoolTString(""); + (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); } } -#line 4325 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4481 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 35: -#line 477 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 539 "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 4335 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4491 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 36: -#line 485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 548 "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 4346 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4502 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 37: -#line 491 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 554 "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 4355 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 38: -#line 495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 558 "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 4364 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 39: -#line 499 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if ((yyvsp[-1].interm).op != EOpNull) { char errorOp[2] = {0, 0}; @@ -4381,318 +4539,320 @@ yyreduce: (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } } -#line 4385 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4541 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 40: -#line 519 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 582 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 4391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 41: -#line 520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 583 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 4397 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 42: -#line 521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 584 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 4403 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 43: -#line 522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 585 "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 4410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 44: -#line 528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 45: -#line 529 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 592 "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 4426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 46: -#line 534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 597 "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 4436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 47: -#line 539 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 602 "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 4447 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 48: -#line 548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4453 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 49: -#line 549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 612 "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 4463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 50: -#line 554 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 617 "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 4473 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4629 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 51: -#line 562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 625 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4635 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 52: -#line 563 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 626 "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 4490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4646 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 53: -#line 569 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 632 "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); } -#line 4501 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4657 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 54: -#line 578 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4663 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 55: -#line 579 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 642 "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 4517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4673 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 56: -#line 584 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 647 "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 4527 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4683 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 57: -#line 589 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 652 "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 4537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 58: -#line 594 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 657 "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 4547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 59: -#line 602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 665 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 60: -#line 603 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 666 "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 4566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4723 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 61: -#line 611 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 675 "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 4579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 62: -#line 622 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4585 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4743 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 63: -#line 623 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 688 "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 4596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4754 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 64: -#line 632 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 697 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4602 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4760 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 65: -#line 633 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 698 "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 4613 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 66: -#line 642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 67: -#line 643 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 708 "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); } -#line 4630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 68: -#line 652 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 717 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4794 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 69: -#line 653 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 718 "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); } -#line 4646 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4804 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 70: -#line 661 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 71: -#line 662 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 727 "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 4662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4820 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 72: -#line 670 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4668 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4826 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 73: -#line 671 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 736 "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 4678 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4836 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 74: -#line 679 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 744 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4684 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 75: -#line 680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 745 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.controlFlowNestingLevel; } -#line 4692 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4850 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 76: -#line 683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 748 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); @@ -4705,20 +4865,21 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 4709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4867 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 77: -#line 698 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4715 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4873 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 78: -#line 699 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 764 "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)); @@ -4728,119 +4889,119 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } } -#line 4732 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 79: -#line 714 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAssign; } -#line 4741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4900 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 80: -#line 718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 784 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpMulAssign; } -#line 4750 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4909 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 81: -#line 722 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpDivAssign; } -#line 4759 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 82: -#line 726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpModAssign; } -#line 4769 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4928 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 83: -#line 731 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 797 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAddAssign; } -#line 4778 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4937 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 84: -#line 735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpSubAssign; } -#line 4787 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 85: -#line 739 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 805 "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; } -#line 4796 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4955 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 86: -#line 743 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 809 "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; } -#line 4805 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4964 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 87: -#line 747 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 813 "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; } -#line 4814 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 88: -#line 751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 817 "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; } -#line 4823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 89: -#line 755 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 821 "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; } -#line 4832 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4991 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 90: -#line 762 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 828 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4840 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 4999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 91: -#line 765 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 831 "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); @@ -4849,117 +5010,116 @@ yyreduce: (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 4853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 92: -#line 776 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 842 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 4862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5021 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 93: -#line 783 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 849 "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 } -#line 4872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5031 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 94: -#line 788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 854 "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 4882 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5041 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 95: -#line 793 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 859 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 4895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5053 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 96: -#line 801 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); (yyval.interm.intermNode) = 0; } -#line 4904 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 97: -#line 805 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 870 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 4913 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5071 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 98: -#line 809 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 874 "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; } -#line 4922 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 99: -#line 813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 878 "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; } -#line 4932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 100: -#line 818 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 883 "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; } -#line 4942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 101: -#line 823 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 888 "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; } -#line 4953 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 102: -#line 832 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 4959 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5117 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 103: -#line 832 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.structNestingLevel; parseContext.blockName = (yyvsp[-4].lex).string; @@ -4969,54 +5129,54 @@ yyreduce: (yyval.interm).loc = (yyvsp[-5].interm.type).loc; (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 4973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5131 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 104: -#line 843 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 908 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.identifierList) = new TIdentifierList; (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 4982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5140 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 105: -#line 847 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 912 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 4991 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 106: -#line 854 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 919 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).function = (yyvsp[-1].interm.function); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 5000 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5158 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 107: -#line 861 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 926 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 108: -#line 864 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 929 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 5016 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5174 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 109: -#line 871 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 936 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); @@ -5025,11 +5185,11 @@ yyreduce: else delete (yyvsp[0].interm).param.type; } -#line 5029 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5187 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 110: -#line 879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 944 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // Only first parameter of one-parameter functions can be void @@ -5047,11 +5207,11 @@ yyreduce: (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); } } -#line 5051 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 111: -#line 899 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 964 "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", @@ -5071,11 +5231,11 @@ yyreduce: function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; } -#line 5075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 112: -#line 922 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 987 "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"); @@ -5091,11 +5251,11 @@ yyreduce: (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).param = param; } -#line 5095 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 113: -#line 937 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1002 "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"); @@ -5115,11 +5275,11 @@ yyreduce: (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).param = param; } -#line 5119 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5277 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 114: -#line 962 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1027 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -5131,11 +5291,11 @@ yyreduce: parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 5135 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 115: -#line 973 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1038 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); @@ -5143,11 +5303,11 @@ yyreduce: 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 5147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5305 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 116: -#line 983 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1048 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -5158,11 +5318,11 @@ yyreduce: 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 5162 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 117: -#line 993 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1058 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); @@ -5170,118 +5330,120 @@ yyreduce: 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 5174 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5332 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 118: -#line 1003 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1068 "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 5185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 119: -#line 1012 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[0].interm); } -#line 5193 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5351 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 120: -#line 1015 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1080 "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 5202 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5360 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 121: -#line 1019 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1084 "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 5211 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 122: -#line 1023 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1088 "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); } -#line 5221 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5379 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 123: -#line 1028 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1093 "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); } -#line 5231 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5389 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 124: -#line 1036 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1101 "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); + } -#line 5241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 125: -#line 1041 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1108 "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 5251 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5411 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 126: -#line 1046 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1113 "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); } -#line 5261 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5421 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 127: -#line 1051 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1118 "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); } -#line 5271 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5431 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 128: -#line 1056 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1123 "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 5281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 129: -#line 1065 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1132 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -5290,14 +5452,13 @@ yyreduce: 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 5297 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 130: -#line 1076 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1142 "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)); @@ -5322,22 +5483,22 @@ yyreduce: (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) (yyval.interm.type).qualifier.smooth = true; } -#line 5326 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 131: -#line 1103 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1169 "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 5337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 132: -#line 1112 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1178 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); @@ -5345,11 +5506,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.smooth = true; } -#line 5349 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 133: -#line 1119 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1185 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); @@ -5357,114 +5518,160 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.flat = true; } -#line 5361 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 134: -#line 1126 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 5377 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5532 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 135: -#line 1137 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1200 "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 } -#line 5391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5544 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 136: -#line 1149 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1207 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[-1].interm.type); + 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; } -#line 5399 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5557 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 137: -#line 1155 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1215 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); + // 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; } -#line 5407 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5572 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 138: -#line 1158 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1225 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // 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; + } +#line 5584 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 139: +#line 1232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // 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; + } +#line 5596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 140: +#line 1243 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[-1].interm.type); + } +#line 5604 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 141: +#line 1249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 142: +#line 1252 "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); } -#line 5417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5622 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 139: -#line 1165 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 143: +#line 1259 "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 5426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5631 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 140: -#line 1169 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 144: +#line 1263 "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)); } -#line 5435 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 141: -#line 1173 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 145: +#line 1267 "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 5445 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5650 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 142: -#line 1181 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 146: +#line 1276 "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; } -#line 5456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5661 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 143: -#line 1190 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 147: +#line 1286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5464 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 144: -#line 1193 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 148: +#line 1289 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[-1].interm.type); if ((yyval.interm.type).basicType == EbtVoid) @@ -5473,80 +5680,157 @@ yyreduce: (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 5477 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5682 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 145: -#line 1204 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 149: +#line 1300 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 146: -#line 1207 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 150: +#line 1303 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 5493 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 147: -#line 1210 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 151: +#line 1306 "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 5502 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 148: -#line 1214 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 149: -#line 1218 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 150: -#line 1222 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - // allow inheritance of storage qualifier from block declaration - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 151: -#line 1226 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type) = (yyvsp[0].interm.type); - } -#line 5537 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 152: -#line 1232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1310 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5716 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 153: +#line 1314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5725 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 154: +#line 1319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + // allow inheritance of storage qualifier from block declaration + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5734 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 155: +#line 1323 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type) = (yyvsp[0].interm.type); + } +#line 5742 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 156: +#line 1330 "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 } -#line 5546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5751 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 153: -#line 1236 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 157: +#line 1334 "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; + } +#line 5761 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 158: +#line 1339 "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; + } +#line 5772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 159: +#line 1345 "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; + } +#line 5783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 160: +#line 1351 "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; + } +#line 5795 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 161: +#line 1358 "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; + } +#line 5805 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 162: +#line 1363 "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, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqShared; + } +#line 5818 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 163: +#line 1371 "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; + } +#line 5828 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 164: +#line 1377 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); @@ -5559,11 +5843,11 @@ yyreduce: (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5845 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 154: -#line 1248 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 165: +#line 1389 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); @@ -5578,3325 +5862,3413 @@ yyreduce: else (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 5582 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 155: -#line 1262 "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; - } -#line 5592 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 156: -#line 1267 "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; - } -#line 5603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 157: -#line 1273 "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; - } -#line 5614 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 158: -#line 1279 "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; - } -#line 5626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 159: -#line 1286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 166: +#line 1403 "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; } -#line 5637 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 160: -#line 1292 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 167: +#line 1409 "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; } -#line 5647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 161: -#line 1297 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 168: +#line 1414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); + 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 = EvqUniform; + (yyval.interm.type).qualifier.storage = EvqHitAttrNV; } -#line 5657 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5898 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 162: -#line 1302 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 169: +#line 1422 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); + 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 = EvqBuffer; + (yyval.interm.type).qualifier.storage = EvqPayloadNV; } -#line 5667 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5911 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 163: -#line 1307 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 170: +#line 1430 "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"); + 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 = EvqShared; + (yyval.interm.type).qualifier.storage = EvqPayloadInNV; } -#line 5680 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 164: -#line 1315 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 171: +#line 1438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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; + } +#line 5937 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 172: +#line 1446 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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; + } +#line 5949 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 173: +#line 1453 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.coherent = true; } -#line 5689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 165: -#line 1319 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 174: +#line 1457 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (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 5968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 175: +#line 1462 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (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 5978 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 176: +#line 1467 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (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 5988 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 177: +#line 1472 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (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 5998 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 178: +#line 1477 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (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 6008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 179: +#line 1482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.volatil = true; } -#line 5698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 166: -#line 1323 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 180: +#line 1486 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.restrict = true; } -#line 5707 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6026 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 167: -#line 1327 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 181: +#line 1490 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.readonly = true; } -#line 5716 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6035 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 168: -#line 1331 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 182: +#line 1494 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.writeonly = true; } -#line 5725 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6044 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 169: -#line 1335 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 183: +#line 1498 "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); } -#line 5736 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6055 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 170: -#line 1341 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 184: +#line 1504 "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); } -#line 5747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 171: -#line 1350 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 185: +#line 1515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nonUniform = true; } -#line 5756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6075 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 172: -#line 1357 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 186: +#line 1522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // TODO } -#line 5764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 173: -#line 1360 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 187: +#line 1525 "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 } -#line 5774 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 174: -#line 1368 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 188: +#line 1534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type) = (yyvsp[0].interm.type); - (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); - } -#line 5783 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 175: -#line 1372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); (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; + (yyval.interm.type).typeParameters = (yyvsp[0].interm.typeParameters); } -#line 5794 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 176: -#line 1381 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 189: +#line 1539 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6115 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 190: +#line 1549 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).arraySizes = new TArraySizes; (yyval.interm).arraySizes->addInnerSize(); } -#line 5804 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6125 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 177: -#line 1386 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 191: +#line 1554 "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); + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 5817 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 178: -#line 1394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 192: +#line 1562 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm) = (yyvsp[-2].interm); (yyval.interm).arraySizes->addInnerSize(); } -#line 5826 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 179: -#line 1398 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 193: +#line 1566 "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); + parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 5838 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 180: -#line 1408 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 194: +#line 1576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); + } +#line 6167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 195: +#line 1579 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = 0; + } +#line 6175 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 196: +#line 1585 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); + } +#line 6183 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 197: +#line 1591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = new TArraySizes; + + TArraySize size; + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); + (yyval.interm.typeParameters)->addInnerSize(size); + } +#line 6195 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 198: +#line 1598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); + + TArraySize size; + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); + (yyval.interm.typeParameters)->addInnerSize(size); + } +#line 6207 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 199: +#line 1608 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtVoid; } -#line 5847 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 181: -#line 1412 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 200: +#line 1612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 5856 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 182: -#line 1416 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtDouble; - } -#line 5866 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 183: -#line 1421 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.float16Check((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 5876 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 184: -#line 1426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 5886 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 185: -#line 1431 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 5896 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 186: -#line 1436 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 201: +#line 1616 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 5905 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 187: -#line 1440 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 202: +#line 1620 "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; } -#line 5915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6244 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 188: -#line 1445 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 203: +#line 1625 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitInt8Check((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 = EbtBool; + } +#line 6253 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 204: +#line 1629 "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); + } +#line 6263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 205: +#line 1634 "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); + } +#line 6273 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 206: +#line 1639 "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); + } +#line 6283 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 207: +#line 1644 "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).setVector(2); + } +#line 6293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 208: +#line 1649 "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).setVector(3); + } +#line 6303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 209: +#line 1654 "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).setVector(4); + } +#line 6313 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 210: +#line 1659 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(2); + } +#line 6323 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 211: +#line 1664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(3); + } +#line 6333 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 212: +#line 1669 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).setVector(4); + } +#line 6343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 213: +#line 1674 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6354 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 214: +#line 1680 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6365 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 215: +#line 1686 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6376 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 216: +#line 1692 "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).setMatrix(2, 2); + } +#line 6386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 217: +#line 1697 "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).setMatrix(3, 3); + } +#line 6396 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 218: +#line 1702 "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).setMatrix(4, 4); + } +#line 6406 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 219: +#line 1707 "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).setMatrix(2, 2); + } +#line 6416 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 220: +#line 1712 "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).setMatrix(2, 3); + } +#line 6426 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 221: +#line 1717 "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).setMatrix(2, 4); + } +#line 6436 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 222: +#line 1722 "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).setMatrix(3, 2); + } +#line 6446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 223: +#line 1727 "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).setMatrix(3, 3); + } +#line 6456 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 224: +#line 1732 "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).setMatrix(3, 4); + } +#line 6466 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 225: +#line 1737 "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).setMatrix(4, 2); + } +#line 6476 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 226: +#line 1742 "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).setMatrix(4, 3); + } +#line 6486 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 227: +#line 1747 "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).setMatrix(4, 4); + } +#line 6496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 228: +#line 1753 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double"); + if (! parseContext.symbolTable.atBuiltInLevel()) + parseContext.doubleCheck((yyvsp[0].lex).loc, "double"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtDouble; + } +#line 6506 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 229: +#line 1758 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 230: +#line 1763 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 231: +#line 1768 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 232: +#line 1773 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 5925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 189: -#line 1450 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 233: +#line 1778 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitInt8Check((yyvsp[0].lex).loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + 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 5935 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 190: -#line 1455 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 234: +#line 1783 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); + 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 5945 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 191: -#line 1460 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 235: +#line 1788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); + 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 5955 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6576 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 192: -#line 1465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 236: +#line 1793 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 5965 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6586 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 193: -#line 1470 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 237: +#line 1798 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 5975 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6596 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 194: -#line 1475 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 238: +#line 1803 "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; } -#line 5985 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6606 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 195: -#line 1480 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 239: +#line 1808 "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; } -#line 5995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6616 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 196: -#line 1485 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 240: +#line 1813 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtBool; - } -#line 6004 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 197: -#line 1489 "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); - } -#line 6014 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 198: -#line 1494 "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); - } -#line 6024 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 199: -#line 1499 "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); - } -#line 6034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 200: -#line 1504 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + 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 6045 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6627 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 201: -#line 1510 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 241: +#line 1819 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + 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 6056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6638 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 202: -#line 1516 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 242: +#line 1825 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double vector"); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); + if (! parseContext.symbolTable.atBuiltInLevel()) + 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 6067 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 203: -#line 1522 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 243: +#line 1831 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + 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 6078 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6660 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 204: -#line 1528 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 244: +#line 1837 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + 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 6089 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6671 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 205: -#line 1534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 245: +#line 1843 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); + 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 6100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6682 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 206: -#line 1540 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 246: +#line 1849 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 6111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6693 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 207: -#line 1546 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 247: +#line 1855 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 6122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6704 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 208: -#line 1552 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 248: +#line 1861 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 6133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6715 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 209: -#line 1558 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 249: +#line 1867 "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(2); } -#line 6144 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6726 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 210: -#line 1564 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 250: +#line 1873 "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(3); } -#line 6155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6737 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 211: -#line 1570 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 251: +#line 1879 "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 6166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6748 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 212: -#line 1576 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 252: +#line 1885 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { + 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 = EbtBool; + (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(2); } -#line 6176 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6759 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 213: -#line 1581 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 253: +#line 1891 "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).setVector(3); - } -#line 6186 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 214: -#line 1586 "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).setVector(4); - } -#line 6196 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 215: -#line 1591 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(2); - } -#line 6206 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 216: -#line 1596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(3); - } -#line 6216 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 217: -#line 1601 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); - (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).setVector(4); - } -#line 6226 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 218: -#line 1606 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt8Check((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 6237 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 219: -#line 1612 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt8Check((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 6248 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 220: -#line 1618 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt8Check((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 6259 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 221: -#line 1624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((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 6270 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 222: -#line 1630 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((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 6281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 223: -#line 1636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((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 6292 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 224: -#line 1642 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6303 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 225: -#line 1648 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6314 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 226: -#line 1654 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6325 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 227: -#line 1660 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6336 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 228: -#line 1666 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6347 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 229: -#line 1672 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6358 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 230: -#line 1678 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6369 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 231: -#line 1684 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6380 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 232: -#line 1690 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - 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 6391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 233: -#line 1696 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt8Check((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 6402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 234: -#line 1702 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt8Check((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + 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 6413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6770 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 235: -#line 1708 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 254: +#line 1897 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.explicitInt8Check((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); + 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 6781 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 255: +#line 1903 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 256: +#line 1909 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6803 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 257: +#line 1915 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6814 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 258: +#line 1921 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6825 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 259: +#line 1927 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6836 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 260: +#line 1933 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6847 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 261: +#line 1939 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6858 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 262: +#line 1945 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6869 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 263: +#line 1951 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6880 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 264: +#line 1957 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 265: +#line 1963 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 266: +#line 1969 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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 6424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 236: -#line 1714 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((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 6435 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 237: -#line 1720 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((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 6446 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 238: -#line 1726 "MachineIndependent/glslang.y" /* yacc.c:1646 */ - { - parseContext.explicitInt16Check((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 6457 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 239: -#line 1732 "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 = EbtUint; - (yyval.interm.type).setVector(2); - } -#line 6468 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 240: -#line 1738 "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 = EbtUint; - (yyval.interm.type).setVector(3); - } -#line 6479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 241: -#line 1744 "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 = EbtUint; - (yyval.interm.type).setVector(4); - } -#line 6490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 242: -#line 1750 "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 = EbtUint64; - (yyval.interm.type).setVector(2); - } -#line 6501 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 243: -#line 1756 "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 = EbtUint64; - (yyval.interm.type).setVector(3); - } -#line 6512 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 244: -#line 1762 "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 = EbtUint64; - (yyval.interm.type).setVector(4); - } -#line 6523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 245: -#line 1768 "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).setMatrix(2, 2); - } -#line 6533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 246: -#line 1773 "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).setMatrix(3, 3); - } -#line 6543 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 247: -#line 1778 "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).setMatrix(4, 4); - } -#line 6553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 248: -#line 1783 "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).setMatrix(2, 2); - } -#line 6563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 249: -#line 1788 "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).setMatrix(2, 3); - } -#line 6573 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 250: -#line 1793 "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).setMatrix(2, 4); - } -#line 6583 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 251: -#line 1798 "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).setMatrix(3, 2); - } -#line 6593 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 252: -#line 1803 "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).setMatrix(3, 3); - } -#line 6603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 253: -#line 1808 "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).setMatrix(3, 4); - } -#line 6613 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 254: -#line 1813 "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).setMatrix(4, 2); - } -#line 6623 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 255: -#line 1818 "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).setMatrix(4, 3); - } -#line 6633 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 256: -#line 1823 "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).setMatrix(4, 4); - } -#line 6643 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 257: -#line 1828 "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 = EbtDouble; - (yyval.interm.type).setMatrix(2, 2); - } -#line 6654 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 258: -#line 1834 "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 = EbtDouble; - (yyval.interm.type).setMatrix(3, 3); - } -#line 6665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 259: -#line 1840 "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 = EbtDouble; - (yyval.interm.type).setMatrix(4, 4); - } -#line 6676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 260: -#line 1846 "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 = EbtDouble; - (yyval.interm.type).setMatrix(2, 2); - } -#line 6687 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 261: -#line 1852 "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 = EbtDouble; - (yyval.interm.type).setMatrix(2, 3); - } -#line 6698 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 262: -#line 1858 "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 = EbtDouble; - (yyval.interm.type).setMatrix(2, 4); - } -#line 6709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 263: -#line 1864 "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 = EbtDouble; - (yyval.interm.type).setMatrix(3, 2); - } -#line 6720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 264: -#line 1870 "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 = EbtDouble; - (yyval.interm.type).setMatrix(3, 3); - } -#line 6731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 265: -#line 1876 "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 = EbtDouble; - (yyval.interm.type).setMatrix(3, 4); - } -#line 6742 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 266: -#line 1882 "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 = EbtDouble; - (yyval.interm.type).setMatrix(4, 2); - } -#line 6753 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6913 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 267: -#line 1888 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1975 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + 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 = EbtDouble; - (yyval.interm.type).setMatrix(4, 3); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(2); } -#line 6764 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 268: -#line 1894 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1981 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.doubleCheck((yyvsp[0].lex).loc, "double matrix"); + 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 = EbtDouble; - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(3); } -#line 6775 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6935 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 269: -#line 1900 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + 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 = EbtFloat16; - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.type).basicType = EbtUint16; + (yyval.interm.type).setVector(4); } -#line 6786 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 270: -#line 1906 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1993 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + 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 = EbtFloat16; - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(2); } -#line 6797 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6957 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 271: -#line 1912 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1999 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + 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 = EbtFloat16; - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(3); } -#line 6808 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6968 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 272: -#line 1918 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2005 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + 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 = EbtFloat16; - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).setVector(4); } -#line 6819 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6979 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 273: -#line 1924 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2011 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", 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; - (yyval.interm.type).setMatrix(2, 3); + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(2); } -#line 6830 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 6990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 274: -#line 1930 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2017 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", 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; - (yyval.interm.type).setMatrix(2, 4); + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(3); } -#line 6841 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7001 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 275: -#line 1936 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2023 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", 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; - (yyval.interm.type).setMatrix(3, 2); + (yyval.interm.type).basicType = EbtUint64; + (yyval.interm.type).setVector(4); } -#line 6852 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 276: -#line 1942 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2029 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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).setMatrix(3, 3); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 2); } -#line 6863 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7023 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 277: -#line 1948 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2035 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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).setMatrix(3, 4); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(3, 3); } -#line 6874 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 278: -#line 1954 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2041 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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).setMatrix(4, 2); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); } -#line 6885 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7045 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 279: -#line 1960 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2047 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { - parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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).setMatrix(4, 3); + (yyval.interm.type).basicType = EbtDouble; + (yyval.interm.type).setMatrix(2, 2); } -#line 6896 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 280: -#line 1966 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2053 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(2, 3); + } +#line 7067 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 281: +#line 2059 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(2, 4); + } +#line 7078 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 282: +#line 2065 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(3, 2); + } +#line 7089 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 283: +#line 2071 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(3, 3); + } +#line 7100 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 284: +#line 2077 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(3, 4); + } +#line 7111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 285: +#line 2083 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(4, 2); + } +#line 7122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 286: +#line 2089 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(4, 3); + } +#line 7133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 287: +#line 2095 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); + if (! 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 = EbtDouble; + (yyval.interm.type).setMatrix(4, 4); + } +#line 7144 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 288: +#line 2101 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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); + } +#line 7155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 289: +#line 2107 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(3, 3); + } +#line 7166 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 290: +#line 2113 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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(4, 4); } -#line 6907 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 281: -#line 1972 "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 6918 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 282: -#line 1978 "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 6929 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 283: -#line 1984 "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 6940 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 284: -#line 1990 "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 6951 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 285: -#line 1996 "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 6962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 286: -#line 2002 "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 6973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 287: -#line 2008 "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 6984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 288: -#line 2014 "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 6995 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 289: -#line 2020 "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 7006 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 290: -#line 2026 "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 7017 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7177 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 291: -#line 2032 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2119 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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); + } +#line 7188 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 292: +#line 2125 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, 3); + } +#line 7199 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 293: +#line 2131 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, 4); + } +#line 7210 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 294: +#line 2137 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(3, 2); + } +#line 7221 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 295: +#line 2143 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(3, 3); + } +#line 7232 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 296: +#line 2149 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(3, 4); + } +#line 7243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 297: +#line 2155 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(4, 2); + } +#line 7254 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 298: +#line 2161 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(4, 3); + } +#line 7265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 299: +#line 2167 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(4, 4); + } +#line 7276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 300: +#line 2173 "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 7287 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 301: +#line 2179 "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 7298 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 302: +#line 2185 "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 7309 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 303: +#line 2191 "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 7320 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 304: +#line 2197 "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 7331 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 305: +#line 2203 "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 7342 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 306: +#line 2209 "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 7353 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 307: +#line 2215 "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 7364 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 308: +#line 2221 "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 7375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 309: +#line 2227 "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 7386 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 310: +#line 2233 "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 7028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7397 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 292: -#line 2038 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 311: +#line 2239 "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 7039 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7408 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 293: -#line 2044 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 312: +#line 2245 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7050 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7419 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 294: -#line 2050 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 313: +#line 2251 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7061 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7430 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 295: -#line 2056 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 314: +#line 2257 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7072 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 296: -#line 2062 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 315: +#line 2263 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7083 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7452 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 297: -#line 2068 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 316: +#line 2269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7094 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7463 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 298: -#line 2074 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 317: +#line 2275 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7105 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 299: -#line 2080 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 318: +#line 2281 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7116 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 300: -#line 2086 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 319: +#line 2287 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7127 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7496 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 301: -#line 2092 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 320: +#line 2293 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7138 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7507 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 302: -#line 2098 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 321: +#line 2299 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7518 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 303: -#line 2104 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 322: +#line 2305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7160 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 304: -#line 2110 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 323: +#line 2311 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { 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 7171 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 305: -#line 2116 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 324: +#line 2317 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtAccStructNV; + } +#line 7549 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 325: +#line 2321 "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 7181 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7559 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 306: -#line 2121 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 326: +#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); } -#line 7191 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 307: -#line 2126 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 327: +#line 2332 "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 7201 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7579 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 308: -#line 2131 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 328: +#line 2337 "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 7211 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7589 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 309: -#line 2136 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 329: +#line 2342 "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 7221 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 310: -#line 2141 "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 7231 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 311: -#line 2146 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 330: +#line 2347 "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 7241 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 312: -#line 2151 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 331: +#line 2352 "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 7251 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 313: -#line 2156 "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 7261 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 314: -#line 2161 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 332: +#line 2357 "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 7271 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7629 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 315: -#line 2166 "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 7281 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 316: -#line 2171 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 333: +#line 2362 "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 7291 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7639 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 317: -#line 2176 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 334: +#line 2368 "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 7649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 335: +#line 2373 "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 7659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 336: +#line 2378 "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 7669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 337: +#line 2383 "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 7301 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 318: -#line 2181 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 338: +#line 2388 "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); } -#line 7311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7689 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 319: -#line 2186 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 339: +#line 2393 "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(EbtFloat16, Esd1D); -#endif } -#line 7324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7700 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 320: -#line 2194 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 340: +#line 2399 "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(EbtFloat16, Esd2D); -#endif } -#line 7337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7711 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 321: -#line 2202 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 341: +#line 2405 "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(EbtFloat16, Esd3D); -#endif } -#line 7350 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7722 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 322: -#line 2210 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 342: +#line 2411 "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(EbtFloat16, EsdCube); -#endif } -#line 7363 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7733 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 323: -#line 2218 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 343: +#line 2417 "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(EbtFloat16, Esd1D, false, true); -#endif } -#line 7376 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7744 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 324: -#line 2226 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 344: +#line 2423 "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(EbtFloat16, Esd2D, false, true); -#endif } -#line 7389 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7755 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 325: -#line 2234 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 345: +#line 2429 "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(EbtFloat16, EsdCube, false, true); -#endif } -#line 7402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7766 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 326: -#line 2242 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 346: +#line 2435 "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(EbtFloat16, Esd1D, true); -#endif } -#line 7415 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7777 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 327: -#line 2250 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 347: +#line 2441 "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(EbtFloat16, Esd2D, true); -#endif } -#line 7428 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 328: -#line 2258 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 348: +#line 2447 "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(EbtFloat16, Esd1D, true, true); -#endif } -#line 7441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7799 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 329: -#line 2266 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 349: +#line 2453 "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(EbtFloat16, Esd2D, true, true); -#endif } -#line 7454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7810 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 330: -#line 2274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 350: +#line 2459 "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(EbtFloat16, EsdCube, true); -#endif } -#line 7467 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7821 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 331: -#line 2282 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 351: +#line 2465 "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(EbtFloat16, EsdCube, true, true); -#endif } -#line 7480 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7832 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 332: -#line 2290 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 352: +#line 2471 "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); } -#line 7490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 333: -#line 2295 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 353: +#line 2477 "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); } -#line 7500 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7852 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 334: -#line 2300 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 354: +#line 2482 "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); } -#line 7510 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 335: -#line 2305 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 355: +#line 2487 "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); } -#line 7520 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7872 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 336: -#line 2310 "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, true); - } -#line 7530 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 337: -#line 2315 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 356: +#line 2492 "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, true); } -#line 7540 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7882 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 338: -#line 2320 "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); - } -#line 7550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 339: -#line 2325 "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); - } -#line 7560 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 340: -#line 2330 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 357: +#line 2497 "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); } -#line 7570 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7892 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 341: -#line 2335 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 358: +#line 2502 "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, Esd3D); } -#line 7580 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7902 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 342: -#line 2340 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 359: +#line 2507 "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); } -#line 7590 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7912 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 343: -#line 2345 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 360: +#line 2513 "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, true); + } +#line 7922 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 361: +#line 2518 "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); + } +#line 7932 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 362: +#line 2523 "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); + } +#line 7942 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 363: +#line 2528 "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); } -#line 7600 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7952 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 344: -#line 2350 "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); - } -#line 7610 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 345: -#line 2355 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 364: +#line 2533 "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, true); } -#line 7620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 346: -#line 2360 "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); - } -#line 7630 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 347: -#line 2365 "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); - } -#line 7640 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 348: -#line 2370 "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(EbtFloat16, EsdRect); -#endif - } -#line 7653 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 349: -#line 2378 "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(EbtFloat16, EsdRect, false, true); -#endif - } -#line 7666 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 350: -#line 2386 "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); - } -#line 7676 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 351: -#line 2391 "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, EsdRect); - } -#line 7686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 352: -#line 2396 "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); - } -#line 7696 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 353: -#line 2401 "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(EbtFloat16, EsdBuffer); -#endif - } -#line 7709 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 354: -#line 2409 "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); - } -#line 7719 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 355: -#line 2414 "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); - } -#line 7729 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 356: -#line 2419 "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); - } -#line 7739 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 357: -#line 2424 "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(EbtFloat16, Esd2D, false, false, true); -#endif - } -#line 7752 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 358: -#line 2432 "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); - } -#line 7762 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 359: -#line 2437 "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, false, false, true); - } -#line 7772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 360: -#line 2442 "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); - } -#line 7782 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 361: -#line 2447 "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(EbtFloat16, Esd2D, true, false, true); -#endif - } -#line 7795 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 362: -#line 2455 "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, true, false, true); - } -#line 7805 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 363: -#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(EbtUint, Esd2D, true, false, true); - } -#line 7815 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 364: -#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.setPureSampler(false); - } -#line 7825 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7962 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 365: -#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.setPureSampler(true); - } -#line 7835 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 366: -#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.setTexture(EbtFloat, Esd1D); - } -#line 7845 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 367: -#line 2480 "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, Esd1D); -#endif - } -#line 7858 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 368: -#line 2488 "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); - } -#line 7868 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 369: -#line 2493 "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); -#endif - } -#line 7881 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 370: -#line 2501 "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, Esd3D); - } -#line 7891 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 371: -#line 2506 "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, Esd3D); -#endif - } -#line 7904 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 372: -#line 2514 "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); - } -#line 7914 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 373: -#line 2519 "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, EsdCube); -#endif - } -#line 7927 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 374: -#line 2527 "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, Esd1D, true); - } -#line 7937 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 375: -#line 2532 "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, Esd1D, true); -#endif - } -#line 7950 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 376: -#line 2540 "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); - } -#line 7960 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 377: -#line 2545 "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); -#endif - } -#line 7973 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 378: -#line 2553 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2538 "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, true); } -#line 7983 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7972 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 379: -#line 2558 "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, EsdCube, true); -#endif - } -#line 7996 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 380: -#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.setTexture(EbtInt, Esd1D); - } -#line 8006 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 381: -#line 2571 "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 8016 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 382: -#line 2576 "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 8026 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 383: -#line 2581 "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 8036 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 384: -#line 2586 "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 8046 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 385: -#line 2591 "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 8056 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 386: -#line 2596 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 366: +#line 2543 "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 8066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 387: -#line 2601 "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 8076 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 388: -#line 2606 "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 8086 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 389: -#line 2611 "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 8096 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 390: -#line 2616 "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 8106 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 391: -#line 2621 "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 8116 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 392: -#line 2626 "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 8126 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ - break; - - case 393: -#line 2631 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 367: +#line 2548 "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 8136 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 7992 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 368: +#line 2554 "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); + } +#line 8002 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 369: +#line 2559 "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); + } +#line 8012 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 370: +#line 2564 "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, Esd3D); + } +#line 8022 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 371: +#line 2569 "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); + } +#line 8032 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 372: +#line 2574 "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); + } +#line 8042 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 373: +#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.setTexture(EbtInt, Esd2D); + } +#line 8052 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 374: +#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.setTexture(EbtInt, Esd3D); + } +#line 8062 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 375: +#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.setTexture(EbtInt, EsdCube); + } +#line 8072 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 376: +#line 2594 "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 8082 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 377: +#line 2599 "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 8092 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 378: +#line 2604 "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 8102 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 379: +#line 2609 "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 8112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 380: +#line 2614 "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 8122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 381: +#line 2619 "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(false); + } +#line 8132 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 382: +#line 2624 "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); + } +#line 8142 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + 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(EbtFloat, EsdRect); + } +#line 8152 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + 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(EbtFloat, EsdRect, false, true); + } +#line 8162 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 385: +#line 2640 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(EbtFloat16, EsdRect); + } +#line 8173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 386: +#line 2646 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(EbtFloat16, EsdRect, false, true); + } +#line 8184 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 387: +#line 2652 "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); + } +#line 8194 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 388: +#line 2657 "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, EsdRect); + } +#line 8204 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 389: +#line 2662 "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); + } +#line 8214 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 390: +#line 2667 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(EbtFloat16, EsdBuffer); + } +#line 8225 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 391: +#line 2673 "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); + } +#line 8235 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 392: +#line 2678 "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); + } +#line 8245 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 393: +#line 2683 "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); + } +#line 8255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 394: -#line 2636 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 2688 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(EbtFloat16, Esd2D, false, false, true); + } +#line 8266 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 395: +#line 2694 "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); + } +#line 8276 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 396: +#line 2699 "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, false, false, true); + } +#line 8286 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 397: +#line 2704 "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); + } +#line 8296 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 398: +#line 2709 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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(EbtFloat16, Esd2D, true, false, true); + } +#line 8307 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 399: +#line 2715 "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, true, false, true); + } +#line 8317 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 400: +#line 2720 "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); + } +#line 8327 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 401: +#line 2725 "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, Esd1D); + } +#line 8337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 402: +#line 2730 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, Esd1D); + } +#line 8348 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 403: +#line 2736 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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); + } +#line 8359 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 404: +#line 2742 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, Esd3D); + } +#line 8370 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 405: +#line 2748 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, EsdCube); + } +#line 8381 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 406: +#line 2754 "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, Esd1D, true); + } +#line 8391 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 407: +#line 2759 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, Esd1D, true); + } +#line 8402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 408: +#line 2765 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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); + } +#line 8413 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 409: +#line 2771 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + 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, EsdCube, true); + } +#line 8424 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 410: +#line 2777 "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 8434 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 411: +#line 2782 "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 8444 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 412: +#line 2787 "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 8454 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 413: +#line 2792 "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 8464 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 414: +#line 2797 "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 8146 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8474 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 395: -#line 2641 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 415: +#line 2802 "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 8159 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8485 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 396: -#line 2649 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 416: +#line 2808 "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 8169 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8495 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 397: -#line 2654 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 417: +#line 2813 "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 8179 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8505 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 398: -#line 2659 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 418: +#line 2818 "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 8189 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8515 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 399: -#line 2664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 419: +#line 2823 "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 8202 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8526 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 400: -#line 2672 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 420: +#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(EbtInt, EsdBuffer); } -#line 8212 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8536 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 401: -#line 2677 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 421: +#line 2834 "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 8222 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 402: -#line 2682 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 422: +#line 2839 "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 8232 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 403: -#line 2687 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 423: +#line 2844 "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 8245 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8567 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 404: -#line 2695 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 424: +#line 2850 "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 8255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8577 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 405: -#line 2700 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 425: +#line 2855 "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 8265 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 406: -#line 2705 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 426: +#line 2860 "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 8275 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 407: -#line 2710 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 427: +#line 2865 "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 8288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8608 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 408: -#line 2718 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 428: +#line 2871 "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 8298 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8618 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 409: -#line 2723 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 429: +#line 2876 "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 8308 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8628 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 410: -#line 2728 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 430: +#line 2881 "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 8318 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8638 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 411: -#line 2733 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 431: +#line 2886 "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 8331 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8649 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 412: -#line 2741 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 432: +#line 2892 "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 8341 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8659 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 413: -#line 2746 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 433: +#line 2897 "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 8351 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8669 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 414: -#line 2751 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 434: +#line 2902 "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 8361 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8679 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 415: -#line 2756 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 435: +#line 2907 "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 8374 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8690 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 416: -#line 2764 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 436: +#line 2913 "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 8384 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8700 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 417: -#line 2769 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 437: +#line 2918 "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 8394 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8710 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 418: -#line 2774 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 438: +#line 2923 "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 8404 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 419: -#line 2779 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 439: +#line 2928 "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 8417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 420: -#line 2787 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 440: +#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, Esd3D); } -#line 8427 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8741 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 421: -#line 2792 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 441: +#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, Esd3D); } -#line 8437 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8751 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 422: -#line 2797 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 442: +#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, EsdRect); } -#line 8447 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8761 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 423: -#line 2802 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 443: +#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, EsdRect); -#endif } -#line 8460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8772 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 424: -#line 2810 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 444: +#line 2955 "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 8470 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8782 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 425: -#line 2815 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 445: +#line 2960 "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 8480 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 426: -#line 2820 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 446: +#line 2965 "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 8490 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8802 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 427: -#line 2825 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 447: +#line 2970 "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 8503 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8813 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 428: -#line 2833 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 448: +#line 2976 "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 8513 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 429: -#line 2838 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 449: +#line 2981 "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 8523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8833 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 430: -#line 2843 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 450: +#line 2986 "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 8533 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8843 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 431: -#line 2848 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 451: +#line 2991 "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, EsdBuffer); -#endif } -#line 8546 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8854 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 432: -#line 2856 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 452: +#line 2997 "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 8556 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 433: -#line 2861 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 453: +#line 3002 "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 8566 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8874 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 434: -#line 2866 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 454: +#line 3007 "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 8576 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8884 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 435: -#line 2871 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 455: +#line 3012 "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 8589 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8895 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 436: -#line 2879 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 456: +#line 3018 "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 8599 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8905 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 437: -#line 2884 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 457: +#line 3023 "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 8609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8915 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 438: -#line 2889 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 458: +#line 3028 "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 8619 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8925 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 439: -#line 2894 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 459: +#line 3033 "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 8632 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8936 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 440: -#line 2902 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 460: +#line 3039 "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 8642 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8946 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 441: -#line 2907 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 461: +#line 3044 "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 8652 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8956 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 442: -#line 2912 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 462: +#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(EbtFloat, EsdCube, true); } -#line 8662 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8966 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 443: -#line 2917 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 463: +#line 3054 "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 8675 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8977 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 444: -#line 2925 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 464: +#line 3060 "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 8685 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8987 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 445: -#line 2930 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 465: +#line 3065 "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 8695 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 8997 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 446: -#line 2935 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 466: +#line 3070 "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 8705 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 447: -#line 2940 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 467: +#line 3075 "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 8718 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 448: -#line 2948 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 468: +#line 3081 "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 8728 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 449: -#line 2953 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 469: +#line 3086 "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 8738 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9038 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 450: -#line 2958 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 470: +#line 3091 "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 8748 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 451: -#line 2963 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 471: +#line 3096 "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 8761 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9059 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 452: -#line 2971 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 472: +#line 3102 "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 8771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9069 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 453: -#line 2976 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 473: +#line 3107 "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 8781 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9079 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 454: -#line 2981 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 474: +#line 3112 "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 8792 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 455: -#line 2987 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 475: +#line 3118 "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 9101 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 476: +#line 3124 "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 8803 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 456: -#line 2993 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 477: +#line 3130 "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 8814 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9123 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 457: -#line 2999 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 478: +#line 3136 "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 8828 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9135 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 458: -#line 3008 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 479: +#line 3143 "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 8842 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9147 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 459: -#line 3017 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 480: +#line 3150 "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 8853 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9158 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 460: -#line 3023 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 481: +#line 3156 "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 8864 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9169 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 461: -#line 3029 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 482: +#line 3162 "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 8875 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9180 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 462: -#line 3035 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 483: +#line 3168 "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 8886 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9191 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 463: -#line 3041 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 484: +#line 3174 "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 9202 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 485: +#line 3180 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtInt; + (yyval.interm.type).coopmat = true; + } +#line 9213 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 486: +#line 3186 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtUint; + (yyval.interm.type).coopmat = true; + } +#line 9224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 487: +#line 3193 "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 8896 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9234 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 464: -#line 3046 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 488: +#line 3198 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // // This is for user defined type names. The lexical phase looked up the @@ -8910,47 +9282,47 @@ yyreduce: } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 8914 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9252 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 465: -#line 3062 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 489: +#line 3214 "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 8924 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9262 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 466: -#line 3067 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 490: +#line 3219 "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 8934 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9272 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 467: -#line 3072 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 491: +#line 3224 "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 8944 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9282 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 468: -#line 3080 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 492: +#line 3232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 8950 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9288 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 469: -#line 3080 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 493: +#line 3232 "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); @@ -8962,17 +9334,17 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 8966 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9304 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 470: -#line 3091 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 494: +#line 3243 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 8972 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9310 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 471: -#line 3091 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 495: +#line 3243 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); (yyval.interm.type).init((yyvsp[-4].lex).loc); @@ -8980,19 +9352,19 @@ yyreduce: (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 8984 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9322 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 472: -#line 3101 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 496: +#line 3253 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 8992 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9330 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 473: -#line 3104 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 497: +#line 3256 "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) { @@ -9003,16 +9375,16 @@ yyreduce: (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 9007 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9345 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 474: -#line 3117 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 498: +#line 3269 "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"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); } @@ -9030,16 +9402,16 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9034 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9372 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 475: -#line 3139 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 499: +#line 3291 "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"); - if (parseContext.profile == EEsProfile) + if (parseContext.isEsProfile()) parseContext.arraySizeRequiredCheck((yyvsp[-2].interm.type).loc, *(yyvsp[-2].interm.type).arraySizes); } @@ -9059,38 +9431,38 @@ yyreduce: (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 9063 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9401 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 476: -#line 3166 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 500: +#line 3318 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9072 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9410 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 477: -#line 3170 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 501: +#line 3322 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 9080 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9418 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 478: -#line 3176 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 502: +#line 3328 "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 9090 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9428 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 479: -#line 3181 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 503: +#line 3333 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); @@ -9099,219 +9471,235 @@ yyreduce: (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 9103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9441 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 480: -#line 3192 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 504: +#line 3344 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9111 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9449 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 481: -#line 3195 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 505: +#line 3348 "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 9122 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9460 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 482: -#line 3201 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 506: +#line 3354 "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 9133 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9471 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 483: -#line 3210 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 507: +#line 3365 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); } -#line 9141 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9479 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 484: -#line 3213 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 508: +#line 3368 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); } -#line 9149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9487 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 485: -#line 3219 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 509: +#line 3375 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9155 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9493 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 486: -#line 3223 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 510: +#line 3379 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9161 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9499 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 487: -#line 3224 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 511: +#line 3380 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9167 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9505 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 488: -#line 3230 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 512: +#line 3386 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9511 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 489: -#line 3231 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 513: +#line 3387 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9179 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9517 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 490: -#line 3232 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 514: +#line 3388 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9185 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9523 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 491: -#line 3233 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 515: +#line 3389 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9191 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 492: -#line 3234 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 516: +#line 3390 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9197 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9535 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 493: -#line 3235 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 517: +#line 3391 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9203 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9541 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 494: -#line 3236 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 518: +#line 3392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9209 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9547 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 495: -#line 3240 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 519: +#line 3394 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } +#line 9553 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 520: +#line 3400 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + { + parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "demote"); + parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); + (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDemote, (yyvsp[-1].lex).loc); + } +#line 9563 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ + break; + + case 521: +#line 3409 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9215 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9569 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 496: -#line 3241 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 522: +#line 3410 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 9224 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9578 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 497: -#line 3245 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 523: +#line 3414 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 9233 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 498: -#line 3249 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 524: +#line 3418 "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 9243 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9597 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 499: -#line 3257 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 525: +#line 3426 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9249 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9603 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 500: -#line 3258 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 526: +#line 3427 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9255 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9609 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 501: -#line 3262 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 527: +#line 3431 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.controlFlowNestingLevel; } -#line 9263 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9617 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 502: -#line 3265 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 528: +#line 3434 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9272 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9626 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 503: -#line 3269 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 529: +#line 3438 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9282 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 504: -#line 3274 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 530: +#line 3443 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9293 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9647 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 505: -#line 3283 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 531: +#line 3452 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9301 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9655 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 506: -#line 3286 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 532: +#line 3455 "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 9311 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9665 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 507: -#line 3294 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 533: +#line 3463 "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 || @@ -9320,11 +9708,11 @@ yyreduce: (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 9324 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9678 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 508: -#line 3302 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 534: +#line 3471 "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)) { @@ -9333,76 +9721,76 @@ yyreduce: } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 9337 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9691 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 509: -#line 3313 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 535: +#line 3482 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9343 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9697 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 510: -#line 3314 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 536: +#line 3483 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 9349 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 511: -#line 3318 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 537: +#line 3487 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9357 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9711 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 512: -#line 3321 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 538: +#line 3491 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9366 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9720 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 513: -#line 3327 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 539: +#line 3498 "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 9375 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9729 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 514: -#line 3334 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 540: +#line 3505 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); } -#line 9384 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9738 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 515: -#line 3338 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 541: +#line 3509 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 9393 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9747 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 516: -#line 3346 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 542: +#line 3517 "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 9402 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9756 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 517: -#line 3350 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 543: +#line 3521 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); @@ -9413,28 +9801,28 @@ yyreduce: else (yyval.interm.intermTypedNode) = 0; } -#line 9417 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9771 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 518: -#line 3363 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 544: +#line 3534 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9425 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9779 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 519: -#line 3366 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 545: +#line 3538 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9434 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9788 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 520: -#line 3372 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 546: +#line 3545 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; @@ -9443,11 +9831,11 @@ yyreduce: parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 9447 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9801 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 521: -#line 3380 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 547: +#line 3553 "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(); @@ -9457,27 +9845,27 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9461 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9815 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 522: -#line 3392 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 548: +#line 3565 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; } -#line 9469 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 523: -#line 3395 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 549: +#line 3568 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9477 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9831 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 524: -#line 3401 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 550: +#line 3574 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -9490,11 +9878,11 @@ yyreduce: (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 9494 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9848 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 525: -#line 3413 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 551: +#line 3586 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -9504,28 +9892,28 @@ yyreduce: else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 9508 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9862 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 526: -#line 3425 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 552: +#line 3598 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9516 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9870 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 527: -#line 3428 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 553: +#line 3602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9525 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9879 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 528: -#line 3434 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 554: +#line 3609 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); @@ -9534,11 +9922,11 @@ yyreduce: ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9538 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9892 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 529: -#line 3442 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 555: +#line 3617 "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); @@ -9546,21 +9934,21 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9550 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9904 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 530: -#line 3449 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 556: +#line 3624 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9560 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9914 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 531: -#line 3454 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 557: +#line 3629 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -9572,22 +9960,22 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9576 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9930 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 532: -#line 3465 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 558: +#line 3640 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 9587 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9941 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 533: -#line 3471 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 559: +#line 3646 "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); @@ -9600,81 +9988,81 @@ yyreduce: --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 9604 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9958 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 534: -#line 3486 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 560: +#line 3661 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9612 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9966 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 535: -#line 3489 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 561: +#line 3664 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9620 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9974 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 536: -#line 3495 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 562: +#line 3670 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 9628 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9982 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 537: -#line 3498 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 563: +#line 3673 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermTypedNode) = 0; } -#line 9636 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9990 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 538: -#line 3504 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 564: +#line 3679 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 9645 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 9999 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 539: -#line 3508 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 565: +#line 3683 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); } -#line 9654 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10008 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 540: -#line 3515 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 566: +#line 3690 "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 9664 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10018 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 541: -#line 3520 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 567: +#line 3695 "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 9674 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10028 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 542: -#line 3525 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 568: +#line 3700 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) @@ -9682,83 +10070,83 @@ yyreduce: if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 9686 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10040 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 543: -#line 3532 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 569: +#line 3707 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 9694 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10048 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 544: -#line 3535 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 570: +#line 3710 "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 9703 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10057 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 545: -#line 3544 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 571: +#line 3719 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 9712 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10066 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 546: -#line 3548 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 572: +#line 3723 "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 9723 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10077 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 547: -#line 3557 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 573: +#line 3732 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9731 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10085 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 548: -#line 3560 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 574: +#line 3735 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 9739 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10093 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 549: -#line 3563 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 575: +#line 3739 "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 9749 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10103 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 550: -#line 3571 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 576: +#line 3748 "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 9758 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10112 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 551: -#line 3575 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 577: +#line 3752 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) @@ -9774,52 +10162,52 @@ yyreduce: (yyval.interm.intermNode)->getAsAggregate()->setDebug(parseContext.contextPragma.debug); (yyval.interm.intermNode)->getAsAggregate()->setPragmaTable(parseContext.contextPragma.pragmaTable); } -#line 9778 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10132 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 552: -#line 3593 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 578: +#line 3771 "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 9787 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10141 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 553: -#line 3599 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 579: +#line 3777 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = (yyvsp[0].interm.attributes); } -#line 9795 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10149 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 554: -#line 3602 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 580: +#line 3780 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); } -#line 9803 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10157 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 555: -#line 3607 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 581: +#line 3785 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); } -#line 9811 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10165 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; - case 556: -#line 3610 "MachineIndependent/glslang.y" /* yacc.c:1646 */ + case 582: +#line 3788 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); } -#line 9819 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10173 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; -#line 9823 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 10177 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -10047,5 +10435,5 @@ yyreturn: #endif return yyresult; } -#line 3614 "MachineIndependent/glslang.y" /* yacc.c:1906 */ +#line 3793 "MachineIndependent/glslang.y" /* yacc.c:1906 */ diff --git a/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp.h b/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp.h index 7cfb79766f..f4f4114730 100644 --- a/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp.h +++ b/Externals/glslang/glslang/MachineIndependent/glslang_tab.cpp.h @@ -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 @@ -45,403 +45,423 @@ extern int yydebug; # define YYTOKENTYPE enum yytokentype { - ATTRIBUTE = 258, - VARYING = 259, - FLOAT16_T = 260, - FLOAT = 261, - FLOAT32_T = 262, - DOUBLE = 263, - 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, - COHERENT = 338, - VOLATILE = 339, - RESTRICT = 340, - READONLY = 341, - WRITEONLY = 342, - DVEC2 = 343, - DVEC3 = 344, - DVEC4 = 345, - DMAT2 = 346, - DMAT3 = 347, - DMAT4 = 348, - F16VEC2 = 349, - F16VEC3 = 350, - F16VEC4 = 351, - F16MAT2 = 352, - F16MAT3 = 353, - F16MAT4 = 354, - F32VEC2 = 355, - F32VEC3 = 356, - F32VEC4 = 357, - F32MAT2 = 358, - F32MAT3 = 359, - F32MAT4 = 360, - F64VEC2 = 361, - F64VEC3 = 362, - F64VEC4 = 363, - F64MAT2 = 364, - F64MAT3 = 365, - F64MAT4 = 366, - NOPERSPECTIVE = 367, - FLAT = 368, - SMOOTH = 369, - LAYOUT = 370, - __EXPLICITINTERPAMD = 371, - MAT2X2 = 372, - MAT2X3 = 373, - MAT2X4 = 374, - MAT3X2 = 375, - MAT3X3 = 376, - MAT3X4 = 377, - MAT4X2 = 378, - MAT4X3 = 379, - MAT4X4 = 380, - DMAT2X2 = 381, - DMAT2X3 = 382, - DMAT2X4 = 383, - DMAT3X2 = 384, - DMAT3X3 = 385, - DMAT3X4 = 386, - DMAT4X2 = 387, - DMAT4X3 = 388, - DMAT4X4 = 389, - F16MAT2X2 = 390, - F16MAT2X3 = 391, - F16MAT2X4 = 392, - F16MAT3X2 = 393, - F16MAT3X3 = 394, - F16MAT3X4 = 395, - F16MAT4X2 = 396, - F16MAT4X3 = 397, - F16MAT4X4 = 398, - F32MAT2X2 = 399, - F32MAT2X3 = 400, - F32MAT2X4 = 401, - F32MAT3X2 = 402, - F32MAT3X3 = 403, - F32MAT3X4 = 404, - F32MAT4X2 = 405, - F32MAT4X3 = 406, - F32MAT4X4 = 407, - F64MAT2X2 = 408, - F64MAT2X3 = 409, - F64MAT2X4 = 410, - F64MAT3X2 = 411, - F64MAT3X3 = 412, - F64MAT3X4 = 413, - F64MAT4X2 = 414, - F64MAT4X3 = 415, - F64MAT4X4 = 416, - ATOMIC_UINT = 417, - SAMPLER1D = 418, - SAMPLER2D = 419, - SAMPLER3D = 420, - SAMPLERCUBE = 421, - SAMPLER1DSHADOW = 422, - SAMPLER2DSHADOW = 423, - SAMPLERCUBESHADOW = 424, - SAMPLER1DARRAY = 425, - SAMPLER2DARRAY = 426, - SAMPLER1DARRAYSHADOW = 427, - SAMPLER2DARRAYSHADOW = 428, - ISAMPLER1D = 429, - ISAMPLER2D = 430, - ISAMPLER3D = 431, - ISAMPLERCUBE = 432, - ISAMPLER1DARRAY = 433, - ISAMPLER2DARRAY = 434, - USAMPLER1D = 435, - USAMPLER2D = 436, - USAMPLER3D = 437, - USAMPLERCUBE = 438, - USAMPLER1DARRAY = 439, - USAMPLER2DARRAY = 440, - SAMPLER2DRECT = 441, - SAMPLER2DRECTSHADOW = 442, - ISAMPLER2DRECT = 443, - USAMPLER2DRECT = 444, - SAMPLERBUFFER = 445, - ISAMPLERBUFFER = 446, - USAMPLERBUFFER = 447, - SAMPLERCUBEARRAY = 448, - SAMPLERCUBEARRAYSHADOW = 449, - ISAMPLERCUBEARRAY = 450, - USAMPLERCUBEARRAY = 451, - SAMPLER2DMS = 452, - ISAMPLER2DMS = 453, - USAMPLER2DMS = 454, - SAMPLER2DMSARRAY = 455, - ISAMPLER2DMSARRAY = 456, - USAMPLER2DMSARRAY = 457, - SAMPLEREXTERNALOES = 458, - F16SAMPLER1D = 459, - F16SAMPLER2D = 460, - F16SAMPLER3D = 461, - F16SAMPLER2DRECT = 462, - F16SAMPLERCUBE = 463, - F16SAMPLER1DARRAY = 464, - F16SAMPLER2DARRAY = 465, - F16SAMPLERCUBEARRAY = 466, - F16SAMPLERBUFFER = 467, - F16SAMPLER2DMS = 468, - F16SAMPLER2DMSARRAY = 469, - F16SAMPLER1DSHADOW = 470, - F16SAMPLER2DSHADOW = 471, - F16SAMPLER1DARRAYSHADOW = 472, - F16SAMPLER2DARRAYSHADOW = 473, - F16SAMPLER2DRECTSHADOW = 474, - F16SAMPLERCUBESHADOW = 475, - F16SAMPLERCUBEARRAYSHADOW = 476, - SAMPLER = 477, - SAMPLERSHADOW = 478, - TEXTURE1D = 479, - TEXTURE2D = 480, - TEXTURE3D = 481, - TEXTURECUBE = 482, - TEXTURE1DARRAY = 483, - TEXTURE2DARRAY = 484, - ITEXTURE1D = 485, - ITEXTURE2D = 486, - ITEXTURE3D = 487, - ITEXTURECUBE = 488, - ITEXTURE1DARRAY = 489, - ITEXTURE2DARRAY = 490, - UTEXTURE1D = 491, - UTEXTURE2D = 492, - UTEXTURE3D = 493, - UTEXTURECUBE = 494, - UTEXTURE1DARRAY = 495, - UTEXTURE2DARRAY = 496, - TEXTURE2DRECT = 497, - ITEXTURE2DRECT = 498, - UTEXTURE2DRECT = 499, - TEXTUREBUFFER = 500, - ITEXTUREBUFFER = 501, - UTEXTUREBUFFER = 502, - TEXTURECUBEARRAY = 503, - ITEXTURECUBEARRAY = 504, - UTEXTURECUBEARRAY = 505, - TEXTURE2DMS = 506, - ITEXTURE2DMS = 507, - UTEXTURE2DMS = 508, - TEXTURE2DMSARRAY = 509, - ITEXTURE2DMSARRAY = 510, - UTEXTURE2DMSARRAY = 511, - F16TEXTURE1D = 512, - F16TEXTURE2D = 513, - F16TEXTURE3D = 514, - F16TEXTURE2DRECT = 515, - F16TEXTURECUBE = 516, - F16TEXTURE1DARRAY = 517, - F16TEXTURE2DARRAY = 518, - F16TEXTURECUBEARRAY = 519, - F16TEXTUREBUFFER = 520, - F16TEXTURE2DMS = 521, - F16TEXTURE2DMSARRAY = 522, - SUBPASSINPUT = 523, - SUBPASSINPUTMS = 524, - ISUBPASSINPUT = 525, - ISUBPASSINPUTMS = 526, - USUBPASSINPUT = 527, - USUBPASSINPUTMS = 528, - F16SUBPASSINPUT = 529, - F16SUBPASSINPUTMS = 530, - IMAGE1D = 531, - IIMAGE1D = 532, - UIMAGE1D = 533, - IMAGE2D = 534, - IIMAGE2D = 535, - UIMAGE2D = 536, - IMAGE3D = 537, - IIMAGE3D = 538, - UIMAGE3D = 539, - IMAGE2DRECT = 540, - IIMAGE2DRECT = 541, - UIMAGE2DRECT = 542, - IMAGECUBE = 543, - IIMAGECUBE = 544, - UIMAGECUBE = 545, - IMAGEBUFFER = 546, - IIMAGEBUFFER = 547, - UIMAGEBUFFER = 548, - IMAGE1DARRAY = 549, - IIMAGE1DARRAY = 550, - UIMAGE1DARRAY = 551, - IMAGE2DARRAY = 552, - IIMAGE2DARRAY = 553, - UIMAGE2DARRAY = 554, - IMAGECUBEARRAY = 555, - IIMAGECUBEARRAY = 556, - UIMAGECUBEARRAY = 557, - IMAGE2DMS = 558, - IIMAGE2DMS = 559, - UIMAGE2DMS = 560, - IMAGE2DMSARRAY = 561, - IIMAGE2DMSARRAY = 562, - UIMAGE2DMSARRAY = 563, - F16IMAGE1D = 564, - F16IMAGE2D = 565, - F16IMAGE3D = 566, - F16IMAGE2DRECT = 567, - F16IMAGECUBE = 568, - F16IMAGE1DARRAY = 569, - F16IMAGE2DARRAY = 570, - F16IMAGECUBEARRAY = 571, - F16IMAGEBUFFER = 572, - F16IMAGE2DMS = 573, - F16IMAGE2DMSARRAY = 574, - STRUCT = 575, - VOID = 576, - WHILE = 577, - IDENTIFIER = 578, - TYPE_NAME = 579, - FLOATCONSTANT = 580, - DOUBLECONSTANT = 581, - INT16CONSTANT = 582, - UINT16CONSTANT = 583, - INT32CONSTANT = 584, - UINT32CONSTANT = 585, - INTCONSTANT = 586, - UINTCONSTANT = 587, - INT64CONSTANT = 588, - UINT64CONSTANT = 589, - BOOLCONSTANT = 590, - FLOAT16CONSTANT = 591, - LEFT_OP = 592, - RIGHT_OP = 593, - INC_OP = 594, - DEC_OP = 595, - LE_OP = 596, - GE_OP = 597, - EQ_OP = 598, - NE_OP = 599, - AND_OP = 600, - OR_OP = 601, - XOR_OP = 602, - MUL_ASSIGN = 603, - DIV_ASSIGN = 604, - ADD_ASSIGN = 605, - MOD_ASSIGN = 606, - LEFT_ASSIGN = 607, - RIGHT_ASSIGN = 608, - AND_ASSIGN = 609, - XOR_ASSIGN = 610, - OR_ASSIGN = 611, - SUB_ASSIGN = 612, - LEFT_PAREN = 613, - RIGHT_PAREN = 614, - LEFT_BRACKET = 615, - RIGHT_BRACKET = 616, - LEFT_BRACE = 617, - RIGHT_BRACE = 618, - DOT = 619, - COMMA = 620, - COLON = 621, - EQUAL = 622, - SEMICOLON = 623, - BANG = 624, - DASH = 625, - TILDE = 626, - PLUS = 627, - STAR = 628, - SLASH = 629, - PERCENT = 630, - LEFT_ANGLE = 631, - RIGHT_ANGLE = 632, - VERTICAL_BAR = 633, - CARET = 634, - AMPERSAND = 635, - QUESTION = 636, - INVARIANT = 637, - PRECISE = 638, - HIGH_PRECISION = 639, - MEDIUM_PRECISION = 640, - LOW_PRECISION = 641, - PRECISION = 642, - PACKED = 643, - RESOURCE = 644, - SUPERP = 645 + CONST = 258, + BOOL = 259, + INT = 260, + UINT = 261, + FLOAT = 262, + BVEC2 = 263, + BVEC3 = 264, + BVEC4 = 265, + IVEC2 = 266, + IVEC3 = 267, + IVEC4 = 268, + UVEC2 = 269, + UVEC3 = 270, + UVEC4 = 271, + VEC2 = 272, + VEC3 = 273, + VEC4 = 274, + MAT2 = 275, + MAT3 = 276, + MAT4 = 277, + MAT2X2 = 278, + MAT2X3 = 279, + MAT2X4 = 280, + MAT3X2 = 281, + MAT3X3 = 282, + MAT3X4 = 283, + MAT4X2 = 284, + MAT4X3 = 285, + MAT4X4 = 286, + SAMPLER2D = 287, + SAMPLER3D = 288, + SAMPLERCUBE = 289, + SAMPLER2DSHADOW = 290, + SAMPLERCUBESHADOW = 291, + SAMPLER2DARRAY = 292, + SAMPLER2DARRAYSHADOW = 293, + ISAMPLER2D = 294, + ISAMPLER3D = 295, + ISAMPLERCUBE = 296, + ISAMPLER2DARRAY = 297, + USAMPLER2D = 298, + USAMPLER3D = 299, + USAMPLERCUBE = 300, + USAMPLER2DARRAY = 301, + SAMPLER = 302, + SAMPLERSHADOW = 303, + TEXTURE2D = 304, + TEXTURE3D = 305, + TEXTURECUBE = 306, + TEXTURE2DARRAY = 307, + ITEXTURE2D = 308, + ITEXTURE3D = 309, + ITEXTURECUBE = 310, + ITEXTURE2DARRAY = 311, + UTEXTURE2D = 312, + UTEXTURE3D = 313, + UTEXTURECUBE = 314, + UTEXTURE2DARRAY = 315, + ATTRIBUTE = 316, + VARYING = 317, + FLOAT16_T = 318, + FLOAT32_T = 319, + DOUBLE = 320, + FLOAT64_T = 321, + INT64_T = 322, + UINT64_T = 323, + INT32_T = 324, + UINT32_T = 325, + INT16_T = 326, + UINT16_T = 327, + INT8_T = 328, + UINT8_T = 329, + I64VEC2 = 330, + I64VEC3 = 331, + I64VEC4 = 332, + U64VEC2 = 333, + U64VEC3 = 334, + U64VEC4 = 335, + I32VEC2 = 336, + I32VEC3 = 337, + I32VEC4 = 338, + U32VEC2 = 339, + U32VEC3 = 340, + U32VEC4 = 341, + I16VEC2 = 342, + I16VEC3 = 343, + I16VEC4 = 344, + U16VEC2 = 345, + U16VEC3 = 346, + U16VEC4 = 347, + I8VEC2 = 348, + I8VEC3 = 349, + I8VEC4 = 350, + U8VEC2 = 351, + U8VEC3 = 352, + U8VEC4 = 353, + DVEC2 = 354, + DVEC3 = 355, + DVEC4 = 356, + DMAT2 = 357, + DMAT3 = 358, + DMAT4 = 359, + F16VEC2 = 360, + F16VEC3 = 361, + F16VEC4 = 362, + F16MAT2 = 363, + F16MAT3 = 364, + F16MAT4 = 365, + F32VEC2 = 366, + F32VEC3 = 367, + F32VEC4 = 368, + F32MAT2 = 369, + F32MAT3 = 370, + F32MAT4 = 371, + F64VEC2 = 372, + F64VEC3 = 373, + F64VEC4 = 374, + F64MAT2 = 375, + F64MAT3 = 376, + F64MAT4 = 377, + DMAT2X2 = 378, + DMAT2X3 = 379, + DMAT2X4 = 380, + DMAT3X2 = 381, + DMAT3X3 = 382, + DMAT3X4 = 383, + DMAT4X2 = 384, + DMAT4X3 = 385, + DMAT4X4 = 386, + F16MAT2X2 = 387, + F16MAT2X3 = 388, + F16MAT2X4 = 389, + F16MAT3X2 = 390, + F16MAT3X3 = 391, + F16MAT3X4 = 392, + F16MAT4X2 = 393, + F16MAT4X3 = 394, + F16MAT4X4 = 395, + F32MAT2X2 = 396, + F32MAT2X3 = 397, + F32MAT2X4 = 398, + F32MAT3X2 = 399, + F32MAT3X3 = 400, + F32MAT3X4 = 401, + F32MAT4X2 = 402, + F32MAT4X3 = 403, + F32MAT4X4 = 404, + F64MAT2X2 = 405, + F64MAT2X3 = 406, + F64MAT2X4 = 407, + F64MAT3X2 = 408, + F64MAT3X3 = 409, + F64MAT3X4 = 410, + F64MAT4X2 = 411, + F64MAT4X3 = 412, + F64MAT4X4 = 413, + ATOMIC_UINT = 414, + ACCSTRUCTNV = 415, + FCOOPMATNV = 416, + ICOOPMATNV = 417, + UCOOPMATNV = 418, + SAMPLERCUBEARRAY = 419, + SAMPLERCUBEARRAYSHADOW = 420, + ISAMPLERCUBEARRAY = 421, + USAMPLERCUBEARRAY = 422, + SAMPLER1D = 423, + SAMPLER1DARRAY = 424, + SAMPLER1DARRAYSHADOW = 425, + ISAMPLER1D = 426, + SAMPLER1DSHADOW = 427, + SAMPLER2DRECT = 428, + SAMPLER2DRECTSHADOW = 429, + ISAMPLER2DRECT = 430, + USAMPLER2DRECT = 431, + SAMPLERBUFFER = 432, + ISAMPLERBUFFER = 433, + USAMPLERBUFFER = 434, + SAMPLER2DMS = 435, + ISAMPLER2DMS = 436, + USAMPLER2DMS = 437, + SAMPLER2DMSARRAY = 438, + ISAMPLER2DMSARRAY = 439, + USAMPLER2DMSARRAY = 440, + SAMPLEREXTERNALOES = 441, + SAMPLEREXTERNAL2DY2YEXT = 442, + ISAMPLER1DARRAY = 443, + USAMPLER1D = 444, + USAMPLER1DARRAY = 445, + F16SAMPLER1D = 446, + F16SAMPLER2D = 447, + F16SAMPLER3D = 448, + F16SAMPLER2DRECT = 449, + F16SAMPLERCUBE = 450, + F16SAMPLER1DARRAY = 451, + F16SAMPLER2DARRAY = 452, + F16SAMPLERCUBEARRAY = 453, + F16SAMPLERBUFFER = 454, + F16SAMPLER2DMS = 455, + F16SAMPLER2DMSARRAY = 456, + F16SAMPLER1DSHADOW = 457, + F16SAMPLER2DSHADOW = 458, + F16SAMPLER1DARRAYSHADOW = 459, + F16SAMPLER2DARRAYSHADOW = 460, + F16SAMPLER2DRECTSHADOW = 461, + F16SAMPLERCUBESHADOW = 462, + F16SAMPLERCUBEARRAYSHADOW = 463, + IMAGE1D = 464, + IIMAGE1D = 465, + UIMAGE1D = 466, + IMAGE2D = 467, + IIMAGE2D = 468, + UIMAGE2D = 469, + IMAGE3D = 470, + IIMAGE3D = 471, + UIMAGE3D = 472, + IMAGE2DRECT = 473, + IIMAGE2DRECT = 474, + UIMAGE2DRECT = 475, + IMAGECUBE = 476, + IIMAGECUBE = 477, + UIMAGECUBE = 478, + IMAGEBUFFER = 479, + IIMAGEBUFFER = 480, + UIMAGEBUFFER = 481, + IMAGE1DARRAY = 482, + IIMAGE1DARRAY = 483, + UIMAGE1DARRAY = 484, + IMAGE2DARRAY = 485, + IIMAGE2DARRAY = 486, + UIMAGE2DARRAY = 487, + IMAGECUBEARRAY = 488, + IIMAGECUBEARRAY = 489, + UIMAGECUBEARRAY = 490, + IMAGE2DMS = 491, + IIMAGE2DMS = 492, + UIMAGE2DMS = 493, + IMAGE2DMSARRAY = 494, + IIMAGE2DMSARRAY = 495, + UIMAGE2DMSARRAY = 496, + F16IMAGE1D = 497, + F16IMAGE2D = 498, + F16IMAGE3D = 499, + F16IMAGE2DRECT = 500, + F16IMAGECUBE = 501, + F16IMAGE1DARRAY = 502, + F16IMAGE2DARRAY = 503, + F16IMAGECUBEARRAY = 504, + F16IMAGEBUFFER = 505, + F16IMAGE2DMS = 506, + F16IMAGE2DMSARRAY = 507, + TEXTURECUBEARRAY = 508, + ITEXTURECUBEARRAY = 509, + UTEXTURECUBEARRAY = 510, + TEXTURE1D = 511, + ITEXTURE1D = 512, + UTEXTURE1D = 513, + TEXTURE1DARRAY = 514, + ITEXTURE1DARRAY = 515, + UTEXTURE1DARRAY = 516, + TEXTURE2DRECT = 517, + ITEXTURE2DRECT = 518, + UTEXTURE2DRECT = 519, + TEXTUREBUFFER = 520, + ITEXTUREBUFFER = 521, + UTEXTUREBUFFER = 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, + LEFT_OP = 548, + RIGHT_OP = 549, + INC_OP = 550, + DEC_OP = 551, + LE_OP = 552, + GE_OP = 553, + EQ_OP = 554, + NE_OP = 555, + AND_OP = 556, + OR_OP = 557, + XOR_OP = 558, + MUL_ASSIGN = 559, + DIV_ASSIGN = 560, + ADD_ASSIGN = 561, + MOD_ASSIGN = 562, + LEFT_ASSIGN = 563, + RIGHT_ASSIGN = 564, + AND_ASSIGN = 565, + XOR_ASSIGN = 566, + OR_ASSIGN = 567, + SUB_ASSIGN = 568, + LEFT_PAREN = 569, + RIGHT_PAREN = 570, + LEFT_BRACKET = 571, + RIGHT_BRACKET = 572, + LEFT_BRACE = 573, + RIGHT_BRACE = 574, + DOT = 575, + COMMA = 576, + COLON = 577, + EQUAL = 578, + SEMICOLON = 579, + BANG = 580, + DASH = 581, + TILDE = 582, + PLUS = 583, + STAR = 584, + SLASH = 585, + PERCENT = 586, + LEFT_ANGLE = 587, + RIGHT_ANGLE = 588, + VERTICAL_BAR = 589, + CARET = 590, + AMPERSAND = 591, + QUESTION = 592, + INVARIANT = 593, + HIGH_PRECISION = 594, + MEDIUM_PRECISION = 595, + LOW_PRECISION = 596, + PRECISION = 597, + PACKED = 598, + RESOURCE = 599, + SUPERP = 600, + FLOATCONSTANT = 601, + INTCONSTANT = 602, + UINTCONSTANT = 603, + BOOLCONSTANT = 604, + IDENTIFIER = 605, + TYPE_NAME = 606, + CENTROID = 607, + IN = 608, + OUT = 609, + INOUT = 610, + STRUCT = 611, + VOID = 612, + WHILE = 613, + BREAK = 614, + CONTINUE = 615, + DO = 616, + ELSE = 617, + FOR = 618, + IF = 619, + DISCARD = 620, + RETURN = 621, + SWITCH = 622, + CASE = 623, + DEFAULT = 624, + UNIFORM = 625, + SHARED = 626, + BUFFER = 627, + FLAT = 628, + SMOOTH = 629, + LAYOUT = 630, + DOUBLECONSTANT = 631, + INT16CONSTANT = 632, + UINT16CONSTANT = 633, + FLOAT16CONSTANT = 634, + INT32CONSTANT = 635, + UINT32CONSTANT = 636, + INT64CONSTANT = 637, + UINT64CONSTANT = 638, + SUBROUTINE = 639, + DEMOTE = 640, + PAYLOADNV = 641, + PAYLOADINNV = 642, + HITATTRNV = 643, + CALLDATANV = 644, + CALLDATAINNV = 645, + PATCH = 646, + SAMPLE = 647, + NONUNIFORM = 648, + COHERENT = 649, + VOLATILE = 650, + RESTRICT = 651, + READONLY = 652, + WRITEONLY = 653, + DEVICECOHERENT = 654, + QUEUEFAMILYCOHERENT = 655, + WORKGROUPCOHERENT = 656, + SUBGROUPCOHERENT = 657, + NONPRIVATE = 658, + NOPERSPECTIVE = 659, + EXPLICITINTERPAMD = 660, + PERVERTEXNV = 661, + PERPRIMITIVENV = 662, + PERVIEWNV = 663, + PERTASKNV = 664, + PRECISE = 665 }; #endif /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE YYSTYPE; + union YYSTYPE { -#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909 */ +#line 96 "MachineIndependent/glslang.y" /* yacc.c:1909 */ struct { glslang::TSourceLoc loc; @@ -474,10 +494,13 @@ union YYSTYPE glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; + glslang::TArraySizes* typeParameters; } interm; -#line 480 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ +#line 501 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */ }; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif diff --git a/Externals/glslang/glslang/MachineIndependent/intermOut.cpp b/Externals/glslang/glslang/MachineIndependent/intermOut.cpp old mode 100755 new mode 100644 index 17c5b42a33..3a93aedafb --- a/Externals/glslang/glslang/MachineIndependent/intermOut.cpp +++ b/Externals/glslang/glslang/MachineIndependent/intermOut.cpp @@ -35,6 +35,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #include "localintermediate.h" #include "../Include/InfoSink.h" @@ -43,6 +45,7 @@ #else #include #endif +#include namespace { @@ -172,8 +175,12 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) 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().isReference(); + 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; @@ -206,6 +213,13 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) case EOpLogicalXor: out.debug << "logical-xor"; break; case EOpLogicalAnd: out.debug << "logical-and"; break; + case EOpAbsDifference: out.debug << "absoluteDifference"; break; + case EOpAddSaturate: out.debug << "addSaturate"; break; + case EOpSubSaturate: out.debug << "subtractSaturate"; break; + case EOpAverage: out.debug << "average"; break; + case EOpAverageRounded: out.debug << "averageRounded"; break; + case EOpMul32x16: out.debug << "multiply32x16"; break; + default: out.debug << ""; } @@ -232,6 +246,7 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) 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; @@ -419,6 +434,8 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break; case EOpConvDoubleToUint64: out.debug << "Convert double 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; @@ -547,6 +564,9 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpFindLSB: out.debug << "findLSB"; break; case EOpFindMSB: out.debug << "findMSB"; break; + case EOpCountLeadingZeros: out.debug << "countLeadingZeros"; break; + case EOpCountTrailingZeros: out.debug << "countTrailingZeros"; break; + case EOpNoise: out.debug << "noise"; break; case EOpBallot: out.debug << "ballot"; break; @@ -607,7 +627,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) 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; @@ -630,7 +649,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) 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; @@ -640,7 +658,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break; -#ifdef AMD_EXTENSIONS case EOpMinInvocations: out.debug << "minInvocations"; break; case EOpMaxInvocations: out.debug << "maxInvocations"; break; case EOpAddInvocations: out.debug << "addInvocations"; break; @@ -669,11 +686,12 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) 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"); } @@ -808,6 +826,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break; 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; @@ -851,7 +871,6 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpReadInvocation: out.debug << "readInvocation"; break; -#ifdef AMD_EXTENSIONS case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break; case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break; case EOpWriteInvocation: out.debug << "writeInvocation"; break; @@ -859,9 +878,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpMin3: out.debug << "min3"; break; case EOpMax3: out.debug << "max3"; break; case EOpMid3: out.debug << "mid3"; break; - case EOpTime: out.debug << "time"; break; -#endif case EOpAtomicAdd: out.debug << "AtomicAdd"; break; case EOpAtomicMin: out.debug << "AtomicMin"; break; @@ -871,6 +888,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node 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; @@ -894,10 +913,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break; case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break; case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break; -#ifdef AMD_EXTENSIONS + case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break; + case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break; case EOpImageLoadLod: out.debug << "imageLoadLod"; break; case EOpImageStoreLod: out.debug << "imageStoreLod"; break; -#endif case EOpTextureQuerySize: out.debug << "textureSize"; break; case EOpTextureQueryLod: out.debug << "textureQueryLod"; break; @@ -924,11 +943,9 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break; case EOpTextureGradClamp: out.debug << "textureGradClamp"; break; case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break; -#ifdef AMD_EXTENSIONS case EOpTextureGatherLod: out.debug << "textureGatherLod"; break; case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break; case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break; -#endif case EOpSparseTexture: out.debug << "sparseTexture"; break; case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break; @@ -946,13 +963,15 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break; case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break; case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break; -#ifdef AMD_EXTENSIONS case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break; case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break; case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break; case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break; -#endif - + 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; case EOpAddCarry: out.debug << "addCarry"; break; case EOpSubBorrow: out.debug << "subBorrow"; break; case EOpUMulExtended: out.debug << "uMulExtended"; break; @@ -966,9 +985,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break; case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break; -#ifdef AMD_EXTENSIONS case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break; -#endif case EOpSinCos: out.debug << "sincos"; break; case EOpGenMul: out.debug << "mul"; break; @@ -1035,9 +1052,45 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break; case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break; + 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; + case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; + 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; + + case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break; + case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break; + case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break; + + case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; + default: out.debug.message(EPrefixError, "Bad aggregation op"); } @@ -1129,9 +1182,12 @@ static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraO 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 << " : "; - long long b = *reinterpret_cast(&value); - for (int i = 0; i < 8 * sizeof(value); ++i, ++b) { + for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) { out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0"); b <<= 1; } @@ -1329,6 +1385,7 @@ bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node) case EOpContinue: out.debug << "Branch: Continue"; break; case EOpReturn: out.debug << "Branch: Return"; break; case EOpCase: out.debug << "case: "; break; + case EOpDemote: out.debug << "Demote"; break; case EOpDefault: out.debug << "default: "; break; default: out.debug << "Branch: Unknown Branch"; break; } @@ -1439,8 +1496,17 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } infoSink.debug << "\n"; } + if (interlockOrdering != EioNone) + infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n"; break; + 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 case EShLangCompute: infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; { @@ -1469,3 +1535,5 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } } // end namespace glslang + +#endif // not GLSLANG_WEB \ No newline at end of file diff --git a/Externals/glslang/glslang/MachineIndependent/iomapper.cpp b/Externals/glslang/glslang/MachineIndependent/iomapper.cpp index 297c123712..3262c0a203 100644 --- a/Externals/glslang/glslang/MachineIndependent/iomapper.cpp +++ b/Externals/glslang/glslang/MachineIndependent/iomapper.cpp @@ -33,16 +33,13 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #include "../Include/Common.h" #include "../Include/InfoSink.h" -#include "iomapper.h" -#include "LiveTraverser.h" -#include "localintermediate.h" #include "gl_types.h" - -#include -#include +#include "iomapper.h" // // Map IO bindings. @@ -61,60 +58,9 @@ // c. implicit dead bindings are left un-bound. // - namespace glslang { -struct TVarEntryInfo -{ - int id; - TIntermSymbol* symbol; - bool live; - int newBinding; - int newSet; - int newLocation; - int newComponent; - int newIndex; - - struct TOrderById - { - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) - { - return l.id < r.id; - } - }; - - struct TOrderByPriority - { - // ordering: - // 1) has both binding and set - // 2) has binding but no set - // 3) has no binding but set - // 4) has no binding and no set - inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) - { - const TQualifier& lq = l.symbol->getQualifier(); - const TQualifier& rq = r.symbol->getQualifier(); - - // simple rules: - // has binding gives 2 points - // has set gives 1 point - // who has the most points is more important. - int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); - int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); - - if (lPoints == rPoints) - return l.id < r.id; - return lPoints > rPoints; - } - }; -}; - - - -typedef std::vector TVarLiveMap; - -class TVarGatherTraverser : public TLiveTraverser -{ +class TVarGatherTraverser : public TLiveTraverser { public: TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList) : TLiveTraverser(i, traverseDeadCode, true, true, false) @@ -124,7 +70,6 @@ public: { } - virtual void visitSymbol(TIntermSymbol* base) { TVarLiveMap* target = nullptr; @@ -132,16 +77,17 @@ public: target = &inputList; else if (base->getQualifier().storage == EvqVaryingOut) target = &outputList; - else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().layoutPushConstant) + else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) target = &uniformList; - if (target) { - TVarEntryInfo ent = { base->getId(), base, !traverseAll }; - TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById()); - if (at != target->end() && at->id == ent.id) - at->live = at->live || !traverseAll; // update live state + TVarEntryInfo ent = {base->getId(), base, ! traverseAll}; + ent.stage = intermediate.getStage(); + TVarLiveMap::iterator at = target->find( + ent.symbol->getName()); // std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById()); + if (at != target->end() && at->second.id == ent.id) + at->second.live = at->second.live || ! traverseAll; // update live state else - target->insert(at, ent); + (*target)[ent.symbol->getName()] = ent; } } @@ -162,9 +108,7 @@ public: { } - - virtual void visitSymbol(TIntermSymbol* base) - { + virtual void visitSymbol(TIntermSymbol* base) { const TVarLiveMap* source; if (base->getQualifier().storage == EvqVaryingIn) source = &inputList; @@ -176,23 +120,23 @@ public: return; TVarEntryInfo ent = { base->getId() }; - TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById()); + TVarLiveMap::const_iterator at = source->find(base->getName()); if (at == source->end()) return; - if (at->id != ent.id) + if (at->second.id != ent.id) return; - if (at->newBinding != -1) - base->getWritableType().getQualifier().layoutBinding = at->newBinding; - if (at->newSet != -1) - base->getWritableType().getQualifier().layoutSet = at->newSet; - if (at->newLocation != -1) - base->getWritableType().getQualifier().layoutLocation = at->newLocation; - if (at->newComponent != -1) - base->getWritableType().getQualifier().layoutComponent = at->newComponent; - if (at->newIndex != -1) - base->getWritableType().getQualifier().layoutIndex = at->newIndex; + if (at->second.newBinding != -1) + base->getWritableType().getQualifier().layoutBinding = at->second.newBinding; + if (at->second.newSet != -1) + base->getWritableType().getQualifier().layoutSet = at->second.newSet; + if (at->second.newLocation != -1) + base->getWritableType().getQualifier().layoutLocation = at->second.newLocation; + if (at->second.newComponent != -1) + base->getWritableType().getQualifier().layoutComponent = at->second.newComponent; + if (at->second.newIndex != -1) + base->getWritableType().getQualifier().layoutIndex = at->second.newIndex; } private: @@ -210,10 +154,12 @@ struct TNotifyUniformAdaptor , resolver(r) { } - inline void operator()(TVarEntryInfo& ent) + + inline void operator()(std::pair& entKey) { - resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + resolver.notifyBinding(stage, entKey.second); } + private: TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&); }; @@ -222,49 +168,46 @@ struct TNotifyInOutAdaptor { EShLanguage stage; TIoMapResolver& resolver; - inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) + inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r) : stage(s) , resolver(r) { } - inline void operator()(TVarEntryInfo& ent) + + inline void operator()(std::pair& entKey) { - resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); + resolver.notifyInOut(stage, entKey.second); } + private: TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&); }; -struct TResolverUniformAdaptor -{ - TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm) +struct TResolverUniformAdaptor { + TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e) : stage(s) , resolver(r) , infoSink(i) , error(e) - , intermediate(interm) { } - inline void operator()(TVarEntryInfo& ent) - { + inline void operator()(std::pair& entKey) { + TVarEntryInfo& ent = entKey.second; ent.newLocation = -1; ent.newComponent = -1; ent.newBinding = -1; ent.newSet = -1; ent.newIndex = -1; - const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), - ent.live); + const bool isValid = resolver.validateBinding(stage, ent); if (isValid) { - ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), - ent.live); - ent.newSet = resolver.resolveSet(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live); - ent.newLocation = resolver.resolveUniformLocation(stage, ent.symbol->getName().c_str(), - ent.symbol->getType(), ent.live); + resolver.resolveBinding(stage, ent); + resolver.resolveSet(stage, ent); + resolver.resolveUniformLocation(stage, ent); if (ent.newBinding != -1) { if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) { - TString err = "mapped binding out of range: " + ent.symbol->getName(); + TString err = "mapped binding out of range: " + entKey.first; infoSink.info.message(EPrefixInternalError, err.c_str()); error = true; @@ -272,273 +215,682 @@ struct TResolverUniformAdaptor } if (ent.newSet != -1) { if (ent.newSet >= int(TQualifier::layoutSetEnd)) { - TString err = "mapped set out of range: " + ent.symbol->getName(); + TString err = "mapped set out of range: " + entKey.first; infoSink.info.message(EPrefixInternalError, err.c_str()); error = true; } } } else { - TString errorMsg = "Invalid binding: " + ent.symbol->getName(); + TString errorMsg = "Invalid binding: " + entKey.first; infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); error = true; } } + inline void setStage(EShLanguage s) { stage = s; } + EShLanguage stage; TIoMapResolver& resolver; TInfoSink& infoSink; bool& error; - TIntermediate& intermediate; private: TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&); }; -struct TResolverInOutAdaptor -{ - TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm) +struct TResolverInOutAdaptor { + TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e) : stage(s) , resolver(r) , infoSink(i) , error(e) - , intermediate(interm) { } - inline void operator()(TVarEntryInfo& ent) + inline void operator()(std::pair& entKey) { + TVarEntryInfo& ent = entKey.second; ent.newLocation = -1; ent.newComponent = -1; ent.newBinding = -1; ent.newSet = -1; ent.newIndex = -1; - const bool isValid = resolver.validateInOut(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); + const bool isValid = resolver.validateInOut(stage, ent); if (isValid) { - ent.newLocation = resolver.resolveInOutLocation(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); - ent.newComponent = resolver.resolveInOutComponent(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); - ent.newIndex = resolver.resolveInOutIndex(stage, - ent.symbol->getName().c_str(), - ent.symbol->getType(), - ent.live); + resolver.resolveInOutLocation(stage, ent); + resolver.resolveInOutComponent(stage, ent); + resolver.resolveInOutIndex(stage, ent); } 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; } } + inline void setStage(EShLanguage s) { stage = s; } + EShLanguage stage; TIoMapResolver& resolver; TInfoSink& infoSink; bool& error; - TIntermediate& intermediate; private: TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&); }; -// Base class for shared TIoMapResolver services, used by several derivations. -struct TDefaultIoResolverBase : public glslang::TIoMapResolver +// The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings + +struct TSymbolValidater { - TDefaultIoResolverBase(const TIntermediate &intermediate) : - intermediate(intermediate), - nextUniformLocation(0), - nextInputLocation(0), - nextOutputLocation(0) - { } - - int getBaseBinding(TResourceType res, unsigned int set) const { - return selectBaseBinding(intermediate.getShiftBinding(res), - intermediate.getShiftBindingForSet(res, set)); + TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount], + TVarLiveMap* uniform[EShLangCount], bool& hadError) + : preStage(EShLangCount) + , currentStage(EShLangCount) + , nextStage(EShLangCount) + , resolver(r) + , infoSink(i) + , hadError(hadError) + { + memcpy(inVarMaps, in, EShLangCount * (sizeof(TVarLiveMap*))); + memcpy(outVarMaps, out, EShLangCount * (sizeof(TVarLiveMap*))); + memcpy(uniformVarMap, uniform, EShLangCount * (sizeof(TVarLiveMap*))); } - const std::vector& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); } - - bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } - bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); } - - typedef std::vector TSlotSet; - typedef std::unordered_map TSlotSetMap; - TSlotSetMap slots; - - TSlotSet::iterator findSlot(int set, int slot) - { - return std::lower_bound(slots[set].begin(), slots[set].end(), slot); - } - - bool checkEmpty(int set, int slot) - { - TSlotSet::iterator at = findSlot(set, slot); - return !(at != slots[set].end() && *at == slot); - } - - int reserveSlot(int set, int slot) - { - 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); - - return slot; - } - - int getFreeSlot(int set, int base) - { - TSlotSet::iterator at = findSlot(set, base); - if (at == slots[set].end()) - return reserveSlot(set, base); - - // look in locksteps, if they not match, then there is a free slot - for (; at != slots[set].end(); ++at, ++base) - if (*at != base) - break; - return reserveSlot(set, base); - } - - virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0; - - virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0; - - int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override - { - if (type.getQualifier().hasSet()) - return type.getQualifier().layoutSet; - - // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) - if (getResourceSetBinding().size() == 1) - return atoi(getResourceSetBinding()[0].c_str()); - - return 0; - } - int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override - { - // kick out of not doing this - if (!doAutoLocationMapping()) - return -1; - - // 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.getBasicType() == EbtAtomicUint || - (type.containsOpaque() && intermediate.getSpv().openGl == 0)) - return -1; - - // no locations on blocks of built-in variables - if (type.isStruct()) { - if (type.getStruct()->size() < 1) - return -1; - if ((*type.getStruct())[0].type->isBuiltIn()) - return -1; + inline void operator()(std::pair& entKey) { + TVarEntryInfo& ent1 = entKey.second; + TIntermSymbol* base = ent1.symbol; + const TType& type = ent1.symbol->getType(); + const TString& name = entKey.first; + TString mangleName1, mangleName2; + type.appendMangledName(mangleName1); + EShLanguage stage = ent1.stage; + if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + nextStage = EShLangCount; + for (int i = currentStage + 1; i < EShLangCount; i++) { + if (inVarMaps[i] != nullptr) + nextStage = static_cast(i); + } } - - int 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 - { - // kick out of not doing this - if (!doAutoLocationMapping()) - return -1; - - // no locations added if already present, or a built-in variable - if (type.getQualifier().hasLocation() || type.isBuiltIn()) - return -1; - - // no locations on blocks of built-in variables - if (type.isStruct()) { - if (type.getStruct()->size() < 1) - return -1; - if ((*type.getStruct())[0].type->isBuiltIn()) - return -1; + if (base->getQualifier().storage == EvqVaryingIn) { + // validate stage in; + if (preStage == EShLangCount) + return; + if (outVarMaps[preStage] != nullptr) { + auto ent2 = outVarMaps[preStage]->find(name); + if (ent2 != outVarMaps[preStage]->end()) { + ent2->second.symbol->getType().appendMangledName(mangleName2); + if (mangleName1 == mangleName2) + return; + else { + TString err = "Invalid In/Out variable type : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + } + return; + } + } else if (base->getQualifier().storage == EvqVaryingOut) { + // validate stage out; + if (nextStage == EShLangCount) + return; + if (outVarMaps[nextStage] != nullptr) { + auto ent2 = inVarMaps[nextStage]->find(name); + if (ent2 != inVarMaps[nextStage]->end()) { + ent2->second.symbol->getType().appendMangledName(mangleName2); + if (mangleName1 == mangleName2) + return; + else { + TString err = "Invalid In/Out variable type : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + } + return; + } + } else if (base->getQualifier().isUniformOrBuffer() && ! base->getQualifier().isPushConstant()) { + // validate uniform type; + for (int i = 0; i < EShLangCount; i++) { + if (i != currentStage && outVarMaps[i] != nullptr) { + auto ent2 = uniformVarMap[i]->find(name); + if (ent2 != uniformVarMap[i]->end()) { + ent2->second.symbol->getType().appendMangledName(mangleName2); + if (mangleName1 != mangleName2) { + TString err = "Invalid Uniform variable type : " + entKey.first; + infoSink.info.message(EPrefixInternalError, err.c_str()); + hadError = true; + } + mangleName2.clear(); + } + } + } } - - // 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 - { - return -1; - } - int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override - { - return -1; } + TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount]; + // Use for mark pre stage, to get more interface symbol information. + EShLanguage preStage, currentStage, nextStage; + // Use for mark current shader stage for resolver + TIoMapResolver& resolver; + TInfoSink& infoSink; + bool& hadError; - void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} - void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {} - void endNotifications(EShLanguage) override {} - void beginNotifications(EShLanguage) override {} - void beginResolve(EShLanguage) override {} - void endResolve(EShLanguage) override {} - -protected: - 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 { - return descriptorSetBase != -1 ? descriptorSetBase : base; - } - - static int getLayoutSet(const glslang::TType& type) { - if (type.getQualifier().hasSet()) - return type.getQualifier().layoutSet; - else - return 0; - } - - static bool isSamplerType(const glslang::TType& type) { - return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); - } - - static bool isTextureType(const glslang::TType& type) { - return (type.getBasicType() == glslang::EbtSampler && - (type.getSampler().isTexture() || type.getSampler().isSubpass())); - } - - static bool isUboType(const glslang::TType& type) { - return type.getQualifier().storage == EvqUniform; - } +private: + TSymbolValidater& operator=(TSymbolValidater&); }; +struct TSlotCollector { + TSlotCollector(TIoMapResolver& r, TInfoSink& i) : resolver(r), infoSink(i) { } + + inline void operator()(std::pair& entKey) { + resolver.reserverStorageSlot(entKey.second, infoSink); + resolver.reserverResourceSlot(entKey.second, infoSink); + } + TIoMapResolver& resolver; + TInfoSink& infoSink; + +private: + TSlotCollector& operator=(TSlotCollector&); +}; + +TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate) + : intermediate(intermediate) + , nextUniformLocation(intermediate.getUniformLocationBase()) + , nextInputLocation(0) + , nextOutputLocation(0) +{ + memset(stageMask, false, sizeof(bool) * (EShLangCount + 1)); +} + +int TDefaultIoResolverBase::getBaseBinding(TResourceType res, unsigned int set) const { + return selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set)); +} + +const std::vector& TDefaultIoResolverBase::getResourceSetBinding() const { + return intermediate.getResourceSetBinding(); +} + +bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); } + +bool TDefaultIoResolverBase::doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); } + +TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) { + return std::lower_bound(slots[set].begin(), slots[set].end(), slot); +} + +bool TDefaultIoResolverBase::checkEmpty(int set, int slot) { + TSlotSet::iterator at = findSlot(set, slot); + return ! (at != slots[set].end() && *at == slot); +} + +int TDefaultIoResolverBase::reserveSlot(int set, int slot, int size) { + TSlotSet::iterator at = findSlot(set, slot); + // tolerate aliasing, by not double-recording aliases + // (policy about appropriateness of the alias is higher up) + 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 TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) { + TSlotSet::iterator at = findSlot(set, base); + if (at == slots[set].end()) + return reserveSlot(set, base, size); + // look for a big enough gap + for (; at != slots[set].end(); ++at) { + if (*at - base >= size) + break; + base = *at + 1; + } + return reserveSlot(set, base, size); +} + +int TDefaultIoResolverBase::resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + if (type.getQualifier().hasSet()) { + return ent.newSet = type.getQualifier().layoutSet; + } + // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN) + if (getResourceSetBinding().size() == 1) { + return ent.newSet = atoi(getResourceSetBinding()[0].c_str()); + } + return ent.newSet = 0; +} + +int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const char* name = ent.symbol->getName().c_str(); + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + // 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.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { + return ent.newLocation = -1; + } + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + int location = intermediate.getUniformLocationOverride(name); + if (location != -1) { + return ent.newLocation = location; + } + location = nextUniformLocation; + nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type); + return ent.newLocation = location; +} + +int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + + // no locations added if already present, or a built-in variable + if (type.getQualifier().hasLocation() || type.isBuiltIn()) { + return ent.newLocation = -1; + } + + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + // 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. + typeLocationSize = computeTypeLocationSize(type, stage); + nextLocation += typeLocationSize; + return ent.newLocation = location; +} + +int TDefaultIoResolverBase::resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) { + return ent.newComponent = -1; +} + +int TDefaultIoResolverBase::resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) { return ent.newIndex = -1; } + +uint32_t TDefaultIoResolverBase::computeTypeLocationSize(const TType& type, EShLanguage stage) { + 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); + } + return typeLocationSize; +} + +//TDefaultGlslIoResolver +TResourceType TDefaultGlslIoResolver::getResourceType(const glslang::TType& type) { + if (isImageType(type)) { + return EResImage; + } + if (isTextureType(type)) { + return EResTexture; + } + if (isSsboType(type)) { + return EResSsbo; + } + if (isSamplerType(type)) { + return EResSampler; + } + if (isUboType(type)) { + return EResUbo; + } + return EResCount; +} + +TDefaultGlslIoResolver::TDefaultGlslIoResolver(const TIntermediate& intermediate) + : TDefaultIoResolverBase(intermediate) + , preStage(EShLangCount) + , currentStage(EShLangCount) +{ } + +int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getName(); + if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + } + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + // expand the location to each element if the symbol is a struct or array + if (type.getQualifier().hasLocation()) { + return ent.newLocation = type.getQualifier().layoutLocation; + } + // no locations added if already present, or a built-in variable + if (type.isBuiltIn()) { + return ent.newLocation = -1; + } + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + int typeLocationSize = computeTypeLocationSize(type, stage); + int location = type.getQualifier().layoutLocation; + bool hasLocation = false; + EShLanguage keyStage(EShLangCount); + TStorageQualifier storage; + storage = EvqInOut; + if (type.getQualifier().isPipeInput()) { + // If this symbol is a input, search pre stage's out + keyStage = preStage; + } + if (type.getQualifier().isPipeOutput()) { + // If this symbol is a output, search next stage's in + keyStage = currentStage; + } + // The in/out in current stage is not declared with location, but it is possible declared + // with explicit location in other stages, find the storageSlotMap firstly to check whether + // the in/out has location + int resourceKey = buildStorageKey(keyStage, storage); + if (! storageSlotMap[resourceKey].empty()) { + TVarSlotMap::iterator iter = storageSlotMap[resourceKey].find(name); + if (iter != storageSlotMap[resourceKey].end()) { + // If interface resource be found, set it has location and this symbol's new location + // equal the symbol's explicit location declarated in pre or next stage. + // + // vs: out vec4 a; + // fs: layout(..., location = 3,...) in vec4 a; + hasLocation = true; + location = iter->second; + // if we want deal like that: + // vs: layout(location=4) out vec4 a; + // out vec4 b; + // + // fs: in vec4 a; + // layout(location = 4) in vec4 b; + // we need retraverse the map. + } + if (! hasLocation) { + // If interface resource note found, It's mean the location in two stage are both implicit declarat. + // So we should find a new slot for this interface. + // + // vs: out vec4 a; + // fs: in vec4 a; + location = getFreeSlot(resourceKey, 0, typeLocationSize); + storageSlotMap[resourceKey][name] = location; + } + } else { + // the first interface declarated in a program. + TVarSlotMap varSlotMap; + location = getFreeSlot(resourceKey, 0, typeLocationSize); + varSlotMap[name] = location; + storageSlotMap[resourceKey] = varSlotMap; + } + //Update location + return ent.newLocation = location; +} + +int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getName(); + // kick out of not doing this + if (! doAutoLocationMapping()) { + return ent.newLocation = -1; + } + // expand the location to each element if the symbol is a struct or array + if (type.getQualifier().hasLocation() && (type.isStruct() || type.isArray())) { + return ent.newLocation = type.getQualifier().layoutLocation; + } else { + // 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.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { + return ent.newLocation = -1; + } + // no locations on blocks of built-in variables + if (type.isStruct()) { + if (type.getStruct()->size() < 1) { + return ent.newLocation = -1; + } + if ((*type.getStruct())[0].type->isBuiltIn()) { + return ent.newLocation = -1; + } + } + } + int location = intermediate.getUniformLocationOverride(name.c_str()); + if (location != -1) { + return ent.newLocation = location; + } + + int size = TIntermediate::computeTypeUniformLocationSize(type); + + // The uniform in current stage is not declared with location, but it is possible declared + // with explicit location in other stages, find the storageSlotMap firstly to check whether + // the uniform has location + bool hasLocation = false; + int resourceKey = buildStorageKey(EShLangCount, EvqUniform); + TVarSlotMap& slotMap = storageSlotMap[resourceKey]; + // Check dose shader program has uniform resource + if (! slotMap.empty()) { + // If uniform resource not empty, try find a same name uniform + TVarSlotMap::iterator iter = slotMap.find(name); + if (iter != slotMap.end()) { + // If uniform resource be found, set it has location and this symbol's new location + // equal the uniform's explicit location declarated in other stage. + // + // vs: uniform vec4 a; + // fs: layout(..., location = 3,...) uniform vec4 a; + hasLocation = true; + location = iter->second; + } + if (! hasLocation) { + // No explicit location declaraten in other stage. + // So we should find a new slot for this uniform. + // + // vs: uniform vec4 a; + // fs: uniform vec4 a; + location = getFreeSlot(resourceKey, 0, computeTypeLocationSize(type, currentStage)); + storageSlotMap[resourceKey][name] = location; + } + } else { + // the first uniform declarated in a program. + TVarSlotMap varSlotMap; + location = getFreeSlot(resourceKey, 0, size); + varSlotMap[name] = location; + storageSlotMap[resourceKey] = varSlotMap; + } + return ent.newLocation = location; +} + +int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getName(); + // On OpenGL arrays of opaque types take a seperate binding for each element + int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1; + TResourceType resource = getResourceType(type); + // don't need to handle uniform symbol, it will be handled in resolveUniformLocation + if (resource == EResUbo && type.getBasicType() != EbtBlock) { + return ent.newBinding = -1; + } + // There is no 'set' qualifier in OpenGL shading language, each resource has its own + // binding name space, so remap the 'set' to resource type which make each resource + // binding is valid from 0 to MAX_XXRESOURCE_BINDINGS + int set = resource; + if (resource < EResCount) { + if (type.getQualifier().hasBinding()) { + ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings); + return ent.newBinding; + } else if (ent.live && doAutoBindingMapping()) { + // The resource in current stage is not declared with binding, but it is possible declared + // with explicit binding in other stages, find the resourceSlotMap firstly to check whether + // the resource has binding, don't need to allocate if it already has a binding + bool hasBinding = false; + if (! resourceSlotMap[resource].empty()) { + TVarSlotMap::iterator iter = resourceSlotMap[resource].find(name); + if (iter != resourceSlotMap[resource].end()) { + hasBinding = true; + ent.newBinding = iter->second; + } + } + if (! hasBinding) { + TVarSlotMap varSlotMap; + // 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 + int binding = getFreeSlot(resource, getBaseBinding(resource, set), numBindings); + varSlotMap[name] = binding; + resourceSlotMap[resource] = varSlotMap; + ent.newBinding = binding; + } + return ent.newBinding; + } + } + return ent.newBinding = -1; +} + +void TDefaultGlslIoResolver::beginResolve(EShLanguage stage) { + // reset stage state + if (stage == EShLangCount) + preStage = currentStage = stage; + // update stage state + else if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + } +} + +void TDefaultGlslIoResolver::endResolve(EShLanguage /*stage*/) { + // TODO nothing +} + +void TDefaultGlslIoResolver::beginCollect(EShLanguage stage) { + // reset stage state + if (stage == EShLangCount) + preStage = currentStage = stage; + // update stage state + else if (currentStage != stage) { + preStage = currentStage; + currentStage = stage; + } +} + +void TDefaultGlslIoResolver::endCollect(EShLanguage /*stage*/) { + // TODO nothing +} + +void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getName(); + TStorageQualifier storage = type.getQualifier().storage; + EShLanguage stage(EShLangCount); + switch (storage) { + case EvqUniform: + if (type.getBasicType() != EbtBlock && type.getQualifier().hasLocation()) { + // + // Reserve the slots for the uniforms who has explicit location + int storageKey = buildStorageKey(EShLangCount, EvqUniform); + int location = type.getQualifier().layoutLocation; + TVarSlotMap& varSlotMap = storageSlotMap[storageKey]; + TVarSlotMap::iterator iter = varSlotMap.find(name); + if (iter == varSlotMap.end()) { + int numLocations = TIntermediate::computeTypeUniformLocationSize(type); + reserveSlot(storageKey, location, numLocations); + varSlotMap[name] = location; + } else { + // Allocate location by name for OpenGL driver, so the uniform in different + // stages should be declared with the same location + if (iter->second != location) { + TString errorMsg = "Invalid location: " + name; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + } + } + } + break; + case EvqVaryingIn: + case EvqVaryingOut: + // + // Reserve the slots for the inout who has explicit location + if (type.getQualifier().hasLocation()) { + stage = storage == EvqVaryingIn ? preStage : stage; + stage = storage == EvqVaryingOut ? currentStage : stage; + int storageKey = buildStorageKey(stage, EvqInOut); + int location = type.getQualifier().layoutLocation; + TVarSlotMap& varSlotMap = storageSlotMap[storageKey]; + TVarSlotMap::iterator iter = varSlotMap.find(name); + if (iter == varSlotMap.end()) { + int numLocations = TIntermediate::computeTypeUniformLocationSize(type); + reserveSlot(storageKey, location, numLocations); + varSlotMap[name] = location; + } else { + // Allocate location by name for OpenGL driver, so the uniform in different + // stages should be declared with the same location + if (iter->second != location) { + TString errorMsg = "Invalid location: " + name; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + } + } + } + break; + default: + break; + } +} + +void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) { + const TType& type = ent.symbol->getType(); + const TString& name = ent.symbol->getName(); + int resource = getResourceType(type); + if (type.getQualifier().hasBinding()) { + TVarSlotMap& varSlotMap = resourceSlotMap[resource]; + TVarSlotMap::iterator iter = varSlotMap.find(name); + int binding = type.getQualifier().layoutBinding; + if (iter == varSlotMap.end()) { + // Reserve the slots for the ubo, ssbo and opaques who has explicit binding + int numBindings = type.isSizedArray() ? type.getCumulativeArraySize() : 1; + varSlotMap[name] = binding; + reserveSlot(resource, binding, numBindings); + } else { + // Allocate binding by name for OpenGL driver, so the resource in different + // stages should be declared with the same binding + if (iter->second != binding) { + TString errorMsg = "Invalid binding: " + name; + infoSink.info.message(EPrefixInternalError, errorMsg.c_str()); + } + } + } +} + +//TDefaultGlslIoResolver end + /* * Basic implementation of glslang::TIoMapResolver that replaces the * previous offset behavior. @@ -549,67 +901,51 @@ protected: /* * Default resolver */ -struct TDefaultIoResolver : public TDefaultIoResolverBase -{ - TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } +struct TDefaultIoResolver : public TDefaultIoResolverBase { + TDefaultIoResolver(const TIntermediate& intermediate) : TDefaultIoResolverBase(intermediate) { } - bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override - { - return true; - } + bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } - int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override - { - const int set = getLayoutSet(type); - - if (type.getQualifier().hasBinding()) { - if (isImageType(type)) - return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding); - - if (isTextureType(type)) - return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); - - if (isSsboType(type)) - return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding); - - if (isSamplerType(type)) - return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); - - if (isUboType(type)) - return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); - } 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)); - - if (isTextureType(type)) - return getFreeSlot(set, getBaseBinding(EResTexture, set)); - - if (isSsboType(type)) - return getFreeSlot(set, getBaseBinding(EResSsbo, set)); - - if (isSamplerType(type)) - return getFreeSlot(set, getBaseBinding(EResSampler, set)); - - if (isUboType(type)) - return getFreeSlot(set, getBaseBinding(EResUbo, set)); + TResourceType getResourceType(const glslang::TType& type) override { + if (isImageType(type)) { + return EResImage; } - - return -1; + if (isTextureType(type)) { + return EResTexture; + } + if (isSsboType(type)) { + return EResSsbo; + } + if (isSamplerType(type)) { + return EResSampler; + } + if (isUboType(type)) { + return EResUbo; + } + return EResCount; } -protected: - static bool isImageType(const glslang::TType& type) { - return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); - } - - static bool isSsboType(const glslang::TType& type) { - return type.getQualifier().storage == EvqBuffer; + int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override { + const TType& type = ent.symbol->getType(); + 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; + TResourceType resource = getResourceType(type); + if (resource < EResCount) { + if (type.getQualifier().hasBinding()) { + return ent.newBinding = reserveSlot( + set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings); + } else if (ent.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 + return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set), numBindings); + } + } + return ent.newBinding = -1; } }; +#ifdef ENABLE_HLSL /******************************************************************************** The following IO resolver maps types in HLSL register space, as follows: @@ -627,7 +963,7 @@ t - for shader resource views (SRV) BYTEADDRESSBUFFER BUFFER TBUFFER - + s - for samplers SAMPLER SAMPLER1D @@ -653,98 +989,69 @@ b - for constant buffer views (CBV) CBUFFER CONSTANTBUFFER ********************************************************************************/ -struct TDefaultHlslIoResolver : public TDefaultIoResolverBase -{ - TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { } +struct TDefaultHlslIoResolver : public TDefaultIoResolverBase { + TDefaultHlslIoResolver(const TIntermediate& intermediate) : TDefaultIoResolverBase(intermediate) { } - bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override - { - return true; - } + bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } - int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override - { - const int set = getLayoutSet(type); - - if (type.getQualifier().hasBinding()) { - if (isUavType(type)) - return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding); - - if (isSrvType(type)) - return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding); - - if (isSamplerType(type)) - return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding); - - if (isUboType(type)) - return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding); - } 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 (isUavType(type)) - return getFreeSlot(set, getBaseBinding(EResUav, set)); - - if (isSrvType(type)) - return getFreeSlot(set, getBaseBinding(EResTexture, set)); - - if (isSamplerType(type)) - return getFreeSlot(set, getBaseBinding(EResSampler, set)); - - if (isUboType(type)) - return getFreeSlot(set, getBaseBinding(EResUbo, set)); + TResourceType getResourceType(const glslang::TType& type) override { + if (isUavType(type)) { + return EResUav; } - - return -1; + if (isSrvType(type)) { + return EResTexture; + } + if (isSamplerType(type)) { + return EResSampler; + } + if (isUboType(type)) { + return EResUbo; + } + return EResCount; } -protected: - // Return true if this is a SRV (shader resource view) type: - static bool isSrvType(const glslang::TType& type) { - return isTextureType(type) || type.getQualifier().storage == EvqBuffer; - } - - // Return true if this is a UAV (unordered access view) type: - static bool isUavType(const glslang::TType& type) { - if (type.getQualifier().readonly) - return false; - - return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || - (type.getQualifier().storage == EvqBuffer); + int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override { + const TType& type = ent.symbol->getType(); + const int set = getLayoutSet(type); + TResourceType resource = getResourceType(type); + if (resource < EResCount) { + if (type.getQualifier().hasBinding()) { + return ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding); + } else if (ent.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 + return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set)); + } + } + return ent.newBinding = -1; } }; - +#endif // Map I/O variables to provided offsets, and make bindings for // unbound but live variables. // // Returns false if the input is too malformed to do this. -bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver) -{ - bool somethingToDo = !intermediate.getResourceSetBinding().empty() || - intermediate.getAutoMapBindings() || - intermediate.getAutoMapLocations(); - - for (int res = 0; res < EResCount; ++res) { - somethingToDo = somethingToDo || - (intermediate.getShiftBinding(TResourceType(res)) != 0) || - intermediate.hasShiftBindingForSet(TResourceType(res)); +bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSink& infoSink, TIoMapResolver* resolver) { + bool somethingToDo = ! intermediate.getResourceSetBinding().empty() || intermediate.getAutoMapBindings() || + intermediate.getAutoMapLocations(); + // Restrict the stricter condition to further check 'somethingToDo' only if 'somethingToDo' has not been set, reduce + // unnecessary or insignificant for-loop operation after 'somethingToDo' have been true. + for (int res = 0; (res < EResCount && !somethingToDo); ++res) { + somethingToDo = somethingToDo || (intermediate.getShiftBinding(TResourceType(res)) != 0) || + intermediate.hasShiftBindingForSet(TResourceType(res)); } - - if (!somethingToDo && resolver == nullptr) + if (! somethingToDo && resolver == nullptr) return true; - if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive()) return false; - TIntermNode* root = intermediate.getTreeRoot(); if (root == nullptr) return false; - // if no resolver is provided, use the default resolver with the given shifts and auto map settings TDefaultIoResolver defaultResolver(intermediate); +#ifdef ENABLE_HLSL TDefaultHlslIoResolver defaultHlslResolver(intermediate); - if (resolver == nullptr) { // TODO: use a passed in IO mapper for this if (intermediate.usingHlslIoMapping()) @@ -752,47 +1059,191 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi else resolver = &defaultResolver; } + resolver->addStage(stage); +#else + resolver = &defaultResolver; +#endif TVarLiveMap inVarMap, outVarMap, uniformVarMap; + TVarLiveVector inVector, outVector, uniformVector; TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap); TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap); - root->traverse(&iter_binding_all); iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); - - while (!iter_binding_live.functions.empty()) { + while (! iter_binding_live.functions.empty()) { TIntermNode* function = iter_binding_live.functions.back(); iter_binding_live.functions.pop_back(); function->traverse(&iter_binding_live); } - // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info. - std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority()); - + std::for_each(inVarMap.begin(), inVarMap.end(), + [&inVector](TVarLivePair p) { inVector.push_back(p); }); + std::sort(inVector.begin(), inVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + std::for_each(outVarMap.begin(), outVarMap.end(), + [&outVector](TVarLivePair p) { outVector.push_back(p); }); + std::sort(outVector.begin(), outVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + std::for_each(uniformVarMap.begin(), uniformVarMap.end(), + [&uniformVector](TVarLivePair p) { uniformVector.push_back(p); }); + std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); bool hadError = false; TNotifyInOutAdaptor inOutNotify(stage, *resolver); TNotifyUniformAdaptor uniformNotify(stage, *resolver); - TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate); - TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate); + TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError); + TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError); resolver->beginNotifications(stage); - std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify); - std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify); - std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify); + std::for_each(inVector.begin(), inVector.end(), inOutNotify); + std::for_each(outVector.begin(), outVector.end(), inOutNotify); + std::for_each(uniformVector.begin(), uniformVector.end(), uniformNotify); resolver->endNotifications(stage); resolver->beginResolve(stage); - std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve); - std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve); - std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve); + std::for_each(inVector.begin(), inVector.end(), inOutResolve); + std::for_each(inVector.begin(), inVector.end(), [&inVarMap](TVarLivePair p) { + auto at = inVarMap.find(p.second.symbol->getName()); + if (at != inVarMap.end()) + at->second = p.second; + }); + std::for_each(outVector.begin(), outVector.end(), inOutResolve); + std::for_each(outVector.begin(), outVector.end(), [&outVarMap](TVarLivePair p) { + auto at = outVarMap.find(p.second.symbol->getName()); + if (at != outVarMap.end()) + at->second = p.second; + }); + std::for_each(uniformVector.begin(), uniformVector.end(), uniformResolve); + std::for_each(uniformVector.begin(), uniformVector.end(), [&uniformVarMap](TVarLivePair p) { + auto at = uniformVarMap.find(p.second.symbol->getName()); + if (at != uniformVarMap.end()) + at->second = p.second; + }); resolver->endResolve(stage); - if (!hadError) { - // sort by id again, so we can use lower bound to find entries - std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById()); TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap); root->traverse(&iter_iomap); } - return !hadError; } +// Map I/O variables to provided offsets, and make bindings for +// unbound but live variables. +// +// Returns false if the input is too malformed to do this. +bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSink& infoSink, TIoMapResolver* resolver) { + + bool somethingToDo = ! intermediate.getResourceSetBinding().empty() || intermediate.getAutoMapBindings() || + intermediate.getAutoMapLocations(); + // Restrict the stricter condition to further check 'somethingToDo' only if 'somethingToDo' has not been set, reduce + // unnecessary or insignificant for-loop operation after 'somethingToDo' have been true. + for (int res = 0; (res < EResCount && !somethingToDo); ++res) { + somethingToDo = somethingToDo || (intermediate.getShiftBinding(TResourceType(res)) != 0) || + intermediate.hasShiftBindingForSet(TResourceType(res)); + } + if (! somethingToDo && resolver == nullptr) { + return true; + } + if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive()) { + return false; + } + TIntermNode* root = intermediate.getTreeRoot(); + if (root == nullptr) { + return false; + } + // if no resolver is provided, use the default resolver with the given shifts and auto map settings + TDefaultGlslIoResolver defaultResolver(intermediate); + if (resolver == nullptr) { + resolver = &defaultResolver; + } + resolver->addStage(stage); + inVarMaps[stage] = new TVarLiveMap, outVarMaps[stage] = new TVarLiveMap(), uniformVarMap[stage] = new TVarLiveMap(); + TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage], + *uniformVarMap[stage]); + TVarGatherTraverser iter_binding_live(intermediate, false, *inVarMaps[stage], *outVarMaps[stage], + *uniformVarMap[stage]); + root->traverse(&iter_binding_all); + iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); + while (! iter_binding_live.functions.empty()) { + TIntermNode* function = iter_binding_live.functions.back(); + iter_binding_live.functions.pop_back(); + function->traverse(&iter_binding_live); + } + TNotifyInOutAdaptor inOutNotify(stage, *resolver); + TNotifyUniformAdaptor uniformNotify(stage, *resolver); + // Resolve current stage input symbol location with previous stage output here, + // uniform symbol, ubo, ssbo and opaque symbols are per-program resource, + // will resolve uniform symbol location and ubo/ssbo/opaque binding in doMap() + resolver->beginNotifications(stage); + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), inOutNotify); + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), inOutNotify); + std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), uniformNotify); + resolver->endNotifications(stage); + TSlotCollector slotCollector(*resolver, infoSink); + resolver->beginCollect(stage); + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), slotCollector); + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), slotCollector); + std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), slotCollector); + resolver->endCollect(stage); + intermediates[stage] = &intermediate; + return !hadError; +} + +bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { + resolver->endResolve(EShLangCount); + if (!hadError) { + //Resolve uniform location, ubo/ssbo/opaque bindings across stages + TResolverUniformAdaptor uniformResolve(EShLangCount, *resolver, infoSink, hadError); + TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError); + TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps, outVarMaps, uniformVarMap, hadError); + TVarLiveVector uniformVector; + resolver->beginResolve(EShLangCount); + for (int stage = EShLangVertex; stage < EShLangCount; stage++) { + if (inVarMaps[stage] != nullptr) { + inOutResolve.setStage(EShLanguage(stage)); + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), symbolValidater); + std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(), inOutResolve); + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), symbolValidater); + std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(), inOutResolve); + } + if (uniformVarMap[stage] != nullptr) { + uniformResolve.setStage(EShLanguage(stage)); + // sort entries by priority. see TVarEntryInfo::TOrderByPriority for info. + std::for_each(uniformVarMap[stage]->begin(), uniformVarMap[stage]->end(), + [&uniformVector](TVarLivePair p) { uniformVector.push_back(p); }); + } + } + std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + std::for_each(uniformVector.begin(), uniformVector.end(), symbolValidater); + std::for_each(uniformVector.begin(), uniformVector.end(), uniformResolve); + std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool { + return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second); + }); + resolver->endResolve(EShLangCount); + for (size_t stage = 0; stage < EShLangCount; stage++) { + if (intermediates[stage] != nullptr) { + // traverse each stage, set new location to each input/output and unifom symbol, set new binding to + // ubo, ssbo and opaque symbols + TVarLiveMap** pUniformVarMap = uniformVarMap; + std::for_each(uniformVector.begin(), uniformVector.end(), [pUniformVarMap, stage](TVarLivePair p) { + auto at = pUniformVarMap[stage]->find(p.second.symbol->getName()); + if (at != pUniformVarMap[stage]->end()) + at->second = p.second; + }); + TVarSetTraverser iter_iomap(*intermediates[stage], *inVarMaps[stage], *outVarMaps[stage], + *uniformVarMap[stage]); + intermediates[stage]->getTreeRoot()->traverse(&iter_iomap); + } + } + return !hadError; + } else { + return false; + } +} + } // end namespace glslang + +#endif // GLSLANG_WEB diff --git a/Externals/glslang/glslang/MachineIndependent/iomapper.h b/Externals/glslang/glslang/MachineIndependent/iomapper.h index 5e0d4391cc..684e88d571 100644 --- a/Externals/glslang/glslang/MachineIndependent/iomapper.h +++ b/Externals/glslang/glslang/MachineIndependent/iomapper.h @@ -33,11 +33,15 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #ifndef _IOMAPPER_INCLUDED #define _IOMAPPER_INCLUDED -#include "../Public/ShaderLang.h" - +#include +#include "LiveTraverser.h" +#include +#include // // A reflection database and its interface, consistent with the OpenGL API reflection queries. // @@ -47,17 +51,249 @@ class TInfoSink; namespace glslang { class TIntermediate; +struct TVarEntryInfo { + int id; + TIntermSymbol* symbol; + bool live; + int newBinding; + int newSet; + int newLocation; + int newComponent; + int newIndex; + EShLanguage stage; + struct TOrderById { + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; } + }; + + struct TOrderByPriority { + // ordering: + // 1) has both binding and set + // 2) has binding but no set + // 3) has no binding but set + // 4) has no binding and no set + inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { + const TQualifier& lq = l.symbol->getQualifier(); + const TQualifier& rq = r.symbol->getQualifier(); + + // simple rules: + // has binding gives 2 points + // has set gives 1 point + // who has the most points is more important. + int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); + int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); + + if (lPoints == rPoints) + return l.id < r.id; + return lPoints > rPoints; + } + }; +}; + +// Base class for shared TIoMapResolver services, used by several derivations. +struct TDefaultIoResolverBase : public glslang::TIoMapResolver { +public: + TDefaultIoResolverBase(const TIntermediate& intermediate); + typedef std::vector TSlotSet; + typedef std::unordered_map TSlotSetMap; + + // grow the reflection stage by stage + void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {} + void notifyInOut(EShLanguage, TVarEntryInfo& /*ent*/) override {} + void beginNotifications(EShLanguage) override {} + void endNotifications(EShLanguage) override {} + void beginResolve(EShLanguage) override {} + void endResolve(EShLanguage) override {} + void beginCollect(EShLanguage) override {} + void endCollect(EShLanguage) override {} + void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} + void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} + int getBaseBinding(TResourceType res, unsigned int set) const; + const std::vector& getResourceSetBinding() const; + virtual TResourceType getResourceType(const glslang::TType& type) = 0; + bool doAutoBindingMapping() const; + bool doAutoLocationMapping() const; + TSlotSet::iterator findSlot(int set, int slot); + bool checkEmpty(int set, int slot); + bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } + int reserveSlot(int set, int slot, int size = 1); + int getFreeSlot(int set, int base, int size = 1); + int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; + int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + void addStage(EShLanguage stage) override { + if (stage < EShLangCount) + stageMask[stage] = true; + } + uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage); + + TSlotSetMap slots; + +protected: + TDefaultIoResolverBase(TDefaultIoResolverBase&); + TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&); + const TIntermediate& intermediate; + int nextUniformLocation; + int nextInputLocation; + int nextOutputLocation; + bool stageMask[EShLangCount + 1]; + // Return descriptor set specific base if there is one, and the generic base otherwise. + int selectBaseBinding(int base, int descriptorSetBase) const { + return descriptorSetBase != -1 ? descriptorSetBase : base; + } + + static int getLayoutSet(const glslang::TType& type) { + if (type.getQualifier().hasSet()) + return type.getQualifier().layoutSet; + else + return 0; + } + + static bool isSamplerType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); + } + + static bool isTextureType(const glslang::TType& type) { + return (type.getBasicType() == glslang::EbtSampler && + (type.getSampler().isTexture() || type.getSampler().isSubpass())); + } + + static bool isUboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqUniform; + } + + static bool isImageType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); + } + + static bool isSsboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqBuffer; + } + + // Return true if this is a SRV (shader resource view) type: + static bool isSrvType(const glslang::TType& type) { + return isTextureType(type) || type.getQualifier().storage == EvqBuffer; + } + + // Return true if this is a UAV (unordered access view) type: + static bool isUavType(const glslang::TType& type) { + if (type.getQualifier().isReadOnly()) + return false; + return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || + (type.getQualifier().storage == EvqBuffer); + } +}; + +// Defaulf I/O resolver for OpenGL +struct TDefaultGlslIoResolver : public TDefaultIoResolverBase { +public: + typedef std::map TVarSlotMap; // + typedef std::map TSlotMap; // + TDefaultGlslIoResolver(const TIntermediate& intermediate); + bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; } + TResourceType getResourceType(const glslang::TType& type) override; + int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; + int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override; + void beginResolve(EShLanguage /*stage*/) override; + void endResolve(EShLanguage stage) override; + void beginCollect(EShLanguage) override; + void endCollect(EShLanguage) override; + void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override; + void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override; + // in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol. + // We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage. + // if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key. + // Note: both stage and type must less then 0xffff. + int buildStorageKey(EShLanguage stage, TStorageQualifier type) { + assert(static_cast(stage) <= 0x0000ffff && static_cast(type) <= 0x0000ffff); + return (stage << 16) | type; + } + +protected: + // Use for mark pre stage, to get more interface symbol information. + EShLanguage preStage; + // Use for mark current shader stage for resolver + EShLanguage currentStage; + // Slot map for storage resource(location of uniform and interface symbol) It's a program share slot + TSlotMap resourceSlotMap; + // Slot map for other resource(image, ubo, ssbo), It's a program share slot. + TSlotMap storageSlotMap; +}; + +typedef std::map TVarLiveMap; + +// override function "operator=", if a vector being sort, +// when use vc++, the sort function will call : +// pair& operator=(const pair<_Other1, _Other2>& _Right) +// { +// first = _Right.first; +// second = _Right.second; +// return (*this); +// } +// that will make a const type handing on left. +// override this function can avoid a compiler error. +// In the future, if the vc++ compiler can handle such a situation, +// this part of the code will be removed. +struct TVarLivePair : std::pair { + TVarLivePair(std::pair& _Right) : pair(_Right.first, _Right.second) {} + TVarLivePair& operator=(const TVarLivePair& _Right) { + const_cast(first) = _Right.first; + second = _Right.second; + return (*this); + } +}; +typedef std::vector TVarLiveVector; // I/O mapper class TIoMapper { public: TIoMapper() {} virtual ~TIoMapper() {} - // grow the reflection stage by stage - bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); + bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); + bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; } +}; + +// I/O mapper for OpenGL +class TGlslIoMapper : public TIoMapper { +public: + TGlslIoMapper() { + memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); + memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); + memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1)); + memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1)); + } + virtual ~TGlslIoMapper() { + for (size_t stage = 0; stage < EShLangCount; stage++) { + if (inVarMaps[stage] != nullptr) { + delete inVarMaps[stage]; + inVarMaps[stage] = nullptr; + } + if (outVarMaps[stage] != nullptr) { + delete outVarMaps[stage]; + outVarMaps[stage] = nullptr; + } + if (uniformVarMap[stage] != nullptr) { + delete uniformVarMap[stage]; + uniformVarMap[stage] = nullptr; + } + if (intermediates[stage] != nullptr) + intermediates[stage] = nullptr; + } + } + // grow the reflection stage by stage + bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override; + bool doMap(TIoMapResolver*, TInfoSink&) override; + TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], + *uniformVarMap[EShLangCount]; + TIntermediate* intermediates[EShLangCount]; + bool hadError = false; }; } // end namespace glslang #endif // _IOMAPPER_INCLUDED + +#endif // GLSLANG_WEB diff --git a/Externals/glslang/glslang/MachineIndependent/limits.cpp b/Externals/glslang/glslang/MachineIndependent/limits.cpp index 64d191b472..51d9300341 100644 --- a/Externals/glslang/glslang/MachineIndependent/limits.cpp +++ b/Externals/glslang/glslang/MachineIndependent/limits.cpp @@ -187,12 +187,14 @@ bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) // void TParseContext::constantIndexExpressionCheck(TIntermNode* index) { +#ifndef GLSLANG_WEB TIndexTraverser it(inductiveLoopIds); index->traverse(&it); if (it.bad) error(it.badLoc, "Non-constant-index-expression", "limitations", ""); +#endif } } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/linkValidate.cpp b/Externals/glslang/glslang/MachineIndependent/linkValidate.cpp index c540ae6477..fe51ec93ff 100644 --- a/Externals/glslang/glslang/MachineIndependent/linkValidate.cpp +++ b/Externals/glslang/glslang/MachineIndependent/linkValidate.cpp @@ -1,6 +1,7 @@ // // Copyright (C) 2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. +// Copyright (C) 2015-2018 Google, Inc. // // All rights reserved. // @@ -55,8 +56,10 @@ namespace glslang { // void TIntermediate::error(TInfoSink& infoSink, const char* message) { +#ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixError); infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; +#endif ++numErrors; } @@ -64,8 +67,10 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message) // Link-time warning. void TIntermediate::warn(TInfoSink& infoSink, const char* message) { +#ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixWarning); infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; +#endif } // TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block @@ -77,12 +82,15 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message) // 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"); +#ifndef GLSLANG_WEB + mergeCallGraphs(infoSink, unit); + mergeModes(infoSink, unit); + mergeTrees(infoSink, unit); +#endif +} +void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) +{ if (unit.getNumEntryPoints() > 0) { if (getNumEntryPoints() > 0) error(infoSink, "can't handle multiple entry points per stage"); @@ -92,25 +100,71 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) } } numEntryPoints += unit.getNumEntryPoints(); + + callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); +} + +#ifndef GLSLANG_WEB + +#define MERGE_MAX(member) member = std::max(member, unit.member) +#define MERGE_TRUE(member) if (unit.member) member = unit.member; + +void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) +{ + if (language != unit.language) + error(infoSink, "stages must match when linking into a single stage"); + + if (getSource() == EShSourceNone) + setSource(unit.getSource()); + if (getSource() != unit.getSource()) + error(infoSink, "can't link compilation units from different source languages"); + + if (treeRoot == nullptr) { + profile = unit.profile; + version = unit.version; + requestedExtensions = unit.requestedExtensions; + } else { + if ((isEsProfile()) != (unit.isEsProfile())) + 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()); + } + + MERGE_MAX(spvVersion.spv); + MERGE_MAX(spvVersion.vulkanGlsl); + MERGE_MAX(spvVersion.vulkan); + MERGE_MAX(spvVersion.openGl); + 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"); + 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 (! earlyFragmentTests) - earlyFragmentTests = unit.earlyFragmentTests; - - if (!postDepthCoverage) - postDepthCoverage = unit.postDepthCoverage; - - if (depthLayout == EldNone) - depthLayout = unit.depthLayout; - else if (depthLayout != unit.depthLayout) - error(infoSink, "Contradictory depth layouts"); - - blendEquations |= unit.blendEquations; + if (vertices == TQualifier::layoutNotSet) + vertices = unit.vertices; + else if (vertices != unit.vertices) { + if (language == EShLangGeometry || language == EShLangMeshNV) + error(infoSink, "Contradictory layout max_vertices values"); + else if (language == EShLangTessControl) + error(infoSink, "Contradictory layout vertices values"); + else + assert(0); + } + 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); + } if (inputPrimitive == ElgNone) inputPrimitive = unit.inputPrimitive; @@ -122,16 +176,8 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) else if (outputPrimitive != unit.outputPrimitive) error(infoSink, "Contradictory output layout primitives"); - if (vertices == TQualifier::layoutNotSet) - vertices = unit.vertices; - else if (vertices != unit.vertices) { - if (language == EShLangGeometry) - error(infoSink, "Contradictory layout max_vertices values"); - else if (language == EShLangTessControl) - error(infoSink, "Contradictory layout vertices values"); - else - assert(0); - } + if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) + error(infoSink, "gl_FragCoord redeclarations must match across shaders"); if (vertexSpacing == EvsNone) vertexSpacing = unit.vertexSpacing; @@ -143,63 +189,222 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) 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) + if (!localSizeNotDefault[i] && unit.localSizeNotDefault[i]) { localSize[i] = unit.localSize[i]; + localSizeNotDefault[i] = true; + } else if (localSize[i] != unit.localSize[i]) error(infoSink, "Contradictory local size"); - if (localSizeSpecId[i] != TQualifier::layoutNotSet) + if (localSizeSpecId[i] == TQualifier::layoutNotSet) localSizeSpecId[i] = unit.localSizeSpecId[i]; else if (localSizeSpecId[i] != unit.localSizeSpecId[i]) 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; + if (unit.xfbBuffers[b].contains32BitType) + xfbBuffers[b].contains32BitType = true; + if (unit.xfbBuffers[b].contains16BitType) + xfbBuffers[b].contains16BitType = true; // TODO: 4.4 link: enhanced layouts: compare ranges } - if (unit.treeRoot == 0) + MERGE_TRUE(multiStream); + MERGE_TRUE(layoutOverrideCoverage); + MERGE_TRUE(geoPassthroughEXT); + + 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... - - version = std::max(version, unit.version); - requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end()); + numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks; + numTaskNVBlocks += unit.numTaskNVBlocks; // 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()); } +#endif + +// 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. @@ -293,6 +498,7 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) // void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage) { +#ifndef GLSLANG_WEB bool writeTypeComparison = false; // Types have to match @@ -327,7 +533,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } // Precise... - if (! crossStage && symbol.getQualifier().noContraction != unitSymbol.getQualifier().noContraction) { + if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) { error(infoSink, "Presence of precise qualifier must match:"); writeTypeComparison = true; } @@ -336,19 +542,24 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth || symbol.getQualifier().flat != unitSymbol.getQualifier().flat || - symbol.getQualifier().sample != unitSymbol.getQualifier().sample || - symbol.getQualifier().patch != unitSymbol.getQualifier().patch || - symbol.getQualifier().nopersp != unitSymbol.getQualifier().nopersp) { + symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() || + symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() || + symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) { error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); writeTypeComparison = true; } // 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; } @@ -381,6 +592,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy if (writeTypeComparison) infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" << unitSymbol.getType().getCompleteString() << "\"\n"; +#endif } // @@ -395,15 +607,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) return; if (numEntryPoints < 1) { - if (source == EShSourceGlsl) + if (getSource() == EShSourceGlsl) error(infoSink, "Missing entry point: Each stage requires one entry point"); else warn(infoSink, "Entry point not found"); } - if (numPushConstants > 1) - error(infoSink, "Only one push_constant block is allowed per stage"); - // recursion and missing body checking checkCallGraphCycles(infoSink); checkCallGraphBodies(infoSink, keepUncalled); @@ -411,6 +620,10 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) // overlap/alias/missing I/O, etc. inOutLocationCheck(infoSink); +#ifndef GLSLANG_WEB + if (getNumPushConstants() > 1) + error(infoSink, "Only one push_constant block is allowed per stage"); + // invocations if (invocations == TQualifier::layoutNotSet) invocations = 1; @@ -426,8 +639,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) 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); + else if (xfbBuffers[b].contains32BitType) + RoundToPow2(xfbBuffers[b].implicitStride, 4); + else if (xfbBuffers[b].contains16BitType) + RoundToPow2(xfbBuffers[b].implicitStride, 2); // "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 @@ -442,17 +659,24 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) 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"; - } else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { + } else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) { 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"; } + // "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"; + } // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." @@ -471,7 +695,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) error(infoSink, "At least one shader must specify an output layout(vertices=...)"); break; case EShLangTessEvaluation: - if (source == EShSourceGlsl) { + if (getSource() == EShSourceGlsl) { if (inputPrimitive == ElgNone) error(infoSink, "At least one shader must specify an input layout primitive"); if (vertexSpacing == EvsNone) @@ -483,17 +707,9 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) 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: @@ -505,6 +721,38 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) break; case EShLangCompute: break; + 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; default: error(infoSink, "Unknown Stage."); break; @@ -526,6 +774,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) } finalLinkTraverser; treeRoot->traverse(&finalLinkTraverser); +#endif } // @@ -699,7 +948,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink) // 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(); @@ -712,13 +961,13 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink) } } - if (profile == EEsProfile) { + if (isEsProfile()) { if (numFragOut > 1 && fragOutWithNoLocation) error(infoSink, "when more than one fragment shader output, all must have location qualifiers"); } } -TIntermSequence& TIntermediate::findLinkerObjects() const +TIntermAggregate* TIntermediate::findLinkerObjects() const { // Get the top-level globals TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); @@ -726,7 +975,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const // 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. @@ -734,7 +983,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const // 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) { @@ -775,7 +1024,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ return -1; int size; - if (qualifier.isUniformOrBuffer()) { + if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) { if (type.isSizedArray()) size = type.getCumulativeArraySize(); else @@ -805,6 +1054,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // So, for the case of dvec3, we need two independent ioRanges. int collision = -1; // no collision +#ifndef GLSLANG_WEB if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && (qualifier.isPipeInput() || qualifier.isPipeOutput())) { // Dealing with dvec3 in/out split across two locations. @@ -831,7 +1081,9 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ if (collision < 0) usedIo[set].push_back(range2); } - } else { + } else +#endif + { // Not a dvec3 in/out split across two locations, generic path. // Need a single IO-range block. @@ -845,10 +1097,10 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ } // combine location and component ranges - TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0); + TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.getIndex() : 0); // check for collisions, except for vertex inputs on desktop targeting OpenGL - if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) + if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) collision = checkLocationRange(set, range, type, typeCollision); if (collision < 0) @@ -926,10 +1178,15 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage) // 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.isSizedArray()) + if (type.isSizedArray() && !type.getQualifier().isPerView()) return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage); - else + else { +#ifndef GLSLANG_WEB + // 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 @@ -1003,6 +1260,8 @@ int TIntermediate::computeTypeUniformLocationSize(const TType& type) return 1; } +#ifndef GLSLANG_WEB + // 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. @@ -1015,7 +1274,7 @@ int TIntermediate::addXfbBufferOffset(const TType& type) TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer]; // compute the range - unsigned int size = computeTypeXfbSize(type, buffer.containsDouble); + unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType); buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size); TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1); @@ -1034,11 +1293,13 @@ int TIntermediate::addXfbBufferOffset(const TType& type) // 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. +// 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 { - // "...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 @@ -1049,29 +1310,45 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness assert(type.isSizedArray()); TType elementType(type, 0); - return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble); + return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType); } if (type.isStruct()) { unsigned int size = 0; - bool structContainsDouble = false; + bool structContains64BitType = false; + bool structContains32BitType = false; + bool structContains16BitType = false; 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; + bool memberContains32BitType = false; + bool memberContains16BitType = false; + int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType); + if (memberContains64BitType) { + structContains64BitType = true; RoundToPow2(size, 8); + } else if (memberContains32BitType) { + structContains32BitType = true; + RoundToPow2(size, 4); + } else if (memberContains16BitType) { + structContains16BitType = true; + RoundToPow2(size, 2); } size += memberSize; } - if (structContainsDouble) { - containsDouble = true; + if (structContains64BitType) { + contains64BitType = true; RoundToPow2(size, 8); + } else if (structContains32BitType) { + contains32BitType = true; + RoundToPow2(size, 4); + } else if (structContains16BitType) { + contains16BitType = true; + RoundToPow2(size, 2); } return size; } @@ -1088,13 +1365,22 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains numComponents = 1; } - if (type.getBasicType() == EbtDouble) { - containsDouble = true; + if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) { + contains64BitType = true; return 8 * numComponents; - } else + } 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; + } } +#endif + const int baseAlignmentVec4Std140 = 16; // Return the size and alignment of a component of the given type. @@ -1102,6 +1388,10 @@ const int baseAlignmentVec4Std140 = 16; // Return value is the alignment.. int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) { +#ifdef GLSLANG_WEB + size = 4; return 4; +#endif + switch (type.getBasicType()) { case EbtInt64: case EbtUint64: @@ -1111,6 +1401,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) 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; } } @@ -1129,10 +1420,11 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) // 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 @@ -1196,7 +1488,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b 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); @@ -1216,7 +1508,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b 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); @@ -1255,7 +1547,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b // 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); @@ -1283,4 +1575,149 @@ bool TIntermediate::improperStraddle(const TType& type, int size, int offset) : 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.isReference()); + int size = getBlockSize(*type.getReferentType()); + + int align = type.getBufferReferenceAlignment(); + + if (align) { + size = (size + align - 1) & ~(align-1); + } + + return size; +} + } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/localintermediate.h b/Externals/glslang/glslang/MachineIndependent/localintermediate.h old mode 100755 new mode 100644 index f3a0e413e2..683290af74 --- a/Externals/glslang/glslang/MachineIndependent/localintermediate.h +++ b/Externals/glslang/glslang/MachineIndependent/localintermediate.h @@ -2,6 +2,8 @@ // 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 @@ -41,6 +43,8 @@ #include "../Public/ShaderLang.h" #include "Versions.h" +#include +#include #include #include #include @@ -143,14 +147,19 @@ struct TOffsetRange { TRange offset; }; +#ifndef GLSLANG_WEB // Things that need to be tracked per xfb buffer. struct TXfbBuffer { - TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), containsDouble(false) { } + TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false), + contains32BitType(false), contains16BitType(false) { } std::vector ranges; // byte offsets that have already been assigned unsigned int stride; unsigned int implicitStride; - bool containsDouble; + bool contains64BitType; + bool contains32BitType; + bool contains16BitType; }; +#endif // Track a set of strings describing how the module was processed. // Using the form: @@ -204,174 +213,74 @@ class TSymbolTable; class TSymbol; class TVariable; +// +// 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 +}; + // // 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"), implicitCounterName("@count"), - language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0), + language(l), + profile(p), version(v), treeRoot(0), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), + invertY(false), + useStorageBuffer(false), + nanMinMaxClamp(false), + depthReplacing(false) +#ifndef GLSLANG_WEB + , + implicitThisName("@this"), implicitCounterName("@count"), + source(EShSourceNone), + useVulkanMemoryModel(false), invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), - vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), - postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false), + vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false), + postDepthCoverage(false), depthLayout(EldNone), hlslFunctionality1(false), blendEquations(0), xfbMode(false), multiStream(false), -#ifdef NV_EXTENSIONS layoutOverrideCoverage(false), geoPassthroughEXT(false), -#endif + numShaderRecordNVBlocks(0), + computeDerivativeMode(LayoutDerivativeNone), + primitives(TQualifier::layoutNotSet), + numTaskNVBlocks(0), autoMapBindings(false), autoMapLocations(false), - invertY(false), flattenUniformArrays(false), useUnknownFormat(false), hlslOffsets(false), - useStorageBuffer(false), hlslIoMapping(false), + useVariablePointers(false), textureSamplerTransformMode(EShTexSampTransKeep), needToLegalize(false), - binaryDoubleOutput(false) + binaryDoubleOutput(false), + usePhysicalStorageBuffer(false), + uniformLocationBase(0) +#endif { localSize[0] = 1; localSize[1] = 1; localSize[2] = 1; + localSizeNotDefault[0] = false; + localSizeNotDefault[1] = false; + localSizeNotDefault[2] = false; localSizeSpecId[0] = TQualifier::layoutNotSet; localSizeSpecId[1] = TQualifier::layoutNotSet; localSizeSpecId[2] = TQualifier::layoutNotSet; +#ifndef GLSLANG_WEB xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); - shiftBinding.fill(0); +#endif } - void setLimits(const TBuiltInResource& r) { resources = r; } - - bool postProcess(TIntermNode*, EShLanguage); - void output(TInfoSink&, bool tree); - void removeTree(); - - void setSource(EShSource s) { source = s; } - EShSource getSource() const { return source; } - void setEntryPointName(const char* ep) - { - entryPointName = ep; - processes.addProcess("entry-point"); - processes.addArgument(entryPointName); - } - void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; } - const std::string& getEntryPointName() const { return entryPointName; } - const std::string& getEntryPointMangledName() const { return entryPointMangledName; } - - void setShiftBinding(TResourceType res, unsigned int shift) - { - shiftBinding[res] = shift; - - const char* name = getResourceName(res); - if (name != nullptr) - processes.addIfNonZero(name, shift); - } - - unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; } - - void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set) - { - if (shift == 0) // ignore if there's no shift: it's a no-op. - return; - - shiftBindingForSet[res][set] = shift; - - const char* name = getResourceName(res); - if (name != nullptr) { - processes.addProcess(name); - processes.addArgument(shift); - processes.addArgument(set); - } - } - - int getShiftBindingForSet(TResourceType res, unsigned int set) const - { - const auto shift = shiftBindingForSet[res].find(set); - return shift == shiftBindingForSet[res].end() ? -1 : shift->second; - } - bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); } - - void setResourceSetBinding(const std::vector& shift) - { - resourceSetBinding = shift; - if (shift.size() > 0) { - processes.addProcess("resource-set-binding"); - for (int s = 0; s < (int)shift.size(); ++s) - processes.addArgument(shift[s]); - } - } - const std::vector& getResourceSetBinding() const { return resourceSetBinding; } - void setAutoMapBindings(bool map) - { - autoMapBindings = map; - if (autoMapBindings) - processes.addProcess("auto-map-bindings"); - } - bool getAutoMapBindings() const { return autoMapBindings; } - void setAutoMapLocations(bool map) - { - autoMapLocations = map; - if (autoMapLocations) - processes.addProcess("auto-map-locations"); - } - bool getAutoMapLocations() const { return autoMapLocations; } - void setInvertY(bool invert) - { - invertY = invert; - if (invertY) - processes.addProcess("invert-y"); - } - bool getInvertY() const { return invertY; } - - void setFlattenUniformArrays(bool flatten) - { - flattenUniformArrays = flatten; - if (flattenUniformArrays) - processes.addProcess("flatten-uniform-arrays"); - } - bool getFlattenUniformArrays() const { return flattenUniformArrays; } - void setNoStorageFormat(bool b) - { - useUnknownFormat = b; - if (useUnknownFormat) - processes.addProcess("no-storage-format"); - } - bool getNoStorageFormat() const { return useUnknownFormat; } - void setHlslOffsets() - { - hlslOffsets = true; - if (hlslOffsets) - processes.addProcess("hlsl-offsets"); - } - bool usingHlslOFfsets() const { return hlslOffsets; } - void setUseStorageBuffer() - { - useStorageBuffer = true; - processes.addProcess("use-storage-buffer"); - } - bool usingStorageBuffer() const { return useStorageBuffer; } - void setHlslIoMapping(bool b) - { - hlslIoMapping = b; - if (hlslIoMapping) - processes.addProcess("hlsl-iomap"); - } - bool usingHlslIoMapping() { return hlslIoMapping; } - - 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; } void setVersion(int v) { version = v; } int getVersion() const { return version; } @@ -387,11 +296,49 @@ public: 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; + case EShTargetSpv_1_4: + processes.addProcess("target-env spirv1.4"); + break; + case EShTargetSpv_1_5: + processes.addProcess("target-env spirv1.5"); + break; + default: + processes.addProcess("target-env spirvUnknown"); + break; + } + // target-environment processes - if (spvVersion.vulkan > 0) + 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; + case EShTargetVulkan_1_2: + processes.addProcess("target-env vulkan1.2"); + break; + default: processes.addProcess("target-env vulkanUnknown"); + break; + } if (spvVersion.openGl > 0) processes.addProcess("target-env opengl"); } @@ -406,15 +353,47 @@ public: int getNumEntryPoints() const { return numEntryPoints; } int getNumErrors() const { return numErrors; } void addPushConstantCount() { ++numPushConstants; } + void setLimits(const TBuiltInResource& r) { resources = r; } + + bool postProcess(TIntermNode*, EShLanguage); + void removeTree(); + + void setEntryPointName(const char* ep) + { + entryPointName = ep; + processes.addProcess("entry-point"); + processes.addArgument(entryPointName); + } + void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; } + const std::string& getEntryPointName() const { return entryPointName; } + const std::string& getEntryPointMangledName() const { return entryPointMangledName; } + + void setInvertY(bool invert) + { + invertY = invert; + if (invertY) + processes.addProcess("invert-y"); + } + bool getInvertY() const { return invertY; } + +#ifdef ENABLE_HLSL + void setSource(EShSource s) { source = s; } + EShSource getSource() const { return source; } +#else + void setSource(EShSource s) { assert(s == EShSourceGlsl); } + EShSource getSource() const { return EShSourceGlsl; } +#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; - std::tuple addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) 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); @@ -481,6 +460,169 @@ public: void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); + void setUseStorageBuffer() + { + useStorageBuffer = true; + processes.addProcess("use-storage-buffer"); + } + bool usingStorageBuffer() const { return useStorageBuffer; } + void setDepthReplacing() { depthReplacing = true; } + bool isDepthReplacing() const { return depthReplacing; } + bool setLocalSize(int dim, int size) + { + if (localSizeNotDefault[dim]) + return size == localSize[dim]; + localSizeNotDefault[dim] = true; + localSize[dim] = size; + return true; + } + unsigned int getLocalSize(int dim) const { return localSize[dim]; } + bool setLocalSizeSpecId(int dim, int id) + { + if (localSizeSpecId[dim] != TQualifier::layoutNotSet) + return id == localSizeSpecId[dim]; + localSizeSpecId[dim] = id; + return true; + } + int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } +#ifdef GLSLANG_WEB + void output(TInfoSink&, bool tree) { } + + bool isEsProfile() const { return false; } + bool getXfbMode() const { return false; } + bool isMultiStream() const { return false; } + TLayoutGeometry getOutputPrimitive() const { return ElgNone; } + bool getPostDepthCoverage() const { return false; } + bool getEarlyFragmentTests() const { return false; } + TLayoutDepth getDepth() const { return EldNone; } + bool getPixelCenterInteger() const { return false; } + void setOriginUpperLeft() { } + bool getOriginUpperLeft() const { return true; } + TInterlockOrdering getInterlockOrdering() const { return EioNone; } + + bool getAutoMapBindings() const { return false; } + bool getAutoMapLocations() const { return false; } + int getNumPushConstants() const { return 0; } + void addShaderRecordNVCount() { } + void addTaskNVCount() { } + void setUseVulkanMemoryModel() { } + bool usingVulkanMemoryModel() const { return false; } + bool usingPhysicalStorageBuffer() const { return false; } + bool usingVariablePointers() const { return false; } + unsigned getXfbStride(int buffer) const { return 0; } + bool hasLayoutDerivativeModeNone() const { return false; } + ComputeDerivativeMode getLayoutDerivativeModeNone() const { return LayoutDerivativeNone; } +#else + void output(TInfoSink&, bool tree); + + bool isEsProfile() const { return profile == EEsProfile; } + + void setShiftBinding(TResourceType res, unsigned int shift) + { + shiftBinding[res] = shift; + + const char* name = getResourceName(res); + if (name != nullptr) + processes.addIfNonZero(name, shift); + } + + unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; } + + void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set) + { + if (shift == 0) // ignore if there's no shift: it's a no-op. + return; + + shiftBindingForSet[res][set] = shift; + + const char* name = getResourceName(res); + if (name != nullptr) { + processes.addProcess(name); + processes.addArgument(shift); + processes.addArgument(set); + } + } + + int getShiftBindingForSet(TResourceType res, unsigned int set) const + { + const auto shift = shiftBindingForSet[res].find(set); + return shift == shiftBindingForSet[res].end() ? -1 : shift->second; + } + bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); } + + void setResourceSetBinding(const std::vector& shift) + { + resourceSetBinding = shift; + if (shift.size() > 0) { + processes.addProcess("resource-set-binding"); + for (int s = 0; s < (int)shift.size(); ++s) + processes.addArgument(shift[s]); + } + } + const std::vector& getResourceSetBinding() const { return resourceSetBinding; } + void setAutoMapBindings(bool map) + { + autoMapBindings = map; + if (autoMapBindings) + processes.addProcess("auto-map-bindings"); + } + bool getAutoMapBindings() const { return autoMapBindings; } + void setAutoMapLocations(bool map) + { + autoMapLocations = map; + if (autoMapLocations) + processes.addProcess("auto-map-locations"); + } + bool getAutoMapLocations() const { return autoMapLocations; } + +#ifdef ENABLE_HLSL + void setFlattenUniformArrays(bool flatten) + { + flattenUniformArrays = flatten; + if (flattenUniformArrays) + processes.addProcess("flatten-uniform-arrays"); + } + bool getFlattenUniformArrays() const { return flattenUniformArrays; } +#endif + void setNoStorageFormat(bool b) + { + useUnknownFormat = b; + if (useUnknownFormat) + processes.addProcess("no-storage-format"); + } + bool getNoStorageFormat() const { return useUnknownFormat; } + 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; } + +#ifdef ENABLE_HLSL + 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; + } +#endif + + void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } + int getNumPushConstants() const { return numPushConstants; } + void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; } + void addTaskNVCount() { ++numTaskNVBlocks; } + bool setInvocations(int i) { if (invocations != TQualifier::layoutNotSet) @@ -524,23 +666,14 @@ public: void setPointMode() { pointMode = true; } bool getPointMode() const { return pointMode; } - bool setLocalSize(int dim, int size) + bool setInterlockOrdering(TInterlockOrdering o) { - if (localSize[dim] > 1) - return size == localSize[dim]; - localSize[dim] = size; + if (interlockOrdering != EioNone) + return interlockOrdering == o; + interlockOrdering = o; return true; } - unsigned int getLocalSize(int dim) const { return localSize[dim]; } - - bool setLocalSizeSpecId(int dim, int id) - { - if (localSizeSpecId[dim] != TQualifier::layoutNotSet) - return id == localSizeSpecId[dim]; - localSizeSpecId[dim] = id; - return true; - } - int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } + TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; } void setXfbMode() { xfbMode = true; } bool getXfbMode() const { return xfbMode; } @@ -554,14 +687,10 @@ public: return true; } TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; } - void setOriginUpperLeft() { originUpperLeft = true; } - bool getOriginUpperLeft() const { return originUpperLeft; } - void setPixelCenterInteger() { pixelCenterInteger = true; } - bool getPixelCenterInteger() const { return pixelCenterInteger; } - void setEarlyFragmentTests() { earlyFragmentTests = true; } - bool getEarlyFragmentTests() const { return earlyFragmentTests; } void setPostDepthCoverage() { postDepthCoverage = true; } bool getPostDepthCoverage() const { return postDepthCoverage; } + void setEarlyFragmentTests() { earlyFragmentTests = true; } + bool getEarlyFragmentTests() const { return earlyFragmentTests; } bool setDepth(TLayoutDepth d) { if (depthLayout != EldNone) @@ -570,19 +699,98 @@ public: return true; } TLayoutDepth getDepth() const { return depthLayout; } - void setDepthReplacing() { depthReplacing = true; } - bool isDepthReplacing() const { return depthReplacing; } - - void setHlslFunctionality1() { hlslFunctionality1 = true; } - bool getHlslFunctionality1() const { return hlslFunctionality1; } - + void setOriginUpperLeft() { originUpperLeft = true; } + bool getOriginUpperLeft() const { return originUpperLeft; } + void setPixelCenterInteger() { pixelCenterInteger = true; } + bool getPixelCenterInteger() const { return pixelCenterInteger; } void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); } unsigned int getBlendEquations() const { return blendEquations; } + bool setXfbBufferStride(int buffer, unsigned stride) + { + if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd) + return xfbBuffers[buffer].stride == stride; + xfbBuffers[buffer].stride = stride; + return true; + } + unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; } + int addXfbBufferOffset(const TType&); + unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const; + unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const; + void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; } + bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; } + void setGeoPassthroughEXT() { geoPassthroughEXT = true; } + bool getGeoPassthroughEXT() const { return geoPassthroughEXT; } + void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; } + bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; } + 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; } + const char* addSemanticName(const TString& name) + { + return semanticNameSet.insert(name).first->c_str(); + } + 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; } +#endif // GLSLANG_WEB + +#ifdef ENABLE_HLSL + void setHlslFunctionality1() { hlslFunctionality1 = true; } + bool getHlslFunctionality1() const { return hlslFunctionality1; } + void setHlslOffsets() + { + hlslOffsets = true; + if (hlslOffsets) + processes.addProcess("hlsl-offsets"); + } + bool usingHlslOffsets() const { return hlslOffsets; } + void setHlslIoMapping(bool b) + { + hlslIoMapping = b; + if (hlslIoMapping) + processes.addProcess("hlsl-iomap"); + } + bool usingHlslIoMapping() { return hlslIoMapping; } +#else + bool getHlslFunctionality1() const { return false; } + bool usingHlslOffsets() const { return false; } + bool usingHlslIoMapping() { return false; } +#endif void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void merge(TInfoSink&, TIntermediate&); void finalCheck(TInfoSink&, bool keepUncalled); + bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const; + TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; + void addIoAccessed(const TString& name) { ioAccessed.insert(name); } bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); } @@ -593,38 +801,27 @@ public: static int computeTypeLocationSize(const TType&, EShLanguage); static int computeTypeUniformLocationSize(const TType&); - bool setXfbBufferStride(int buffer, unsigned stride) - { - if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd) - return xfbBuffers[buffer].stride == stride; - xfbBuffers[buffer].stride = stride; - return true; - } - unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; } - int addXfbBufferOffset(const TType&); - unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const; 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 - void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; } - bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; } - void setGeoPassthroughEXT() { geoPassthroughEXT = true; } - bool getGeoPassthroughEXT() const { return geoPassthroughEXT; } -#endif - - const char* addSemanticName(const TString& name) - { - return semanticNameSet.insert(name).first->c_str(); - } + void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; } + bool getNanMinMaxClamp() const { return nanMinMaxClamp; } 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]); } @@ -632,19 +829,38 @@ public: void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } const std::vector& getProcesses() const { return processes.getProcesses(); } - void setNeedsLegalization() { needToLegalize = true; } - bool needsLegalization() const { return needToLegalize; } + // Certain explicit conversions are allowed conditionally +#ifdef GLSLANG_WEB + bool getArithemeticInt8Enabled() const { return false; } + bool getArithemeticInt16Enabled() const { return false; } + bool getArithemeticFloat16Enabled() const { return false; } +#else + bool getArithemeticInt8Enabled() const { + return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8); + } + bool getArithemeticInt16Enabled() const { + return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_AMD_gpu_shader_int16) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16); + } - void setBinaryDoubleOutput() { binaryDoubleOutput = true; } - bool getBinaryDoubleOutput() { return binaryDoubleOutput; } - - const char* const implicitThisName; - const char* const implicitCounterName; + bool getArithemeticFloat16Enabled() const { + return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) || + extensionRequested(E_GL_AMD_gpu_shader_half_float) || + extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16); + } +#endif 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&); @@ -652,7 +868,7 @@ protected: 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; @@ -665,15 +881,25 @@ protected: bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&); void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root); bool isConversionAllowed(TOperator op, TIntermTyped* node) const; - TIntermUnary* createConversion(TBasicType convertTo, TIntermTyped* node) const; std::tuple getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const; + + // JohnK: I think this function should go away. + // This data structure is just a log to pass on to back ends. + // Versioning and extensions are handled in Version.cpp, with a rich + // set of functions for querying stages, versions, extension enable/disabled, etc. +#ifdef GLSLANG_WEB + bool extensionRequested(const char *extension) const { return false; } +#else bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();} +#endif + 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; // source profile int version; // source version @@ -685,6 +911,20 @@ protected: int numErrors; int numPushConstants; bool recursive; + bool invertY; + bool useStorageBuffer; + bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN + bool depthReplacing; + int localSize[3]; + bool localSizeNotDefault[3]; + int localSizeSpecId[3]; +#ifndef GLSLANG_WEB +public: + const char* const implicitThisName; + const char* const implicitCounterName; +protected: + EShSource source; // source language, known a bit later + bool useVulkanMemoryModel; int invocations; int vertices; TLayoutGeometry inputPrimitive; @@ -693,61 +933,65 @@ protected: bool originUpperLeft; TVertexSpacing vertexSpacing; TVertexOrder vertexOrder; + TInterlockOrdering interlockOrdering; bool pointMode; - int localSize[3]; - int localSizeSpecId[3]; bool earlyFragmentTests; 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; -#endif + int numShaderRecordNVBlocks; + ComputeDerivativeMode computeDerivativeMode; + int primitives; + int numTaskNVBlocks; // Base shift values std::array shiftBinding; // Per-descriptor-set shift values - std::array, EResCount> shiftBindingForSet; + std::array, EResCount> shiftBindingForSet; std::vector resourceSetBinding; bool autoMapBindings; bool autoMapLocations; - bool invertY; bool flattenUniformArrays; bool useUnknownFormat; bool hlslOffsets; - bool useStorageBuffer; bool hlslIoMapping; + bool useVariablePointers; - typedef std::list TGraph; - TGraph callGraph; - - 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; EShTextureSamplerTransformMode textureSamplerTransformMode; + bool needToLegalize; + bool binaryDoubleOutput; + bool usePhysicalStorageBuffer; + + std::unordered_map uniformLocationOverrides; + int uniformLocationBase; +#endif + + std::unordered_set usedConstantId; // specialization constant ids used + std::vector usedAtomics; // sets of bindings used by atomic counters + std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers + // set of names of statically read/written I/O that might need extra checking + std::set ioAccessed; // source code of shader, useful as part of debug information 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; - private: void operator=(TIntermediate&); // prevent assignments }; diff --git a/Externals/glslang/glslang/MachineIndependent/parseVersions.h b/Externals/glslang/glslang/MachineIndependent/parseVersions.h old mode 100755 new mode 100644 index b2aaa39955..aa1964fc2e --- a/Externals/glslang/glslang/MachineIndependent/parseVersions.h +++ b/Externals/glslang/glslang/MachineIndependent/parseVersions.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2016 Google, Inc. +// Copyright (C) 2015-2018 Google, Inc. // Copyright (C) 2017 ARM Limited. // // All rights reserved. @@ -57,44 +57,131 @@ public: TParseVersions(TIntermediate& interm, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) - : infoSink(infoSink), version(version), profile(profile), language(language), - spvVersion(spvVersion), forwardCompatible(forwardCompatible), - intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } + : +#ifndef GLSLANG_WEB + forwardCompatible(forwardCompatible), + profile(profile), +#endif + infoSink(infoSink), version(version), + language(language), + spvVersion(spvVersion), + intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } virtual ~TParseVersions() { } + void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); + void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); +#ifdef GLSLANG_WEB + const EProfile profile = EEsProfile; + bool isEsProfile() const { return true; } + void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) + { + if (! (EEsProfile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); + } + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc) + { + if ((EEsProfile & profileMask) && (minVersion == 0 || version < minVersion)) + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); + } + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc) + { + profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); + } + void initializeExtensionBehavior() { } + void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { } + void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { } + void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc) { } + void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc) { } + TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; } + bool extensionTurnedOn(const char* const extension) { return false; } + bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; } + void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { } + void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { } + void checkExtensionStage(const TSourceLoc&, const char* const extension) { } + void fullIntegerCheck(const TSourceLoc&, const char* op) { } + void doubleCheck(const TSourceLoc&, const char* op) { } + bool float16Arithmetic() { return false; } + void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } + bool int16Arithmetic() { return false; } + void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } + bool int8Arithmetic() { return false; } + void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } + void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + bool relaxedErrors() const { return false; } + bool suppressWarnings() const { return true; } + bool isForwardCompatible() const { return false; } +#else + bool forwardCompatible; // true if errors are to be given for use of deprecated features + EProfile profile; // the declared profile in the shader (core by default) + bool isEsProfile() const { return profile == EEsProfile; } + void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc); + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc); + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc); virtual void initializeExtensionBehavior(); - virtual void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc); - virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc); - virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc); - virtual void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); - virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); - virtual void unimplemented(const TSourceLoc&, const char* featureDesc); - virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); - virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc); + virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc); virtual TExtensionBehavior getExtensionBehavior(const char*); virtual bool extensionTurnedOn(const char* const extension); virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); + virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior); + virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], + const char* featureDesc); + virtual void checkExtensionStage(const TSourceLoc&, const char* const extension); virtual void fullIntegerCheck(const TSourceLoc&, const char* op); + + virtual void unimplemented(const TSourceLoc&, const char* featureDesc); virtual void doubleCheck(const TSourceLoc&, const char* op); virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false); -#ifdef AMD_EXTENSIONS + 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); 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 fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void intcoopmatCheck(const TSourceLoc&, const char *op, bool builtIn = false); + bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } + bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } + bool isForwardCompatible() const { return forwardCompatible; } +#endif // GLSLANG_WEB 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); + +#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL) + void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { addError(); } + void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { } + void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { addError(); } + void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, + const char* szExtraInfoFormat, ...) { } +#else virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) = 0; virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, @@ -103,6 +190,7 @@ public: const char* szExtraInfoFormat, ...) = 0; virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) = 0; +#endif void addError() { ++numErrors; } int getNumErrors() const { return numErrors; } @@ -116,19 +204,20 @@ public: void setCurrentString(int string) { currentScanner->setString(string); } void getPreamble(std::string&); - bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } - bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } +#ifdef ENABLE_HLSL bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } + bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } +#else + bool isReadingHLSL() const { return false; } +#endif TInfoSink& infoSink; // compilation mode int version; // version, updated by #version in the shader - EProfile profile; // the declared profile in the shader (core by default) EShLanguage language; // really the stage SpvVersion spvVersion; - bool forwardCompatible; // true if errors are to be given for use of deprecated features TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree protected: diff --git a/Externals/glslang/glslang/MachineIndependent/pch.cpp b/Externals/glslang/glslang/MachineIndependent/pch.cpp new file mode 100644 index 0000000000..b7a08654a5 --- /dev/null +++ b/Externals/glslang/glslang/MachineIndependent/pch.cpp @@ -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 --git a/Externals/glslang/glslang/MachineIndependent/pch.h b/Externals/glslang/glslang/MachineIndependent/pch.h new file mode 100644 index 0000000000..6ea3761ea1 --- /dev/null +++ b/Externals/glslang/glslang/MachineIndependent/pch.h @@ -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 --git a/Externals/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/Externals/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp old mode 100644 new mode 100755 index 8048fa513d..d7ff485c0a --- a/Externals/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/Externals/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -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 @@ int TPpContext::CPPdefine(TPpToken* ppToken) // 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 @@ int TPpContext::CPPdefine(TPpToken* ppToken) return token; } - mac.emptyArgs = 0; const int argAtom = atomStrings.getAddAtom(ppToken->name); // check for duplication of parameter name @@ -146,10 +147,13 @@ int TPpContext::CPPdefine(TPpToken* ppToken) } 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 @@ int TPpContext::CPPdefine(TPpToken* ppToken) 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,24 +535,28 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo 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) { - if (! shortCircuit && parseContext.profile == EEsProfile) { + case MacroExpandStarted: + break; + case MacroExpandUndef: + if (! shortCircuit && parseContext.isEsProfile()) { const char* message = "undefined macro in expression not allowed in es profile"; if (parseContext.relaxedErrors()) parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name); else parseContext.ppError(ppToken->loc, message, "preprocessor evaluation", ppToken->name); } + break; } token = scanToken(ppToken); + if (err) + break; } return token; @@ -647,6 +671,7 @@ int TPpContext::CPPinclude(TPpToken* ppToken) 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 { @@ -697,6 +722,7 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentLine(lineRes); if (token != '\n') { +#ifndef GLSLANG_WEB if (token == PpAtomConstString) { parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line"); // We need to save a copy of the string instead of pointing @@ -706,7 +732,9 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentSourceName(sourceName); hasFile = true; token = scanToken(ppToken); - } else { + } else +#endif + { token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken); if (! fileErr) { parseContext.setCurrentString(fileRes); @@ -767,10 +795,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken) case PpAtomConstUint: case PpAtomConstInt64: case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS case PpAtomConstInt16: case PpAtomConstUint16: -#endif case PpAtomConstFloat: case PpAtomConstDouble: case PpAtomConstFloat16: @@ -855,8 +881,7 @@ int TPpContext::CPPextension(TPpToken* ppToken) 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 != ':') { @@ -930,18 +955,20 @@ int TPpContext::readCPPline(TPpToken* ppToken) case PpAtomIfndef: token = CPPifdef(0, ppToken); break; + case PpAtomLine: + token = CPPline(ppToken); + break; +#ifndef GLSLANG_WEB case PpAtomInclude: if(!parseContext.isReadingHLSL()) { parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); } token = CPPinclude(ppToken); break; - case PpAtomLine: - token = CPPline(ppToken); - break; case PpAtomPragma: token = CPPpragma(ppToken); break; +#endif case PpAtomUndef: token = CPPundef(ppToken); break; @@ -1011,20 +1038,29 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* 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; @@ -1106,7 +1142,8 @@ int TPpContext::tZeroInput::scan(TPpToken* ppToken) if (done) return EndOfInput; - strcpy(ppToken->name, "0"); + ppToken->name[0] = '0'; + ppToken->name[1] = 0; ppToken->ival = 0; ppToken->space = false; done = true; @@ -1115,14 +1152,18 @@ int TPpContext::tZeroInput::scan(TPpToken* ppToken) } // -// 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); @@ -1131,7 +1172,7 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka 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) @@ -1139,50 +1180,55 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka 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++) @@ -1193,63 +1239,70 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka 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)); } @@ -1264,7 +1317,7 @@ int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOka macro->busy = 1; macro->body.reset(); - return 1; + return MacroExpandStarted; } } // end namespace glslang diff --git a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp index c89b37688a..cc003a8d12 100755 --- a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp +++ b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -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 diff --git a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h old mode 100755 new mode 100644 index b3a39c5cbc..8470e172a2 --- a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h @@ -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 @@ -83,6 +84,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "../ParseHelper.h" +#include "PpTokens.h" /* windows only pragma */ #ifdef _MSC_VER @@ -183,6 +185,13 @@ protected: 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. @@ -204,7 +213,8 @@ public: 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; } @@ -235,24 +245,79 @@ public: // 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; }; // @@ -260,12 +325,12 @@ public: // 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; @@ -312,6 +377,10 @@ protected: 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(); } @@ -336,6 +405,7 @@ protected: 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; } @@ -400,7 +470,7 @@ protected: 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 @@ -410,14 +480,18 @@ protected: 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 { @@ -526,7 +600,7 @@ protected: 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) { @@ -541,9 +615,9 @@ protected: 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: @@ -583,8 +657,6 @@ protected: 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 diff --git a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp index 0c620a5f5b..c293af3c1e 100755 --- a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -2,6 +2,8 @@ // 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 @@ -94,12 +96,19 @@ namespace glslang { /////////////////////////////////// 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) { const auto saveName = [&](int ch) { @@ -133,6 +142,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) ch = getChar(); int firstDecimal = len; +#ifdef ENABLE_HLSL // 1.#INF or -1.#INF if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) { if ((len < 2) || @@ -160,6 +170,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) } } } +#endif // Consume leading-zero digits after the decimal point while (ch == '0') { @@ -248,6 +259,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) // Suffix: bool isDouble = false; bool isFloat16 = false; +#ifndef GLSLANG_WEB if (ch == 'l' || ch == 'L') { if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); @@ -286,11 +298,15 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) saveName(ch); isFloat16 = true; } - } else if (ch == 'f' || ch == 'F') { + } else +#endif + if (ch == 'f' || ch == 'F') { +#ifndef GLSLANG_WEB 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"); +#endif if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); saveName(ch); @@ -316,16 +332,32 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) 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(ppToken->name); + strtodStream.str(numstr.c_str()); strtodStream >> ppToken->dval; - // Assume failure combined with a large exponent was overflow, in - // an attempt to set INF. Otherwise, assume underflow, and set 0.0. 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 - else + // 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 } } @@ -417,6 +449,14 @@ int TPpContext::characterLiteral(TPpToken* ppToken) // // 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; @@ -430,16 +470,14 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) static const char* const Int64_Extensions[] = { E_GL_ARB_gpu_shader_int64, - E_GL_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_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_KHX_shader_explicit_arithmetic_types, - E_GL_KHX_shader_explicit_arithmetic_types_int16 }; + 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; @@ -546,6 +584,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; +#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -554,7 +593,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) } else ungetch(); -#ifdef AMD_EXTENSIONS nextCh = getch(); if ((nextCh == 's' || nextCh == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { @@ -563,12 +601,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) isInt16 = true; } else ungetch(); -#endif } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; -#ifdef AMD_EXTENSIONS } else if ((ch == 's' || ch == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) @@ -656,6 +692,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; +#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -664,7 +701,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) } else ungetch(); -#ifdef AMD_EXTENSIONS nextCh = getch(); if ((nextCh == 's' || nextCh == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { @@ -673,12 +709,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) isInt16 = true; } else ungetch(); -#endif } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; -#ifdef AMD_EXTENSIONS } else if ((ch == 's' || ch == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) @@ -747,6 +781,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; +#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -755,7 +790,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) } else ungetch(); -#ifdef AMD_EXTENSIONS nextCh = getch(); if ((nextCh == 's' || nextCh == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { @@ -764,12 +798,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) isInt16 = true; } else ungetch(); -#endif } else if (ch == 'l' || ch == 'L') { if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt64 = true; -#ifdef AMD_EXTENSIONS } else if ((ch == 's' || ch == 'S') && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { if (len < MaxTokenLength) @@ -1061,8 +1093,17 @@ int TPpContext::tokenize(TPpToken& ppToken) 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: @@ -1089,7 +1130,7 @@ int TPpContext::tokenize(TPpToken& ppToken) 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; } @@ -1126,61 +1167,69 @@ int TPpContext::tokenPaste(int token, TPpToken& ppToken) break; } - // get the token after the ## - token = scanToken(&pastedPpToken); + // 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); - // This covers end of argument expansion - if (token == tMarkerInput::marker) { - parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); - break; - } + // This covers end of argument expansion + if (token == tMarkerInput::marker) { + parseContext.ppError(ppToken.loc, "unexpected location; end of argument", "##", ""); + return resultToken; + } - // 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 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; - } - strncat(ppToken.name, pastedPpToken.name, MaxTokenLength - strlen(ppToken.name)); + // 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", "##", ""); - } + // 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 --git a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp index d8088e7d4d..7ed58703f2 100755 --- a/Externals/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp +++ b/Externals/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp @@ -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,150 +99,34 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace glslang { - -namespace { - - // When recording (and playing back) should the backing name string - // be saved (restored)? - bool SaveName(int atom) - { - switch (atom) { - case PpAtomIdentifier: - case PpAtomConstString: - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: - #ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: - #endif - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - return true; - default: - return false; - } - } - - // When recording (and playing back) should the numeric value - // be saved (restored)? - bool SaveValue(int atom) - { - switch (atom) { - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: - #ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: - #endif - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - return true; - default: - return false; - } - } -} - -// 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. +// 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) { - // save the atom - assert((atom & ~0xff) == 0); - putSubtoken(static_cast(atom)); - - // save the backing name string - if (SaveName(atom)) { - const char* s = ppToken->name; - while (*s) - putSubtoken(*s++); - putSubtoken(0); - } - - // save the numeric value - if (SaveValue(atom)) { - const char* n = reinterpret_cast(&ppToken->i64val); - for (int i = 0; i < sizeof(ppToken->i64val); ++i) - putSubtoken(*n++); - } + 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) { - // get the atom - int atom = getSubtoken(); - if (atom == EndOfInput) - return atom; + if (atEnd()) + return EndOfInput; - // init the token - ppToken->clear(); + int atom = stream[currentPos++].get(*ppToken); ppToken->loc = parseContext.getCurrentLoc(); - // get the backing name string - if (SaveName(atom)) { - int ch = getSubtoken(); - int len = 0; - 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; - } - +#ifndef GLSLANG_WEB // Check for ##, unless the current # is the last character if (atom == '#') { - if (current < data.size()) { - if (getSubtoken() == '#') { - parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); - parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); - atom = PpAtomPaste; - } else - ungetSubtoken(); + if (peekToken('#')) { + parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); + currentPos++; + atom = PpAtomPaste; } } - - // get the numeric value - if (SaveValue(atom)) { - char* n = reinterpret_cast(&ppToken->i64val); - for (int i = 0; i < sizeof(ppToken->i64val); ++i) - *n++ = getSubtoken(); - } +#endif return atom; } @@ -254,15 +140,14 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) { // 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 ## @@ -271,18 +156,18 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) // 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; } @@ -291,23 +176,21 @@ bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes) 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 --git a/Externals/glslang/glslang/MachineIndependent/propagateNoContraction.cpp b/Externals/glslang/glslang/MachineIndependent/propagateNoContraction.cpp index ae95688ae8..83a3230f51 100644 --- a/Externals/glslang/glslang/MachineIndependent/propagateNoContraction.cpp +++ b/Externals/glslang/glslang/MachineIndependent/propagateNoContraction.cpp @@ -37,6 +37,8 @@ // propagate the 'noContraction' qualifier. // +#ifndef GLSLANG_WEB + #include "propagateNoContraction.h" #include @@ -79,7 +81,7 @@ typedef std::unordered_set ReturnBranchNodeSet; // the node has 'noContraction' qualifier, otherwise false. bool isPreciseObjectNode(glslang::TIntermTyped* node) { - return node->getType().getQualifier().noContraction; + return node->getType().getQualifier().isNoContraction(); } // Returns true if the opcode is a dereferencing one. @@ -864,3 +866,5 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate) } } }; + +#endif // GLSLANG_WEB \ No newline at end of file diff --git a/Externals/glslang/glslang/MachineIndependent/reflection.cpp b/Externals/glslang/glslang/MachineIndependent/reflection.cpp index 4818b10832..b09367113c 100644 --- a/Externals/glslang/glslang/MachineIndependent/reflection.cpp +++ b/Externals/glslang/glslang/MachineIndependent/reflection.cpp @@ -33,6 +33,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #include "../Include/Common.h" #include "reflection.h" #include "LiveTraverser.h" @@ -93,72 +95,133 @@ public: // 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; + + + TReflection::TNameToIndex &ioMapper = + input ? reflection.pipeInNameToIndex : reflection.pipeOutNameToIndex; + + 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 = ioMapper.find(name.c_str()); + if (it == ioMapper.end()) { + // seperate pipe i/o params from uniforms and blocks + // in is only for input in first stage as out is only for last stage. check traverse in call stack. + ioMapper[name.c_str()] = static_cast(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; - } + 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; - return offset; + // 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 block data size. - // Block arrayness is not taken into account, each element is backed by a separate buffer. - int getBlockSize(const TType& blockType) + // Calculate the stride of an array type + int getArrayStride(const TType& baseType, const TType& type) { - const TTypeList& memberList = *blockType.getStruct(); - int lastIndex = (int)memberList.size() - 1; - int lastOffset = getOffset(blockType, lastIndex); + int dummySize; + int stride; - int lastMemberSize; - int dummyStride; - intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride, - blockType.getQualifier().layoutPacking == ElpStd140, - blockType.getQualifier().layoutMatrix == ElmRowMajor); + // consider blocks to have 0 stride, so that all offsets are relative to the start of their block + if (type.getBasicType() == EbtBlock) + return 0; - return lastOffset + lastMemberSize; + 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; + + 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 +232,19 @@ public: // 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 +253,54 @@ public: 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 +312,65 @@ public: // 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 +378,10 @@ public: 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 +389,100 @@ public: 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->isAtomic()) + 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 +532,10 @@ public: 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 +543,60 @@ public: 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) { + TType structDerefType(base->getType(), 0); + + const TType &structType = base->getType().isArray() ? structDerefType : base->getType(); + const TTypeList& typeList = *structType.getStruct(); + + TVector memberOffsets; + + memberOffsets.resize(typeList.size()); + getOffsets(structType, memberOffsets); + + for (int i = 0; i < (int)typeList.size(); ++i) { + TType derefType(structType, 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(structType, 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 +626,39 @@ public: 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,7 +711,6 @@ public: case EsdBuffer: return GL_SAMPLER_BUFFER; } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch ((int)sampler.dim) { case Esd1D: @@ -444,7 +739,6 @@ public: case EsdBuffer: return GL_FLOAT16_SAMPLER_BUFFER_AMD; } -#endif case EbtInt: switch ((int)sampler.dim) { case Esd1D: @@ -507,7 +801,6 @@ public: case EsdBuffer: return GL_IMAGE_BUFFER; } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch ((int)sampler.dim) { case Esd1D: @@ -526,7 +819,6 @@ public: case EsdBuffer: return GL_FLOAT16_IMAGE_BUFFER_AMD; } -#endif case EbtInt: switch ((int)sampler.dim) { case Esd1D: @@ -592,9 +884,7 @@ public: switch (type.getBasicType()) { case EbtFloat: return GL_FLOAT_VEC2 + offset; case EbtDouble: return GL_DOUBLE_VEC2 + offset; -#ifdef AMD_EXTENSIONS case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset; -#endif case EbtInt: return GL_INT_VEC2 + offset; case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset; case EbtInt64: return GL_INT64_ARB + offset; @@ -654,7 +944,6 @@ public: default: return 0; } } -#ifdef AMD_EXTENSIONS case EbtFloat16: switch (type.getMatrixCols()) { case 2: @@ -679,7 +968,6 @@ public: default: return 0; } } -#endif default: return 0; } @@ -688,9 +976,7 @@ public: switch (type.getBasicType()) { case EbtFloat: return GL_FLOAT; case EbtDouble: return GL_DOUBLE; -#ifdef AMD_EXTENSIONS case EbtFloat16: return GL_FLOAT16_NV; -#endif case EbtInt: return GL_INT; case EbtUint: return GL_UNSIGNED_INT; case EbtInt64: return GL_INT64_ARB; @@ -746,8 +1032,47 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base) 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"); } // @@ -768,14 +1093,32 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat // build counter block index associations for buffers void TReflection::buildCounterIndices(const TIntermediate& intermediate) { +#ifdef ENABLE_HLSL // search for ones that have counters for (int i = 0; i < int(indexToUniformBlock.size()); ++i) { - const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name)); + const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str()); const int index = getIndex(counterName); if (index >= 0) indexToUniformBlock[i].counterIndex = index; } +#endif +} + +// 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. @@ -803,6 +1146,7 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate) } buildCounterIndices(intermediate); + buildUniformStageMask(intermediate); return true; } @@ -819,9 +1163,24 @@ void TReflection::dump() 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) { @@ -841,3 +1200,5 @@ void TReflection::dump() } } // end namespace glslang + +#endif // GLSLANG_WEB diff --git a/Externals/glslang/glslang/MachineIndependent/reflection.h b/Externals/glslang/glslang/MachineIndependent/reflection.h index bf233e33eb..efdc8934fb 100644 --- a/Externals/glslang/glslang/MachineIndependent/reflection.h +++ b/Externals/glslang/glslang/MachineIndependent/reflection.h @@ -33,6 +33,8 @@ // POSSIBILITY OF SUCH DAMAGE. // +#ifndef GLSLANG_WEB + #ifndef _REFLECTION_INCLUDED #define _REFLECTION_INCLUDED @@ -52,49 +54,11 @@ class TIntermediate; 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 +89,57 @@ public: 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)indexToAttribute.size()) - return indexToAttribute[i]; + if (i >= 0 && i < (int)indexToPipeInput.size()) + return indexToPipeInput[i]; else return badReflection; } - // for mapping any name to its index (block names, uniform names and attribute names) + // 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)indexToPipeOutput.size()) + return indexToPipeOutput[i]; + else + return badReflection; + } + + // 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); @@ -148,6 +152,20 @@ public: // see getIndex(const char*) int getIndex(const TString& name) const { return getIndex(name.c_str()); } + + // for mapping any name to its index (only pipe input/output names) + int getPipeIOIndex(const char* name, const bool inOrOut) const + { + TNameToIndex::const_iterator it = inOrOut ? pipeInNameToIndex.find(name) : pipeOutNameToIndex.find(name); + if (it == (inOrOut ? pipeInNameToIndex.end() : pipeOutNameToIndex.end())) + return -1; + else + return it->second; + } + + // see gePipeIOIndex(const char*, const bool) + int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); } + // Thread local size unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; } @@ -157,17 +175,43 @@ protected: friend class glslang::TReflectionTraverser; 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 + TNameToIndex pipeInNameToIndex; // maps pipe in names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers. + TNameToIndex pipeOutNameToIndex; // maps pipe out names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers. TMapIndexToReflection indexToUniform; TMapIndexToReflection indexToUniformBlock; - TMapIndexToReflection indexToAttribute; + TMapIndexToReflection indexToBufferVariable; + TMapIndexToReflection indexToBufferBlock; + TMapIndexToReflection indexToPipeInput; + TMapIndexToReflection indexToPipeOutput; + TIndices atomicCounterUniformIndices; unsigned int localSize[3]; }; @@ -175,3 +219,5 @@ protected: } // end namespace glslang #endif // _REFLECTION_INCLUDED + +#endif // GLSLANG_WEB \ No newline at end of file diff --git a/Externals/glslang/glslang/OSDependent/Unix/CMakeLists.txt b/Externals/glslang/glslang/OSDependent/Unix/CMakeLists.txt index 1bf49e1256..9994314fd5 100644 --- a/Externals/glslang/glslang/OSDependent/Unix/CMakeLists.txt +++ b/Externals/glslang/glslang/OSDependent/Unix/CMakeLists.txt @@ -2,7 +2,25 @@ add_library(OSDependent STATIC ossource.cpp ../osinclude.h) set_property(TARGET OSDependent PROPERTY FOLDER glslang) set_property(TARGET OSDependent PROPERTY POSITION_INDEPENDENT_CODE ON) +# Link pthread +set(CMAKE_THREAD_PREFER_PTHREAD ON) +if(${CMAKE_VERSION} VERSION_LESS "3.1.0" OR CMAKE_CROSSCOMPILING) + # Needed as long as we support CMake 2.8 for Ubuntu 14.04, + # which does not support the recommended Threads::Threads target. + # https://cmake.org/cmake/help/v2.8.12/cmake.html#module:FindThreads + # Also needed when cross-compiling to work around + # https://gitlab.kitware.com/cmake/cmake/issues/16920 + find_package(Threads) + target_link_libraries(OSDependent ${CMAKE_THREAD_LIBS_INIT}) +else() + # This is the recommended way, so we use it for 3.1+. + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads) + target_link_libraries(OSDependent Threads::Threads) +endif() + if(ENABLE_GLSLANG_INSTALL) - install(TARGETS OSDependent + install(TARGETS OSDependent EXPORT OSDependentTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/glslang/OSDependent/Unix/ossource.cpp b/Externals/glslang/glslang/OSDependent/Unix/ossource.cpp index f59bbceb4a..3f029f0239 100644 --- a/Externals/glslang/glslang/OSDependent/Unix/ossource.cpp +++ b/Externals/glslang/glslang/OSDependent/Unix/ossource.cpp @@ -45,7 +45,10 @@ #include #include #include + +#if !defined(__Fuchsia__) #include +#endif namespace glslang { @@ -70,7 +73,7 @@ static void DetachThreadLinux(void *) // void OS_CleanupThreadData(void) { -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__Fuchsia__) DetachThreadLinux(NULL); #else int old_cancel_state, old_cancel_type; diff --git a/Externals/glslang/glslang/OSDependent/Web/CMakeLists.txt b/Externals/glslang/glslang/OSDependent/Web/CMakeLists.txt new file mode 100644 index 0000000000..e8238c3504 --- /dev/null +++ b/Externals/glslang/glslang/OSDependent/Web/CMakeLists.txt @@ -0,0 +1,24 @@ +add_executable(glslang.js "glslang.js.cpp") +glslang_set_link_args(glslang.js) +target_link_libraries(glslang.js glslang SPIRV) +if(EMSCRIPTEN) + set_target_properties(glslang.js PROPERTIES + OUTPUT_NAME "glslang" + SUFFIX ".js") + em_link_pre_js(glslang.js "${CMAKE_CURRENT_SOURCE_DIR}/glslang.pre.js") + + target_link_options(glslang.js PRIVATE + "SHELL:--bind -s MODULARIZE=1") + if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE) + target_link_options(glslang.js PRIVATE + "SHELL:-s ENVIRONMENT=node -s BINARYEN_ASYNC_COMPILATION=0") + else() + target_link_options(glslang.js PRIVATE + "SHELL:-s ENVIRONMENT=web,worker") + endif() + + if(NOT ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE) + add_custom_command(TARGET glslang.js POST_BUILD + COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js) + endif() +endif(EMSCRIPTEN) diff --git a/Externals/glslang/glslang/OSDependent/Web/glslang.after.js b/Externals/glslang/glslang/OSDependent/Web/glslang.after.js new file mode 100644 index 0000000000..c2cfc35a48 --- /dev/null +++ b/Externals/glslang/glslang/OSDependent/Web/glslang.after.js @@ -0,0 +1,26 @@ +export default (() => { + const initialize = () => { + return new Promise(resolve => { + Module({ + locateFile() { + const i = import.meta.url.lastIndexOf('/') + return import.meta.url.substring(0, i) + '/glslang.wasm'; + }, + onRuntimeInitialized() { + resolve({ + compileGLSLZeroCopy: this.compileGLSLZeroCopy, + compileGLSL: this.compileGLSL, + }); + }, + }); + }); + }; + + let instance; + return () => { + if (!instance) { + instance = initialize(); + } + return instance; + }; +})(); diff --git a/Externals/glslang/glslang/OSDependent/Web/glslang.js.cpp b/Externals/glslang/glslang/OSDependent/Web/glslang.js.cpp new file mode 100644 index 0000000000..6cb93fe27e --- /dev/null +++ b/Externals/glslang/glslang/OSDependent/Web/glslang.js.cpp @@ -0,0 +1,269 @@ +// +// Copyright (C) 2019 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. +// + +#include +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "../../../SPIRV/GlslangToSpv.h" +#include "../../../glslang/Public/ShaderLang.h" + +#ifndef __EMSCRIPTEN__ +#define EMSCRIPTEN_KEEPALIVE +#endif + +const TBuiltInResource DefaultTBuiltInResource = { + /* .MaxLights = */ 32, + /* .MaxClipPlanes = */ 6, + /* .MaxTextureUnits = */ 32, + /* .MaxTextureCoords = */ 32, + /* .MaxVertexAttribs = */ 64, + /* .MaxVertexUniformComponents = */ 4096, + /* .MaxVaryingFloats = */ 64, + /* .MaxVertexTextureImageUnits = */ 32, + /* .MaxCombinedTextureImageUnits = */ 80, + /* .MaxTextureImageUnits = */ 32, + /* .MaxFragmentUniformComponents = */ 4096, + /* .MaxDrawBuffers = */ 32, + /* .MaxVertexUniformVectors = */ 128, + /* .MaxVaryingVectors = */ 8, + /* .MaxFragmentUniformVectors = */ 16, + /* .MaxVertexOutputVectors = */ 16, + /* .MaxFragmentInputVectors = */ 15, + /* .MinProgramTexelOffset = */ -8, + /* .MaxProgramTexelOffset = */ 7, + /* .MaxClipDistances = */ 8, + /* .MaxComputeWorkGroupCountX = */ 65535, + /* .MaxComputeWorkGroupCountY = */ 65535, + /* .MaxComputeWorkGroupCountZ = */ 65535, + /* .MaxComputeWorkGroupSizeX = */ 1024, + /* .MaxComputeWorkGroupSizeY = */ 1024, + /* .MaxComputeWorkGroupSizeZ = */ 64, + /* .MaxComputeUniformComponents = */ 1024, + /* .MaxComputeTextureImageUnits = */ 16, + /* .MaxComputeImageUniforms = */ 8, + /* .MaxComputeAtomicCounters = */ 8, + /* .MaxComputeAtomicCounterBuffers = */ 1, + /* .MaxVaryingComponents = */ 60, + /* .MaxVertexOutputComponents = */ 64, + /* .MaxGeometryInputComponents = */ 64, + /* .MaxGeometryOutputComponents = */ 128, + /* .MaxFragmentInputComponents = */ 128, + /* .MaxImageUnits = */ 8, + /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8, + /* .MaxCombinedShaderOutputResources = */ 8, + /* .MaxImageSamples = */ 0, + /* .MaxVertexImageUniforms = */ 0, + /* .MaxTessControlImageUniforms = */ 0, + /* .MaxTessEvaluationImageUniforms = */ 0, + /* .MaxGeometryImageUniforms = */ 0, + /* .MaxFragmentImageUniforms = */ 8, + /* .MaxCombinedImageUniforms = */ 8, + /* .MaxGeometryTextureImageUnits = */ 16, + /* .MaxGeometryOutputVertices = */ 256, + /* .MaxGeometryTotalOutputComponents = */ 1024, + /* .MaxGeometryUniformComponents = */ 1024, + /* .MaxGeometryVaryingComponents = */ 64, + /* .MaxTessControlInputComponents = */ 128, + /* .MaxTessControlOutputComponents = */ 128, + /* .MaxTessControlTextureImageUnits = */ 16, + /* .MaxTessControlUniformComponents = */ 1024, + /* .MaxTessControlTotalOutputComponents = */ 4096, + /* .MaxTessEvaluationInputComponents = */ 128, + /* .MaxTessEvaluationOutputComponents = */ 128, + /* .MaxTessEvaluationTextureImageUnits = */ 16, + /* .MaxTessEvaluationUniformComponents = */ 1024, + /* .MaxTessPatchComponents = */ 120, + /* .MaxPatchVertices = */ 32, + /* .MaxTessGenLevel = */ 64, + /* .MaxViewports = */ 16, + /* .MaxVertexAtomicCounters = */ 0, + /* .MaxTessControlAtomicCounters = */ 0, + /* .MaxTessEvaluationAtomicCounters = */ 0, + /* .MaxGeometryAtomicCounters = */ 0, + /* .MaxFragmentAtomicCounters = */ 8, + /* .MaxCombinedAtomicCounters = */ 8, + /* .MaxAtomicCounterBindings = */ 1, + /* .MaxVertexAtomicCounterBuffers = */ 0, + /* .MaxTessControlAtomicCounterBuffers = */ 0, + /* .MaxTessEvaluationAtomicCounterBuffers = */ 0, + /* .MaxGeometryAtomicCounterBuffers = */ 0, + /* .MaxFragmentAtomicCounterBuffers = */ 1, + /* .MaxCombinedAtomicCounterBuffers = */ 1, + /* .MaxAtomicCounterBufferSize = */ 16384, + /* .MaxTransformFeedbackBuffers = */ 4, + /* .MaxTransformFeedbackInterleavedComponents = */ 64, + /* .MaxCullDistances = */ 8, + /* .MaxCombinedClipAndCullDistances = */ 8, + /* .MaxSamples = */ 4, + /* .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, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, + }}; + +static bool initialized = false; + +extern "C" { + +/* + * Takes in a GLSL shader as a string and converts it to SPIR-V in binary form. + * + * |glsl| Null-terminated string containing the shader to be converted. + * |stage_int| Magic number indicating the type of shader being processed. +* Legal values are as follows: + * Vertex = 0 + * Fragment = 4 + * Compute = 5 + * |gen_debug| Flag to indicate if debug information should be generated. + * |spirv| Output parameter for a pointer to the resulting SPIR-V data. + * |spirv_len| Output parameter for the length of the output binary buffer. + * + * Returns a void* pointer which, if not null, must be destroyed by + * destroy_output_buffer.o. (This is not the same pointer returned in |spirv|.) + * If null, the compilation failed. + */ +EMSCRIPTEN_KEEPALIVE +void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uint32_t** spirv, size_t* spirv_len) +{ + if (glsl == nullptr) { + fprintf(stderr, "Input pointer null\n"); + return nullptr; + } + if (spirv == nullptr || spirv_len == nullptr) { + fprintf(stderr, "Output pointer null\n"); + return nullptr; + } + *spirv = nullptr; + *spirv_len = 0; + + if (stage_int != 0 && stage_int != 4 && stage_int != 5) { + fprintf(stderr, "Invalid shader stage\n"); + return nullptr; + } + EShLanguage stage = static_cast(stage_int); + + if (!initialized) { + glslang::InitializeProcess(); + initialized = true; + } + + glslang::TShader shader(stage); + shader.setStrings(&glsl, 1); + shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100); + shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1); + shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + if (!shader.parse(&DefaultTBuiltInResource, 100, true, EShMsgDefault)) { + fprintf(stderr, "Parse failed\n"); + fprintf(stderr, "%s\n", shader.getInfoLog()); + return nullptr; + } + + glslang::TProgram program; + program.addShader(&shader); + if (!program.link(EShMsgDefault)) { + fprintf(stderr, "Link failed\n"); + fprintf(stderr, "%s\n", program.getInfoLog()); + return nullptr; + } + + glslang::SpvOptions spvOptions; + spvOptions.generateDebugInfo = gen_debug; + spvOptions.optimizeSize = false; + spvOptions.disassemble = false; + spvOptions.validate = false; + + std::vector* output = new std::vector; + glslang::GlslangToSpv(*program.getIntermediate(stage), *output, nullptr, &spvOptions); + + *spirv_len = output->size(); + *spirv = output->data(); + return output; +} + +/* + * Destroys a buffer created by convert_glsl_to_spirv + */ +EMSCRIPTEN_KEEPALIVE +void destroy_output_buffer(void* p) +{ + delete static_cast*>(p); +} + +} // extern "C" + +/* + * For non-Emscripten builds we supply a generic main, so that the glslang.js + * build target can generate an executable with a trivial use case instead of + * generating a WASM binary. This is done so that there is a target that can be + * built and output analyzed using desktop tools, since WASM binaries are + * specific to the Emscripten toolchain. + */ +#ifndef __EMSCRIPTEN__ +int main() { + const char* input = R"(#version 310 es + +void main() { })"; + + uint32_t* output; + size_t output_len; + + void* id = convert_glsl_to_spirv(input, 4, false, &output, &output_len); + assert(output != nullptr); + assert(output_len != 0); + destroy_output_buffer(id); + return 0; +} +#endif // ifndef __EMSCRIPTEN__ diff --git a/Externals/glslang/glslang/OSDependent/Web/glslang.pre.js b/Externals/glslang/glslang/OSDependent/Web/glslang.pre.js new file mode 100644 index 0000000000..7d3fd0234c --- /dev/null +++ b/Externals/glslang/glslang/OSDependent/Web/glslang.pre.js @@ -0,0 +1,45 @@ +Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug) { + gen_debug = !!gen_debug; + + var shader_stage_int; + if (shader_stage === 'vertex') { + shader_stage_int = 0; + } else if (shader_stage === 'fragment') { + shader_stage_int = 4; + } else if (shader_stage === 'compute') { + shader_stage_int = 5; + } else { + throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'"); + } + + var p_output = Module['_malloc'](4); + var p_output_len = Module['_malloc'](4); + var id = ccall('convert_glsl_to_spirv', + 'number', + ['string', 'number', 'boolean', 'number', 'number'], + [glsl, shader_stage_int, gen_debug, p_output, p_output_len]); + var output = getValue(p_output, 'i32'); + var output_len = getValue(p_output_len, 'i32'); + Module['_free'](p_output); + Module['_free'](p_output_len); + + if (id === 0) { + throw new Error('GLSL compilation failed'); + } + + var ret = {}; + var outputIndexU32 = output / 4; + ret['data'] = Module['HEAPU32'].subarray(outputIndexU32, outputIndexU32 + output_len); + ret['free'] = function() { + Module['_destroy_output_buffer'](id); + }; + + return ret; +}; + +Module['compileGLSL'] = function(glsl, shader_stage, gen_debug) { + var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug); + var ret = compiled['data'].slice() + compiled['free'](); + return ret; +}; diff --git a/Externals/glslang/glslang/OSDependent/Windows/CMakeLists.txt b/Externals/glslang/glslang/OSDependent/Windows/CMakeLists.txt index f257418abb..c050ef61de 100644 --- a/Externals/glslang/glslang/OSDependent/Windows/CMakeLists.txt +++ b/Externals/glslang/glslang/OSDependent/Windows/CMakeLists.txt @@ -15,6 +15,7 @@ if(WIN32) endif(WIN32) if(ENABLE_GLSLANG_INSTALL) - install(TARGETS OSDependent + install(TARGETS OSDependent EXPORT OSDependentTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/glslang/Public/ShaderLang.h b/Externals/glslang/glslang/Public/ShaderLang.h old mode 100644 new mode 100755 index 5c629eeb88..4fe5c7df19 --- a/Externals/glslang/glslang/Public/ShaderLang.h +++ b/Externals/glslang/glslang/Public/ShaderLang.h @@ -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 @@ -70,7 +68,7 @@ // 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 7 +#define GLSLANG_MINOR_VERSION 13 // // Call before doing any other compiler/linker operations. @@ -82,7 +80,7 @@ SH_IMPORT_EXPORT int ShInitialize(); // // 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. @@ -94,6 +92,14 @@ typedef enum { EShLangGeometry, EShLangFragment, EShLangCompute, + EShLangRayGenNV, + EShLangIntersectNV, + EShLangAnyHitNV, + EShLangClosestHitNV, + EShLangMissNV, + EShLangCallableNV, + EShLangTaskNV, + EShLangMeshNV, EShLangCount, } EShLanguage; // would be better as stage, but this is ancient now @@ -104,6 +110,14 @@ typedef enum { 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 { @@ -112,33 +126,38 @@ class TType; typedef enum { EShSourceNone, - EShSourceGlsl, - EShSourceHlsl, -} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead + EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL) + EShSourceHlsl, // HLSL +} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead typedef enum { - EShClientNone, + EShClientNone, // use when there is no client, e.g. for validation EShClientVulkan, EShClientOpenGL, } EShClient; typedef enum { EShTargetNone, - EShTargetSpv, // preferred spelling + EShTargetSpv, // SPIR-V (preferred spelling) EshTargetSpv = EShTargetSpv, // legacy spelling } EShTargetLanguage; typedef enum { - EShTargetVulkan_1_0 = (1 << 22), - EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), - EShTargetOpenGL_450 = 450, + EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0 + EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1 + EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2 + EShTargetOpenGL_450 = 450, // OpenGL } EShTargetClientVersion; typedef EShTargetClientVersion EshTargetClientVersion; typedef enum { - EShTargetSpv_1_0 = (1 << 16), - EShTargetSpv_1_3 = (1 << 16) | (3 << 8), + EShTargetSpv_1_0 = (1 << 16), // SPIR-V 1.0 + EShTargetSpv_1_1 = (1 << 16) | (1 << 8), // SPIR-V 1.1 + EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2 + EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3 + EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4 + EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5 } EShTargetLanguageVersion; struct TInputLanguage { @@ -216,8 +235,23 @@ enum EShMessages { 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. @@ -397,16 +431,45 @@ public: 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); +#ifdef ENABLE_HLSL void setHlslIoMapping(bool hlslIoMap); void setFlattenUniformArrays(bool flatten); +#endif void setNoStorageFormat(bool useUnknownFormat); + void setNanMinMaxClamp(bool nanMinMaxClamp); void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); // 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. + // + // setEnvInput: The input source language and stage. If generating code for a + // specific client, the input client semantics to use and the + // version of the that client's input semantics to use, otherwise + // use EShClientNone and version of 0, e.g. for validation mode. + // Note 'version' does not describe the target environment, + // just the version of the source dialect to compile under. + // + // See the definitions of TEnvironment, EShSource, EShLanguage, + // and EShClient for choices and more detail. + // + // setEnvClient: The client that will be hosting the execution, and it's version. + // Note 'version' is not the version of the languages involved, but + // the version of the client environment. + // Use EShClientNone and version of 0 if there is no client, e.g. + // for validation mode. + // + // See EShTargetClientVersion for choices. + // + // setEnvTarget: The language to translate to when generating code, and that + // language's version. + // Use EShTargetNone and version of 0 if there is no client, e.g. + // for validation mode. + // void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version) { environment.input.languageFamily = lang; @@ -424,8 +487,15 @@ public: environment.target.language = lang; environment.target.version = version; } + + void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; } + +#ifdef ENABLE_HLSL void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; } bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; } +#else + bool getEnvTargetHlslFunctionality1() const { return false; } +#endif // Interface to #include handlers. // @@ -532,6 +602,8 @@ public: 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, @@ -574,8 +646,46 @@ private: TShader& operator=(TShader&); }; -class TReflection; -class TIoMapper; +#ifndef GLSLANG_WEB + +// +// 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; +struct TVarEntryInfo; // Allows to customize the binding layout after linking. // All used uniform variables will invoke at least validateBinding. @@ -596,53 +706,65 @@ class TIoMapper; // notifiy callbacks, this phase ends with a call to endNotifications. // Phase two starts directly after the call to endNotifications // and calls all other callbacks to validate and to get the -// bindings, sets, locations, component and color indices. +// bindings, sets, locations, component and color indices. // // NOTE: that still limit checks are applied to bindings and sets // and may result in an error. class TIoMapResolver { public: - virtual ~TIoMapResolver() {} + virtual ~TIoMapResolver() {} - // Should return true if the resulting/current binding would be okay. - // Basic idea is to do aliasing binding checks with this. - virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current binding should be overridden. - // Return -1 if the current binding (including no binding) should be kept. - virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current set should be overridden. - // Return -1 if the current set (including no set) should be kept. - virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current location should be overridden. - // Return -1 if the current location (including no location) should be kept. - virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return true if the resulting/current setup would be okay. - // Basic idea is to do aliasing checks and reject invalid semantic names. - virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current location should be overridden. - // Return -1 if the current location (including no location) should be kept. - virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current component index should be overridden. - // Return -1 if the current component index (including no index) should be kept. - virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Should return a value >= 0 if the current color index should be overridden. - // Return -1 if the current color index (including no index) should be kept. - virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Notification of a uniform variable - virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Notification of a in or out variable - virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; - // Called by mapIO when it has finished the notify pass - virtual void endNotifications(EShLanguage stage) = 0; - // Called by mapIO when it starts its notify pass for the given stage - virtual void beginNotifications(EShLanguage stage) = 0; - // Called by mipIO when it starts its resolve pass for the given stage - virtual void beginResolve(EShLanguage stage) = 0; - // Called by mapIO when it has finished the resolve pass - virtual void endResolve(EShLanguage stage) = 0; + // Should return true if the resulting/current binding would be okay. + // Basic idea is to do aliasing binding checks with this. + virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current binding should be overridden. + // Return -1 if the current binding (including no binding) should be kept. + virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current set should be overridden. + // Return -1 if the current set (including no set) should be kept. + virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return true if the resulting/current setup would be okay. + // Basic idea is to do aliasing checks and reject invalid semantic names. + virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current component index should be overridden. + // Return -1 if the current component index (including no index) should be kept. + virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current color index should be overridden. + // Return -1 if the current color index (including no index) should be kept. + virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Notification of a uniform variable + virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Notification of a in or out variable + virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Called by mapIO when it starts its notify pass for the given stage + virtual void beginNotifications(EShLanguage stage) = 0; + // Called by mapIO when it has finished the notify pass + virtual void endNotifications(EShLanguage stage) = 0; + // Called by mipIO when it starts its resolve pass for the given stage + virtual void beginResolve(EShLanguage stage) = 0; + // Called by mapIO when it has finished the resolve pass + virtual void endResolve(EShLanguage stage) = 0; + // Called by mapIO when it starts its symbol collect for teh given stage + virtual void beginCollect(EShLanguage stage) = 0; + // Called by mapIO when it has finished the symbol collect + virtual void endCollect(EShLanguage stage) = 0; + // Called by TSlotCollector to resolve storage locations or bindings + virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; + // Called by TSlotCollector to resolve resource locations or bindings + virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; + // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline + virtual void addStage(EShLanguage stage) = 0; }; +#endif // GLSLANG_WEB + // Make one TProgram per set of shaders that will get linked together. Add all // the shaders that are to be linked together. After calling shader.parse() // for all shaders, call link(). @@ -654,7 +776,7 @@ public: TProgram(); virtual ~TProgram(); void addShader(TShader* shader) { stages[shader->stage].push_back(shader); } - + std::list& getShaders(EShLanguage stage) { return stages[stage]; } // Link Validation interface bool link(EShMessages); const char* getInfoLog(); @@ -662,35 +784,101 @@ public: TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } +#ifndef GLSLANG_WEB + // 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 getUniformBlockBinding(int index) const; // returns the block 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 getReflectionPipeIOIndex(const char* name, const bool inOrOut) 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); } + + int getPipeIOIndex(const char *name, const bool inOrOut) const + { return getReflectionPipeIOIndex(name, inOrOut); } + + // 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(); - // I/O mapping: apply base offsets and map live unbound variables // If resolver is not provided it uses the previous approach // and respects auto assignment and offsets. - bool mapIO(TIoMapResolver* resolver = NULL); + bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); +#endif protected: bool linkStage(EShLanguage, EShMessages); @@ -700,8 +888,9 @@ protected: TIntermediate* intermediate[EShLangCount]; bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage TInfoSink* infoSink; +#ifndef GLSLANG_WEB TReflection* reflection; - TIoMapper* ioMapper; +#endif bool linked; private: diff --git a/Externals/glslang/glslang/updateGrammar b/Externals/glslang/glslang/updateGrammar index f8fa81dab9..9384db9488 100755 --- a/Externals/glslang/glslang/updateGrammar +++ b/Externals/glslang/glslang/updateGrammar @@ -1,3 +1,16 @@ -#!/usr/bin/env bash +#!/bin/bash + +if [ "$1" = 'web' ] +then + m4 -P -DGLSLANG_WEB MachineIndependent/glslang.m4 > MachineIndependent/glslang.y +elif [ "$#" -eq 0 ] +then + m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y +else + echo usage: + echo $0 web + echo $0 + exit +fi bison --defines=MachineIndependent/glslang_tab.cpp.h -t MachineIndependent/glslang.y -o MachineIndependent/glslang_tab.cpp diff --git a/Externals/glslang/gtests/AST.FromFile.cpp b/Externals/glslang/gtests/AST.FromFile.cpp old mode 100755 new mode 100644 index b89fc51564..50046719b4 --- a/Externals/glslang/gtests/AST.FromFile.cpp +++ b/Externals/glslang/gtests/AST.FromFile.cpp @@ -41,26 +41,22 @@ namespace { using CompileToAstTest = GlslangTest<::testing::TestWithParam>; -#ifdef NV_EXTENSIONS using CompileToAstTestNV = GlslangTest<::testing::TestWithParam>; -#endif TEST_P(CompileToAstTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::AST); } -#ifdef NV_EXTENSIONS // Compiling GLSL to SPIR-V under OpenGL semantics (NV extensions enabled). TEST_P(CompileToAstTestNV, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::AST); } -#endif // clang-format off INSTANTIATE_TEST_CASE_P( @@ -93,9 +89,13 @@ INSTANTIATE_TEST_CASE_P( "cppSimple.vert", "cppIndent.vert", "cppIntMinOverNegativeOne.frag", + "cppMerge.frag", "cppNest.vert", "cppBad.vert", "cppBad2.vert", + "cppBad3.vert", + "cppBad4.vert", + "cppBad5.vert", "cppComplexExpr.vert", "cppDeepNest.frag", "cppPassMacroName.frag", @@ -113,6 +113,7 @@ INSTANTIATE_TEST_CASE_P( "300operations.frag", "300block.frag", "300samplerExternal.frag", + "300samplerExternalYUV.frag", "310.comp", "310.vert", "310.geom", @@ -120,6 +121,7 @@ INSTANTIATE_TEST_CASE_P( "310.tesc", "310.tese", "310implicitSizeArrayError.vert", + "310.inheritMemory.frag", "310AofA.vert", "310runtimeArray.vert", "320.comp", @@ -231,11 +233,51 @@ INSTANTIATE_TEST_CASE_P( "precise_struct_block.vert", "maxClipDistances.vert", "findFunction.frag", + "constantUnaryConversion.comp", + "glsl.450.subgroup.frag", + "glsl.450.subgroup.geom", + "glsl.450.subgroup.tesc", + "glsl.450.subgroup.tese", + "glsl.450.subgroup.vert", + "glsl.450.subgroupArithmetic.comp", + "glsl.450.subgroupBasic.comp", + "glsl.450.subgroupBallot.comp", + "glsl.450.subgroupBallotNeg.comp", + "glsl.450.subgroupClustered.comp", + "glsl.450.subgroupClusteredNeg.comp", + "glsl.450.subgroupPartitioned.comp", + "glsl.450.subgroupShuffle.comp", + "glsl.450.subgroupShuffleRelative.comp", + "glsl.450.subgroupQuad.comp", + "glsl.450.subgroupVote.comp", + "glsl.460.subgroup.mesh", + "glsl.460.subgroup.task", + "glsl.460.subgroup.rahit", + "glsl.460.subgroup.rcall", + "glsl.460.subgroup.rchit", + "glsl.460.subgroup.rgen", + "glsl.460.subgroup.rint", + "glsl.460.subgroup.rmiss", + "glsl.es320.subgroup.frag", + "glsl.es320.subgroup.geom", + "glsl.es320.subgroup.tesc", + "glsl.es320.subgroup.tese", + "glsl.es320.subgroup.vert", + "glsl.es320.subgroupArithmetic.comp", + "glsl.es320.subgroupBasic.comp", + "glsl.es320.subgroupBallot.comp", + "glsl.es320.subgroupBallotNeg.comp", + "glsl.es320.subgroupClustered.comp", + "glsl.es320.subgroupClusteredNeg.comp", + "glsl.es320.subgroupPartitioned.comp", + "glsl.es320.subgroupShuffle.comp", + "glsl.es320.subgroupShuffleRelative.comp", + "glsl.es320.subgroupQuad.comp", + "glsl.es320.subgroupVote.comp", })), FileNameAsCustomTestSuffix ); -#ifdef NV_EXTENSIONS INSTANTIATE_TEST_CASE_P( Glsl, CompileToAstTestNV, ::testing::ValuesIn(std::vector({ @@ -243,7 +285,6 @@ INSTANTIATE_TEST_CASE_P( })), FileNameAsCustomTestSuffix ); -#endif // clang-format on } // anonymous namespace diff --git a/Externals/glslang/gtests/CMakeLists.txt b/Externals/glslang/gtests/CMakeLists.txt index 15b73f4bde..dc53f5c329 100644 --- a/Externals/glslang/gtests/CMakeLists.txt +++ b/Externals/glslang/gtests/CMakeLists.txt @@ -20,17 +20,22 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Link.FromFile.Vk.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Pp.FromFile.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Spv.FromFile.cpp) - # -- Remapper tests - ${CMAKE_CURRENT_SOURCE_DIR}/Remap.FromFile.cpp) + if(ENABLE_SPVREMAPPER) + set(TEST_SOURCES ${TEST_SOURCES} + ${CMAKE_CURRENT_SOURCE_DIR}/Remap.FromFile.cpp) + endif() + + glslang_pch(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/pch.cpp) add_executable(glslangtests ${TEST_SOURCES}) set_property(TARGET glslangtests PROPERTY FOLDER tests) glslang_set_link_args(glslangtests) if(ENABLE_GLSLANG_INSTALL) - install(TARGETS glslangtests + install(TARGETS glslangtests EXPORT glslangtestsTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(EXPORT glslangtestsTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif(ENABLE_GLSLANG_INSTALL) set(GLSLANG_TEST_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../Test") @@ -46,8 +51,13 @@ if(BUILD_TESTING) ${gtest_SOURCE_DIR}/include) set(LIBRARIES - SPVRemapper glslang OSDependent OGLCompiler glslang + glslang OSDependent OGLCompiler glslang SPIRV glslang-default-resource-limits) + + if(ENABLE_SPVREMAPPER) + set(LIBRARIES ${LIBRARIES} SPVRemapper) + endif() + if(ENABLE_HLSL) set(LIBRARIES ${LIBRARIES} HLSL) endif(ENABLE_HLSL) diff --git a/Externals/glslang/gtests/Config.FromFile.cpp b/Externals/glslang/gtests/Config.FromFile.cpp index f3a27724d1..d6fbf20565 100644 --- a/Externals/glslang/gtests/Config.FromFile.cpp +++ b/Externals/glslang/gtests/Config.FromFile.cpp @@ -51,6 +51,7 @@ TEST_P(ConfigTest, FromFile) { TestCaseSpec testCase = GetParam(); GlslangResult result; + result.validationResult = true; // Get the contents for input shader and limit configurations. std::string shaderContents, configContents; @@ -99,7 +100,7 @@ INSTANTIATE_TEST_CASE_P( ::testing::ValuesIn(std::vector({ {"specExamples.vert", "baseResults/test.conf", "specExamplesConf.vert.out", (EShMessages)(EShMsgAST | EShMsgCascadingErrors)}, {"100Limits.vert", "100.conf", "100LimitsConf.vert.out", EShMsgCascadingErrors}, - })), + })) ); // clang-format on diff --git a/Externals/glslang/gtests/HexFloat.cpp b/Externals/glslang/gtests/HexFloat.cpp index ddbee1f464..ead4fd39c9 100644 --- a/Externals/glslang/gtests/HexFloat.cpp +++ b/Externals/glslang/gtests/HexFloat.cpp @@ -127,7 +127,7 @@ INSTANTIATE_TEST_CASE_P( {float(ldexp(1.0, -127) / 2.0 + (ldexp(1.0, -127) / 4.0f)), "0x1.8p-128"}, - })),); + }))); INSTANTIATE_TEST_CASE_P( Float32NanTests, HexFloatTest, @@ -145,7 +145,7 @@ INSTANTIATE_TEST_CASE_P( {uint32_t(0x7f800c00), "0x1.0018p+128"}, // +nan {uint32_t(0x7F80F000), "0x1.01ep+128"}, // +nan {uint32_t(0x7FFFFFFF), "0x1.fffffep+128"}, // +nan - })),); + }))); INSTANTIATE_TEST_CASE_P( Float64Tests, HexDoubleTest, @@ -218,7 +218,7 @@ INSTANTIATE_TEST_CASE_P( {ldexp(1.0, -1023) / 2.0 + (ldexp(1.0, -1023) / 4.0), "0x1.8p-1024"}, - })),); + }))); INSTANTIATE_TEST_CASE_P( Float64NanTests, HexDoubleTest, @@ -237,7 +237,7 @@ INSTANTIATE_TEST_CASE_P( {uint64_t(0x7FF0000000000001LL), "0x1.0000000000001p+1024"}, // -nan {uint64_t(0x7FF0000300000000LL), "0x1.00003p+1024"}, // -nan {uint64_t(0x7FFFFFFFFFFFFFFFLL), "0x1.fffffffffffffp+1024"}, // -nan - })),); + }))); TEST(HexFloatStreamTest, OperatorLeftShiftPreservesFloatAndFill) { std::stringstream s; @@ -282,7 +282,7 @@ INSTANTIATE_TEST_CASE_P( {"0xFFp+0", 255.f}, {"0x0.8p+0", 0.5f}, {"0x0.4p+0", 0.25f}, - })),); + }))); INSTANTIATE_TEST_CASE_P( Float32DecodeInfTests, DecodeHexFloatTest, @@ -292,7 +292,7 @@ INSTANTIATE_TEST_CASE_P( {"0x32p+127", uint32_t(0x7F800000)}, // inf {"0x32p+500", uint32_t(0x7F800000)}, // inf {"-0x32p+127", uint32_t(0xFF800000)}, // -inf - })),); + }))); INSTANTIATE_TEST_CASE_P( Float64DecodeTests, DecodeHexDoubleTest, @@ -315,7 +315,7 @@ INSTANTIATE_TEST_CASE_P( {"0xFFp+0", 255.}, {"0x0.8p+0", 0.5}, {"0x0.4p+0", 0.25}, - })),); + }))); INSTANTIATE_TEST_CASE_P( Float64DecodeInfTests, DecodeHexDoubleTest, @@ -326,7 +326,7 @@ INSTANTIATE_TEST_CASE_P( {"0x32p+1023", uint64_t(0x7FF0000000000000)}, // inf {"0x32p+5000", uint64_t(0x7FF0000000000000)}, // inf {"-0x32p+1023", uint64_t(0xFFF0000000000000)}, // -inf - })),); + }))); TEST(FloatProxy, ValidConversion) { EXPECT_THAT(FloatProxy(1.f).getAsFloat(), Eq(1.0f)); @@ -495,7 +495,7 @@ INSTANTIATE_TEST_CASE_P( {std::numeric_limits::infinity(), "0x1p+128"}, {-std::numeric_limits::infinity(), "-0x1p+128"}, - })),); + }))); INSTANTIATE_TEST_CASE_P( Float64Tests, FloatProxyDoubleTest, @@ -532,7 +532,7 @@ INSTANTIATE_TEST_CASE_P( {std::numeric_limits::infinity(), "0x1p+1024"}, {-std::numeric_limits::infinity(), "-0x1p+1024"}, - })),); + }))); // double is used so that unbiased_exponent can be used with the output // of ldexp directly. @@ -793,7 +793,7 @@ INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatRoundTest, {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -129)), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToPositiveInfinity}, {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -131)), std::make_pair(half_bits_set({0}), false), spvutils::kRoundToNegativeInfinity}, {static_cast(ldexp(float_fractions({0, 1, 11, 13}), -130)), std::make_pair(half_bits_set({0, 9}), false), spvutils::kRoundToNearestEven}, - })),); + }))); // clang-format on struct UpCastSignificandCase { @@ -837,7 +837,7 @@ INSTANTIATE_TEST_CASE_P(F16toF32, HexFloatRoundUpSignificandTest, {0x0F00, 0x600000}, {0x0F01, 0x602000}, {0x0FFF, 0x7FE000}, - })),); + }))); struct DownCastTest { float source_float; @@ -914,7 +914,7 @@ INSTANTIATE_TEST_CASE_P(F32ToF16, HexFloatFP32To16Tests, {-std::numeric_limits::infinity(), negative_infinity, {spvutils::kRoundToZero, spvutils::kRoundToPositiveInfinity, spvutils::kRoundToNegativeInfinity, spvutils::kRoundToNearestEven}}, // Nans are below because we cannot test for equality. - })),); + }))); struct UpCastCase{ uint16_t source_half; @@ -965,7 +965,7 @@ INSTANTIATE_TEST_CASE_P(F16ToF32, HexFloatFP16To32Tests, // inf {0x7C00, std::numeric_limits::infinity()}, {0xFC00, -std::numeric_limits::infinity()}, - })),); + }))); TEST(HexFloatOperationTests, NanTests) { using HF = spvutils::HexFloat>; @@ -1071,7 +1071,7 @@ INSTANTIATE_TEST_CASE_P( // We can't have -1e40 and negate_value == true since // that represents an original case of "--1e40" which // is invalid. - }),); + })); using ParseNormalFloat16Test = ::testing::TestWithParam>; @@ -1114,7 +1114,7 @@ INSTANTIATE_TEST_CASE_P( BadFloatParseCase("-2.0", true, uint16_t{0}), BadFloatParseCase("+0.0", true, uint16_t{0}), BadFloatParseCase("+2.0", true, uint16_t{0}), - }),); + })); // A test case for detecting infinities. template @@ -1149,7 +1149,7 @@ INSTANTIATE_TEST_CASE_P( {"-1e40", false, -FLT_MAX}, {"1e400", false, FLT_MAX}, {"-1e400", false, -FLT_MAX}, - })),); + }))); using FloatProxyParseOverflowDoubleTest = ::testing::TestWithParam>; @@ -1176,7 +1176,7 @@ INSTANTIATE_TEST_CASE_P( {"-1e40", true, -1e40}, {"1e400", false, DBL_MAX}, {"-1e400", false, -DBL_MAX}, - })),); + }))); using FloatProxyParseOverflowFloat16Test = ::testing::TestWithParam>; @@ -1207,7 +1207,7 @@ INSTANTIATE_TEST_CASE_P( {"-1e38", false, uint16_t{0xfbff}}, {"-1e40", false, uint16_t{0xfbff}}, {"-1e400", false, uint16_t{0xfbff}}, - })),); + }))); TEST(FloatProxy, Max) { EXPECT_THAT(FloatProxy::max().getAsFloat().get_value(), diff --git a/Externals/glslang/gtests/Hlsl.FromFile.cpp b/Externals/glslang/gtests/Hlsl.FromFile.cpp old mode 100644 new mode 100755 index 861c098837..59c687d870 --- a/Externals/glslang/gtests/Hlsl.FromFile.cpp +++ b/Externals/glslang/gtests/Hlsl.FromFile.cpp @@ -61,20 +61,23 @@ using HlslCompileTest = GlslangTest<::testing::TestWithParam>; using HlslCompileAndFlattenTest = GlslangTest<::testing::TestWithParam>; using HlslLegalizeTest = GlslangTest<::testing::TestWithParam>; +using HlslDebugTest = GlslangTest<::testing::TestWithParam>; +using HlslDX9CompatibleTest = GlslangTest<::testing::TestWithParam>; +using HlslLegalDebugTest = GlslangTest<::testing::TestWithParam>; // Compiling HLSL to pre-legalized SPIR-V under Vulkan semantics. Expected // to successfully generate both AST and SPIR-V. TEST_P(HlslCompileTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName, - Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::BothASTAndSpv, true, GetParam().entryPoint); } TEST_P(HlslVulkan1_1CompileTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName, - Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_1, + Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_1, glslang::EShTargetSpv_1_3, Target::BothASTAndSpv, true, GetParam().entryPoint); } @@ -90,11 +93,41 @@ TEST_P(HlslCompileAndFlattenTest, FromFile) TEST_P(HlslLegalizeTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName, - Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv, true, GetParam().entryPoint, "/baseLegalResults/", true); } +// Compiling HLSL to pre-legalized SPIR-V. Expected to successfully generate +// SPIR-V with debug instructions, particularly line info. +TEST_P(HlslDebugTest, FromFile) +{ + loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName, + Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, + Target::Spv, true, GetParam().entryPoint, + "/baseResults/", false, true); +} + +TEST_P(HlslDX9CompatibleTest, FromFile) +{ + loadFileCompileAndCheckWithOptions(GlobalTestSettings.testRoot, GetParam().fileName, Source::HLSL, + Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, + Target::BothASTAndSpv, true, + GetParam().entryPoint, "/baseResults/", + EShMessages::EShMsgHlslDX9Compatible); +} + +// Compiling HLSL to legalized SPIR-V with debug instructions. Expected to +// successfully generate SPIR-V with debug instructions preserved through +// legalization, particularly line info. +TEST_P(HlslLegalDebugTest, FromFile) +{ + loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam().fileName, + Source::HLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, + Target::Spv, true, GetParam().entryPoint, + "/baseResults/", true, true); +} + // clang-format off INSTANTIATE_TEST_CASE_P( ToSpirv, HlslCompileTest, @@ -153,6 +186,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.depthLess.frag", "PixelShaderFunction"}, {"hlsl.discard.frag", "PixelShaderFunction"}, {"hlsl.doLoop.frag", "PixelShaderFunction"}, + {"hlsl.earlydepthstencil.frag", "main"}, {"hlsl.emptystructreturn.frag", "main"}, {"hlsl.emptystructreturn.vert", "main"}, {"hlsl.emptystruct.init.vert", "main"}, @@ -196,6 +230,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.hull.void.tesc", "main"}, {"hlsl.hull.ctrlpt-1.tesc", "main"}, {"hlsl.hull.ctrlpt-2.tesc", "main"}, + {"hlsl.format.rwtexture.frag", "main"}, {"hlsl.groupid.comp", "main"}, {"hlsl.identifier.sample.frag", "main"}, {"hlsl.if.frag", "PixelShaderFunction"}, @@ -317,7 +352,9 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.shapeConvRet.frag", "main"}, {"hlsl.self_cast.frag", "main"}, {"hlsl.snorm.uav.comp", "main"}, + {"hlsl.specConstant.frag", "main"}, {"hlsl.staticMemberFunction.frag", "main"}, + {"hlsl.staticFuncInit.frag", "main"}, {"hlsl.store.rwbyteaddressbuffer.type.comp", "main"}, {"hlsl.stringtoken.frag", "main"}, {"hlsl.string.frag", "main"}, @@ -381,7 +418,8 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.typeGraphCopy.vert", "main"}, {"hlsl.typedef.frag", "PixelShaderFunction"}, {"hlsl.whileLoop.frag", "PixelShaderFunction"}, - {"hlsl.void.frag", "PixelShaderFunction"} + {"hlsl.void.frag", "PixelShaderFunction"}, + {"hlsl.type.type.conversion.all.frag", "main"} }), FileNameAsCustomTestSuffix ); @@ -398,6 +436,8 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.wavequery.frag", "PixelShaderFunction"}, {"hlsl.wavereduction.comp", "CSMain"}, {"hlsl.wavevote.comp", "CSMain"}, + { "hlsl.type.type.conversion.valid.frag", "main" }, + {"hlsl.int.dot.frag", "main"} }), FileNameAsCustomTestSuffix ); @@ -433,5 +473,34 @@ INSTANTIATE_TEST_CASE_P( // clang-format on #endif +// clang-format off +INSTANTIATE_TEST_CASE_P( + ToSpirv, HlslDebugTest, + ::testing::ValuesIn(std::vector{ + {"hlsl.pp.line2.frag", "MainPs"} + }), + FileNameAsCustomTestSuffix +); + +INSTANTIATE_TEST_CASE_P( + ToSpirv, HlslDX9CompatibleTest, + ::testing::ValuesIn(std::vector{ + {"hlsl.sample.dx9.frag", "main"}, + {"hlsl.sample.dx9.vert", "main"}, + }), + FileNameAsCustomTestSuffix +); + +// clang-format off +INSTANTIATE_TEST_CASE_P( + ToSpirv, HlslLegalDebugTest, + ::testing::ValuesIn(std::vector{ + {"hlsl.pp.line4.frag", "MainPs"} + }), + FileNameAsCustomTestSuffix +); + +// clang-format on + } // anonymous namespace } // namespace glslangtest diff --git a/Externals/glslang/gtests/Link.FromFile.Vk.cpp b/Externals/glslang/gtests/Link.FromFile.Vk.cpp index 0a616d827f..fe96bd9a8e 100644 --- a/Externals/glslang/gtests/Link.FromFile.Vk.cpp +++ b/Externals/glslang/gtests/Link.FromFile.Vk.cpp @@ -77,16 +77,16 @@ TEST_P(LinkTestVulkan, FromFile) if (success && (controls & EShMsgSpvRules)) { spv::SpvBuildLogger logger; std::vector spirv_binary; - glslang::SpvOptions options; - options.disableOptimizer = true; + options().disableOptimizer = true; glslang::GlslangToSpv(*program.getIntermediate(shaders.front()->getStage()), - spirv_binary, &logger, &options); + spirv_binary, &logger, &options()); std::ostringstream disassembly_stream; spv::Parameterize(); spv::Disassemble(disassembly_stream, spirv_binary); result.spirvWarningsErrors = logger.getAllMessages(); result.spirv = disassembly_stream.str(); + result.validationResult = !options().validate || logger.getAllMessages().empty(); } std::ostringstream stream; @@ -98,7 +98,8 @@ TEST_P(LinkTestVulkan, FromFile) std::string expectedOutput; tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); - checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname); + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname, + result.spirvWarningsErrors); } // clang-format off @@ -106,7 +107,8 @@ INSTANTIATE_TEST_CASE_P( Glsl, LinkTestVulkan, ::testing::ValuesIn(std::vector>({ {"link1.vk.frag", "link2.vk.frag"}, - })), + {"spv.unit1.frag", "spv.unit2.frag", "spv.unit3.frag"}, + })) ); // clang-format on diff --git a/Externals/glslang/gtests/Link.FromFile.cpp b/Externals/glslang/gtests/Link.FromFile.cpp index ab845bf59e..abc33a910b 100644 --- a/Externals/glslang/gtests/Link.FromFile.cpp +++ b/Externals/glslang/gtests/Link.FromFile.cpp @@ -50,6 +50,7 @@ TEST_P(LinkTest, FromFile) const size_t fileCount = fileNames.size(); const EShMessages controls = DeriveOptions(Source::GLSL, Semantics::OpenGL, Target::AST); GlslangResult result; + result.validationResult = true; // Compile each input shader file. std::vector> shaders; @@ -100,7 +101,7 @@ INSTANTIATE_TEST_CASE_P( {"max_vertices_0.geom"}, {"es-link1.frag", "es-link2.frag"}, {"missingBodies.vert"} - })), + })) ); // clang-format on diff --git a/Externals/glslang/gtests/Pp.FromFile.cpp b/Externals/glslang/gtests/Pp.FromFile.cpp index 13daac0d67..1bea8775dc 100644 --- a/Externals/glslang/gtests/Pp.FromFile.cpp +++ b/Externals/glslang/gtests/Pp.FromFile.cpp @@ -50,6 +50,7 @@ TEST_P(PreprocessingTest, FromFile) INSTANTIATE_TEST_CASE_P( Glsl, PreprocessingTest, ::testing::ValuesIn(std::vector({ + "preprocessor.bad_arg.vert", "preprocessor.cpp_style_line_directive.vert", "preprocessor.cpp_style___FILE__.vert", "preprocessor.edge_cases.vert", diff --git a/Externals/glslang/gtests/Spv.FromFile.cpp b/Externals/glslang/gtests/Spv.FromFile.cpp old mode 100755 new mode 100644 index 4b1ff462cc..0e46e790f7 --- a/Externals/glslang/gtests/Spv.FromFile.cpp +++ b/Externals/glslang/gtests/Spv.FromFile.cpp @@ -1,5 +1,6 @@ // // Copyright (C) 2016 Google, Inc. +// Copyright (C) 2019 ARM Limited. // // All rights reserved. // @@ -63,19 +64,18 @@ std::string FileNameAsCustomTestSuffixIoMap( } using CompileVulkanToSpirvTest = GlslangTest<::testing::TestWithParam>; +using CompileVulkanToSpirvDeadCodeElimTest = GlslangTest<::testing::TestWithParam>; +using CompileVulkanToDebugSpirvTest = GlslangTest<::testing::TestWithParam>; using CompileVulkan1_1ToSpirvTest = GlslangTest<::testing::TestWithParam>; +using CompileToSpirv14Test = GlslangTest<::testing::TestWithParam>; using CompileOpenGLToSpirvTest = GlslangTest<::testing::TestWithParam>; using VulkanSemantics = GlslangTest<::testing::TestWithParam>; using OpenGLSemantics = GlslangTest<::testing::TestWithParam>; using VulkanAstSemantics = GlslangTest<::testing::TestWithParam>; using HlslIoMap = GlslangTest<::testing::TestWithParam>; using GlslIoMap = GlslangTest<::testing::TestWithParam>; -#ifdef AMD_EXTENSIONS using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam>; -#endif -#ifdef NV_EXTENSIONS using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam>; -#endif using CompileUpgradeTextureToSampledTextureAndDropSamplersTest = GlslangTest<::testing::TestWithParam>; // Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully @@ -83,14 +83,39 @@ using CompileUpgradeTextureToSampledTextureAndDropSamplersTest = GlslangTest<::t TEST_P(CompileVulkanToSpirvTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv); } +TEST_P(CompileVulkanToSpirvDeadCodeElimTest, FromFile) +{ + loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, + Target::Spv); +} + +// Compiling GLSL to SPIR-V with debug info under Vulkan semantics. Expected +// to successfully generate SPIR-V. +TEST_P(CompileVulkanToDebugSpirvTest, FromFile) +{ + loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), + Source::GLSL, Semantics::Vulkan, + glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, + Target::Spv, true, "", + "/baseResults/", false, true); +} + TEST_P(CompileVulkan1_1ToSpirvTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_1, + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_1, glslang::EShTargetSpv_1_3, + Target::Spv); +} + +TEST_P(CompileToSpirv14Test, FromFile) +{ + loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_1, glslang::EShTargetSpv_1_4, Target::Spv); } @@ -99,7 +124,7 @@ TEST_P(CompileVulkan1_1ToSpirvTest, FromFile) TEST_P(CompileOpenGLToSpirvTest, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv); } @@ -108,7 +133,7 @@ TEST_P(CompileOpenGLToSpirvTest, FromFile) TEST_P(VulkanSemantics, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv, false); } @@ -117,7 +142,7 @@ TEST_P(VulkanSemantics, FromFile) TEST_P(OpenGLSemantics, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::OpenGL, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv, false); } @@ -125,7 +150,7 @@ TEST_P(OpenGLSemantics, FromFile) TEST_P(VulkanAstSemantics, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::AST); } @@ -159,27 +184,23 @@ TEST_P(GlslIoMap, FromFile) GetParam().flattenUniforms); } -#ifdef AMD_EXTENSIONS // Compiling GLSL to SPIR-V under Vulkan semantics (AMD extensions enabled). // Expected to successfully generate SPIR-V. TEST_P(CompileVulkanToSpirvTestAMD, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv); } -#endif -#ifdef NV_EXTENSIONS // Compiling GLSL to SPIR-V under Vulkan semantics (NV extensions enabled). // Expected to successfully generate SPIR-V. TEST_P(CompileVulkanToSpirvTestNV, FromFile) { loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(), - Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, + Source::GLSL, Semantics::Vulkan, glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, Target::Spv); } -#endif TEST_P(CompileUpgradeTextureToSampledTextureAndDropSamplersTest, FromFile) { @@ -215,6 +236,12 @@ INSTANTIATE_TEST_CASE_P( "spv.140.frag", "spv.150.geom", "spv.150.vert", + "spv.16bitstorage.frag", + "spv.16bitstorage_Error.frag", + "spv.16bitstorage-int.frag", + "spv.16bitstorage_Error-int.frag", + "spv.16bitstorage-uint.frag", + "spv.16bitstorage_Error-uint.frag", "spv.300BuiltIns.vert", "spv.300layout.frag", "spv.300layout.vert", @@ -231,6 +258,13 @@ INSTANTIATE_TEST_CASE_P( "spv.450.tesc", "spv.450.geom", "spv.450.noRedecl.tesc", + "spv.8bitstorage-int.frag", + "spv.8bitstorage_Error-int.frag", + "spv.8bitstorage-uint.frag", + "spv.8bitstorage_Error-uint.frag", + "spv.8bitstorage-ubo.vert", + "spv.8bitstorage-ssbo.vert", + "spv.8bit-16bit-construction.frag", "spv.accessChain.frag", "spv.aggOps.frag", "spv.always-discard.frag", @@ -241,14 +275,41 @@ INSTANTIATE_TEST_CASE_P( "spv.bool.vert", "spv.boolInBlock.frag", "spv.branch-return.vert", + "spv.bufferhandle1.frag", + "spv.bufferhandle10.frag", + "spv.bufferhandle11.frag", + "spv.bufferhandle12.frag", + "spv.bufferhandle13.frag", + "spv.bufferhandle14.frag", + "spv.bufferhandle15.frag", + "spv.bufferhandle16.frag", + "spv.bufferhandle17_Errors.frag", + "spv.bufferhandle18.frag", + "spv.bufferhandle19_Errors.frag", + "spv.bufferhandle2.frag", + "spv.bufferhandle3.frag", + "spv.bufferhandle4.frag", + "spv.bufferhandle5.frag", + "spv.bufferhandle6.frag", + "spv.bufferhandle7.frag", + "spv.bufferhandle8.frag", + "spv.bufferhandle9.frag", + "spv.bufferhandleUvec2.frag", + "spv.bufferhandle_Error.frag", "spv.builtInXFB.vert", + "spv.conditionalDemote.frag", "spv.conditionalDiscard.frag", + "spv.constructComposite.comp", "spv.constStruct.vert", + "spv.constConstruct.vert", "spv.controlFlowAttributes.frag", "spv.conversion.frag", + "spv.coopmat.comp", + "spv.coopmat_Error.comp", "spv.dataOut.frag", "spv.dataOutIndirect.frag", "spv.dataOutIndirect.vert", + "spv.demoteDisabled.frag", "spv.deepRvalue.frag", "spv.depthOut.frag", "spv.discard-dce.frag", @@ -256,16 +317,26 @@ INSTANTIATE_TEST_CASE_P( "spv.earlyReturnDiscard.frag", "spv.extPostDepthCoverage.frag", "spv.extPostDepthCoverage_Error.frag", + "spv.float16convertonlyarith.comp", + "spv.float16convertonlystorage.comp", "spv.flowControl.frag", "spv.forLoop.frag", "spv.forwardFun.frag", + "spv.fragmentDensity.frag", + "spv.fragmentDensity.vert", + "spv.fragmentDensity-es.frag", + "spv.fragmentDensity-neg.frag", + "spv.fsi.frag", + "spv.fsi_Error.frag", "spv.fullyCovered.frag", "spv.functionCall.frag", "spv.functionNestedOpaque.vert", "spv.functionSemantics.frag", + "spv.functionParameterTypes.frag", "spv.GeometryShaderPassthrough.geom", "spv.interpOps.frag", "spv.int64.frag", + "spv.intcoopmat.comp", "spv.intOps.vert", "spv.layoutNested.vert", "spv.length.frag", @@ -283,6 +354,7 @@ INSTANTIATE_TEST_CASE_P( "spv.noDeadDecorations.vert", "spv.nonSquare.vert", "spv.nonuniform.frag", + "spv.nonuniform2.frag", "spv.noWorkgroup.comp", "spv.offsets.frag", "spv.Operations.frag", @@ -290,11 +362,14 @@ INSTANTIATE_TEST_CASE_P( "spv.precision.frag", "spv.precisionNonESSamp.frag", "spv.prepost.frag", + "spv.privateVariableTypes.frag", "spv.qualifiers.vert", "spv.sample.frag", "spv.sampleId.frag", "spv.samplePosition.frag", "spv.sampleMaskOverrideCoverage.frag", + "spv.scalarlayout.frag", + "spv.scalarlayoutfloat16.frag", "spv.shaderBallot.comp", "spv.shaderDrawParams.vert", "spv.shaderGroupVote.comp", @@ -339,11 +414,41 @@ INSTANTIATE_TEST_CASE_P( "spv.storageBuffer.vert", "spv.precise.tese", "spv.precise.tesc", + "spv.volatileAtomic.comp", "spv.vulkan100.subgroupArithmetic.comp", "spv.vulkan100.subgroupPartitioned.comp", "spv.xfb.vert", "spv.xfb2.vert", "spv.xfb3.vert", + "spv.samplerlessTextureFunctions.frag", + "spv.smBuiltins.vert", + "spv.smBuiltins.frag", + })), + FileNameAsCustomTestSuffix +); + +// Cases with deliberately unreachable code. +// By default the compiler will aggressively eliminate +// unreachable merges and continues. +INSTANTIATE_TEST_CASE_P( + GlslWithDeadCode, CompileVulkanToSpirvDeadCodeElimTest, + ::testing::ValuesIn(std::vector({ + "spv.dead-after-continue.vert", + "spv.dead-after-discard.frag", + "spv.dead-after-return.vert", + "spv.dead-after-loop-break.vert", + "spv.dead-after-switch-break.vert", + "spv.dead-complex-continue-after-return.vert", + "spv.dead-complex-merge-after-return.vert", + })), + FileNameAsCustomTestSuffix +); + +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, CompileVulkanToDebugSpirvTest, + ::testing::ValuesIn(std::vector({ + "spv.pp.line.frag", })), FileNameAsCustomTestSuffix ); @@ -352,6 +457,9 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( Glsl, CompileVulkan1_1ToSpirvTest, ::testing::ValuesIn(std::vector({ + "spv.1.3.8bitstorage-ubo.vert", + "spv.1.3.8bitstorage-ssbo.vert", + "spv.1.3.coopmat.comp", "spv.deviceGroup.frag", "spv.drawParams.vert", "spv.int8.frag", @@ -360,7 +468,10 @@ INSTANTIATE_TEST_CASE_P( "spv.explicittypes.frag", "spv.float32.frag", "spv.float64.frag", + "spv.memoryScopeSemantics.comp", + "spv.memoryScopeSemantics_Error.comp", "spv.multiView.frag", + "spv.RayGenShader11.rgen", "spv.subgroup.frag", "spv.subgroup.geom", "spv.subgroup.tesc", @@ -369,6 +480,7 @@ INSTANTIATE_TEST_CASE_P( "spv.subgroupArithmetic.comp", "spv.subgroupBasic.comp", "spv.subgroupBallot.comp", + "spv.subgroupBallotNeg.comp", "spv.subgroupClustered.comp", "spv.subgroupClusteredNeg.comp", "spv.subgroupPartitioned.comp", @@ -376,11 +488,46 @@ INSTANTIATE_TEST_CASE_P( "spv.subgroupShuffleRelative.comp", "spv.subgroupQuad.comp", "spv.subgroupVote.comp", + "spv.subgroupExtendedTypesArithmetic.comp", + "spv.subgroupExtendedTypesArithmeticNeg.comp", + "spv.subgroupExtendedTypesBallot.comp", + "spv.subgroupExtendedTypesBallotNeg.comp", + "spv.subgroupExtendedTypesClustered.comp", + "spv.subgroupExtendedTypesClusteredNeg.comp", + "spv.subgroupExtendedTypesPartitioned.comp", + "spv.subgroupExtendedTypesPartitionedNeg.comp", + "spv.subgroupExtendedTypesShuffle.comp", + "spv.subgroupExtendedTypesShuffleNeg.comp", + "spv.subgroupExtendedTypesShuffleRelative.comp", + "spv.subgroupExtendedTypesShuffleRelativeNeg.comp", + "spv.subgroupExtendedTypesQuad.comp", + "spv.subgroupExtendedTypesQuadNeg.comp", + "spv.subgroupExtendedTypesVote.comp", + "spv.subgroupExtendedTypesVoteNeg.comp", "spv.vulkan110.storageBuffer.vert", })), FileNameAsCustomTestSuffix ); +// clang-format off +INSTANTIATE_TEST_CASE_P( + Glsl, CompileToSpirv14Test, + ::testing::ValuesIn(std::vector({ + "spv.1.4.LoopControl.frag", + "spv.1.4.NonWritable.frag", + "spv.1.4.OpEntryPoint.frag", + "spv.1.4.OpSelect.frag", + "spv.1.4.OpCopyLogical.comp", + "spv.1.4.OpCopyLogicalBool.comp", + "spv.1.4.OpCopyLogical.funcall.frag", + "spv.1.4.image.frag", + "spv.1.4.sparseTexture.frag", + "spv.1.4.texture.frag", + "spv.1.4.constructComposite.comp", + })), + FileNameAsCustomTestSuffix +); + // clang-format off INSTANTIATE_TEST_CASE_P( Hlsl, HlslIoMap, @@ -423,6 +570,10 @@ INSTANTIATE_TEST_CASE_P( "spv.rankShift.comp", "spv.specConst.vert", "spv.OVR_multiview.vert", + "spv.xfbOffsetOnBlockMembersAssignment.vert", + "spv.xfbOffsetOnStructMembersAssignment.vert", + "spv.xfbOverlapOffsetCheckWithBlockAndMember.vert", + "spv.xfbStrideJustOnce.vert", })), FileNameAsCustomTestSuffix ); @@ -433,6 +584,8 @@ INSTANTIATE_TEST_CASE_P( "vulkan.frag", "vulkan.vert", "vulkan.comp", + "samplerlessTextureFunctions.frag", + "spv.specConstArrayCheck.vert", })), FileNameAsCustomTestSuffix ); @@ -457,10 +610,10 @@ INSTANTIATE_TEST_CASE_P( FileNameAsCustomTestSuffix ); -#ifdef AMD_EXTENSIONS INSTANTIATE_TEST_CASE_P( Glsl, CompileVulkanToSpirvTestAMD, ::testing::ValuesIn(std::vector({ + "spv.16bitxfb.vert", "spv.float16.frag", "spv.float16Fetch.frag", "spv.imageLoadStoreLod.frag", @@ -472,9 +625,7 @@ INSTANTIATE_TEST_CASE_P( })), FileNameAsCustomTestSuffix ); -#endif -#ifdef NV_EXTENSIONS INSTANTIATE_TEST_CASE_P( Glsl, CompileVulkanToSpirvTestNV, ::testing::ValuesIn(std::vector({ @@ -487,10 +638,41 @@ INSTANTIATE_TEST_CASE_P( "spv.multiviewPerViewAttributes.vert", "spv.multiviewPerViewAttributes.tesc", "spv.atomicInt64.comp", + "spv.shadingRate.frag", + "spv.RayGenShader.rgen", + "spv.RayGenShaderArray.rgen", + "spv.RayGenShader_Errors.rgen", + "spv.RayConstants.rgen", + "spv.IntersectShader.rint", + "spv.IntersectShader_Errors.rint", + "spv.AnyHitShader.rahit", + "spv.AnyHitShader_Errors.rahit", + "spv.ClosestHitShader.rchit", + "spv.ClosestHitShader_Errors.rchit", + "spv.MissShader.rmiss", + "spv.MissShader_Errors.rmiss", + "spv.RayCallable.rcall", + "spv.RayCallable_Errors.rcall", + "spv.fragmentShaderBarycentric.frag", + "spv.fragmentShaderBarycentric2.frag", + "spv.computeShaderDerivatives.comp", + "spv.computeShaderDerivatives2.comp", + "spv.shaderImageFootprint.frag", + "spv.meshShaderBuiltins.mesh", + "spv.meshShaderUserDefined.mesh", + "spv.meshShaderPerViewBuiltins.mesh", + "spv.meshShaderPerViewUserDefined.mesh", + "spv.meshShaderPerView_Errors.mesh", + "spv.meshShaderSharedMem.mesh", + "spv.meshShaderTaskMem.mesh", + "spv.320.meshShaderUserDefined.mesh", + "spv.meshShaderRedeclBuiltins.mesh", + "spv.meshShaderRedeclPerViewBuiltins.mesh", + "spv.meshTaskShader.task", + "spv.perprimitiveNV.frag", })), FileNameAsCustomTestSuffix ); -#endif INSTANTIATE_TEST_CASE_P( Glsl, CompileUpgradeTextureToSampledTextureAndDropSamplersTest, diff --git a/Externals/glslang/gtests/TestFixture.cpp b/Externals/glslang/gtests/TestFixture.cpp index 77bada5f7d..baf4d16dd6 100644 --- a/Externals/glslang/gtests/TestFixture.cpp +++ b/Externals/glslang/gtests/TestFixture.cpp @@ -60,6 +60,22 @@ EShLanguage GetShaderStage(const std::string& stage) return EShLangFragment; } else if (stage == "comp") { return EShLangCompute; + } else if (stage == "rgen") { + return EShLangRayGenNV; + } else if (stage == "rint") { + return EShLangIntersectNV; + } else if (stage == "rahit") { + return EShLangAnyHitNV; + } else if (stage == "rchit") { + return EShLangClosestHitNV; + } else if (stage == "rmiss") { + return EShLangMissNV; + } else if (stage == "rcall") { + return EShLangCallableNV; + } else if (stage == "task") { + return EShLangTaskNV; + } else if (stage == "mesh") { + return EShLangMeshNV; } else { assert(0 && "Unknown shader stage"); return EShLangCount; diff --git a/Externals/glslang/gtests/TestFixture.h b/Externals/glslang/gtests/TestFixture.h old mode 100644 new mode 100755 index a58978d339..8d2ebd9257 --- a/Externals/glslang/gtests/TestFixture.h +++ b/Externals/glslang/gtests/TestFixture.h @@ -111,7 +111,10 @@ public: : defaultVersion(100), defaultProfile(ENoProfile), forceVersionProfile(false), - isForwardCompatible(false) {} + isForwardCompatible(false) { + // Perform validation by default. + spirvOptions.validate = true; + } // Tries to load the contents from the file at the given |path|. On success, // writes the contents into |contents|. On failure, errors out. @@ -137,15 +140,18 @@ public: // write |real| to the given file named as |fname| if update mode is on. void checkEqAndUpdateIfRequested(const std::string& expected, const std::string& real, - const std::string& fname) + const std::string& fname, + const std::string& errorsAndWarnings = "") { // In order to output the message we want under proper circumstances, // we need the following operator<< stuff. EXPECT_EQ(expected, real) << (GlobalTestSettings.updateMode ? ("Mismatch found and update mode turned on - " - "flushing expected result output.") - : ""); + "flushing expected result output.\n") + : "") + << "The following warnings/errors occurred:\n" + << errorsAndWarnings; // Update the expected output file if requested. // It looks weird to duplicate the comparison between expected_output @@ -168,6 +174,7 @@ public: std::vector shaderResults; std::string linkingOutput; std::string linkingError; + bool validationResult; std::string spirvWarningsErrors; std::string spirv; // Optional SPIR-V disassembly text. }; @@ -177,12 +184,19 @@ public: // and modifies |shader| on success. bool compile(glslang::TShader* shader, const std::string& code, const std::string& entryPointName, EShMessages controls, - const TBuiltInResource* resources=nullptr) + const TBuiltInResource* resources=nullptr, + const std::string* shaderName=nullptr) { const char* shaderStrings = code.data(); const int shaderLengths = static_cast(code.size()); + const char* shaderNames = nullptr; - shader->setStringsWithLengths(&shaderStrings, &shaderLengths, 1); + if ((controls & EShMsgDebugInfo) && shaderName != nullptr) { + shaderNames = shaderName->data(); + shader->setStringsWithLengthsAndNames( + &shaderStrings, &shaderLengths, &shaderNames, 1); + } else + shader->setStringsWithLengths(&shaderStrings, &shaderLengths, 1); if (!entryPointName.empty()) shader->setEntryPoint(entryPointName.c_str()); return shader->parse( (resources ? resources : &glslang::DefaultTBuiltInResource), @@ -195,12 +209,14 @@ public: // during the process. If the target includes SPIR-V, also disassembles // the result and returns disassembly text. GlslangResult compileAndLink( - const std::string shaderName, const std::string& code, + const std::string& shaderName, const std::string& code, const std::string& entryPointName, EShMessages controls, glslang::EShTargetClientVersion clientTargetVersion, + glslang::EShTargetLanguageVersion targetLanguageVersion, bool flattenUniformArrays = false, EShTextureSamplerTransformMode texSampTransMode = EShTexSampTransKeep, bool enableOptimizer = false, + bool enableDebug = false, bool automap = true) { const EShLanguage stage = GetShaderStage(GetSuffix(shaderName)); @@ -211,7 +227,9 @@ public: shader.setAutoMapBindings(true); } shader.setTextureSamplerTransformMode(texSampTransMode); +#ifdef ENABLE_HLSL shader.setFlattenUniformArrays(flattenUniformArrays); +#endif if (controls & EShMsgSpvRules) { if (controls & EShMsgVulkanRules) { @@ -219,9 +237,7 @@ public: : glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100); shader.setEnvClient(glslang::EShClientVulkan, clientTargetVersion); - shader.setEnvTarget(glslang::EShTargetSpv, - clientTargetVersion == glslang::EShTargetVulkan_1_1 ? glslang::EShTargetSpv_1_3 - : glslang::EShTargetSpv_1_0); + shader.setEnvTarget(glslang::EShTargetSpv, targetLanguageVersion); } else { shader.setEnvInput((controls & EShMsgReadHlsl) ? glslang::EShSourceHlsl : glslang::EShSourceGlsl, @@ -231,7 +247,8 @@ public: } } - bool success = compile(&shader, code, entryPointName, controls); + bool success = compile( + &shader, code, entryPointName, controls, nullptr, &shaderName); glslang::TProgram program; program.addShader(&shader); @@ -241,20 +258,21 @@ public: if (success && (controls & EShMsgSpvRules)) { std::vector spirv_binary; - glslang::SpvOptions options; - options.disableOptimizer = !enableOptimizer; + options().disableOptimizer = !enableOptimizer; + options().generateDebugInfo = enableDebug; glslang::GlslangToSpv(*program.getIntermediate(stage), - spirv_binary, &logger, &options); + spirv_binary, &logger, &options()); std::ostringstream disassembly_stream; spv::Parameterize(); spv::Disassemble(disassembly_stream, spirv_binary); + bool validation_result = !options().validate || logger.getAllMessages().empty(); return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, program.getInfoLog(), program.getInfoDebugLog(), - logger.getAllMessages(), disassembly_stream.str()}; + validation_result, logger.getAllMessages(), disassembly_stream.str()}; } else { return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, - program.getInfoLog(), program.getInfoDebugLog(), "", ""}; + program.getInfoLog(), program.getInfoDebugLog(), true, "", ""}; } } @@ -284,7 +302,9 @@ public: shader.setShiftSsboBinding(baseSsboBinding); shader.setAutoMapBindings(autoMapBindings); shader.setAutoMapLocations(true); +#ifdef ENABLE_HLSL shader.setFlattenUniformArrays(flattenUniformArrays); +#endif bool success = compile(&shader, code, entryPointName, controls); @@ -292,24 +312,27 @@ public: program.addShader(&shader); success &= program.link(controls); +#ifndef GLSLANG_WEB success &= program.mapIO(); +#endif spv::SpvBuildLogger logger; if (success && (controls & EShMsgSpvRules)) { std::vector spirv_binary; glslang::GlslangToSpv(*program.getIntermediate(stage), - spirv_binary, &logger); + spirv_binary, &logger, &options()); std::ostringstream disassembly_stream; spv::Parameterize(); spv::Disassemble(disassembly_stream, spirv_binary); + bool validation_result = !options().validate || logger.getAllMessages().empty(); return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, program.getInfoLog(), program.getInfoDebugLog(), - logger.getAllMessages(), disassembly_stream.str()}; + validation_result, logger.getAllMessages(), disassembly_stream.str()}; } else { return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, - program.getInfoLog(), program.getInfoDebugLog(), "", ""}; + program.getInfoLog(), program.getInfoDebugLog(), true, "", ""}; } } @@ -339,19 +362,20 @@ public: if (success && (controls & EShMsgSpvRules)) { std::vector spirv_binary; glslang::GlslangToSpv(*program.getIntermediate(stage), - spirv_binary, &logger); + spirv_binary, &logger, &options()); spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, remapOptions); std::ostringstream disassembly_stream; spv::Parameterize(); spv::Disassemble(disassembly_stream, spirv_binary); + bool validation_result = !options().validate || logger.getAllMessages().empty(); return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, program.getInfoLog(), program.getInfoDebugLog(), - logger.getAllMessages(), disassembly_stream.str()}; + validation_result, logger.getAllMessages(), disassembly_stream.str()}; } else { return {{{shaderName, shader.getInfoLog(), shader.getInfoDebugLog()},}, - program.getInfoLog(), program.getInfoDebugLog(), "", ""}; + program.getInfoLog(), program.getInfoDebugLog(), true, "", ""}; } } @@ -372,9 +396,9 @@ public: return {{{shaderName, "", ""},}, "", "", - "", disassembly_stream.str()}; + true, "", disassembly_stream.str()}; } else { - return {{{shaderName, "", ""},}, "", "", "", ""}; + return {{{shaderName, "", ""},}, "", "", true, "", ""}; } } @@ -393,7 +417,9 @@ public: } outputIfNotEmpty(result.linkingOutput); outputIfNotEmpty(result.linkingError); - *stream << result.spirvWarningsErrors; + if (!result.validationResult) { + *stream << "Validation failed\n"; + } if (controls & EShMsgSpvRules) { *stream @@ -408,11 +434,13 @@ public: Source source, Semantics semantics, glslang::EShTargetClientVersion clientTargetVersion, + glslang::EShTargetLanguageVersion targetLanguageVersion, Target target, bool automap = true, const std::string& entryPointName="", const std::string& baseDir="/baseResults/", - const bool enableOptimizer = false) + const bool enableOptimizer = false, + const bool enableDebug = false) { const std::string inputFname = testDir + "/" + testName; const std::string expectedOutputFname = @@ -425,15 +453,46 @@ public: EShMessages controls = DeriveOptions(source, semantics, target); if (enableOptimizer) controls = static_cast(controls & ~EShMsgHlslLegalization); - GlslangResult result = compileAndLink(testName, input, entryPointName, controls, clientTargetVersion, false, - EShTexSampTransKeep, enableOptimizer, automap); + if (enableDebug) + controls = static_cast(controls | EShMsgDebugInfo); + GlslangResult result = compileAndLink(testName, input, entryPointName, controls, clientTargetVersion, + targetLanguageVersion, false, EShTexSampTransKeep, enableOptimizer, enableDebug, automap); // Generate the hybrid output in the way of glslangValidator. std::ostringstream stream; outputResultToStream(&stream, result, controls); checkEqAndUpdateIfRequested(expectedOutput, stream.str(), - expectedOutputFname); + expectedOutputFname, result.spirvWarningsErrors); + } + + void loadFileCompileAndCheckWithOptions(const std::string &testDir, + const std::string &testName, + Source source, + Semantics semantics, + glslang::EShTargetClientVersion clientTargetVersion, + glslang::EShTargetLanguageVersion targetLanguageVersion, + Target target, bool automap = true, const std::string &entryPointName = "", + const std::string &baseDir = "/baseResults/", + const EShMessages additionalOptions = EShMessages::EShMsgDefault) + { + const std::string inputFname = testDir + "/" + testName; + const std::string expectedOutputFname = testDir + baseDir + testName + ".out"; + std::string input, expectedOutput; + + tryLoadFile(inputFname, "input", &input); + tryLoadFile(expectedOutputFname, "expected output", &expectedOutput); + + EShMessages controls = DeriveOptions(source, semantics, target); + controls = static_cast(controls | additionalOptions); + GlslangResult result = compileAndLink(testName, input, entryPointName, controls, clientTargetVersion, + targetLanguageVersion, false, EShTexSampTransKeep, false, automap); + + // Generate the hybrid output in the way of glslangValidator. + std::ostringstream stream; + outputResultToStream(&stream, result, controls); + + checkEqAndUpdateIfRequested(expectedOutput, stream.str(), expectedOutputFname); } void loadFileCompileFlattenUniformsAndCheck(const std::string& testDir, @@ -453,14 +512,14 @@ public: const EShMessages controls = DeriveOptions(source, semantics, target); GlslangResult result = compileAndLink(testName, input, entryPointName, controls, - glslang::EShTargetVulkan_1_0, true); + glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, true); // Generate the hybrid output in the way of glslangValidator. std::ostringstream stream; outputResultToStream(&stream, result, controls); checkEqAndUpdateIfRequested(expectedOutput, stream.str(), - expectedOutputFname); + expectedOutputFname, result.spirvWarningsErrors); } void loadFileCompileIoMapAndCheck(const std::string& testDir, @@ -497,7 +556,7 @@ public: outputResultToStream(&stream, result, controls); checkEqAndUpdateIfRequested(expectedOutput, stream.str(), - expectedOutputFname); + expectedOutputFname, result.spirvWarningsErrors); } void loadFileCompileRemapAndCheck(const std::string& testDir, @@ -524,7 +583,7 @@ public: outputResultToStream(&stream, result, controls); checkEqAndUpdateIfRequested(expectedOutput, stream.str(), - expectedOutputFname); + expectedOutputFname, result.spirvWarningsErrors); } void loadFileRemapAndCheck(const std::string& testDir, @@ -551,7 +610,7 @@ public: outputResultToStream(&stream, result, controls); checkEqAndUpdateIfRequested(expectedOutput, stream.str(), - expectedOutputFname); + expectedOutputFname, result.spirvWarningsErrors); } // Preprocesses the given |source| code. On success, returns true, the @@ -623,7 +682,7 @@ public: const EShMessages controls = DeriveOptions(source, semantics, target); GlslangResult result = compileAndLink(testName, input, entryPointName, controls, - glslang::EShTargetVulkan_1_0, false, + glslang::EShTargetVulkan_1_0, glslang::EShTargetSpv_1_0, false, EShTexSampTransUpgradeTextureRemoveSampler); // Generate the hybrid output in the way of glslangValidator. @@ -631,14 +690,17 @@ public: outputResultToStream(&stream, result, controls); checkEqAndUpdateIfRequested(expectedOutput, stream.str(), - expectedOutputFname); + expectedOutputFname, result.spirvWarningsErrors); } + glslang::SpvOptions& options() { return spirvOptions; } + private: const int defaultVersion; const EProfile defaultProfile; const bool forceVersionProfile; const bool isForwardCompatible; + glslang::SpvOptions spirvOptions; }; } // namespace glslangtest diff --git a/Externals/glslang/gtests/pch.cpp b/Externals/glslang/gtests/pch.cpp new file mode 100644 index 0000000000..b7a08654a5 --- /dev/null +++ b/Externals/glslang/gtests/pch.cpp @@ -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 --git a/Externals/glslang/gtests/pch.h b/Externals/glslang/gtests/pch.h new file mode 100644 index 0000000000..94e95b1eb2 --- /dev/null +++ b/Externals/glslang/gtests/pch.h @@ -0,0 +1,39 @@ +#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 "TestFixture.h" + +#endif /* _PCH_H */ diff --git a/Externals/glslang/hlsl/CMakeLists.txt b/Externals/glslang/hlsl/CMakeLists.txt old mode 100755 new mode 100644 index 6d1d8e6ae5..ae0d4d4eb7 --- a/Externals/glslang/hlsl/CMakeLists.txt +++ b/Externals/glslang/hlsl/CMakeLists.txt @@ -17,6 +17,8 @@ set(HEADERS hlslGrammar.h hlslParseables.h) +glslang_pch(SOURCES pch.cpp) + add_library(HLSL ${LIB_TYPE} ${SOURCES} ${HEADERS}) set_property(TARGET HLSL PROPERTY FOLDER hlsl) set_property(TARGET HLSL PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -31,11 +33,13 @@ endif(WIN32) if(ENABLE_GLSLANG_INSTALL) if(BUILD_SHARED_LIBS) - install(TARGETS HLSL + install(TARGETS HLSL EXPORT HLSLTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) else() - install(TARGETS HLSL + install(TARGETS HLSL EXPORT HLSLTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() + install(EXPORT HLSLTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif(ENABLE_GLSLANG_INSTALL) diff --git a/Externals/glslang/hlsl/hlslAttributes.cpp b/Externals/glslang/hlsl/hlslAttributes.cpp index 261cec346f..0cc0d3f4fc 100644 --- a/Externals/glslang/hlsl/hlslAttributes.cpp +++ b/Externals/glslang/hlsl/hlslAttributes.cpp @@ -58,6 +58,49 @@ namespace glslang { return EatConstantId; else if (name == "push_constant") return EatPushConstant; + } else if (nameSpace == "spv") { + if (name == "format_rgba32f") return EatFormatRgba32f; + if (name == "format_rgba16f") return EatFormatRgba16f; + if (name == "format_r32f") return EatFormatR32f; + if (name == "format_rgba8") return EatFormatRgba8; + if (name == "format_rgba8snorm") return EatFormatRgba8Snorm; + if (name == "format_rg32f") return EatFormatRg32f; + if (name == "format_rg16f") return EatFormatRg16f; + if (name == "format_r11fg11fb10f") return EatFormatR11fG11fB10f; + if (name == "format_r16f") return EatFormatR16f; + if (name == "format_rgba16") return EatFormatRgba16; + if (name == "format_rgb10a2") return EatFormatRgb10A2; + if (name == "format_rg16") return EatFormatRg16; + if (name == "format_rg8") return EatFormatRg8; + if (name == "format_r16") return EatFormatR16; + if (name == "format_r8") return EatFormatR8; + if (name == "format_rgba16snorm") return EatFormatRgba16Snorm; + if (name == "format_rg16snorm") return EatFormatRg16Snorm; + if (name == "format_rg8snorm") return EatFormatRg8Snorm; + if (name == "format_r16snorm") return EatFormatR16Snorm; + if (name == "format_r8snorm") return EatFormatR8Snorm; + if (name == "format_rgba32i") return EatFormatRgba32i; + if (name == "format_rgba16i") return EatFormatRgba16i; + if (name == "format_rgba8i") return EatFormatRgba8i; + if (name == "format_r32i") return EatFormatR32i; + if (name == "format_rg32i") return EatFormatRg32i; + if (name == "format_rg16i") return EatFormatRg16i; + if (name == "format_rg8i") return EatFormatRg8i; + if (name == "format_r16i") return EatFormatR16i; + if (name == "format_r8i") return EatFormatR8i; + if (name == "format_rgba32ui") return EatFormatRgba32ui; + if (name == "format_rgba16ui") return EatFormatRgba16ui; + if (name == "format_rgba8ui") return EatFormatRgba8ui; + if (name == "format_r32ui") return EatFormatR32ui; + if (name == "format_rgb10a2ui") return EatFormatRgb10a2ui; + if (name == "format_rg32ui") return EatFormatRg32ui; + if (name == "format_rg16ui") return EatFormatRg16ui; + if (name == "format_rg8ui") return EatFormatRg8ui; + if (name == "format_r16ui") return EatFormatR16ui; + if (name == "format_r8ui") return EatFormatR8ui; + + if (name == "nonwritable") return EatNonWritable; + if (name == "nonreadable") return EatNonReadable; } else if (nameSpace.size() > 0) return EatNone; diff --git a/Externals/glslang/hlsl/hlslGrammar.cpp b/Externals/glslang/hlsl/hlslGrammar.cpp old mode 100755 new mode 100644 index cb05877917..8ab1a900be --- a/Externals/glslang/hlsl/hlslGrammar.cpp +++ b/Externals/glslang/hlsl/hlslGrammar.cpp @@ -1,5 +1,5 @@ // -// Copyright (C) 2016 Google, Inc. +// Copyright (C) 2016-2018 Google, Inc. // Copyright (C) 2016 LunarG, Inc. // // All rights reserved. @@ -126,8 +126,6 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken) // bool HlslGrammar::acceptCompilationUnit() { - TIntermNode* unitNode = nullptr; - if (! acceptDeclarationList(unitNode)) return false; @@ -324,7 +322,7 @@ bool HlslGrammar::acceptSamplerDeclarationDX9(TType& /*type*/) // node for all the initializers. Each function created is a top-level node to grow // into the passed-in nodeList. // -// If 'nodeList' is passed in as non-null, it must an aggregate to extend for +// If 'nodeList' is passed in as non-null, it must be an aggregate to extend for // each top-level node the declaration creates. Otherwise, if only one top-level // node in generated here, that is want is returned in nodeList. // @@ -489,7 +487,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) // Declare the variable and add any initializer code to the AST. // The top-level node is always made into an aggregate, as that's // historically how the AST has been. - initializers = intermediate.growAggregate(initializers, + initializers = intermediate.growAggregate(initializers, parseContext.declareVariable(idToken.loc, *fullName, variableType, expressionNode), idToken.loc); } @@ -506,11 +504,16 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) if (initializers != nullptr) initializers->setOperator(EOpSequence); - // Add the initializers' aggregate to the nodeList we were handed. - if (nodeList) - nodeList = intermediate.growAggregate(nodeList, initializers); - else - nodeList = initializers; + // if we have a locally scoped static, it needs a globally scoped initializer + if (declaredType.getQualifier().storage == EvqGlobal && !parseContext.symbolTable.atGlobalLevel()) { + unitNode = intermediate.growAggregate(unitNode, initializers, idToken.loc); + } else { + // Add the initializers' aggregate to the nodeList we were handed. + if (nodeList) + nodeList = intermediate.growAggregate(nodeList, initializers); + else + nodeList = initializers; + } // SEMICOLON if (! acceptTokenClass(EHTokSemicolon)) { @@ -518,13 +521,11 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList) // was actually an assignment such as "float = 4", where "float" is an identifier. // We put the token back to let further parsing happen for cases where that may // happen. This errors on the side of caution, and mostly triggers the error. - if (peek() == EHTokAssign || peek() == EHTokLeftBracket || peek() == EHTokDot || peek() == EHTokComma) { + if (peek() == EHTokAssign || peek() == EHTokLeftBracket || peek() == EHTokDot || peek() == EHTokComma) recedeToken(); - return false; - } else { + else expected(";"); - return false; - } + return false; } return true; @@ -651,7 +652,7 @@ bool HlslGrammar::acceptQualifier(TQualifier& qualifier) do { switch (peek()) { case EHTokStatic: - qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + qualifier.storage = EvqGlobal; break; case EHTokExtern: // TODO: no meaning in glslang? @@ -1162,6 +1163,49 @@ bool HlslGrammar::acceptSubpassInputType(TType& type) return true; } +// sampler_type for DX9 compatibility +// : SAMPLER +// | SAMPLER1D +// | SAMPLER2D +// | SAMPLER3D +// | SAMPLERCUBE +bool HlslGrammar::acceptSamplerTypeDX9(TType &type) +{ + // read sampler type + const EHlslTokenClass samplerType = peek(); + + TSamplerDim dim = EsdNone; + TType txType(EbtFloat, EvqUniform, 4); // default type is float4 + + bool isShadow = false; + + switch (samplerType) + { + case EHTokSampler: dim = Esd2D; break; + case EHTokSampler1d: dim = Esd1D; break; + case EHTokSampler2d: dim = Esd2D; break; + case EHTokSampler3d: dim = Esd3D; break; + case EHTokSamplerCube: dim = EsdCube; break; + default: + return false; // not a dx9 sampler declaration + } + + advanceToken(); // consume the sampler type keyword + + TArraySizes *arraySizes = nullptr; // TODO: array + + TSampler sampler; + sampler.set(txType.getBasicType(), dim, false, isShadow, false); + + if (!parseContext.setTextureReturnType(sampler, txType, token.loc)) + return false; + + type.shallowCopy(TType(sampler, EvqUniform, arraySizes)); + type.getQualifier().layoutFormat = ElfNone; + + return true; +} + // sampler_type // : SAMPLER // | SAMPLER1D @@ -1444,7 +1488,13 @@ bool HlslGrammar::acceptType(TType& type, TIntermNode*& nodeList) case EHTokSampler2d: // ... case EHTokSampler3d: // ... case EHTokSamplerCube: // ... - case EHTokSamplerState: // ... + if (parseContext.hlslDX9Compatible()) + return acceptSamplerTypeDX9(type); + else + return acceptSamplerType(type); + break; + + case EHTokSamplerState: // fall through case EHTokSamplerComparisonState: // ... return acceptSamplerType(type); break; @@ -3171,6 +3221,11 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node) return false; } + if (arguments == nullptr) { + expected("one or more arguments"); + return false; + } + // hook it up node = parseContext.handleFunctionCall(arguments->getLoc(), constructorFunction, arguments); diff --git a/Externals/glslang/hlsl/hlslGrammar.h b/Externals/glslang/hlsl/hlslGrammar.h old mode 100755 new mode 100644 index 046f7957e5..27706b2b9b --- a/Externals/glslang/hlsl/hlslGrammar.h +++ b/Externals/glslang/hlsl/hlslGrammar.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2016 Google, Inc. +// Copyright (C) 2016-2018 Google, Inc. // Copyright (C) 2016 LunarG, Inc. // // All rights reserved. @@ -52,7 +52,7 @@ namespace glslang { public: HlslGrammar(HlslScanContext& scanner, HlslParseContext& parseContext) : HlslTokenStream(scanner), parseContext(parseContext), intermediate(parseContext.intermediate), - typeIdentifiers(false) { } + typeIdentifiers(false), unitNode(nullptr) { } virtual ~HlslGrammar() { } bool parse(); @@ -84,6 +84,7 @@ namespace glslang { bool acceptStreamOutTemplateType(TType&, TLayoutGeometry&); bool acceptOutputPrimitiveGeometry(TLayoutGeometry&); bool acceptAnnotations(TQualifier&); + bool acceptSamplerTypeDX9(TType &); bool acceptSamplerType(TType&); bool acceptTextureType(TType&); bool acceptSubpassInputType(TType&); @@ -133,6 +134,7 @@ namespace glslang { HlslParseContext& parseContext; // state of parsing and helper functions for building the intermediate TIntermediate& intermediate; // the final product, the intermediate representation, includes the AST bool typeIdentifiers; // shader uses some types as identifiers + TIntermNode* unitNode; }; } // end namespace glslang diff --git a/Externals/glslang/hlsl/hlslOpMap.cpp b/Externals/glslang/hlsl/hlslOpMap.cpp old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslOpMap.h b/Externals/glslang/hlsl/hlslOpMap.h old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslParseHelper.cpp b/Externals/glslang/hlsl/hlslParseHelper.cpp index d80f356b55..be665ac00d 100755 --- a/Externals/glslang/hlsl/hlslParseHelper.cpp +++ b/Externals/glslang/hlsl/hlslParseHelper.cpp @@ -1,5 +1,5 @@ // -// Copyright (C) 2017 Google, Inc. +// Copyright (C) 2017-2018 Google, Inc. // Copyright (C) 2017 LunarG, Inc. // // All rights reserved. @@ -39,6 +39,7 @@ #include "hlslGrammar.h" #include "hlslAttributes.h" +#include "../glslang/Include/Common.h" #include "../glslang/MachineIndependent/Scan.h" #include "../glslang/MachineIndependent/preprocessor/PpContext.h" @@ -97,9 +98,6 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int if (language == EShLangGeometry) globalOutputDefaults.layoutStream = 0; - - if (spvVersion.spv == 0 || spvVersion.vulkan == 0) - infoSink.info << "ERROR: HLSL currently only supported when requesting SPIR-V for Vulkan.\n"; } HlslParseContext::~HlslParseContext() @@ -136,7 +134,7 @@ bool HlslParseContext::parseShaderStrings(TPpContext& ppContext, TInputScanner& // Print a message formated such that if you click on the message it will take you right to // the line through most UIs. const glslang::TSourceLoc& sourceLoc = input.getSourceLoc(); - infoSink.info << sourceLoc.name << "(" << sourceLoc.line << "): error at column " << sourceLoc.column + infoSink.info << sourceLoc.getFilenameStr() << "(" << sourceLoc.line << "): error at column " << sourceLoc.column << ", HLSL parsing failed.\n"; ++numErrors; return false; @@ -656,10 +654,6 @@ TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, const TStr return nullptr; } - // Error check for requiring specific extensions present. - if (symbol && symbol->getNumExtensions()) - requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str()); - const TVariable* variable = nullptr; const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr; TIntermTyped* node = nullptr; @@ -822,7 +816,8 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, base->getAsSymbolNode()->getName().c_str(), ""); else error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", ""); - } else if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst) { + } else 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); @@ -1875,6 +1870,9 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T } break; } + case EatEarlyDepthStencil: + intermediate.setEarlyFragmentTests(); + break; case EatBuiltIn: case EatLocation: // tolerate these because of dual use of entrypoint and type attributes @@ -1902,13 +1900,16 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr // location if (it->getInt(value)) type.getQualifier().layoutLocation = value; + else + error(loc, "needs a literal integer", "location", ""); break; case EatBinding: // binding if (it->getInt(value)) { type.getQualifier().layoutBinding = value; type.getQualifier().layoutSet = 0; - } + } else + error(loc, "needs a literal integer", "binding", ""); // set if (it->getInt(value, 1)) type.getQualifier().layoutSet = value; @@ -1917,7 +1918,9 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr // global cbuffer binding if (it->getInt(value)) globalUniformBinding = value; - // global cbuffer binding + else + error(loc, "needs a literal integer", "global binding", ""); + // global cbuffer set if (it->getInt(value, 1)) globalUniformSet = value; break; @@ -1925,6 +1928,8 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr // input attachment if (it->getInt(value)) type.getQualifier().layoutAttachment = value; + else + error(loc, "needs a literal integer", "input attachment", ""); break; case EatBuiltIn: // PointSize built-in @@ -1945,6 +1950,52 @@ void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttr setSpecConstantId(loc, type.getQualifier(), value); } break; + + // image formats + case EatFormatRgba32f: type.getQualifier().layoutFormat = ElfRgba32f; break; + case EatFormatRgba16f: type.getQualifier().layoutFormat = ElfRgba16f; break; + case EatFormatR32f: type.getQualifier().layoutFormat = ElfR32f; break; + case EatFormatRgba8: type.getQualifier().layoutFormat = ElfRgba8; break; + case EatFormatRgba8Snorm: type.getQualifier().layoutFormat = ElfRgba8Snorm; break; + case EatFormatRg32f: type.getQualifier().layoutFormat = ElfRg32f; break; + case EatFormatRg16f: type.getQualifier().layoutFormat = ElfRg16f; break; + case EatFormatR11fG11fB10f: type.getQualifier().layoutFormat = ElfR11fG11fB10f; break; + case EatFormatR16f: type.getQualifier().layoutFormat = ElfR16f; break; + case EatFormatRgba16: type.getQualifier().layoutFormat = ElfRgba16; break; + case EatFormatRgb10A2: type.getQualifier().layoutFormat = ElfRgb10A2; break; + case EatFormatRg16: type.getQualifier().layoutFormat = ElfRg16; break; + case EatFormatRg8: type.getQualifier().layoutFormat = ElfRg8; break; + case EatFormatR16: type.getQualifier().layoutFormat = ElfR16; break; + case EatFormatR8: type.getQualifier().layoutFormat = ElfR8; break; + case EatFormatRgba16Snorm: type.getQualifier().layoutFormat = ElfRgba16Snorm; break; + case EatFormatRg16Snorm: type.getQualifier().layoutFormat = ElfRg16Snorm; break; + case EatFormatRg8Snorm: type.getQualifier().layoutFormat = ElfRg8Snorm; break; + case EatFormatR16Snorm: type.getQualifier().layoutFormat = ElfR16Snorm; break; + case EatFormatR8Snorm: type.getQualifier().layoutFormat = ElfR8Snorm; break; + case EatFormatRgba32i: type.getQualifier().layoutFormat = ElfRgba32i; break; + case EatFormatRgba16i: type.getQualifier().layoutFormat = ElfRgba16i; break; + case EatFormatRgba8i: type.getQualifier().layoutFormat = ElfRgba8i; break; + case EatFormatR32i: type.getQualifier().layoutFormat = ElfR32i; break; + case EatFormatRg32i: type.getQualifier().layoutFormat = ElfRg32i; break; + case EatFormatRg16i: type.getQualifier().layoutFormat = ElfRg16i; break; + case EatFormatRg8i: type.getQualifier().layoutFormat = ElfRg8i; break; + case EatFormatR16i: type.getQualifier().layoutFormat = ElfR16i; break; + case EatFormatR8i: type.getQualifier().layoutFormat = ElfR8i; break; + case EatFormatRgba32ui: type.getQualifier().layoutFormat = ElfRgba32ui; break; + case EatFormatRgba16ui: type.getQualifier().layoutFormat = ElfRgba16ui; break; + case EatFormatRgba8ui: type.getQualifier().layoutFormat = ElfRgba8ui; break; + case EatFormatR32ui: type.getQualifier().layoutFormat = ElfR32ui; break; + case EatFormatRgb10a2ui: type.getQualifier().layoutFormat = ElfRgb10a2ui; break; + case EatFormatRg32ui: type.getQualifier().layoutFormat = ElfRg32ui; break; + case EatFormatRg16ui: type.getQualifier().layoutFormat = ElfRg16ui; break; + case EatFormatRg8ui: type.getQualifier().layoutFormat = ElfRg8ui; break; + case EatFormatR16ui: type.getQualifier().layoutFormat = ElfR16ui; break; + case EatFormatR8ui: type.getQualifier().layoutFormat = ElfR8ui; break; + case EatFormatUnknown: type.getQualifier().layoutFormat = ElfNone; break; + + case EatNonWritable: type.getQualifier().readonly = true; break; + case EatNonReadable: type.getQualifier().writeonly = true; break; + default: if (! allowEntry) warn(loc, "attribute does not apply to a type", "", ""); @@ -3132,7 +3183,7 @@ TIntermAggregate* HlslParseContext::handleSamplerTextureCombine(const TSourceLoc if (textureShadowEntry != textureShadowVariant.end()) newId = textureShadowEntry->second->get(shadowMode); else - textureShadowVariant[texSymbol->getId()] = new tShadowTextureSymbols; + textureShadowVariant[texSymbol->getId()] = NewPoolObject(tShadowTextureSymbols(), 1); // Sometimes we have to create another symbol (if this texture has been seen before, // and we haven't created the form for this shadow mode). @@ -3211,7 +3262,7 @@ void HlslParseContext::declareStructBufferCounter(const TSourceLoc& loc, const T TType blockType; counterBufferType(loc, blockType); - TString* blockName = new TString(intermediate.addCounterBufferName(name)); + TString* blockName = NewPoolTString(intermediate.addCounterBufferName(name).c_str()); // Counter buffer is not yet in use structBufferCounter[*blockName] = false; @@ -3258,7 +3309,8 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte if (argAggregate) { if (argAggregate->getSequence().empty()) return; - bufferObj = argAggregate->getSequence()[0]->getAsTyped(); + if (argAggregate->getSequence()[0]) + bufferObj = argAggregate->getSequence()[0]->getAsTyped(); } else { bufferObj = arguments->getAsSymbolNode(); } @@ -3480,8 +3532,8 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte if (argStride != nullptr) { int size; int stride; - intermediate.getBaseAlignment(argArray->getType(), size, stride, false, - argArray->getType().getQualifier().layoutMatrix == ElmRowMajor); + intermediate.getMemberAlignment(argArray->getType(), size, stride, argArray->getType().getQualifier().layoutPacking, + argArray->getType().getQualifier().layoutMatrix == ElmRowMajor); TIntermTyped* assign = intermediate.addAssign(EOpAssign, argStride, intermediate.addConstantUnion(stride, loc, true), loc); @@ -3757,7 +3809,8 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType if (arguments->getAsTyped()->getBasicType() != EbtSampler) return; } else { - if (argAggregate->getSequence().size() == 0 || + if (argAggregate->getSequence().size() == 0 || + argAggregate->getSequence()[0] == nullptr || argAggregate->getSequence()[0]->getAsTyped()->getBasicType() != EbtSampler) return; } @@ -3773,6 +3826,43 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType break; } + case EOpTextureLod: //is almost EOpTextureBias (only args & operations are different) + { + TIntermTyped *argSamp = argAggregate->getSequence()[0]->getAsTyped(); // sampler + TIntermTyped *argCoord = argAggregate->getSequence()[1]->getAsTyped(); // coord + + assert(argCoord->getVectorSize() == 4); + TIntermTyped *w = intermediate.addConstantUnion(3, loc, true); + TIntermTyped *argLod = intermediate.addIndex(EOpIndexDirect, argCoord, w, loc); + + TOperator constructOp = EOpNull; + const TSampler &sampler = argSamp->getType().getSampler(); + int coordSize = 0; + + switch (sampler.dim) + { + case Esd1D: constructOp = EOpConstructFloat; coordSize = 1; break; // 1D + case Esd2D: constructOp = EOpConstructVec2; coordSize = 2; break; // 2D + case Esd3D: constructOp = EOpConstructVec3; coordSize = 3; break; // 3D + case EsdCube: constructOp = EOpConstructVec3; coordSize = 3; break; // also 3D + default: + break; + } + + TIntermAggregate *constructCoord = new TIntermAggregate(constructOp); + constructCoord->getSequence().push_back(argCoord); + constructCoord->setLoc(loc); + constructCoord->setType(TType(argCoord->getBasicType(), EvqTemporary, coordSize)); + + TIntermAggregate *tex = new TIntermAggregate(EOpTextureLod); + tex->getSequence().push_back(argSamp); // sampler + tex->getSequence().push_back(constructCoord); // coordinate + tex->getSequence().push_back(argLod); // lod + + node = convertReturn(tex, sampler); + + break; + } case EOpTextureBias: { @@ -4377,16 +4467,13 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType txquerylod->getSequence().push_back(txcombine); txquerylod->getSequence().push_back(argCoord); - TIntermTyped* lodComponent = intermediate.addConstantUnion(0, loc, true); + TIntermTyped* lodComponent = intermediate.addConstantUnion( + op == EOpMethodCalculateLevelOfDetail ? 0 : 1, + loc, true); TIntermTyped* lodComponentIdx = intermediate.addIndex(EOpIndexDirect, txquerylod, lodComponent, loc); lodComponentIdx->setType(TType(EbtFloat, EvqTemporary, 1)); - node = lodComponentIdx; - // We cannot currently obtain the unclamped LOD - if (op == EOpMethodCalculateLevelOfDetailUnclamped) - error(loc, "unimplemented: CalculateLevelOfDetailUnclamped", "", ""); - break; } @@ -4574,7 +4661,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*& if (nullptr == symbol) { type.getQualifier().builtIn = builtin; - TVariable* variable = new TVariable(new TString(name), type); + TVariable* variable = new TVariable(NewPoolTString(name), type); symbolTable.insert(*variable); @@ -5262,7 +5349,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct TIntermTyped* arg0 = nullptr; - if (aggregate && aggregate->getSequence().size() > 0) + if (aggregate && aggregate->getSequence().size() > 0 && aggregate->getSequence()[0]) arg0 = aggregate->getSequence()[0]->getAsTyped(); else if (arguments->getAsSymbolNode()) arg0 = arguments->getAsSymbolNode(); @@ -5290,11 +5377,6 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct // - a built-in function not mapped to an operator, or // - a user function. - // Error check for a function requiring specific extensions present. - if (builtIn && fnCandidate->getNumExtensions()) - requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), - fnCandidate->getName().c_str()); - // turn an implicit member-function resolution into an explicit call TString callerName; if (thisDepth == 0) @@ -5736,7 +5818,7 @@ void HlslParseContext::addStructBuffArguments(const TSourceLoc& loc, TIntermAggr std::any_of(aggregate->getSequence().begin(), aggregate->getSequence().end(), [this](const TIntermNode* node) { - return (node->getAsTyped() != nullptr) && hasStructBuffCounter(node->getAsTyped()->getType()); + return (node && node->getAsTyped() != nullptr) && hasStructBuffCounter(node->getAsTyped()->getType()); }); // Nothing to do, if we didn't find one. @@ -6072,13 +6154,22 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi } } - // TODO: learn what all these really mean and how they interact with regNumber and subComponent + // more information about register types see + // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-register const std::vector& resourceInfo = intermediate.getResourceSetBinding(); switch (std::tolower(desc[0])) { - case 'b': - case 't': case 'c': + // c register is the register slot in the global const buffer + // each slot is a vector of 4 32 bit components + qualifier.layoutOffset = regNumber * 4 * 4; + break; + // const buffer register slot + case 'b': + // textrues and structured buffers + case 't': + // samplers case 's': + // uav resources case 'u': // if nothing else has set the binding, do so now // (other mechanisms override this one) @@ -6249,7 +6340,8 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node bool constructingMatrix = false; switch (op) { case EOpConstructTextureSampler: - return constructorTextureSamplerError(loc, function); + error(loc, "unhandled texture constructor", "constructor", ""); + return true; case EOpConstructMat2x2: case EOpConstructMat2x3: case EOpConstructMat2x4: @@ -6441,67 +6533,6 @@ bool HlslParseContext::isScalarConstructor(const TIntermNode* node) (node->getAsAggregate() == nullptr || node->getAsAggregate()->getOp() != EOpNull); } -// Verify all the correct semantics for constructing a combined texture/sampler. -// Return true if the semantics are incorrect. -bool HlslParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function) -{ - TString constructorName = function.getType().getBasicTypeString(); // TODO: performance: should not be making copy; interface needs to change - const char* token = constructorName.c_str(); - - // exactly two arguments needed - if (function.getParamCount() != 2) { - error(loc, "sampler-constructor requires two arguments", token, ""); - return true; - } - - // For now, not allowing arrayed constructors, the rest of this function - // is set up to allow them, if this test is removed: - if (function.getType().isArray()) { - error(loc, "sampler-constructor cannot make an array of samplers", token, ""); - return true; - } - - // first argument - // * the constructor's first argument must be a texture type - // * the dimensionality (1D, 2D, 3D, Cube, Rect, Buffer, MS, and Array) - // of the texture type must match that of the constructed sampler type - // (that is, the suffixes of the type of the first argument and the - // type of the constructor will be spelled the same way) - if (function[0].type->getBasicType() != EbtSampler || - ! function[0].type->getSampler().isTexture() || - function[0].type->isArray()) { - error(loc, "sampler-constructor first argument must be a scalar textureXXX type", token, ""); - return true; - } - // simulate the first argument's impact on the result type, so it can be compared with the encapsulated operator!=() - TSampler texture = function.getType().getSampler(); - texture.combined = false; - texture.shadow = false; - if (texture != function[0].type->getSampler()) { - error(loc, "sampler-constructor first argument must match type and dimensionality of constructor type", token, ""); - return true; - } - - // 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; -} - // Checks to see if a void variable has been declared and raise an error message for such a case // // returns true in case of an error @@ -7869,6 +7900,8 @@ TVariable* HlslParseContext::declareNonArray(const TSourceLoc& loc, const TStrin // Returning nullptr just means there is no code to execute to handle the // initializer, which will, for example, be the case for constant initializers. // +// Returns a subtree that accomplished the initialization. +// TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyped* initializer, TVariable* variable) { // @@ -8176,8 +8209,6 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermTyp TIntermAggregate* aggrNode = node->getAsAggregate(); TOperator op = intermediate.mapTypeToConstructorOp(type); - // Combined texture-sampler constructors are completely semantic checked - // in constructorTextureSamplerError() if (op == EOpConstructTextureSampler) return intermediate.setAggregateOperator(aggrNode, op, type, loc); @@ -8621,7 +8652,7 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS // Process the members fixBlockLocations(loc, type.getQualifier(), typeList, memberWithLocation, memberWithoutLocation); - fixBlockXfbOffsets(type.getQualifier(), typeList); + fixXfbOffsets(type.getQualifier(), typeList); fixBlockUniformOffsets(type.getQualifier(), typeList); // reverse merge, so that currentBlockQualifier now has all layout information @@ -8704,7 +8735,7 @@ void HlslParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qual } } -void HlslParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& typeList) +void HlslParseContext::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 @@ -8717,13 +8748,20 @@ void HlslParseContext::fixBlockXfbOffsets(TQualifier& qualifier, TTypeList& type 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; + bool contains32BitType = false; + bool contains16BitType = false; + int memberSize = intermediate.computeTypeXfbSize(*typeList[member].type, contains64BitType, contains32BitType, contains16BitType); // 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); + else if (contains32BitType) + RoundToPow2(nextOffset, 4); + // "if applied to an aggregate containing a half float or 16-bit integer, the offset must also be a multiple of 2" + else if (contains16BitType) + RoundToPow2(nextOffset, 2); memberQualifier.layoutXfbOffset = nextOffset; } else nextOffset = memberQualifier.layoutXfbOffset; @@ -8745,7 +8783,7 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType { if (! qualifier.isUniformOrBuffer()) return; - if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430) + if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar) return; int offset = 0; @@ -8759,11 +8797,11 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType // 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." diff --git a/Externals/glslang/hlsl/hlslParseHelper.h b/Externals/glslang/hlsl/hlslParseHelper.h old mode 100755 new mode 100644 index 32a1923940..822de896f0 --- a/Externals/glslang/hlsl/hlslParseHelper.h +++ b/Externals/glslang/hlsl/hlslParseHelper.h @@ -1,5 +1,5 @@ // -// Copyright (C) 2016 Google, Inc. +// Copyright (C) 2016-2018 Google, Inc. // Copyright (C) 2016 LunarG, Inc. // // All rights reserved. @@ -122,7 +122,6 @@ public: void integerCheck(const TIntermTyped* node, const char* token); 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 arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); void structArrayCheck(const TSourceLoc&, const TType& structure); @@ -156,7 +155,7 @@ public: void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0); void declareStructBufferCounter(const TSourceLoc& loc, const TType& bufferType, const TString& name); void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation); - void fixBlockXfbOffsets(TQualifier&, TTypeList&); + void fixXfbOffsets(TQualifier&, TTypeList&); void fixBlockUniformOffsets(const TQualifier&, TTypeList&); void addQualifierToExisting(const TSourceLoc&, TQualifier, const TString& identifier); void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); diff --git a/Externals/glslang/hlsl/hlslParseables.cpp b/Externals/glslang/hlsl/hlslParseables.cpp old mode 100755 new mode 100644 index cc847ae22f..a63ecb6052 --- a/Externals/glslang/hlsl/hlslParseables.cpp +++ b/Externals/glslang/hlsl/hlslParseables.cpp @@ -605,7 +605,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c { "determinant", "S", "F", "M", "F", EShLangAll, false }, { "DeviceMemoryBarrier", nullptr, nullptr, "-", "-", EShLangPSCS, false }, { "DeviceMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS, false }, - { "distance", "S", "F", "V,", "F,", EShLangAll, false }, + { "distance", "S", "F", "SV,", "F,", EShLangAll, false }, { "dot", "S", nullptr, "SV,", "FI,", EShLangAll, false }, { "dst", nullptr, nullptr, "V4,", "F,", EShLangAll, false }, // { "errorf", "-", "-", "", "", EShLangAll, false }, TODO: varargs @@ -698,17 +698,17 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c { "step", nullptr, nullptr, "SVM,", "F,", EShLangAll, false }, { "tan", nullptr, nullptr, "SVM", "F", EShLangAll, false }, { "tanh", nullptr, nullptr, "SVM", "F", EShLangAll, false }, - { "tex1D", "V4", "F", "V1,S", "S,F", EShLangPS, false }, - { "tex1D", "V4", "F", "V1,S,V1,", "S,F,,", EShLangPS, false }, - { "tex1Dbias", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, - { "tex1Dgrad", "V4", "F", "V1,,,", "S,F,,", EShLangPS, false }, - { "tex1Dlod", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, - { "tex1Dproj", "V4", "F", "V1,V4", "S,F", EShLangPS, false }, + { "tex1D", "V4", "F", "S,S", "S,F", EShLangPS, false }, + { "tex1D", "V4", "F", "S,S,V1,", "S,F,,", EShLangPS, false }, + { "tex1Dbias", "V4", "F", "S,V4", "S,F", EShLangPS, false }, + { "tex1Dgrad", "V4", "F", "S,,,", "S,F,,", EShLangPS, false }, + { "tex1Dlod", "V4", "F", "S,V4", "S,F", EShLangPS, false }, + { "tex1Dproj", "V4", "F", "S,V4", "S,F", EShLangPS, false }, { "tex2D", "V4", "F", "V2,", "S,F", EShLangPS, false }, { "tex2D", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false }, { "tex2Dbias", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, { "tex2Dgrad", "V4", "F", "V2,,,", "S,F,,", EShLangPS, false }, - { "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, + { "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangAll, false }, { "tex2Dproj", "V4", "F", "V2,V4", "S,F", EShLangPS, false }, { "tex3D", "V4", "F", "V3,", "S,F", EShLangPS, false }, { "tex3D", "V4", "F", "V3,,,", "S,F,,", EShLangPS, false }, diff --git a/Externals/glslang/hlsl/hlslParseables.h b/Externals/glslang/hlsl/hlslParseables.h old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslScanContext.cpp b/Externals/glslang/hlsl/hlslScanContext.cpp old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslScanContext.h b/Externals/glslang/hlsl/hlslScanContext.h old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslTokenStream.cpp b/Externals/glslang/hlsl/hlslTokenStream.cpp old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslTokenStream.h b/Externals/glslang/hlsl/hlslTokenStream.h old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/hlslTokens.h b/Externals/glslang/hlsl/hlslTokens.h old mode 100755 new mode 100644 diff --git a/Externals/glslang/hlsl/pch.cpp b/Externals/glslang/hlsl/pch.cpp new file mode 100644 index 0000000000..b7a08654a5 --- /dev/null +++ b/Externals/glslang/hlsl/pch.cpp @@ -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 --git a/Externals/glslang/hlsl/pch.h b/Externals/glslang/hlsl/pch.h new file mode 100644 index 0000000000..e0bc491781 --- /dev/null +++ b/Externals/glslang/hlsl/pch.h @@ -0,0 +1,54 @@ +#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 "hlslParseHelper.h" +#include "hlslScanContext.h" +#include "hlslGrammar.h" +#include "hlslAttributes.h" + +#include "../glslang/MachineIndependent/Scan.h" +#include "../glslang/MachineIndependent/preprocessor/PpContext.h" + +#include "../glslang/OSDependent/osinclude.h" + +#include +#include +#include +#include +#include + + +#endif /* _PCH_H */ diff --git a/Externals/glslang/known_good.json b/Externals/glslang/known_good.json index 7027d48277..60e2c2d20d 100644 --- a/Externals/glslang/known_good.json +++ b/Externals/glslang/known_good.json @@ -5,14 +5,14 @@ "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Tools", "subdir" : "External/spirv-tools", - "commit" : "545d6ca26d3beddcb8dc5dc363deb1544a2eeb87" + "commit" : "323a81fc5e30e43a04e5e22af4cba98ca2a161e6" }, { "name" : "spirv-tools/external/spirv-headers", "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Headers", "subdir" : "External/spirv-tools/external/spirv-headers", - "commit" : "12f8de9f04327336b699b1b80aa390ae7f9ddbf4" + "commit" : "204cd131c42b90d129073719f2766293ce35c081" } ] } diff --git a/Externals/glslang/known_good_khr.json b/Externals/glslang/known_good_khr.json index 083e7711c6..a64198a81f 100644 --- a/Externals/glslang/known_good_khr.json +++ b/Externals/glslang/known_good_khr.json @@ -12,7 +12,7 @@ "site" : "gitlab", "subrepo" : "spirv/SPIRV-Headers", "subdir" : "External/spirv-tools/external/spirv-headers", - "commit" : "4082a777bd5df31ed45acf40e64263094e85ed2e" + "commit" : "gitlab-prelim-rc4" } ] } diff --git a/Externals/glslang/update_glslang_sources.py b/Externals/glslang/update_glslang_sources.py index 550bc2b143..65be2f6a2c 100755 --- a/Externals/glslang/update_glslang_sources.py +++ b/Externals/glslang/update_glslang_sources.py @@ -66,7 +66,7 @@ def command_retval(cmd, directory): p = subprocess.Popen(cmd, cwd=directory, stdout=subprocess.PIPE) - (stdout, _) = p.communicate() + p.communicate() return p.returncode @@ -95,8 +95,8 @@ class GoodCommit(object): def AddRemote(self): """Add the remote 'known-good' if it does not exist.""" - print('Ignore "fatal" errors for missing known-good remote:') - if command_retval(['git', 'remote', 'show', 'known-good'], self.subdir) != 0: + remotes = command_output(['git', 'remote'], self.subdir).splitlines() + if b'known-good' not in remotes: command_output(['git', 'remote', 'add', 'known-good', self.GetUrl()], self.subdir) def HasCommit(self):