Merge commit 'b5f003d7a3ece37db45578a8a3140b370036fc64' into vulkan-cts
diff --git a/.appveyor.yml b/.appveyor.yml
index 5765d9e..44d5f04 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -17,6 +17,20 @@
only:
- master
+# changes to these files don't need to trigger testing
+skip_commits:
+ files:
+ - README.md
+ - README-spirv-remap.txt
+ - LICENSE.txt
+ - CODE_OF_CONDUCT.md
+ - BUILD.*
+ - WORKSPACE
+ - kokoro/*
+ - make-revision
+ - Android.mk
+ - _config.yml
+
# Travis advances the master-tot tag to current top of the tree after
# each push into the master branch, because it relies on that tag to
# upload build artifacts to the master-tot release. This will cause
@@ -32,6 +46,7 @@
# scripts that run after cloning repository
install:
- C:/Python27/python.exe update_glslang_sources.py
+ - set PATH=C:\ninja;C:\Python36;%PATH%
- git clone https://github.com/google/googletest.git External/googletest
- cd External/googletest
- git checkout 440527a61e1c91188195f7de212c63c77e8f0a45
@@ -65,7 +80,6 @@
bin\glslangValidator.exe
bin\spirv-remap.exe
include\glslang\*
- include\SPIRV\*
lib\glslang%SUFFIX%.lib
lib\HLSL%SUFFIX%.lib
lib\OGLCompiler%SUFFIX%.lib
diff --git a/.clang-format b/.clang-format
index daf8798..8c73a52 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,7 +1,8 @@
Language: Cpp
IndentWidth: 4
+PointerAlignment: Left
BreakBeforeBraces: Custom
-BraceWrapping: { AfterFunction: true, AfterControlStatement: true }
+BraceWrapping: { AfterFunction: true, AfterControlStatement: false }
IndentCaseLabels: false
ReflowComments: false
ColumnLimit: 120
diff --git a/.travis.yml b/.travis.yml
index 2478912..1fa3fc0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -99,7 +99,6 @@
zip ${TARBALL}
bin/glslangValidator
include/glslang/*
- include/SPIRV/*
lib/libglslang${SUFFIX}.a
lib/libHLSL${SUFFIX}.a
lib/libOGLCompiler${SUFFIX}.a
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 0000000..5930608
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,247 @@
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+# Description:
+#
+# Khronos reference front-end for GLSL and ESSL, and sample SPIR-V generator.
+
+licenses(["notice"])
+
+exports_files(["LICENSE"])
+
+COMMON_COPTS = select({
+ "@bazel_tools//src/conditions:windows": [""],
+ "//conditions:default": [
+ "-Wall",
+ "-Wuninitialized",
+ "-Wunused",
+ "-Wunused-local-typedefs",
+ "-Wunused-parameter",
+ "-Wunused-value",
+ "-Wunused-variable",
+ "-Wno-reorder",
+ "-std=c++11",
+ "-fvisibility=hidden",
+ "-fvisibility-inlines-hidden",
+ "-fno-exceptions",
+ "-fno-rtti",
+ ],
+})
+
+cc_library(
+ name = "glslang",
+ srcs = glob(
+ [
+ "glslang/GenericCodeGen/*.cpp",
+ "glslang/MachineIndependent/*.cpp",
+ "glslang/MachineIndependent/preprocessor/*.cpp",
+ "hlsl/*.cpp",
+ ],
+ exclude = [
+ "glslang/MachineIndependent/pch.cpp",
+ "glslang/MachineIndependent/pch.h",
+ "hlsl/pch.cpp",
+ "hlsl/pch.h",
+ ],
+ ) + [
+ "OGLCompilersDLL/InitializeDll.cpp",
+ ] + select({
+ "@bazel_tools//src/conditions:windows":
+ ["glslang/OSDependent/Windows/ossource.cpp"],
+ "//conditions:default":
+ ["glslang/OSDependent/Unix/ossource.cpp"],
+ }),
+ hdrs = glob([
+ "glslang/Include/*.h",
+ "glslang/MachineIndependent/*.h",
+ "glslang/MachineIndependent/preprocessor/*.h",
+ "hlsl/*.h",
+ ]) + [
+ "OGLCompilersDLL/InitializeDll.h",
+ "StandAlone/DirStackFileIncluder.h",
+ "glslang/OSDependent/osinclude.h",
+ "glslang/Public/ShaderLang.h",
+ ],
+ copts = COMMON_COPTS,
+ defines = [
+ "AMD_EXTENSIONS",
+ "ENABLE_HLSL=0",
+ "ENABLE_OPT=0",
+ "NV_EXTENSIONS",
+ ],
+ linkopts = select({
+ "@bazel_tools//src/conditions:windows": [""],
+ "//conditions:default": ["-lm", "-lpthread"],
+ }),
+ linkstatic = 1,
+)
+
+genrule(
+ name = "export_spirv_headers",
+ srcs = [
+ "SPIRV/GLSL.ext.AMD.h",
+ "SPIRV/GLSL.ext.EXT.h",
+ "SPIRV/GLSL.ext.KHR.h",
+ "SPIRV/GLSL.ext.NV.h",
+ "SPIRV/GLSL.std.450.h",
+ "SPIRV/NonSemanticDebugPrintf.h",
+ "SPIRV/spirv.hpp",
+ ],
+ outs = [
+ "include/SPIRV/GLSL.ext.AMD.h",
+ "include/SPIRV/GLSL.ext.EXT.h",
+ "include/SPIRV/GLSL.ext.KHR.h",
+ "include/SPIRV/GLSL.ext.NV.h",
+ "include/SPIRV/GLSL.std.450.h",
+ "include/SPIRV/NonSemanticDebugPrintf.h",
+ "include/SPIRV/spirv.hpp",
+ ],
+ cmd = "mkdir -p $(@D)/include/SPIRV && cp $(SRCS) $(@D)/include/SPIRV/",
+)
+
+cc_library(
+ name = "SPIRV_headers",
+ hdrs = [":export_spirv_headers"],
+ copts = COMMON_COPTS,
+ includes = [
+ "include",
+ "include/SPIRV",
+ ],
+ linkstatic = 1,
+)
+
+cc_library(
+ name = "SPIRV",
+ srcs = glob(
+ ["SPIRV/*.cpp"],
+ exclude = [
+ "SPIRV/SpvTools.cpp",
+ ],
+ ),
+ hdrs = [
+ "SPIRV/GlslangToSpv.h",
+ "SPIRV/Logger.h",
+ "SPIRV/SPVRemapper.h",
+ "SPIRV/SpvBuilder.h",
+ "SPIRV/SpvTools.h",
+ "SPIRV/bitutils.h",
+ "SPIRV/disassemble.h",
+ "SPIRV/doc.h",
+ "SPIRV/hex_float.h",
+ "SPIRV/spvIR.h",
+ ],
+ copts = COMMON_COPTS,
+ includes = ["SPIRV"],
+ linkopts = select({
+ "@bazel_tools//src/conditions:windows": [""],
+ "//conditions:default": ["-lm"],
+ }),
+ linkstatic = 1,
+ deps = [
+ ":SPIRV_headers",
+ ":glslang",
+ ],
+)
+
+cc_library(
+ name = "glslang-default-resource-limits",
+ srcs = ["StandAlone/ResourceLimits.cpp"],
+ hdrs = ["StandAlone/ResourceLimits.h"],
+ copts = COMMON_COPTS,
+ linkstatic = 1,
+ deps = [":glslang"],
+)
+
+cc_binary(
+ name = "glslangValidator",
+ srcs = [
+ "StandAlone/StandAlone.cpp",
+ "StandAlone/Worklist.h",
+ ],
+ copts = COMMON_COPTS,
+ deps = [
+ ":SPIRV",
+ ":glslang",
+ ":glslang-default-resource-limits",
+ ],
+)
+
+cc_binary(
+ name = "spirv-remap",
+ srcs = ["StandAlone/spirv-remap.cpp"],
+ copts = COMMON_COPTS,
+ deps = [
+ ":SPIRV",
+ ":glslang",
+ ":glslang-default-resource-limits",
+ ],
+)
+
+filegroup(
+ name = "test_files",
+ srcs = glob(
+ ["Test/**"],
+ exclude = [
+ "Test/bump",
+ "Test/glslangValidator",
+ "Test/runtests",
+ ],
+ ),
+)
+
+cc_library(
+ name = "glslang_test_lib",
+ testonly = 1,
+ srcs = [
+ "gtests/HexFloat.cpp",
+ "gtests/Initializer.h",
+ "gtests/Settings.cpp",
+ "gtests/Settings.h",
+ "gtests/TestFixture.cpp",
+ "gtests/TestFixture.h",
+ "gtests/main.cpp",
+ ],
+ copts = COMMON_COPTS,
+ data = [":test_files"],
+ defines = select({
+ # Unfortunately we can't use $(location) in cc_library at the moment.
+ # See https://github.com/bazelbuild/bazel/issues/1023
+ # So we'll specify the path manually.
+ "@bazel_tools//src/conditions:windows":
+ ["GLSLANG_TEST_DIRECTORY='\"../../../../../Test\"'"],
+ "//conditions:default":
+ ["GLSLANG_TEST_DIRECTORY='\"Test\"'"],
+ }),
+ linkstatic = 1,
+ deps = [
+ ":SPIRV",
+ ":glslang",
+ ":glslang-default-resource-limits",
+ "@com_google_googletest//:gtest",
+ ],
+)
+
+GLSLANG_TESTS = glob(
+ ["gtests/*.FromFile.cpp"],
+ # Since we are not building the SPIRV-Tools dependency, the following tests
+ # cannot be performed.
+ exclude = [
+ "gtests/Hlsl.FromFile.cpp",
+ "gtests/Spv.FromFile.cpp",
+ ],
+)
+
+[cc_test(
+ name = test_file.replace("gtests/", "").replace(".FromFile.cpp", "") + "_test",
+ srcs = [test_file],
+ copts = COMMON_COPTS,
+ data = [
+ ":test_files",
+ ],
+ deps = [
+ ":SPIRV",
+ ":glslang",
+ ":glslang_test_lib",
+ ],
+) for test_file in GLSLANG_TESTS]
diff --git a/BUILD.gn b/BUILD.gn
index d8bfe61..49b4b0a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -33,10 +33,25 @@
import("//build_overrides/glslang.gni")
+# Both Chromium and Fuchsia use by default a set of warning errors
+# that is far too strict to compile this project. These are also
+# typically appended after |cflags|, overriding target-specific
+# definitions. To work around this, determine which configs to
+# add and remove in order to succesfully build the project.
+if (defined(is_fuchsia_tree) && is_fuchsia_tree) {
+ _configs_to_remove = [ "//build/config:default_warnings" ]
+ _configs_to_add = []
+} else {
+ _configs_to_remove = [ "//build/config/compiler:chromium_code" ]
+ _configs_to_add = [ "//build/config/compiler:no_chromium_code" ]
+}
+
spirv_tools_dir = glslang_spirv_tools_dir
config("glslang_public") {
include_dirs = [ "." ]
+
+ defines = [ "ENABLE_HLSL=1" ]
}
source_set("glslang_sources") {
@@ -45,19 +60,24 @@
sources = [
"OGLCompilersDLL/InitializeDll.cpp",
"OGLCompilersDLL/InitializeDll.h",
+ "SPIRV/GLSL.ext.AMD.h",
"SPIRV/GLSL.ext.EXT.h",
"SPIRV/GLSL.ext.KHR.h",
+ "SPIRV/GLSL.ext.NV.h",
"SPIRV/GLSL.std.450.h",
"SPIRV/GlslangToSpv.cpp",
"SPIRV/GlslangToSpv.h",
"SPIRV/InReadableOrder.cpp",
"SPIRV/Logger.cpp",
"SPIRV/Logger.h",
+ "SPIRV/NonSemanticDebugPrintf.h",
"SPIRV/SPVRemapper.cpp",
"SPIRV/SPVRemapper.h",
"SPIRV/SpvBuilder.cpp",
"SPIRV/SpvBuilder.h",
"SPIRV/SpvPostProcess.cpp",
+ "SPIRV/SpvTools.cpp",
+ "SPIRV/SpvTools.h",
"SPIRV/bitutils.h",
"SPIRV/disassemble.cpp",
"SPIRV/disassemble.h",
@@ -104,7 +124,6 @@
"glslang/MachineIndependent/attribute.cpp",
"glslang/MachineIndependent/attribute.h",
"glslang/MachineIndependent/gl_types.h",
- "glslang/MachineIndependent/glslang.y",
"glslang/MachineIndependent/glslang_tab.cpp",
"glslang/MachineIndependent/glslang_tab.cpp.h",
"glslang/MachineIndependent/intermOut.cpp",
@@ -128,9 +147,25 @@
"glslang/MachineIndependent/reflection.h",
"glslang/OSDependent/osinclude.h",
"glslang/Public/ShaderLang.h",
+ "hlsl/hlslAttributes.cpp",
+ "hlsl/hlslAttributes.h",
+ "hlsl/hlslGrammar.cpp",
+ "hlsl/hlslGrammar.h",
+ "hlsl/hlslOpMap.cpp",
+ "hlsl/hlslOpMap.h",
+ "hlsl/hlslParseHelper.cpp",
+ "hlsl/hlslParseHelper.h",
+ "hlsl/hlslParseables.cpp",
+ "hlsl/hlslParseables.h",
+ "hlsl/hlslScanContext.cpp",
+ "hlsl/hlslScanContext.h",
+ "hlsl/hlslTokenStream.cpp",
+ "hlsl/hlslTokenStream.h",
+ "hlsl/hlslTokens.h",
]
- defines = []
+ defines = [ "ENABLE_OPT=1" ]
+
if (is_win) {
sources += [ "glslang/OSDependent/Windows/ossource.cpp" ]
defines += [ "GLSLANG_OSINCLUDE_WIN32" ]
@@ -140,25 +175,31 @@
}
if (is_clang) {
- cflags_cc = [
+ cflags = [
"-Wno-extra-semi",
"-Wno-ignored-qualifiers",
"-Wno-implicit-fallthrough",
"-Wno-inconsistent-missing-override",
"-Wno-sign-compare",
"-Wno-unused-variable",
+ "-Wno-missing-field-initializers",
+ "-Wno-newline-eof",
]
}
if (is_win && !is_clang) {
cflags = [
- "/wd4018", # signed/unsigned mismatch
- "/wd4189", # local variable is initialized but not referenced
+ "/wd4018", # signed/unsigned mismatch
+ "/wd4189", # local variable is initialized but not referenced
]
}
deps = [
"${spirv_tools_dir}:spvtools_opt",
+ "${spirv_tools_dir}:spvtools_val",
]
+
+ configs -= _configs_to_remove
+ configs += _configs_to_add
}
source_set("glslang_default_resource_limits_sources") {
@@ -166,8 +207,13 @@
"StandAlone/ResourceLimits.cpp",
"StandAlone/ResourceLimits.h",
]
- deps = [ ":glslang_sources" ]
+ deps = [
+ ":glslang_sources",
+ ]
public_configs = [ ":glslang_public" ]
+
+ configs -= _configs_to_remove
+ configs += _configs_to_add
}
executable("glslang_validator") {
@@ -178,9 +224,25 @@
if (!is_win) {
cflags = [ "-Woverflow" ]
}
- defines = [ "ENABLE_OPT=0" ]
+ defines = [ "ENABLE_OPT=1" ]
deps = [
":glslang_default_resource_limits_sources",
":glslang_sources",
]
+
+ configs -= _configs_to_remove
+ configs += _configs_to_add
+}
+
+executable("spirv-remap") {
+ sources = [
+ "StandAlone/spirv-remap.cpp",
+ ]
+ defines = [ "ENABLE_OPT=1" ]
+ deps = [
+ ":glslang_sources",
+ ]
+
+ configs -= _configs_to_remove
+ configs += _configs_to_add
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aafa70e..cd9baf8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,10 +6,17 @@
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)
@@ -23,14 +30,36 @@
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_JS
+ "If using Emscripten, build glslang.js. Otherwise, builds a sample executable for binary-size testing." OFF)
+CMAKE_DEPENDENT_OPTION(ENABLE_GLSLANG_WEBMIN
+ "Reduces glslang to minimum needed for web use"
+ OFF "ENABLE_GLSLANG_JS"
+ OFF)
+CMAKE_DEPENDENT_OPTION(ENABLE_GLSLANG_WEBMIN_DEVEL
+ "For ENABLE_GLSLANG_WEBMIN builds, enables compilation error messages"
+ OFF "ENABLE_GLSLANG_WEBMIN"
+ OFF)
+CMAKE_DEPENDENT_OPTION(ENABLE_EMSCRIPTEN_SINGLE_FILE
+ "If using Emscripten, enables SINGLE_FILE build"
+ OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN"
+ OFF)
+CMAKE_DEPENDENT_OPTION(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE
+ "If using Emscripten, builds to run on Node instead of Web"
+ OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN"
+ OFF)
-option(ENABLE_HLSL "Enables HLSL input support" ON)
+CMAKE_DEPENDENT_OPTION(ENABLE_HLSL
+ "Enables HLSL input support"
+ ON "NOT ENABLE_GLSLANG_WEBMIN"
+ OFF)
+option(ENABLE_RTTI "Enables RTTI" 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)
@@ -46,7 +75,7 @@
# 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")
+ if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio" AND NOT ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" 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}")
@@ -57,21 +86,22 @@
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_WEBMIN)
+ add_definitions(-DGLSLANG_WEB)
+ if(ENABLE_GLSLANG_WEBMIN_DEVEL)
+ add_definitions(-DGLSLANG_WEB_DEVEL)
+ endif(ENABLE_GLSLANG_WEBMIN_DEVEL)
+endif(ENABLE_GLSLANG_WEBMIN)
+
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
if(MSVC)
@@ -88,17 +118,42 @@
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.
-elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
+ if(NOT ENABLE_RTTI)
+ add_compile_options(-fno-rtti)
+ endif()
+ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0")
+ add_compile_options(-Werror=deprecated-copy)
+ endif()
+elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" AND NOT MSVC)
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.
+ if(NOT ENABLE_RTTI)
+ add_compile_options(-fno-rtti)
+ endif()
+elseif(MSVC)
+ if(NOT ENABLE_RTTI)
+ add_compile_options(/GR-) # Disable RTTI
+ endif()
endif()
+if(ENABLE_GLSLANG_JS)
+ if(MSVC)
+ add_compile_options(/Os /GR-)
+ else()
+ add_compile_options(-Os -fno-exceptions)
+ if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" AND NOT MSVC)
+ add_compile_options(-Wno-unused-parameter)
+ add_compile_options(-Wno-unused-variable -Wno-unused-const-variable)
+ endif()
+ endif()
+endif(ENABLE_GLSLANG_JS)
+
# Request C++11
if(${CMAKE_VERSION} VERSION_LESS 3.1)
# CMake versions before 3.1 do not understand CMAKE_CXX_STANDARD
# remove this block once CMake >=3.1 has fixated in the ecosystem
- add_compile_options(-std=c++11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -114,8 +169,14 @@
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)
@@ -140,4 +201,29 @@
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}/$<CONFIGURATION>/localResults)
+ set(VALIDATOR_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/$<CONFIGURATION>/glslangValidator)
+ set(REMAP_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/$<CONFIGURATION>/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/External/CMakeLists.txt b/External/CMakeLists.txt
index 4d96901..6ff4f47 100644
--- a/External/CMakeLists.txt
+++ b/External/CMakeLists.txt
@@ -10,7 +10,8 @@
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/LICENSE.txt b/LICENSE.txt
old mode 100755
new mode 100644
diff --git a/OGLCompilersDLL/CMakeLists.txt b/OGLCompilersDLL/CMakeLists.txt
index 5bb3f0e..e009674 100644
--- a/OGLCompilersDLL/CMakeLists.txt
+++ b/OGLCompilersDLL/CMakeLists.txt
@@ -9,6 +9,7 @@
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/README.md b/README.md
index 7d4fe3a..ff844c0 100755
--- a/README.md
+++ b/README.md
@@ -1,35 +1,70 @@
-Also see the Khronos landing page for glslang as a reference front end:
-
-https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
-
-The above page includes where to get binaries, and is kept up to date
-regarding the feature level of glslang.
-
-glslang
-=======
+# News
[](https://travis-ci.org/KhronosGroup/glslang)
[](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)
-An OpenGL and OpenGL ES shader front end and validator.
+## Planned Deprecations/Removals
+
+1. **SPIRV Folder, 1-May, 2020.** 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 than May 1, 2020.
+See issue #1964.
+
+2. **Visual Studio 2013, 20-July, 2020.** Keeping code compiling for MS Visual Studio 2013 will no longer be
+a goal as of July 20, 2020, the fifth anniversary of the release of Visual Studio 2015.
+
+# Glslang Components and Status
There are several components:
-1. A GLSL/ESSL front-end for reference validation and translation of GLSL/ESSL into an AST.
+### Reference Validator and GLSL/ESSL -> AST Front End
-2. An HLSL front-end for translation of a broad generic HLL into the AST. See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
+An OpenGL GLSL and OpenGL|ES GLSL (ESSL) front-end for reference validation and translation of GLSL/ESSL into an internal abstract syntax tree (AST).
-3. A SPIR-V back end for translating the AST to SPIR-V.
+**Status**: Virtually complete, with results carrying similar weight as the specifications.
-4. A standalone wrapper, `glslangValidator`, that can be used as a command-line tool for the above.
+### HLSL -> AST Front End
-How to add a feature protected by a version/extension/stage/profile: See the
-comment in `glslang/MachineIndependent/Versions.cpp`.
+An HLSL front-end for translation of an approximation of HLSL to glslang's AST form.
+
+**Status**: Partially complete. Semantics are not reference quality and input is not validated.
+This is in contrast to the [DXC project](https://github.com/Microsoft/DirectXShaderCompiler), which receives a much larger investment and attempts to have definitive/reference-level semantics.
+
+See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
+
+### AST -> SPIR-V Back End
+
+Translates glslang's AST to the Khronos-specified SPIR-V intermediate language.
+
+**Status**: Virtually complete.
+
+### Reflector
+
+An API for getting reflection information from the AST, reflection types/variables/etc. from the HLL source (not the SPIR-V).
+
+**Status**: There is a large amount of functionality present, but no specification/goal to measure completeness against. It is accurate for the input HLL and AST, but only approximate for what would later be emitted for SPIR-V.
+
+### Standalone Wrapper
+
+`glslangValidator` is command-line tool for accessing the functionality above.
+
+Status: Complete.
Tasks waiting to be done are documented as GitHub issues.
-Execution of Standalone Wrapper
--------------------------------
+## Other References
+
+Also see the Khronos landing page for glslang as a reference front end:
+
+https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
+
+The above page, while not kept up to date, includes additional information regarding glslang as a reference validator.
+
+# How to Use Glslang
+
+## Execution of Standalone Wrapper
To use the standalone binary form, execute `glslangValidator`, and it will print
a usage statement. Basic operation is to give it a file containing a shader,
@@ -46,8 +81,7 @@
There is also a non-shader extension
* `.conf` for a configuration file of limits, see usage statement for example
-Building
---------
+## Building
Instead of building manually, you can also download the binaries for your
platform directly from the [master-tot release][master-tot-release] on GitHub.
@@ -61,7 +95,7 @@
(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.
@@ -70,7 +104,7 @@
The following steps assume a Bash shell. On Windows, that could be the Git Bash
shell or some other shell of your choosing.
-#### 1) Check-Out this project
+#### 1) Check-Out this project
```bash
cd <parent of where you want glslang to be>
@@ -94,8 +128,8 @@
```
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
@@ -118,6 +152,14 @@
# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo"
```
+For building on Android:
+```bash
+cmake $SOURCE_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_STL=c++_static -DANDROID_PLATFORM=android-24 -DCMAKE_SYSTEM_NAME=Android -DANDROID_TOOLCHAIN=clang -DANDROID_ARM_MODE=arm -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK_ROOT/prebuilt/linux-x86_64/bin/make -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake
+# If on Windows will be -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make.exe
+# -G is needed for building on Windows
+# -DANDROID_ABI can also be armeabi-v7a for 32 bit
+```
+
For building on Windows:
```bash
@@ -155,16 +197,57 @@
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).
-Testing
--------
+### Building to WASM for the Web and Node
+### Building a standalone JS/WASM library for the Web and Node
+
+Use the steps in [Build Steps](#build-steps), with the following notes/exceptions:
+* `emsdk` needs to be present in your executable search path, *PATH* for
+ Bash-like environments:
+ + [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)
+* Wrap cmake call: `emcmake cmake`
+* Set `-DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF`.
+* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
+* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
+* For building a minimum-size web subset of core glslang:
+ + turn on `-DENABLE_GLSLANG_WEBMIN=ON` (disables HLSL)
+ + execute `updateGrammar web` from the glslang subdirectory
+ (or if using your own scripts, `m4` needs a `-DGLSLANG_WEB` argument)
+ + optionally, for GLSL compilation error messages, turn on
+ `-DENABLE_GLSLANG_WEBMIN_DEVEL=ON`
+* 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_JS=ON \
+ -DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF ..
+```
+
+## Building glslang - Using vcpkg
+
+You can download and install glslang using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
+
+ git clone https://github.com/Microsoft/vcpkg.git
+ cd vcpkg
+ ./bootstrap-vcpkg.sh
+ ./vcpkg integrate install
+ ./vcpkg install glslang
+
+The glslang port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
+
+## Testing
Right now, there are two test harnesses existing in glslang: one is [Google
Test](gtests/), one is the [`runtests` script](Test/runtests). The former
@@ -200,6 +283,11 @@
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
@@ -231,8 +319,7 @@
`localtestlist` to list non-tracked tests. This is automatically read
by `runtests` and included in the `diff` and `bump` process.
-Programmatic Interfaces
------------------------
+## Programmatic Interfaces
Another piece of software can programmatically translate shaders to an AST
using one of two different interfaces:
@@ -244,7 +331,8 @@
### 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();
@@ -267,16 +355,25 @@
Reflection queries
```
-See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
-details.
+For just validating (not generating code), substitute 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`.
The `Sh*()` interface takes a "compiler" call-back object, which it calls after
-building call back that is passed the AST and can then execute a backend on it.
+building call back that is passed the AST and can then execute a back end on it.
The following is a simplified resulting run-time call stack:
@@ -287,8 +384,7 @@
In practice, `ShCompile()` takes shader strings, default version, and
warning/error and other options for controlling compilation.
-Basic Internal Operation
-------------------------
+## Basic Internal Operation
* Initial lexical analysis is done by the preprocessor in
`MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
@@ -303,7 +399,7 @@
* The intermediate representation is very high-level, and represented
as an in-memory tree. This serves to lose no information from the
original program, and to have efficient transfer of the result from
- parsing to the back-end. In the AST, constants are propogated and
+ parsing to the back-end. In the AST, constants are propagated and
folded, and a very small amount of dead code is eliminated.
To aid linking and reflection, the last top-level branch in the AST
@@ -335,6 +431,8 @@
- the object does not come from the pool, and you have to do normal
C++ memory management of what you `new`
+* Features can be protected by version/extension/stage/profile:
+ See the comment in `glslang/MachineIndependent/Versions.cpp`.
[cmake]: https://cmake.org/
[python]: https://www.python.org/
diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt
index 1997e74..9040609 100644
--- a/SPIRV/CMakeLists.txt
+++ b/SPIRV/CMakeLists.txt
@@ -25,28 +25,21 @@
spvIR.h
doc.h
SpvTools.h
- disassemble.h)
+ disassemble.h
+ GLSL.ext.AMD.h
+ GLSL.ext.NV.h
+ NonSemanticDebugPrintf.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
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
if (ENABLE_SPVREMAPPER)
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
@@ -67,7 +60,9 @@
PRIVATE ${spirv-tools_SOURCE_DIR}/source
)
target_link_libraries(SPIRV glslang SPIRV-Tools-opt)
- target_include_directories(SPIRV PUBLIC ../External)
+ target_include_directories(SPIRV PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
else()
target_link_libraries(SPIRV glslang)
endif(ENABLE_OPT)
@@ -80,21 +75,29 @@
if(ENABLE_GLSLANG_INSTALL)
if(BUILD_SHARED_LIBS)
if (ENABLE_SPVREMAPPER)
- install(TARGETS SPVRemapper
+ install(TARGETS SPVRemapper EXPORT SPVRemapperTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
- install(TARGETS SPIRV
+ 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()
if (ENABLE_SPVREMAPPER)
- install(TARGETS SPVRemapper
+ install(TARGETS SPVRemapper EXPORT SPVRemapperTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
- install(TARGETS SPIRV
+ 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/SPIRV/GLSL.ext.EXT.h b/SPIRV/GLSL.ext.EXT.h
index e29c055..40164b6 100644
--- a/SPIRV/GLSL.ext.EXT.h
+++ b/SPIRV/GLSL.ext.EXT.h
@@ -34,5 +34,6 @@
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/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h
index 333442b..d783a8f 100644
--- a/SPIRV/GLSL.ext.KHR.h
+++ b/SPIRV/GLSL.ext.KHR.h
@@ -1,5 +1,6 @@
/*
-** Copyright (c) 2014-2016 The Khronos Group Inc.
+** Copyright (c) 2014-2020 The Khronos Group Inc.
+** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
@@ -41,5 +42,10 @@
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";
+static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
+static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing";
+static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
#endif // #ifndef GLSLextKHR_H
diff --git a/SPIRV/GLSL.ext.NV.h b/SPIRV/GLSL.ext.NV.h
index ede2c57..50146da 100644
--- a/SPIRV/GLSL.ext.NV.h
+++ b/SPIRV/GLSL.ext.NV.h
@@ -75,4 +75,7 @@
//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/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 25ef210..3bed678 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1,7 +1,8 @@
//
// Copyright (C) 2014-2016 LunarG, Inc.
-// Copyright (C) 2015-2018 Google, Inc.
+// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -46,10 +47,9 @@
#include "GLSL.std.450.h"
#include "GLSL.ext.KHR.h"
#include "GLSL.ext.EXT.h"
-#ifdef AMD_EXTENSIONS
#include "GLSL.ext.AMD.h"
-#endif
#include "GLSL.ext.NV.h"
+ #include "NonSemanticDebugPrintf.h"
}
// Glslang includes
@@ -89,9 +89,29 @@
};
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
@@ -135,10 +155,10 @@
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<unsigned int>& 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);
@@ -169,7 +189,8 @@
void makeGlobalInitializers(const glslang::TIntermSequence&);
void visitFunctions(const glslang::TIntermSequence&);
void handleFunctionEntry(const glslang::TIntermAggregate* node);
- void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments);
+ void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments,
+ spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
void translateArguments(glslang::TIntermUnary& node, std::vector<spv::Id>& arguments);
spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
@@ -178,36 +199,38 @@
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 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<spv::Id>& operands, glslang::TBasicType typeProxy);
- spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
- spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector<spv::Id>& operands);
- spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
- spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
+ spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy,
+ const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags);
+ spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands,
+ glslang::TBasicType typeProxy);
+ spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation,
+ spv::Id typeId, std::vector<spv::Id>& operands);
+ spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands,
+ glslang::TBasicType typeProxy);
+ spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
-#ifdef NV_EXTENSIONS
void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier);
-#endif
spv::Id createSpvConstant(const glslang::TIntermTyped&);
- spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
+ 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<spv::Id, spv::Id> getForcedType(glslang::TBuiltInVariable builtIn, const glslang::TType&);
+ spv::Id translateForcedType(spv::Id object);
+ spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents);
glslang::SpvOptions& options;
spv::Function* shaderEntry;
@@ -221,22 +244,32 @@
spv::Builder builder;
bool inEntryPoint;
bool entryPointTerminated;
- bool linkageOnly; // true when visiting the set of objects in the AST present only for establishing interface, whether or not they were statically used
+ 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<spv::Id> 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;
+ spv::Id nonSemanticDebugPrintf;
std::unordered_map<const char*, spv::Id> extBuiltinMap;
std::unordered_map<int, spv::Id> symbolValues;
- std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues, rather than a pointer
+ std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues,
+ // rather than a pointer
std::unordered_map<std::string, spv::Function*> functionMap;
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
// for mapping glslang block indices to spv indices (e.g., due to hidden members):
- std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
+ std::unordered_map<int, std::vector<int>> memberRemapper;
+ // for mapping glslang symbol struct to symbol Id
+ std::unordered_map<const glslang::TTypeList*, int> glslangTypeToIdMap;
std::stack<bool> breakForLoop; // false means break for switch
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
// Map pointee types for EbtReference to their forward pointers
std::map<const glslang::TType *, spv::Id> 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 <builtin-variable-id -> AST-required-type-id>
+ std::unordered_map<spv::Id, spv::Id> forceType;
};
//
@@ -246,6 +279,10 @@
// 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) {
@@ -270,18 +307,18 @@
{
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;
-#ifdef NV_EXTENSIONS
- 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 EShLangRayGen: return spv::ExecutionModelRayGenerationKHR;
+ case EShLangIntersect: return spv::ExecutionModelIntersectionKHR;
+ case EShLangAnyHit: return spv::ExecutionModelAnyHitKHR;
+ case EShLangClosestHit: return spv::ExecutionModelClosestHitKHR;
+ case EShLangMiss: return spv::ExecutionModelMissKHR;
+ case EShLangCallable: return spv::ExecutionModelCallableKHR;
case EShLangTaskNV: return spv::ExecutionModelTaskNV;
case EShLangMeshNV: return spv::ExecutionModelMeshNV;
#endif
@@ -334,12 +371,12 @@
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
-#ifdef NV_EXTENSIONS
- 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;
+#ifndef GLSLANG_WEB
+ case glslang::EvqPayload: return spv::DecorationBlock;
+ case glslang::EvqPayloadIn: return spv::DecorationBlock;
+ case glslang::EvqHitAttr: return spv::DecorationBlock;
+ case glslang::EvqCallableData: return spv::DecorationBlock;
+ case glslang::EvqCallableDataIn: return spv::DecorationBlock;
#endif
default:
assert(0);
@@ -351,21 +388,22 @@
}
// Translate glslang type to SPIR-V memory decorations.
-void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory, bool useVulkanMemoryModel)
+void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory,
+ bool useVulkanMemoryModel)
{
if (!useVulkanMemoryModel) {
- if (qualifier.coherent)
+ if (qualifier.isCoherent())
memory.push_back(spv::DecorationCoherent);
- if (qualifier.volatil) {
+ if (qualifier.isVolatile()) {
memory.push_back(spv::DecorationVolatile);
memory.push_back(spv::DecorationCoherent);
}
}
- if (qualifier.restrict)
+ 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);
}
@@ -409,12 +447,12 @@
assert(type.getQualifier().layoutPacking == glslang::ElpNone);
}
return spv::DecorationMax;
-#ifdef NV_EXTENSIONS
- case glslang::EvqPayloadNV:
- case glslang::EvqPayloadInNV:
- case glslang::EvqHitAttrNV:
- case glslang::EvqCallableDataNV:
- case glslang::EvqCallableDataInNV:
+#ifndef GLSLANG_WEB
+ case glslang::EvqPayload:
+ case glslang::EvqPayloadIn:
+ case glslang::EvqHitAttr:
+ case glslang::EvqCallableData:
+ case glslang::EvqCallableDataIn:
return spv::DecorationMax;
#endif
default:
@@ -433,16 +471,14 @@
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;
}
@@ -452,15 +488,18 @@
// 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.
@@ -475,38 +514,41 @@
// 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 TGlslangToSpvTraverser::TranslateMemoryAccess(
+ const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{
- if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) {
- return spv::MemoryAccessMaskNone;
- }
spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone;
- if (coherentFlags.volatil ||
- coherentFlags.coherent ||
- coherentFlags.devicecoherent ||
- coherentFlags.queuefamilycoherent ||
- coherentFlags.workgroupcoherent ||
- coherentFlags.subgroupcoherent) {
+
+#ifndef GLSLANG_WEB
+ if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage)
+ return mask;
+
+ if (coherentFlags.isVolatile() || coherentFlags.anyCoherent()) {
mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask |
spv::MemoryAccessMakePointerVisibleKHRMask;
}
+
if (coherentFlags.nonprivate) {
mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask;
}
@@ -516,21 +558,22 @@
if (mask != spv::MemoryAccessMaskNone) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
+#endif
+
return mask;
}
-spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
+spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(
+ const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{
- if (!glslangIntermediate->usingVulkanMemoryModel()) {
- return spv::ImageOperandsMaskNone;
- }
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) {
+ coherentFlags.anyCoherent()) {
mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask |
spv::ImageOperandsMakeTexelVisibleKHRMask;
}
@@ -543,12 +586,15 @@
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;
+ spv::Builder::AccessChain::CoherentFlags flags = {};
+#ifndef GLSLANG_WEB
flags.coherent = type.getQualifier().coherent;
flags.devicecoherent = type.getQualifier().devicecoherent;
flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent;
@@ -556,22 +602,23 @@
flags.workgroupcoherent = type.getQualifier().workgroupcoherent ||
type.getQualifier().storage == glslang::EvqShared;
flags.subgroupcoherent = type.getQualifier().subgroupcoherent;
+ flags.shadercallcoherent = type.getQualifier().shadercallcoherent;
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.anyCoherent() ||
flags.volatil;
flags.isImage = type.getBasicType() == glslang::EbtSampler;
+#endif
return flags;
}
-spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
+spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(
+ const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{
- spv::Scope scope;
+ 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;
@@ -583,12 +630,14 @@
scope = spv::ScopeWorkgroup;
} else if (coherentFlags.subgroupcoherent) {
scope = spv::ScopeSubgroup;
- } else {
- scope = spv::ScopeMax;
+ } else if (coherentFlags.shadercallcoherent) {
+ scope = spv::ScopeShaderCallKHR;
}
if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
}
+#endif
+
return scope;
}
@@ -597,10 +646,12 @@
// is generated only when using the variable in an executable instruction, but not when
// just declaring a struct member variable with it. This is true for PointSize,
// ClipDistance, and CullDistance.
-spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool memberDeclaration)
+spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn,
+ bool memberDeclaration)
{
switch (builtIn) {
case glslang::EbvPointSize:
+#ifndef GLSLANG_WEB
// Defer adding the capability until the built-in is actually used.
if (! memberDeclaration) {
switch (glslangIntermediate->getStage()) {
@@ -615,8 +666,28 @@
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.
@@ -639,7 +710,7 @@
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;
@@ -656,39 +727,31 @@
return spv::BuiltInSampleMask;
case glslang::EbvLayer:
-#ifdef NV_EXTENSIONS
if (glslangIntermediate->getStage() == EShLangMeshNV) {
return spv::BuiltInLayer;
}
-#endif
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;
@@ -707,17 +770,7 @@
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);
@@ -732,27 +785,27 @@
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);
@@ -794,7 +847,7 @@
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;
@@ -822,15 +875,14 @@
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;
@@ -844,7 +896,6 @@
builder.addCapability(spv::CapabilityFragmentDensityEXT);
return spv::BuiltInFragInvocationCountEXT;
-#ifdef NV_EXTENSIONS
case glslang::EbvViewportMaskNV:
if (!memberDeclaration) {
builder.addExtension(spv::E_SPV_NV_viewport_array2);
@@ -888,35 +939,41 @@
builder.addCapability(spv::CapabilityShadingRateNV);
return spv::BuiltInInvocationsPerPixelNV;
- // raytracing
- 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;
+ // ray tracing
+ case glslang::EbvLaunchId:
+ return spv::BuiltInLaunchIdKHR;
+ case glslang::EbvLaunchSize:
+ return spv::BuiltInLaunchSizeKHR;
+ case glslang::EbvWorldRayOrigin:
+ return spv::BuiltInWorldRayOriginKHR;
+ case glslang::EbvWorldRayDirection:
+ return spv::BuiltInWorldRayDirectionKHR;
+ case glslang::EbvObjectRayOrigin:
+ return spv::BuiltInObjectRayOriginKHR;
+ case glslang::EbvObjectRayDirection:
+ return spv::BuiltInObjectRayDirectionKHR;
+ case glslang::EbvRayTmin:
+ return spv::BuiltInRayTminKHR;
+ case glslang::EbvRayTmax:
+ return spv::BuiltInRayTmaxKHR;
+ case glslang::EbvInstanceCustomIndex:
+ return spv::BuiltInInstanceCustomIndexKHR;
+ case glslang::EbvHitT:
+ return spv::BuiltInHitTKHR;
+ case glslang::EbvHitKind:
+ return spv::BuiltInHitKindKHR;
+ case glslang::EbvObjectToWorld:
+ case glslang::EbvObjectToWorld3x4:
+ return spv::BuiltInObjectToWorldKHR;
+ case glslang::EbvWorldToObject:
+ case glslang::EbvWorldToObject3x4:
+ return spv::BuiltInWorldToObjectKHR;
+ case glslang::EbvIncomingRayFlags:
+ return spv::BuiltInIncomingRayFlagsKHR;
+ case glslang::EbvGeometryIndex:
+ return spv::BuiltInRayGeometryIndexKHR;
+
+ // barycentrics
case glslang::EbvBaryCoordNV:
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
@@ -925,23 +982,44 @@
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
return spv::BuiltInBaryCoordNoPerspNV;
- case glslang::EbvTaskCountNV:
+
+ // mesh shaders
+ case glslang::EbvTaskCountNV:
return spv::BuiltInTaskCountNV;
- case glslang::EbvPrimitiveCountNV:
+ case glslang::EbvPrimitiveCountNV:
return spv::BuiltInPrimitiveCountNV;
- case glslang::EbvPrimitiveIndicesNV:
+ case glslang::EbvPrimitiveIndicesNV:
return spv::BuiltInPrimitiveIndicesNV;
- case glslang::EbvClipDistancePerViewNV:
+ case glslang::EbvClipDistancePerViewNV:
return spv::BuiltInClipDistancePerViewNV;
- case glslang::EbvCullDistancePerViewNV:
+ case glslang::EbvCullDistancePerViewNV:
return spv::BuiltInCullDistancePerViewNV;
- case glslang::EbvLayerPerViewNV:
+ case glslang::EbvLayerPerViewNV:
return spv::BuiltInLayerPerViewNV;
- case glslang::EbvMeshViewCountNV:
+ case glslang::EbvMeshViewCountNV:
return spv::BuiltInMeshViewCountNV;
- case glslang::EbvMeshViewIndicesNV:
+ case glslang::EbvMeshViewIndicesNV:
return spv::BuiltInMeshViewIndicesNV;
-#endif
+
+ // 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;
}
@@ -952,8 +1030,12 @@
{
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:
@@ -990,7 +1072,7 @@
}
// 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;
@@ -1035,7 +1117,8 @@
}
}
-spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const
+spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(
+ const glslang::TIntermSelection& selectionNode) const
{
if (selectionNode.getFlatten())
return spv::SelectionControlFlattenMask;
@@ -1044,7 +1127,8 @@
return spv::SelectionControlMaskNone;
}
-spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) const
+spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode)
+ const
{
if (switchNode.getFlatten())
return spv::SelectionControlFlattenMask;
@@ -1055,7 +1139,7 @@
// 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<unsigned int>& operands) const
{
spv::LoopControlMask control = spv::LoopControlMaskNone;
@@ -1067,7 +1151,29 @@
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;
@@ -1076,33 +1182,33 @@
// Translate glslang type to SPIR-V storage class.
spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type)
{
+ if (type.getBasicType() == glslang::EbtRayQuery)
+ return spv::StorageClassFunction;
if (type.getQualifier().isPipeInput())
return spv::StorageClassInput;
if (type.getQualifier().isPipeOutput())
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;
}
-#ifdef NV_EXTENSIONS
if (type.getQualifier().isUniformOrBuffer() &&
- type.getQualifier().layoutShaderRecordNV) {
- return spv::StorageClassShaderRecordBufferNV;
+ type.getQualifier().isShaderRecord()) {
+ return spv::StorageClassShaderRecordBufferKHR;
}
-#endif
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;
@@ -1110,16 +1216,16 @@
}
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;
-#ifdef NV_EXTENSIONS
- 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;
+ case glslang::EvqShared: return spv::StorageClassWorkgroup;
+#ifndef GLSLANG_WEB
+ case glslang::EvqPayload: return spv::StorageClassRayPayloadKHR;
+ case glslang::EvqPayloadIn: return spv::StorageClassIncomingRayPayloadKHR;
+ case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR;
+ case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR;
+ case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
#endif
default:
assert(0);
@@ -1133,15 +1239,16 @@
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);
@@ -1157,17 +1264,18 @@
// assume a dynamically uniform index
if (baseType.getBasicType() == glslang::EbtSampler) {
if (baseType.getQualifier().hasAttachment()) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityInputAttachmentArrayDynamicIndexingEXT);
- } else if (baseType.isImage() && baseType.getSampler().dim == glslang::EsdBuffer) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ } 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) {
- builder.addExtension("SPV_EXT_descriptor_indexing");
+ } 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
@@ -1177,10 +1285,8 @@
// uniform and buffer blocks are included, unless it is a push_constant
if (type.getBasicType() == glslang::EbtBlock)
return type.getQualifier().isUniformOrBuffer() &&
-#ifdef NV_EXTENSIONS
- ! type.getQualifier().layoutShaderRecordNV &&
-#endif
- ! type.getQualifier().layoutPushConstant;
+ ! type.getQualifier().isShaderRecord() &&
+ ! type.getQualifier().isPushConstant();
// non block...
// basically samplerXXX/subpass/sampler/texture are all included
@@ -1200,16 +1306,21 @@
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)
@@ -1224,6 +1335,8 @@
child.workgroupcoherent = true;
if (parent.subgroupcoherent)
child.subgroupcoherent = true;
+ if (parent.shadercallcoherent)
+ child.shadercallcoherent = true;
if (parent.nonprivate)
child.nonprivate = true;
if (parent.volatil)
@@ -1234,13 +1347,6 @@
child.readonly = true;
if (parent.writeonly)
child.writeonly = true;
-#ifdef NV_EXTENSIONS
- if (parent.perPrimitiveNV)
- child.perPrimitiveNV = true;
- if (parent.perViewNV)
- child.perViewNV = true;
- if (parent.perTaskNV)
- child.perTaskNV = true;
#endif
}
@@ -1261,15 +1367,18 @@
// Implement the TGlslangToSpvTraverser class.
//
-TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate* glslangIntermediate,
- spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
- : TIntermTraverser(true, false, true),
- options(options),
- shaderEntry(nullptr), currentFunction(nullptr),
- sequenceDepth(0), logger(buildLogger),
- builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
- inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
- glslangIntermediate(glslangIntermediate)
+TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
+ const glslang::TIntermediate* glslangIntermediate,
+ spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options) :
+ TIntermTraverser(true, false, true),
+ options(options),
+ shaderEntry(nullptr), currentFunction(nullptr),
+ sequenceDepth(0), logger(buildLogger),
+ builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
+ inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
+ glslangIntermediate(glslangIntermediate),
+ nanMinMaxClamp(glslangIntermediate->getNanMinMaxClamp()),
+ nonSemanticDebugPrintf(0)
{
spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage());
@@ -1310,13 +1419,13 @@
if (glslangIntermediate->usingPhysicalStorageBuffer()) {
addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
- builder.addExtension(spv::E_SPV_EXT_physical_storage_buffer);
+ 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.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
builder.setMemoryModel(addressingModel, memoryModel);
@@ -1330,7 +1439,7 @@
// Add the source extensions
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
for (auto it = sourceExtensions.begin(); it != sourceExtensions.end(); ++it)
- builder.addSourceExtension(it->c_str());
+ builder.addSourceExtension(it->first.c_str());
// Add the top-level modes for this shader.
@@ -1339,12 +1448,95 @@
builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
}
+ if (sourceExtensions.find("GL_EXT_ray_flags_primitive_culling") != sourceExtensions.end()) {
+ builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
+ }
+
unsigned int mode;
switch (glslangIntermediate->getStage()) {
case EShLangVertex:
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);
@@ -1352,7 +1544,8 @@
glslang::TLayoutGeometry primitive;
if (glslangIntermediate->getStage() == EShLangTessControl) {
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
+ glslangIntermediate->getVertices());
primitive = glslangIntermediate->getOutputPrimitive();
} else {
primitive = glslangIntermediate->getInputPrimitive();
@@ -1414,65 +1607,24 @@
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);
+ case EShLangRayGen:
+ case EShLangIntersect:
+ case EShLangAnyHit:
+ case EShLangClosestHit:
+ case EShLangMiss:
+ case EShLangCallable:
+ {
+ auto& extensions = glslangIntermediate->getRequestedExtensions();
+ if (extensions.find("GL_NV_ray_tracing") == extensions.end()) {
+ builder.addCapability(spv::CapabilityRayTracingProvisionalKHR);
+ builder.addExtension("SPV_KHR_ray_tracing");
}
-
- switch(glslangIntermediate->getDepth()) {
- case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
- case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
- default: mode = spv::ExecutionModeMax; break;
+ else {
+ builder.addCapability(spv::CapabilityRayTracingNV);
+ builder.addExtension("SPV_NV_ray_tracing");
}
- if (mode != spv::ExecutionModeMax)
- builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
-
- if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
break;
-
- case EShLangCompute:
- builder.addCapability(spv::CapabilityShader);
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
- glslangIntermediate->getLocalSize(1),
- glslangIntermediate->getLocalSize(2));
-#ifdef NV_EXTENSIONS
- 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);
- }
-#endif
- break;
-
-#ifdef NV_EXTENSIONS
- case EShLangRayGenNV:
- case EShLangIntersectNV:
- case EShLangAnyHitNV:
- case EShLangClosestHitNV:
- case EShLangMissNV:
- case EShLangCallableNV:
- builder.addCapability(spv::CapabilityRayTracingNV);
- builder.addExtension("SPV_NV_ray_tracing");
- break;
+ }
case EShLangTaskNV:
case EShLangMeshNV:
builder.addCapability(spv::CapabilityMeshShadingNV);
@@ -1481,8 +1633,10 @@
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getStage() == EShLangMeshNV) {
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
- builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, glslangIntermediate->getPrimitives());
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
+ glslangIntermediate->getVertices());
+ builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV,
+ glslangIntermediate->getPrimitives());
switch (glslangIntermediate->getOutputPrimitive()) {
case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break;
@@ -1514,8 +1668,10 @@
for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it)
entryPoint->addIdOperand(*it);
- // Add capabilities, extensions, remove unneeded decorations, etc.,
+ // 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();
}
@@ -1543,6 +1699,9 @@
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();
@@ -1550,13 +1709,28 @@
// 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
+ // (for ex SubgroupMasks or 3x4 ObjectToWorld/WorldToObject matrices),
+ // 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
@@ -1574,13 +1748,16 @@
// 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()) {
@@ -1612,11 +1789,18 @@
}
}
}
+#endif
}
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
{
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())
@@ -1683,6 +1867,7 @@
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);
@@ -1699,13 +1884,14 @@
int dummySize;
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
TranslateCoherent(node->getLeft()->getType()),
- glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
+ 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()->getBasicType() == glslang::EbtReference &&
+ if (node->getLeft()->isReference() &&
!node->getLeft()->getType().isArray() &&
node->getOp() == glslang::EOpIndexDirectStruct)
{
@@ -1720,13 +1906,18 @@
{
// This may be, e.g., an anonymous block-member selection, which generally need
// index remapping due to hidden members in anonymous blocks.
- std::vector<int>& 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<int>& remapper = memberRemapper[glslangId];
+ assert(remapper.size() > 0);
+ spvIndex = remapper[glslangIndex];
+ }
}
// normal case for indexing array or structure or block
- builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment());
+ 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.
@@ -1737,8 +1928,8 @@
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.
@@ -1763,9 +1954,11 @@
int dummySize;
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()),
TranslateCoherent(node->getLeft()->getType()),
- glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(),
+ dummySize));
} else
- builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), node->getLeft()->getType().getBufferReferenceAlignment());
+ builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()),
+ node->getLeft()->getType().getBufferReferenceAlignment());
}
return false;
case glslang::EOpVectorSwizzle:
@@ -1776,7 +1969,8 @@
int dummySize;
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()),
TranslateCoherent(node->getLeft()->getType()),
- glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize));
+ glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(),
+ dummySize));
}
return false;
case glslang::EOpMatrixSwizzle:
@@ -1792,7 +1986,8 @@
if (isTrivial(node->getRight()->getAsTyped()))
break; // handle below as a normal binary operation
// otherwise, we need to do dynamic short circuiting on the right operand
- spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(), *node->getRight()->getAsTyped());
+ spv::Id result = createShortCircuit(node->getOp(), *node->getLeft()->getAsTyped(),
+ *node->getRight()->getAsTyped());
builder.clearAccessChain();
builder.setAccessChainRValue(result);
}
@@ -1831,6 +2026,88 @@
}
}
+// Figure out what, if any, type changes are needed when accessing a specific built-in.
+// Returns <the type SPIR-V requires for declarion, the type to translate to on use>.
+// Also see comment for 'forceType', regarding tracking SPIR-V-required types.
+std::pair<spv::Id, spv::Id> TGlslangToSpvTraverser::getForcedType(glslang::TBuiltInVariable glslangBuiltIn,
+ const glslang::TType& glslangType)
+{
+ switch(glslangBuiltIn)
+ {
+ case glslang::EbvSubGroupEqMask:
+ case glslang::EbvSubGroupGeMask:
+ case glslang::EbvSubGroupGtMask:
+ case glslang::EbvSubGroupLeMask:
+ case glslang::EbvSubGroupLtMask: {
+ // these require changing a 64-bit scaler -> a vector of 32-bit components
+ if (glslangType.isVector())
+ break;
+ std::pair<spv::Id, spv::Id> ret(builder.makeVectorType(builder.makeUintType(32), 4),
+ builder.makeUintType(64));
+ return ret;
+ }
+ // There are no SPIR-V builtins defined for these and map onto original non-transposed
+ // builtins. During visitBinary we insert a transpose
+ case glslang::EbvWorldToObject3x4:
+ case glslang::EbvObjectToWorld3x4: {
+ std::pair<spv::Id, spv::Id> ret(builder.makeMatrixType(builder.makeFloatType(32), 4, 3),
+ builder.makeMatrixType(builder.makeFloatType(32), 3, 4)
+ );
+ return ret;
+ }
+ default:
+ break;
+ }
+
+ std::pair<spv::Id, spv::Id> 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<spv::Id> 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 if (builder.isMatrixType(objectTypeId)) {
+ // There are no SPIR-V builtins defined for 3x4 variants of ObjectToWorld/WorldToObject
+ // and we insert a transpose after loading the original non-transposed builtins
+ builder.clearAccessChain();
+ builder.setAccessChainLValue(object);
+ object = builder.accessChainLoad(spv::NoPrecision, spv::DecorationMax, objectTypeId);
+ return builder.createUnaryOp(spv::OpTranspose, desiredTypeId, object);
+
+ } 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, node->getLoc().getFilename());
@@ -1875,7 +2152,8 @@
} else {
glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
block->traverse(this);
- unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst();
+ unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()
+ ->getConstArray()[0].getUConst();
length = builder.createArrayLength(builder.accessChainGetLValue(), member);
}
@@ -1901,25 +2179,45 @@
// Does it need a swizzle inversion? If so, evaluation is inverted;
// operate first on the swizzle base, then apply the swizzle.
spv::Id invertedType = spv::NoType;
- auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); };
+ auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
+ invertedType : convertGlslangToSpvType(node->getType()); };
if (node->getOp() == glslang::EOpInterpolateAtCentroid)
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 ||
+ node->getOp() == glslang::EOpRayQueryProceed ||
+ node->getOp() == glslang::EOpRayQueryGetRayTMin ||
+ node->getOp() == glslang::EOpRayQueryGetRayFlags ||
+ node->getOp() == glslang::EOpRayQueryGetWorldRayOrigin ||
+ node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
+ node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
+ node->getOp() == glslang::EOpRayQueryTerminate ||
+ node->getOp() == glslang::EOpRayQueryConfirmIntersection) {
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()),
@@ -1927,16 +2225,18 @@
// it could be a conversion
if (! result)
- result = createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType());
+ result = createConversion(node->getOp(), decorations, resultType(), operand,
+ node->getOperand()->getBasicType());
// 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();
@@ -1956,6 +2256,7 @@
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)
@@ -1966,6 +2267,7 @@
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;
@@ -1993,12 +2295,20 @@
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;
+ case glslang::EOpRayQueryTerminate:
+ builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operand);
+ return false;
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operand);
+ return false;
+#endif
default:
logger->missingFunctionality("unknown glslang unary");
@@ -2006,6 +2316,40 @@
}
}
+// Construct a composite object, recursively copying members if their types don't match
+spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, std::vector<spv::Id> 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<spv::Id> 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<spv::Id> 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);
@@ -2013,8 +2357,14 @@
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
spv::Id result = spv::NoResult;
- spv::Id invertedType = spv::NoType; // to use to override the natural type of the node
- auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ? invertedType : convertGlslangToSpvType(node->getType()); };
+ spv::Id invertedType = spv::NoType; // to use to override the natural type of the node
+ std::vector<spv::Builder::AccessChain> complexLvalues; // for holding swizzling l-values too complex for
+ // SPIR-V, for an out parameter
+ std::vector<spv::Id> temporaryLvalues; // temporaries to pass, as proxies for complexLValues
+
+ auto resultType = [&invertedType, &node, this](){ return invertedType != spv::NoType ?
+ invertedType :
+ convertGlslangToSpvType(node->getType()); };
// try texturing
result = createImageTextureFunctionCall(node);
@@ -2023,14 +2373,15 @@
builder.setAccessChainRValue(result);
return false;
- } else if (node->getOp() == glslang::EOpImageStore ||
-#ifdef AMD_EXTENSIONS
+ }
+#ifndef GLSLANG_WEB
+ else if (node->getOp() == glslang::EOpImageStore ||
node->getOp() == glslang::EOpImageStoreLod ||
-#endif
node->getOp() == glslang::EOpImageAtomicStore) {
// "imageStore" is a special case, which has no result
return false;
}
+#endif
glslang::TOperator binOp = glslang::EOpNull;
bool reduceComparison = true;
@@ -2038,6 +2389,8 @@
bool noReturnValue = false;
bool atomic = false;
+ spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags;
+
assert(node->getOp());
spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
@@ -2115,7 +2468,6 @@
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
if (result) {
builder.clearAccessChain();
builder.setAccessChainRValue(result);
@@ -2235,7 +2587,7 @@
{
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
std::vector<spv::Id> arguments;
- translateArguments(*node, arguments);
+ translateArguments(*node, arguments, lvalueCoherentFlags);
spv::Id constructed;
if (node->getOp() == glslang::EOpConstructTextureSampler)
constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments);
@@ -2245,7 +2597,7 @@
std::vector<spv::Id> 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
@@ -2298,6 +2650,7 @@
// which can be emitted by the one in createBinaryOperation()
binOp = glslang::EOpMod;
break;
+
case glslang::EOpEmitVertex:
case glslang::EOpEndPrimitive:
case glslang::EOpBarrier:
@@ -2321,10 +2674,6 @@
// These all have 0 operands and will naturally finish up in the code below for 0 operands
break;
- case glslang::EOpAtomicStore:
- noReturnValue = true;
- // fallthrough
- case glslang::EOpAtomicLoad:
case glslang::EOpAtomicAdd:
case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax:
@@ -2336,6 +2685,14 @@
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:
@@ -2350,19 +2707,68 @@
atomic = true;
break;
-#ifdef NV_EXTENSIONS
- case glslang::EOpIgnoreIntersectionNV:
- case glslang::EOpTerminateRayNV:
- case glslang::EOpTraceNV:
- case glslang::EOpExecuteCallableNV:
+ 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::EOpIgnoreIntersection:
+ case glslang::EOpTerminateRay:
+ case glslang::EOpTrace:
+ case glslang::EOpExecuteCallable:
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
noReturnValue = true;
break;
-#endif
+ case glslang::EOpRayQueryInitialize:
+ case glslang::EOpRayQueryTerminate:
+ case glslang::EOpRayQueryGenerateIntersection:
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.addExtension("SPV_KHR_ray_query");
+ builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
+ noReturnValue = true;
+ break;
+ case glslang::EOpRayQueryProceed:
+ case glslang::EOpRayQueryGetIntersectionType:
+ case glslang::EOpRayQueryGetRayTMin:
+ case glslang::EOpRayQueryGetRayFlags:
+ case glslang::EOpRayQueryGetIntersectionT:
+ case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex:
+ case glslang::EOpRayQueryGetIntersectionInstanceId:
+ case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
+ case glslang::EOpRayQueryGetIntersectionGeometryIndex:
+ case glslang::EOpRayQueryGetIntersectionPrimitiveIndex:
+ case glslang::EOpRayQueryGetIntersectionBarycentrics:
+ case glslang::EOpRayQueryGetIntersectionFrontFace:
+ case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque:
+ case glslang::EOpRayQueryGetIntersectionObjectRayDirection:
+ case glslang::EOpRayQueryGetIntersectionObjectRayOrigin:
+ case glslang::EOpRayQueryGetWorldRayDirection:
+ case glslang::EOpRayQueryGetWorldRayOrigin:
+ case glslang::EOpRayQueryGetIntersectionObjectToWorld:
+ case glslang::EOpRayQueryGetIntersectionWorldToObject:
+ builder.addExtension("SPV_KHR_ray_query");
+ builder.addCapability(spv::CapabilityRayQueryProvisionalKHR);
+ 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
+
+ case glslang::EOpDebugPrintf:
+ noReturnValue = true;
+ break;
default:
break;
@@ -2410,26 +2816,33 @@
// 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::EOpInterpolateAtSample:
- case glslang::EOpInterpolateAtOffset:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpInterpolateAtVertex:
-#endif
- if (arg == 0) {
- lvalue = true;
- // Does it need a swizzle inversion? If so, evaluation is inverted;
- // operate first on the swizzle base, then apply the swizzle.
- if (glslangOperands[0]->getAsOperator() &&
- glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle)
- invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
- }
+ case glslang::EOpRayQueryInitialize:
+ case glslang::EOpRayQueryTerminate:
+ case glslang::EOpRayQueryConfirmIntersection:
+ case glslang::EOpRayQueryProceed:
+ case glslang::EOpRayQueryGenerateIntersection:
+ case glslang::EOpRayQueryGetIntersectionType:
+ case glslang::EOpRayQueryGetIntersectionT:
+ case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex:
+ case glslang::EOpRayQueryGetIntersectionInstanceId:
+ case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
+ case glslang::EOpRayQueryGetIntersectionGeometryIndex:
+ case glslang::EOpRayQueryGetIntersectionPrimitiveIndex:
+ case glslang::EOpRayQueryGetIntersectionBarycentrics:
+ case glslang::EOpRayQueryGetIntersectionFrontFace:
+ case glslang::EOpRayQueryGetIntersectionObjectRayDirection:
+ case glslang::EOpRayQueryGetIntersectionObjectRayOrigin:
+ case glslang::EOpRayQueryGetIntersectionObjectToWorld:
+ case glslang::EOpRayQueryGetIntersectionWorldToObject:
+ if (arg == 0)
+ lvalue = true;
break;
+
case glslang::EOpAtomicAdd:
case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax:
@@ -2438,6 +2851,33 @@
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:
+ case glslang::EOpInterpolateAtVertex:
+ if (arg == 0) {
+ lvalue = true;
+
+ // Does it need a swizzle inversion? If so, evaluation is inverted;
+ // operate first on the swizzle base, then apply the swizzle.
+ // That is, we transform
+ //
+ // interpolate(v.zy) -> interpolate(v).zy
+ //
+ if (glslangOperands[0]->getAsOperator() &&
+ glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle)
+ invertedType = convertGlslangToSpvType(
+ glslangOperands[0]->getAsBinaryNode()->getLeft()->getType());
+ }
+ break;
case glslang::EOpAtomicLoad:
case glslang::EOpAtomicStore:
case glslang::EOpAtomicCounterAdd:
@@ -2470,6 +2910,7 @@
if (arg == 1)
lvalue = true;
break;
+#endif
default:
break;
}
@@ -2479,6 +2920,7 @@
else
glslangOperands[arg]->traverse(this);
+#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
node->getOp() == glslang::EOpCooperativeMatrixStore) {
@@ -2493,8 +2935,9 @@
builder.setAccessChain(save);
// Point to the first element of the array.
- builder.accessChainPush(elementId, TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()),
- glslangOperands[arg]->getAsTyped()->getType().getBufferReferenceAlignment());
+ 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;
@@ -2504,7 +2947,8 @@
memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask;
if (node->getOp() == glslang::EOpCooperativeMatrixStore)
memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask;
- if (builder.getStorageClass(builder.getAccessChain().base) == spv::StorageClassPhysicalStorageBufferEXT) {
+ if (builder.getStorageClass(builder.getAccessChain().base) ==
+ spv::StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
@@ -2514,23 +2958,63 @@
memoryAccessOperands.push_back(spv::IdImmediate(false, alignment));
}
- if (memoryAccess & (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) {
- memoryAccessOperands.push_back(spv::IdImmediate(true, builder.makeUintConstant(TranslateMemoryScope(coherentFlags))));
+ 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 {
+ // for l-values, pass the address, for r-values, pass the value
+ if (lvalue) {
+ if (invertedType == spv::NoType && !builder.isSpvLvalue()) {
+ // SPIR-V cannot represent an l-value containing a swizzle that doesn't
+ // reduce to a simple access chain. So, we need a temporary vector to
+ // receive the result, and must later swizzle that into the original
+ // l-value.
+ complexLvalues.push_back(builder.getAccessChain());
+ temporaryLvalues.push_back(builder.createVariable(spv::StorageClassFunction,
+ builder.accessChainGetInferredType(), "swizzleTemp"));
+ operands.push_back(temporaryLvalues.back());
+ } else {
+ operands.push_back(builder.accessChainGetLValue());
+ }
+ 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()));
+ glslang::TOperator glslangOp = node->getOp();
+ if (arg == 1 &&
+ (glslangOp == glslang::EOpRayQueryGetIntersectionType ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionT ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionInstanceCustomIndex ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionInstanceId ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionGeometryIndex ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionPrimitiveIndex ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionBarycentrics ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionFrontFace ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayDirection ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayOrigin ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionObjectToWorld ||
+ glslangOp == glslang::EOpRayQueryGetIntersectionWorldToObject
+ )) {
+ bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
+ operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
+ }
+ else {
+ operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
+ }
+
}
}
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpCooperativeMatrixLoad) {
std::vector<spv::IdImmediate> idImmOps;
@@ -2557,9 +3041,18 @@
builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps);
result = 0;
- } else if (atomic) {
+ } 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 if (node->getOp() == glslang::EOpDebugPrintf) {
+ if (!nonSemanticDebugPrintf) {
+ nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
+ }
+ result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, spv::NonSemanticDebugPrintfDebugPrintf, operands);
+ builder.addExtension(spv::E_SPV_KHR_non_semantic_info);
} else {
// Pass through to generic operations.
switch (glslangOperands.size()) {
@@ -2574,15 +3067,21 @@
result = createUnaryOperation(
node->getOp(), decorations,
resultType(), operands.front(),
- glslangOperands[0]->getAsTyped()->getBasicType());
+ glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags);
}
break;
default:
result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
break;
}
- if (invertedType)
+
+ if (invertedType != spv::NoResult)
result = createInvertedSwizzle(precision, *glslangOperands[0]->getAsBinaryNode(), result);
+
+ for (unsigned int i = 0; i < temporaryLvalues.size(); ++i) {
+ builder.setAccessChain(complexLvalues[i]);
+ builder.accessChainStore(builder.createLoad(temporaryLvalues[i]));
+ }
}
if (noReturnValue)
@@ -2609,6 +3108,19 @@
// 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.
@@ -2627,9 +3139,7 @@
// 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() &&
@@ -2666,14 +3176,16 @@
// 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,
@@ -2776,7 +3288,8 @@
defaultSegment = (int)codeSegments.size();
else if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpCase) {
valueIndexToSegment[caseValues.size()] = (int)codeSegments.size();
- caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0].getIConst());
+ caseValues.push_back(child->getAsBranchNode()->getExpression()->getAsConstantUnion()
+ ->getConstArray()[0].getIConst());
} else
codeSegments.push_back(child);
}
@@ -2789,7 +3302,8 @@
// make the switch statement
std::vector<spv::Block*> segmentBlocks; // returned, as the blocks allocated in the call
- builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, segmentBlocks);
+ builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment,
+ segmentBlocks);
// emit all the code in the segments
breakForLoop.push(false);
@@ -2822,8 +3336,8 @@
builder.createBranch(&blocks.head);
// Loop control:
- unsigned int dependencyLength = glslang::TIntermLoop::dependencyInfinite;
- const spv::LoopControlMask control = TranslateLoopControl(*node, dependencyLength);
+ std::vector<unsigned int> 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
@@ -2833,7 +3347,7 @@
// including merges of its own.
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);
@@ -2923,6 +3437,14 @@
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;
@@ -2931,7 +3453,7 @@
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.
@@ -2944,51 +3466,57 @@
// 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:
case spv::StorageClassPhysicalStorageBufferEXT:
- addPre13Extension(spv::E_SPV_KHR_16bit_storage);
+ 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;
}
}
- const bool contains8BitType = node->getType().containsBasicType(glslang::EbtInt8) ||
- node->getType().containsBasicType(glslang::EbtUint8);
- if (contains8BitType) {
+ if (node->getType().contains8BitInt()) {
if (storageClass == spv::StorageClassPushConstant) {
- builder.addExtension(spv::E_SPV_KHR_8bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStoragePushConstant8);
} else if (storageClass == spv::StorageClassUniform) {
- builder.addExtension(spv::E_SPV_KHR_8bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityUniformAndStorageBuffer8BitAccess);
} else if (storageClass == spv::StorageClassStorageBuffer) {
- builder.addExtension(spv::E_SPV_KHR_8bit_storage);
+ builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
+ } else {
+ builder.addCapability(spv::CapabilityInt8);
}
}
@@ -3003,15 +3531,15 @@
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);
@@ -3032,7 +3560,8 @@
// When inverting a swizzle with a parent op, this function
// will apply the swizzle operation to a completed parent operation.
-spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node, spv::Id parentResult)
+spv::Id TGlslangToSpvTraverser::createInvertedSwizzle(spv::Decoration precision, const glslang::TIntermTyped& node,
+ spv::Id parentResult)
{
std::vector<unsigned> swizzle;
convertSwizzle(*node.getAsBinaryNode()->getRight()->getAsAggregate(), swizzle);
@@ -3069,15 +3598,6 @@
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:
- 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.
@@ -3086,6 +3606,22 @@
else
spvType = builder.makeBoolType();
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;
@@ -3098,12 +3634,6 @@
case glslang::EbtUint16:
spvType = builder.makeUintType(16);
break;
- case glslang::EbtInt:
- spvType = builder.makeIntType(32);
- break;
- case glslang::EbtUint:
- spvType = builder.makeUintType(32);
- break;
case glslang::EbtInt64:
spvType = builder.makeIntType(64);
break;
@@ -3114,22 +3644,41 @@
builder.addCapability(spv::CapabilityAtomicStorage);
spvType = builder.makeUintType(32);
break;
-#ifdef NV_EXTENSIONS
- case glslang::EbtAccStructNV:
- spvType = builder.makeAccelerationStructureNVType();
+ case glslang::EbtAccStruct:
+ spvType = builder.makeAccelerationStructureType();
+ break;
+ case glslang::EbtRayQuery:
+ spvType = builder.makeRayQueryType();
+ 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);
}
@@ -3151,27 +3700,13 @@
// 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;
- 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;
+ case glslang::EbtString:
+ // no type used for OpString
+ return 0;
default:
assert(0);
break;
@@ -3190,6 +3725,10 @@
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);
@@ -3236,10 +3775,12 @@
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)
@@ -3255,7 +3796,7 @@
//
bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member)
{
-#ifdef NV_EXTENSIONS
+#ifndef GLSLANG_WEB
auto& extensions = glslangIntermediate->getRequestedExtensions();
if (member.getFieldName() == "gl_SecondaryViewportMaskNV" &&
@@ -3291,19 +3832,23 @@
{
// Create a vector of struct types for SPIR-V to consume
std::vector<spv::Id> spvMembers;
- int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks
+ int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0,
+ // except sometimes for blocks
std::vector<std::pair<glslang::TType*, glslang::TQualifier> > 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();
@@ -3319,15 +3864,17 @@
// Make forward pointers for any pointer members, and create a list of members to
// convert to spirv types after creating the struct.
- if (glslangMember.getBasicType() == glslang::EbtReference) {
+ 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));
+ convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember,
+ true));
} else {
spvMembers.push_back(
- convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, false));
+ convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember,
+ false));
}
}
}
@@ -3361,7 +3908,7 @@
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;
}
@@ -3386,13 +3933,14 @@
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
-#ifdef NV_EXTENSIONS
+#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
@@ -3402,6 +3950,8 @@
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
@@ -3438,6 +3988,7 @@
if (builtIn != spv::BuiltInMax)
builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
+#ifndef GLSLANG_WEB
// nonuniform
builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier()));
@@ -3447,7 +3998,6 @@
memberQualifier.semanticName);
}
-#ifdef NV_EXTENSIONS
if (builtIn == spv::BuiltInLayer) {
// SPV_NV_viewport_array2 extension
if (glslangMember.getQualifier().layoutViewportRelative){
@@ -3512,11 +4062,11 @@
alignment |= type.getBufferReferenceAlignment();
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
- TranslateNonUniformDecoration(type.getQualifier()),
- nominalTypeId,
- spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
- TranslateMemoryScope(coherentFlags),
- alignment);
+ 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) {
@@ -3530,7 +4080,8 @@
int vecSize = builder.getNumTypeComponents(nominalTypeId);
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
if (nominalTypeId != bvecType)
- loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId, makeSmearedConstant(builder.makeUintConstant(0), vecSize));
+ loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
+ makeSmearedConstant(builder.makeUintConstant(0), vecSize));
}
}
@@ -3579,7 +4130,8 @@
alignment |= type.getBufferReferenceAlignment();
builder.accessChainStore(rvalue,
- spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
+ spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) &
+ ~spv::MemoryAccessMakePointerVisibleKHRMask),
TranslateMemoryScope(coherentFlags), alignment);
}
@@ -3615,6 +4167,20 @@
// 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);
@@ -3626,7 +4192,8 @@
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
- builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), type.getBufferReferenceAlignment());
+ builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type),
+ type.getBufferReferenceAlignment());
// store the member
multiTypeStore(glslangElementType, elementRValue);
@@ -3646,7 +4213,8 @@
// set up the target storage
builder.clearAccessChain();
builder.setAccessChainLValue(lValue);
- builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), type.getBufferReferenceAlignment());
+ builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type),
+ type.getBufferReferenceAlignment());
// store the member
multiTypeStore(glslangMemberType, memberRValue);
@@ -3681,18 +4249,21 @@
}
// Given an array type, returns the integer stride required for that array
-int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
+int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking explicitLayout,
+ glslang::TLayoutMatrix matrixLayout)
{
int size;
int stride;
- glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
+ glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout,
+ matrixLayout == glslang::ElmRowMajor);
return stride;
}
// Given a matrix type, or array (of array) of matrixes type, returns the integer stride required for that matrix
// when used as a member of an interface block
-int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
+int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking explicitLayout,
+ glslang::TLayoutMatrix matrixLayout)
{
glslang::TType elementType;
elementType.shallowCopy(matrixType);
@@ -3700,7 +4271,8 @@
int size;
int stride;
- glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
+ glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout,
+ matrixLayout == glslang::ElmRowMajor);
return stride;
}
@@ -3711,8 +4283,8 @@
// 'currentOffset' should be passed in already initialized, ready to modify, and reflecting
// the migration of data from nextOffset -> currentOffset. It should be -1 on the first call.
// -1 means a non-forced member offset (no decoration needed).
-void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset,
- glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
+void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType,
+ int& currentOffset, int& nextOffset, glslang::TLayoutPacking explicitLayout, glslang::TLayoutMatrix matrixLayout)
{
// this will get a positive value when deemed necessary
nextOffset = -1;
@@ -3742,7 +4314,8 @@
int memberSize;
int dummyStride;
- int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, 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:
@@ -3761,7 +4334,8 @@
glslang::RoundToPow2(currentOffset, memberAlignment);
// Bump up to vec4 if there is a bad straddle
- if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset))
+ if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize,
+ currentOffset))
glslang::RoundToPow2(currentOffset, 16);
nextOffset = currentOffset + memberSize;
@@ -3772,10 +4346,10 @@
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:
@@ -3833,20 +4407,23 @@
// Make all the functions, skeletally, without actually visiting their bodies.
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
{
- const auto getParamDecorations = [&](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
+ const auto getParamDecorations = [&](std::vector<spv::Decoration>& decorations, const glslang::TType& type,
+ bool useVulkanMemoryModel) {
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
if (paramPrecision != spv::NoPrecision)
decorations.push_back(paramPrecision);
TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
- if (type.getBasicType() == glslang::EbtReference) {
+ 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().restrict ? spv::DecorationRestrict : spv::DecorationAliased);
+ decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict :
+ spv::DecorationAliased);
} else {
- decorations.push_back(type.getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
+ decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT :
+ spv::DecorationAliasedPointerEXT);
}
}
};
@@ -3874,8 +4451,12 @@
std::vector<std::vector<spv::Decoration>> 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) {
@@ -3907,6 +4488,14 @@
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);
}
}
}
@@ -3917,7 +4506,8 @@
builder.setBuildPoint(shaderEntry->getLastBlock());
for (int i = 0; i < (int)initializers.size(); ++i) {
glslang::TIntermAggregate* initializer = initializers[i]->getAsAggregate();
- if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() != glslang::EOpLinkerObjects) {
+ if (initializer && initializer->getOp() != glslang::EOpFunction && initializer->getOp() !=
+ glslang::EOpLinkerObjects) {
// We're on a top-level node that's not a function. Treat as an initializer, whose
// code goes into the beginning of the entry point.
@@ -3945,20 +4535,22 @@
builder.setBuildPoint(functionBlock);
}
-void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments)
+void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& 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
- f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
+#ifndef GLSLANG_WEB
+ f16ShadowCompare = sampler.shadow &&
+ glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
#endif
}
@@ -3966,6 +4558,7 @@
builder.clearAccessChain();
glslangArguments[i]->traverse(this);
+#ifndef GLSLANG_WEB
// Special case l-value operands
bool lvalue = false;
switch (node.getOp()) {
@@ -3986,7 +4579,6 @@
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;
@@ -4000,21 +4592,6 @@
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;
@@ -4023,7 +4600,6 @@
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:
@@ -4039,23 +4615,6 @@
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;
@@ -4065,7 +4624,6 @@
if ((sampler.shadow && i == 4) || (! sampler.shadow && i == 3))
lvalue = true;
break;
-#ifdef AMD_EXTENSIONS
case glslang::EOpSparseTextureGatherLod:
if (i == 3)
lvalue = true;
@@ -4079,8 +4637,6 @@
if (i == 3)
lvalue = true;
break;
-#endif
-#ifdef NV_EXTENSIONS
case glslang::EOpImageSampleFootprintNV:
if (i == 4)
lvalue = true;
@@ -4098,14 +4654,16 @@
if (i == 7)
lvalue = true;
break;
-#endif
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()));
}
}
@@ -4126,18 +4684,33 @@
// Process a GLSL texturing op (will be SPV image)
- const glslang::TType &imageType = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
- : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
+ const glslang::TType &imageType = node->getAsAggregate()
+ ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
+ : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
const glslang::TSampler sampler = imageType.getSampler();
-#ifdef AMD_EXTENSIONS
+#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<spv::Id> arguments;
if (node->getAsAggregate())
- translateArguments(*node->getAsAggregate(), arguments);
+ translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags);
else
translateArguments(*node->getAsUnaryNode(), arguments);
spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision());
@@ -4164,6 +4737,7 @@
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);
@@ -4174,6 +4748,7 @@
return builder.createTextureQueryCall(spv::OpImageQueryLevels, params, isUnsignedResult);
case glslang::EOpSparseTexelsResident:
return builder.createUnaryOp(spv::OpImageSparseTexelsResident, builder.makeBoolType(), arguments[0]);
+#endif
default:
assert(0);
break;
@@ -4213,11 +4788,17 @@
spv::IdImmediate coord = { true,
builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) };
operands.push_back(coord);
- if (sampler.ms) {
- spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+ 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);
- spv::IdImmediate imageOperand = { true, *(opIt++) };
- operands.push_back(imageOperand);
+ 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);
@@ -4226,25 +4807,20 @@
spv::IdImmediate coord = { true, *(opIt++) };
operands.push_back(coord);
-#ifdef AMD_EXTENSIONS
if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) {
-#else
- if (node->getOp() == glslang::EOpImageLoad) {
-#endif
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
- if (sampler.ms) {
+ if (sampler.isMultiSample()) {
mask = mask | spv::ImageOperandsSampleMask;
}
-#ifdef AMD_EXTENSIONS
if (cracked.lod) {
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
mask = mask | spv::ImageOperandsLodMask;
}
-#endif
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
- if (mask) {
+ mask = mask | signExtensionMask();
+ if (mask != spv::ImageOperandsMaskNone) {
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
operands.push_back(imageOperands);
}
@@ -4252,14 +4828,13 @@
spv::IdImmediate imageOperand = { true, *opIt++ };
operands.push_back(imageOperand);
}
-#ifdef AMD_EXTENSIONS
if (mask & spv::ImageOperandsLodMask) {
spv::IdImmediate imageOperand = { true, *opIt++ };
operands.push_back(imageOperand);
}
-#endif
if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
- spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
+ spv::IdImmediate imageOperand = { true,
+ builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
operands.push_back(imageOperand);
}
@@ -4274,18 +4849,10 @@
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
// Push the texel value before the operands
-#ifdef AMD_EXTENSIONS
- if (sampler.ms || cracked.lod) {
-#else
- if (sampler.ms) {
-#endif
+ if (sampler.isMultiSample() || cracked.lod) {
spv::IdImmediate texel = { true, *(opIt + 1) };
operands.push_back(texel);
} else {
@@ -4294,19 +4861,18 @@
}
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
- if (sampler.ms) {
+ if (sampler.isMultiSample()) {
mask = mask | spv::ImageOperandsSampleMask;
}
-#ifdef AMD_EXTENSIONS
if (cracked.lod) {
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
mask = mask | spv::ImageOperandsLodMask;
}
-#endif
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask);
- if (mask) {
+ mask = mask | signExtensionMask();
+ if (mask != spv::ImageOperandsMaskNone) {
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
operands.push_back(imageOperands);
}
@@ -4314,14 +4880,13 @@
spv::IdImmediate imageOperand = { true, *opIt++ };
operands.push_back(imageOperand);
}
-#ifdef AMD_EXTENSIONS
if (mask & spv::ImageOperandsLodMask) {
spv::IdImmediate imageOperand = { true, *opIt++ };
operands.push_back(imageOperand);
}
-#endif
if (mask & spv::ImageOperandsMakeTexelAvailableKHRMask) {
- spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
+ spv::IdImmediate imageOperand = { true,
+ builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
operands.push_back(imageOperand);
}
@@ -4329,30 +4894,26 @@
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().word)) == spv::ImageFormatUnknown)
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
- if (sampler.ms) {
+ if (sampler.isMultiSample()) {
mask = mask | spv::ImageOperandsSampleMask;
}
-#ifdef AMD_EXTENSIONS
if (cracked.lod) {
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
mask = mask | spv::ImageOperandsLodMask;
}
-#endif
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
- if (mask) {
+ mask = mask | signExtensionMask();
+ if (mask != spv::ImageOperandsMaskNone) {
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
operands.push_back(imageOperands);
}
@@ -4360,14 +4921,13 @@
spv::IdImmediate imageOperand = { true, *opIt++ };
operands.push_back(imageOperand);
}
-#ifdef AMD_EXTENSIONS
if (mask & spv::ImageOperandsLodMask) {
spv::IdImmediate imageOperand = { true, *opIt++ };
operands.push_back(imageOperand);
}
-#endif
if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
- spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
+ spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(
+ TranslateCoherent(imageType))) };
operands.push_back(imageOperand);
}
@@ -4388,29 +4948,33 @@
// 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.
// For non-MS, the sample value should be 0
- spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
+ spv::IdImmediate sample = { true, sampler.isMultiSample() ? *(opIt++) : builder.makeUintConstant(0) };
operands.push_back(sample);
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));
+ resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(*opIt));
} else {
resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
}
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
+ if (imageType.getQualifier().nonUniform) {
+ builder.addDecoration(pointer, spv::DecorationNonUniformEXT);
+ }
std::vector<spv::Id> operands;
operands.push_back(pointer);
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);
@@ -4431,7 +4995,8 @@
std::vector<spv::Id> comps;
comps.push_back(zero);
comps.push_back(zero);
- operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps));
+ operands.push_back(builder.makeCompositeConstant(
+ builder.makeVectorType(builder.makeIntType(32), 2), comps));
}
for (; opIt != arguments.end(); ++opIt)
@@ -4451,45 +5016,32 @@
// Check for texture functions other than queries
bool sparse = node->isSparseTexture();
-#ifdef NV_EXTENSIONS
bool imageFootprint = node->isImageFootprint();
-#endif
-
- bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
+ 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;
-#ifdef NV_EXTENSIONS
if (imageFootprint)
//Following three extra arguments
// int granularity, bool coarse, out gl_TextureFootprint2DNV footprint
nonBiasArgCount += 3;
-#endif
if ((int)arguments.size() > nonBiasArgCount)
bias = true;
}
@@ -4501,7 +5053,7 @@
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 ||
@@ -4519,11 +5071,7 @@
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) {
@@ -4537,26 +5085,23 @@
else
dRefComp = builder.getNumComponents(params.coords) - 1;
indexes.push_back(dRefComp);
- params.Dref = builder.createCompositeExtract(params.coords, builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes);
+ params.Dref = builder.createCompositeExtract(params.coords,
+ builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes);
}
// lod
if (cracked.lod) {
params.lod = arguments[2 + extraArgs];
++extraArgs;
- } else if (glslangIntermediate->getStage() != EShLangFragment
-#ifdef NV_EXTENSIONS
- // NV_compute_shader_derivatives layout qualifiers allow for implicit LODs
- && !(glslangIntermediate->getStage() == EShLangCompute &&
- (glslangIntermediate->getLayoutDerivativeModeNone() != glslang::LayoutDerivativeNone))
-#endif
- ) {
+ } 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;
}
@@ -4577,6 +5122,7 @@
++extraArgs;
}
+#ifndef GLSLANG_WEB
// lod clamp
if (cracked.lodClamp) {
params.lodClamp = arguments[2 + extraArgs];
@@ -4587,7 +5133,6 @@
params.texelOut = arguments[2 + extraArgs];
++extraArgs;
}
-
// gather component
if (cracked.gather && ! sampler.shadow) {
// default component is 0, if missing, otherwise an argument
@@ -4597,7 +5142,6 @@
} else
params.component = builder.makeIntConstant(0);
}
-#ifdef NV_EXTENSIONS
spv::Id resultStruct = spv::NoResult;
if (imageFootprint) {
//Following three extra arguments
@@ -4614,7 +5158,7 @@
++extraArgs;
}
-#ifdef NV_EXTENSIONS
+#ifndef GLSLANG_WEB
if (imageFootprint) {
builder.addExtension(spv::E_SPV_NV_shader_image_footprint);
builder.addCapability(spv::CapabilityImageFootprintNV);
@@ -4654,7 +5198,8 @@
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);
+ 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++) {
@@ -4666,7 +5211,8 @@
flags.clear();
builder.accessChainPush(builder.makeIntConstant(i), flags, 0);
- builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1), i+1));
+ builder.accessChainStore(builder.createCompositeExtract(res, builder.getContainedTypeId(resType, i+1),
+ i+1));
}
return builder.createCompositeExtract(res, resultType(), 0);
}
@@ -4689,13 +5235,13 @@
// copy the projective coordinate if we have to
if (projTargetComp != projSourceComp) {
spv::Id projComp = builder.createCompositeExtract(params.coords,
- builder.getScalarTypeId(builder.getTypeId(params.coords)),
- projSourceComp);
+ builder.getScalarTypeId(builder.getTypeId(params.coords)), projSourceComp);
params.coords = builder.createCompositeInsert(projComp, params.coords,
- builder.getTypeId(params.coords), projTargetComp);
+ builder.getTypeId(params.coords), projTargetComp);
}
}
+#ifndef GLSLANG_WEB
// nonprivate
if (imageType.getQualifier().nonprivate) {
params.nonprivate = true;
@@ -4705,9 +5251,11 @@
if (imageType.getQualifier().volatil) {
params.volatil = true;
}
+#endif
std::vector<spv::Id> 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())
@@ -4769,7 +5317,8 @@
++lValueCount;
} else if (writableParam(qualifiers[a])) {
// need space to hold the copy
- arg = builder.createVariable(spv::StorageClassFunction, builder.getContainedTypeId(function->getParamType(a)), "param");
+ arg = builder.createVariable(spv::StorageClassFunction,
+ builder.getContainedTypeId(function->getParamType(a)), "param");
if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) {
// need to copy the input into output space
builder.setAccessChain(lValues[lValueCount]);
@@ -4938,6 +5487,30 @@
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:
@@ -4964,8 +5537,8 @@
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);
}
@@ -4977,7 +5550,7 @@
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;
}
@@ -5038,8 +5611,8 @@
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);
}
@@ -5103,8 +5676,8 @@
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);
}
@@ -5143,14 +5716,14 @@
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:
@@ -5160,7 +5733,7 @@
}
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;
@@ -5328,6 +5901,7 @@
case glslang::EOpUnpackHalf2x16:
libCall = spv::GLSLstd450UnpackHalf2x16;
break;
+#ifndef GLSLANG_WEB
case glslang::EOpPackSnorm4x8:
libCall = spv::GLSLstd450PackSnorm4x8;
break;
@@ -5346,6 +5920,7 @@
case glslang::EOpUnpackDouble2x32:
libCall = spv::GLSLstd450UnpackDouble2x32;
break;
+#endif
case glslang::EOpPackInt2x32:
case glslang::EOpUnpackInt2x32:
@@ -5379,31 +5954,7 @@
case glslang::EOpFwidth:
unaryOp = spv::OpFwidth;
break;
- 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:
-#ifdef AMD_EXTENSIONS
- if (typeProxy == glslang::EbtFloat16)
- builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
-#endif
- libCall = spv::GLSLstd450InterpolateAtCentroid;
- break;
+
case glslang::EOpAny:
unaryOp = spv::OpAny;
break;
@@ -5424,6 +5975,48 @@
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::EOpRayQueryProceed:
+ unaryOp = spv::OpRayQueryProceedKHR;
+ break;
+ case glslang::EOpRayQueryGetRayTMin:
+ unaryOp = spv::OpRayQueryGetRayTMinKHR;
+ break;
+ case glslang::EOpRayQueryGetRayFlags:
+ unaryOp = spv::OpRayQueryGetRayFlagsKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayOrigin:
+ unaryOp = spv::OpRayQueryGetWorldRayOriginKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayDirection:
+ unaryOp = spv::OpRayQueryGetWorldRayDirectionKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque:
+ unaryOp = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR;
+ 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:
@@ -5431,7 +6024,7 @@
// Handle all of the atomics in one place, in createAtomicOperation()
std::vector<spv::Id> 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:
@@ -5450,12 +6043,23 @@
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:
@@ -5474,7 +6078,6 @@
case glslang::EOpMinInvocationsExclusiveScanNonUniform:
case glslang::EOpMaxInvocationsExclusiveScanNonUniform:
case glslang::EOpAddInvocationsExclusiveScanNonUniform:
-#endif
{
std::vector<spv::Id> operands;
operands.push_back(operand);
@@ -5519,7 +6122,6 @@
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;
@@ -5534,15 +6136,18 @@
extBuiltins = getExtBuiltins(spv::E_SPV_AMD_gcn_shader);
libCall = spv::CubeFaceCoordAMD;
break;
-#endif
-#ifdef NV_EXTENSIONS
case glslang::EOpSubgroupPartition:
unaryOp = spv::OpGroupNonUniformPartitionNV;
break;
-#endif
case glslang::EOpConstructReference:
unaryOp = spv::OpBitcast;
break;
+#endif
+
+ case glslang::EOpCopyObject:
+ unaryOp = spv::OpCopyObject;
+ break;
+
default:
return 0;
}
@@ -5556,8 +6161,8 @@
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);
}
@@ -5585,14 +6190,14 @@
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;
}
@@ -5684,110 +6289,49 @@
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;
@@ -5822,17 +6366,6 @@
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:
@@ -5858,13 +6391,16 @@
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);
@@ -5891,6 +6427,71 @@
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:
@@ -6001,6 +6602,15 @@
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;
}
@@ -6017,7 +6627,7 @@
result = builder.createUnaryOp(convOp, destType, operand);
result = builder.setPrecision(result, decorations.precision);
- builder.addDecoration(result, decorations.nonUniform);
+ decorations.addNonUniform(builder, result);
return result;
}
@@ -6034,7 +6644,9 @@
}
// For glslang ops that map to SPV atomic opCodes
-spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/,
+ spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy,
+ const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags)
{
spv::Op opCode = spv::OpNop;
@@ -6050,12 +6662,14 @@
case glslang::EOpAtomicMin:
case glslang::EOpImageAtomicMin:
case glslang::EOpAtomicCounterMin:
- opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMin : spv::OpAtomicSMin;
+ opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
+ spv::OpAtomicUMin : spv::OpAtomicSMin;
break;
case glslang::EOpAtomicMax:
case glslang::EOpImageAtomicMax:
case glslang::EOpAtomicCounterMax:
- opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ? spv::OpAtomicUMax : spv::OpAtomicSMax;
+ opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
+ spv::OpAtomicUMax : spv::OpAtomicSMax;
break;
case glslang::EOpAtomicAnd:
case glslang::EOpImageAtomicAnd:
@@ -6120,7 +6734,10 @@
scopeId = builder.makeUintConstant(spv::ScopeDevice);
}
// semantics default to relaxed
- spv::Id semanticsId = builder.makeUintConstant(spv::MemorySemanticsMaskNone);
+ spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() &&
+ glslangIntermediate->usingVulkanMemoryModel() ?
+ spv::MemorySemanticsVolatileMask :
+ spv::MemorySemanticsMaskNone);
spv::Id semanticsId2 = semanticsId;
pointerId = operands[0];
@@ -6131,26 +6748,33 @@
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]));
+ 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]));
+ 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]));
+ semanticsId = builder.makeUintConstant
+ (builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4]));
}
}
// Check for capabilities
unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2);
- if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
+ if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask |
+ spv::MemorySemanticsMakeVisibleKHRMask |
+ spv::MemorySemanticsOutputMemoryKHRMask |
+ spv::MemorySemanticsVolatileMask)) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
@@ -6186,12 +6810,11 @@
}
// Create group invocation operations.
-spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
-#ifdef AMD_EXTENSIONS
bool isUnsigned = isTypeUnsignedInt(typeProxy);
bool isFloat = isTypeFloat(typeProxy);
-#endif
spv::Op opCode = spv::OpNop;
std::vector<spv::IdImmediate> spvGroupOperands;
@@ -6208,7 +6831,6 @@
builder.addCapability(spv::CapabilitySubgroupVoteKHR);
} else {
builder.addCapability(spv::CapabilityGroups);
-#ifdef AMD_EXTENSIONS
if (op == glslang::EOpMinInvocationsNonUniform ||
op == glslang::EOpMaxInvocationsNonUniform ||
op == glslang::EOpAddInvocationsNonUniform ||
@@ -6219,9 +6841,7 @@
op == glslang::EOpMaxInvocationsExclusiveScanNonUniform ||
op == glslang::EOpAddInvocationsExclusiveScanNonUniform)
builder.addExtension(spv::E_SPV_AMD_shader_ballot);
-#endif
-#ifdef AMD_EXTENSIONS
switch (op) {
case glslang::EOpMinInvocations:
case glslang::EOpMaxInvocations:
@@ -6256,7 +6876,6 @@
spv::IdImmediate groupOp = { false, (unsigned)groupOperation };
spvGroupOperands.push_back(groupOp);
}
-#endif
}
for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) {
@@ -6303,7 +6922,6 @@
builder.createCompositeConstruct(uvec2Type, components));
}
-#ifdef AMD_EXTENSIONS
case glslang::EOpMinInvocations:
case glslang::EOpMaxInvocations:
case glslang::EOpAddInvocations:
@@ -6390,7 +7008,6 @@
return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
break;
-#endif
default:
logger->missingFunctionality("invocation operation");
return spv::NoResult;
@@ -6404,20 +7021,15 @@
spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation,
spv::Id typeId, std::vector<spv::Id>& 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 ||
op == spv::OpSubgroupReadInvocationKHR ||
- op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD || op == spv::OpGroupSMinNonUniformAMD ||
- op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD ||
+ 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.
@@ -6541,7 +7153,6 @@
builder.addCapability(spv::CapabilityGroupNonUniform);
builder.addCapability(spv::CapabilityGroupNonUniformQuad);
break;
-#ifdef NV_EXTENSIONS
case glslang::EOpSubgroupPartitionedAdd:
case glslang::EOpSubgroupPartitionedMul:
case glslang::EOpSubgroupPartitionedMin:
@@ -6566,12 +7177,12 @@
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;
@@ -6600,11 +7211,9 @@
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 {
@@ -6615,11 +7224,9 @@
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 {
@@ -6630,11 +7237,9 @@
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) {
@@ -6647,11 +7252,9 @@
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) {
@@ -6664,11 +7267,9 @@
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 {
@@ -6679,11 +7280,9 @@
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 {
@@ -6694,11 +7293,9 @@
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 {
@@ -6756,7 +7353,6 @@
case glslang::EOpSubgroupClusteredXor:
groupOperation = spv::GroupOperationClusteredReduce;
break;
-#ifdef NV_EXTENSIONS
case glslang::EOpSubgroupPartitionedAdd:
case glslang::EOpSubgroupPartitionedMul:
case glslang::EOpSubgroupPartitionedMin:
@@ -6784,7 +7380,6 @@
case glslang::EOpSubgroupPartitionedExclusiveXor:
groupOperation = spv::GroupOperationPartitionedExclusiveScanNV;
break;
-#endif
}
// build the instruction
@@ -6822,7 +7417,8 @@
return builder.createOp(opCode, typeId, spvGroupOperands);
}
-spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision,
+ spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
bool isUnsigned = isTypeUnsignedInt(typeProxy);
bool isFloat = isTypeFloat(typeProxy);
@@ -6842,7 +7438,7 @@
switch (op) {
case glslang::EOpMin:
if (isFloat)
- libCall = spv::GLSLstd450FMin;
+ libCall = nanMinMaxClamp ? spv::GLSLstd450NMin : spv::GLSLstd450FMin;
else if (isUnsigned)
libCall = spv::GLSLstd450UMin;
else
@@ -6854,7 +7450,7 @@
break;
case glslang::EOpMax:
if (isFloat)
- libCall = spv::GLSLstd450FMax;
+ libCall = nanMinMaxClamp ? spv::GLSLstd450NMax : spv::GLSLstd450FMax;
else if (isUnsigned)
libCall = spv::GLSLstd450UMax;
else
@@ -6873,7 +7469,7 @@
case glslang::EOpClamp:
if (isFloat)
- libCall = spv::GLSLstd450FClamp;
+ libCall = nanMinMaxClamp ? spv::GLSLstd450NClamp : spv::GLSLstd450FClamp;
else if (isUnsigned)
libCall = spv::GLSLstd450UClamp;
else
@@ -6916,18 +7512,59 @@
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
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
libCall = spv::GLSLstd450InterpolateAtOffset;
break;
case glslang::EOpAddCarry:
@@ -6969,15 +7606,14 @@
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
- frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), builder.getNumComponents(operands[0]));
+ frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true),
+ builder.getNumComponents(operands[0]));
typeId = builder.makeStructResultType(typeId0, frexpIntType);
consumedOperands = 1;
}
@@ -7003,7 +7639,6 @@
case glslang::EOpSubgroupClusteredOr:
case glslang::EOpSubgroupClusteredXor:
case glslang::EOpSubgroupQuadBroadcast:
-#ifdef NV_EXTENSIONS
case glslang::EOpSubgroupPartitionedAdd:
case glslang::EOpSubgroupPartitionedMul:
case glslang::EOpSubgroupPartitionedMin:
@@ -7025,10 +7660,8 @@
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;
@@ -7082,70 +7715,113 @@
extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_explicit_vertex_parameter);
libCall = spv::InterpolateAtVertexAMD;
break;
-#endif
- 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)) {
- 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)) {
- builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
- }
- if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) {
- builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
- }
- return 0;
- }
- break;
-#ifdef NV_EXTENSIONS
- case glslang::EOpReportIntersectionNV:
- {
+ case glslang::EOpReportIntersection:
typeId = builder.makeBoolType();
- opCode = spv::OpReportIntersectionNV;
- }
- break;
- case glslang::EOpTraceNV:
- {
- builder.createNoResultOp(spv::OpTraceNV, operands);
+ opCode = spv::OpReportIntersectionKHR;
+ break;
+ case glslang::EOpTrace:
+ builder.createNoResultOp(spv::OpTraceRayKHR, operands);
return 0;
- }
- break;
- case glslang::EOpExecuteCallableNV:
- {
- builder.createNoResultOp(spv::OpExecuteCallableNV, operands);
+ case glslang::EOpExecuteCallable:
+ builder.createNoResultOp(spv::OpExecuteCallableKHR, operands);
return 0;
- }
- break;
+
+ case glslang::EOpRayQueryInitialize:
+ builder.createNoResultOp(spv::OpRayQueryInitializeKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryTerminate:
+ builder.createNoResultOp(spv::OpRayQueryTerminateKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryGenerateIntersection:
+ builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operands);
+ return 0;
+ case glslang::EOpRayQueryProceed:
+ typeId = builder.makeBoolType();
+ opCode = spv::OpRayQueryProceedKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionType:
+ typeId = builder.makeUintType(32);
+ opCode = spv::OpRayQueryGetIntersectionTypeKHR;
+ break;
+ case glslang::EOpRayQueryGetRayTMin:
+ typeId = builder.makeFloatType(32);
+ opCode = spv::OpRayQueryGetRayTMinKHR;
+ break;
+ case glslang::EOpRayQueryGetRayFlags:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetRayFlagsKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionT:
+ typeId = builder.makeFloatType(32);
+ opCode = spv::OpRayQueryGetIntersectionTKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionInstanceCustomIndex:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionInstanceCustomIndexKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionInstanceId:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionGeometryIndex:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionGeometryIndexKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionPrimitiveIndex:
+ typeId = builder.makeIntType(32);
+ opCode = spv::OpRayQueryGetIntersectionPrimitiveIndexKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionBarycentrics:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 2);
+ opCode = spv::OpRayQueryGetIntersectionBarycentricsKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionFrontFace:
+ typeId = builder.makeBoolType();
+ opCode = spv::OpRayQueryGetIntersectionFrontFaceKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque:
+ typeId = builder.makeBoolType();
+ opCode = spv::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionObjectRayDirection:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetIntersectionObjectRayDirectionKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionObjectRayOrigin:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetIntersectionObjectRayOriginKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayDirection:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetWorldRayDirectionKHR;
+ break;
+ case glslang::EOpRayQueryGetWorldRayOrigin:
+ typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
+ opCode = spv::OpRayQueryGetWorldRayOriginKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionObjectToWorld:
+ typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3);
+ opCode = spv::OpRayQueryGetIntersectionObjectToWorldKHR;
+ break;
+ case glslang::EOpRayQueryGetIntersectionWorldToObject:
+ typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3);
+ opCode = spv::OpRayQueryGetIntersectionWorldToObjectKHR;
+ break;
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands);
return 0;
-#endif
case glslang::EOpCooperativeMatrixMulAdd:
opCode = spv::OpCooperativeMatrixMulAddNV;
break;
-
+#endif // GLSLANG_WEB
default:
return 0;
}
@@ -7166,7 +7842,7 @@
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(operands[0], typeId, i));
+ id = builder.createBinOp(spv::OpIAdd, typeId, id, builder.createCompositeExtract(mulOp, typeId, i));
}
} else {
switch (consumedOperands) {
@@ -7189,6 +7865,7 @@
}
}
+#ifndef GLSLANG_WEB
// Decode the return types that were structures
switch (op) {
case glslang::EOpAddCarry:
@@ -7218,6 +7895,7 @@
default:
break;
}
+#endif
return builder.setPrecision(id, precision);
}
@@ -7226,15 +7904,10 @@
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
{
// GLSL memory barriers use queuefamily scope in new model, device scope in old model
- spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
+ 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) {
if (glslangIntermediate->usingVulkanMemoryModel()) {
@@ -7255,18 +7928,10 @@
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAllMemory |
spv::MemorySemanticsAcquireReleaseMask);
return 0;
- case glslang::EOpMemoryBarrierAtomicCounter:
- builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask |
- spv::MemorySemanticsAcquireReleaseMask);
- return 0;
case glslang::EOpMemoryBarrierBuffer:
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsUniformMemoryMask |
spv::MemorySemanticsAcquireReleaseMask);
return 0;
- case glslang::EOpMemoryBarrierImage:
- builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask |
- spv::MemorySemanticsAcquireReleaseMask);
- return 0;
case glslang::EOpMemoryBarrierShared:
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsWorkgroupMemoryMask |
spv::MemorySemanticsAcquireReleaseMask);
@@ -7275,6 +7940,15 @@
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 |
@@ -7319,30 +7993,80 @@
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<spv::Id> operands;
return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid);
}
-#ifdef AMD_EXTENSIONS
case glslang::EOpTime:
{
std::vector<spv::Id> args; // Dummy arguments
spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args);
return builder.setPrecision(id, precision);
}
-#endif
-#ifdef NV_EXTENSIONS
- case glslang::EOpIgnoreIntersectionNV:
- builder.createNoResultOp(spv::OpIgnoreIntersectionNV);
+ case glslang::EOpIgnoreIntersection:
+ builder.createNoResultOp(spv::OpIgnoreIntersectionKHR);
return 0;
- case glslang::EOpTerminateRayNV:
- builder.createNoResultOp(spv::OpTerminateRayNV);
+ case glslang::EOpTerminateRay:
+ builder.createNoResultOp(spv::OpTerminateRayKHR);
return 0;
+ case glslang::EOpRayQueryInitialize:
+ builder.createNoResultOp(spv::OpRayQueryInitializeKHR);
+ return 0;
+ case glslang::EOpRayQueryTerminate:
+ builder.createNoResultOp(spv::OpRayQueryTerminateKHR);
+ return 0;
+ case glslang::EOpRayQueryGenerateIntersection:
+ builder.createNoResultOp(spv::OpRayQueryGenerateIntersectionKHR);
+ return 0;
+ case glslang::EOpRayQueryConfirmIntersection:
+ builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR);
+ 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<spv::Id> 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<spv::Id> 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<spv::Id> 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)
@@ -7355,22 +8079,26 @@
}
// it was not found, create it
- id = createSpvVariable(symbol);
+ spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
+ auto forcedType = getForcedType(symbol->getQualifier().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()));
-#ifdef NV_EXTENSIONS
+#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);
- if (symbol->getQualifier().hasIndex())
- builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
- if (symbol->getQualifier().hasComponent())
- builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
// atomic counters use this:
if (symbol->getQualifier().hasOffset())
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
@@ -7409,22 +8137,23 @@
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<spv::Decoration> memory;
- TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel());
+ 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
@@ -7434,6 +8163,7 @@
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);
}
}
@@ -7462,7 +8192,6 @@
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
}
-#endif
if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
@@ -7470,14 +8199,16 @@
symbol->getType().getQualifier().semanticName);
}
- if (symbol->getBasicType() == glslang::EbtReference) {
- builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
+ if (symbol->isReference()) {
+ builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
+ spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
}
+#endif
return id;
}
-#ifdef NV_EXTENSIONS
+#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)
{
@@ -7532,8 +8263,9 @@
// hand off to the non-spec-constant path
assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr);
int nextConst = 0;
- return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(),
- nextConst, false);
+ return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ?
+ node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(),
+ nextConst, false);
}
// We now know we have a specialization constant to build
@@ -7586,7 +8318,8 @@
// If there are not enough elements present in 'consts', 0 will be substituted;
// an empty 'consts' can be used to create a fully zeroed SPIR-V constant.
//
-spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant)
+spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glslang::TType& glslangType,
+ const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant)
{
// vector of constants for SPIR-V
std::vector<spv::Id> spvConsts;
@@ -7613,6 +8346,19 @@
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;
@@ -7625,30 +8371,19 @@
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;
@@ -7660,6 +8395,19 @@
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;
@@ -7672,34 +8420,26 @@
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);
- break;
case glslang::EbtReference:
scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant);
scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar);
break;
+#endif
+ case glslang::EbtString:
+ scalar = builder.getStringId(consts[nextConst].getSConst()->c_str());
+ break;
default:
assert(0);
break;
@@ -7800,7 +8540,8 @@
// Emit short-circuiting code, where 'right' is never evaluated unless
// the left side is true (for &&) or false (for ||).
-spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left, glslang::TIntermTyped& right)
+spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslang::TIntermTyped& left,
+ glslang::TIntermTyped& right)
{
spv::Id boolTypeId = builder.makeBoolType();
@@ -7843,7 +8584,7 @@
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)
@@ -7883,7 +8624,8 @@
// 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 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent
+ // 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
@@ -7903,6 +8645,7 @@
// Write SPIR-V out to a text file with 32-bit hexadecimal words
void OutputSpvHex(const std::vector<unsigned int>& 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())
@@ -7930,6 +8673,7 @@
out << "};";
}
out.close();
+#endif
}
//
@@ -7963,11 +8707,14 @@
#if ENABLE_OPT
// If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan
// eg. forward and remove memory writes of opaque types.
- if ((intermediate.getSource() == EShSourceHlsl || options->optimizeSize) && !options->disableOptimizer)
+ 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);
+ SpirvToolsValidate(intermediate, spirv, logger, prelegalization);
if (options->disassemble)
SpirvToolsDisassemble(std::cout, spirv);
diff --git a/SPIRV/GlslangToSpv.h b/SPIRV/GlslangToSpv.h
index 86e1c23..3907be4 100755
--- a/SPIRV/GlslangToSpv.h
+++ b/SPIRV/GlslangToSpv.h
@@ -40,7 +40,7 @@
#endif
#include "SpvTools.h"
-#include "../glslang/Include/intermediate.h"
+#include "glslang/Include/intermediate.h"
#include <string>
#include <vector>
diff --git a/SPIRV/InReadableOrder.cpp b/SPIRV/InReadableOrder.cpp
index 52b2961..9d9410b 100644
--- a/SPIRV/InReadableOrder.cpp
+++ b/SPIRV/InReadableOrder.cpp
@@ -61,17 +61,22 @@
// Use by calling visit() on the root block.
class ReadableOrderTraverser {
public:
- explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}
+ ReadableOrderTraverser(std::function<void(Block*, spv::ReachReason, Block*)> 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 @@
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<void(Block*)> callback_;
+ std::function<void(Block*, spv::ReachReason, Block*)> callback_;
// Whether a block has already been visited or is being delayed.
std::unordered_set<Block *> visited_, delayed_;
+
+ // The set of blocks that actually are reached via control flow.
+ std::unordered_set<Block *> reachableViaControlFlow_;
};
}
-void spv::inReadableOrder(Block* root, std::function<void(Block*)> callback)
+void spv::inReadableOrder(Block* root, std::function<void(Block*, spv::ReachReason, Block*)> callback)
{
- ReadableOrderTraverser(callback).visit(root);
+ ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr);
}
diff --git a/SPIRV/Logger.cpp b/SPIRV/Logger.cpp
index 48bd4e3..cdc8469 100644
--- a/SPIRV/Logger.cpp
+++ b/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 <algorithm>
@@ -66,3 +68,5 @@
}
} // end spv namespace
+
+#endif
diff --git a/SPIRV/Logger.h b/SPIRV/Logger.h
index 2e4ddaf..411367c 100644
--- a/SPIRV/Logger.h
+++ b/SPIRV/Logger.h
@@ -46,6 +46,14 @@
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 @@
// 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/SPIRV/NonSemanticDebugPrintf.h b/SPIRV/NonSemanticDebugPrintf.h
new file mode 100644
index 0000000..83796d7
--- /dev/null
+++ b/SPIRV/NonSemanticDebugPrintf.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2020 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"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+// https://www.khronos.org/registry/
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+//
+
+#ifndef SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
+#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ NonSemanticDebugPrintfRevision = 1,
+ NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff
+};
+
+enum NonSemanticDebugPrintfInstructions {
+ NonSemanticDebugPrintfDebugPrintf = 1,
+ NonSemanticDebugPrintfInstructionsMax = 0x7fffffff
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
diff --git a/SPIRV/SPVRemapper.h b/SPIRV/SPVRemapper.h
index 97e3f31..d6b9c34 100644
--- a/SPIRV/SPVRemapper.h
+++ b/SPIRV/SPVRemapper.h
@@ -45,7 +45,7 @@
// 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 @@
// 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/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index 138c41c..6cf70a1 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -1,6 +1,7 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -46,7 +47,9 @@
#include "SpvBuilder.h"
+#ifndef GLSLANG_WEB
#include "hex_float.h"
+#endif
#ifndef _WIN32
#include <cstdio>
@@ -230,6 +233,11 @@
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) {
@@ -265,6 +273,11 @@
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) {
@@ -484,7 +497,8 @@
return type->getResultId();
}
-Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format)
+Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled,
+ ImageFormat format)
{
assert(sampled == 1 || sampled == 2);
@@ -516,6 +530,7 @@
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
+#ifndef GLSLANG_WEB
// deal with capabilities
switch (dim) {
case DimBuffer:
@@ -561,6 +576,7 @@
addCapability(CapabilityImageMSArray);
}
}
+#endif
return type->getResultId();
}
@@ -586,22 +602,38 @@
return type->getResultId();
}
-#ifdef NV_EXTENSIONS
-Id Builder::makeAccelerationStructureNVType()
+#ifndef GLSLANG_WEB
+Id Builder::makeAccelerationStructureType()
{
Instruction *type;
- if (groupedTypes[OpTypeAccelerationStructureNV].size() == 0) {
- type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNV);
- groupedTypes[OpTypeAccelerationStructureNV].push_back(type);
+ if (groupedTypes[OpTypeAccelerationStructureKHR].size() == 0) {
+ type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureKHR);
+ groupedTypes[OpTypeAccelerationStructureKHR].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
} else {
- type = groupedTypes[OpTypeAccelerationStructureNV].back();
+ type = groupedTypes[OpTypeAccelerationStructureKHR].back();
+ }
+
+ return type->getResultId();
+}
+
+Id Builder::makeRayQueryType()
+{
+ Instruction *type;
+ if (groupedTypes[OpTypeRayQueryProvisionalKHR].size() == 0) {
+ type = new Instruction(getUniqueId(), NoType, OpTypeRayQueryProvisionalKHR);
+ groupedTypes[OpTypeRayQueryProvisionalKHR].push_back(type);
+ constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
+ module.mapInstruction(type);
+ } else {
+ type = groupedTypes[OpTypeRayQueryProvisionalKHR].back();
}
return type->getResultId();
}
#endif
+
Id Builder::getDerefTypeId(Id resultId) const
{
Id typeId = getTypeId(resultId);
@@ -939,6 +971,10 @@
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;
@@ -963,10 +999,15 @@
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);
@@ -991,25 +1032,33 @@
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, Id typeId, const std::vector<Id>& comps)
@@ -1238,7 +1287,8 @@
// Comments in header
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
- const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& decorations, Block **entry)
+ const std::vector<Id>& paramTypes,
+ const std::vector<std::vector<Decoration>>& decorations, Block **entry)
{
// Make the function and initial instructions in it
Id typeId = makeFunctionType(returnType, paramTypes);
@@ -1306,11 +1356,13 @@
}
// 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:
@@ -1339,7 +1391,8 @@
}
// av/vis/nonprivate are unnecessary and illegal for some storage classes.
-spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const
+spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
+ const
{
switch (sc) {
case spv::StorageClassUniform:
@@ -1358,7 +1411,8 @@
}
// Comments in header
-void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope,
+ unsigned int alignment)
{
Instruction* store = new Instruction(OpStore);
store->addIdOperand(lValue);
@@ -1461,7 +1515,8 @@
// Generate code for spec constants if in spec constant operation
// generation mode.
if (generatingOpCodeForSpecConst) {
- return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite), std::vector<Id>(1, index));
+ return createSpecConstantOp(OpCompositeExtract, typeId, std::vector<Id>(1, composite),
+ std::vector<Id>(1, index));
}
Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract);
extract->addIdOperand(composite);
@@ -1663,7 +1718,8 @@
return op->getResultId();
}
-Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands, const std::vector<unsigned>& literals)
+Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& operands,
+ const std::vector<unsigned>& literals)
{
Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp);
op->addImmediateOperand((unsigned) opCode);
@@ -1806,7 +1862,7 @@
// 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)
+ bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask)
{
static const int maxTextureArgs = 10;
Id texArgs[maxTextureArgs] = {};
@@ -1823,7 +1879,7 @@
if (parameters.component != NoResult)
texArgs[numArgs++] = parameters.component;
-#ifdef NV_EXTENSIONS
+#ifndef GLSLANG_WEB
if (parameters.granularity != NoResult)
texArgs[numArgs++] = parameters.granularity;
if (parameters.coarse != NoResult)
@@ -1833,8 +1889,8 @@
//
// 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);
@@ -1870,6 +1926,7 @@
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
texArgs[numArgs++] = parameters.offsets;
}
+#ifndef GLSLANG_WEB
if (parameters.sample) {
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
texArgs[numArgs++] = parameters.sample;
@@ -1887,6 +1944,8 @@
if (parameters.volatil) {
mask = mask | ImageOperandsVolatileTexelKHRMask;
}
+#endif
+ mask = mask | signExtensionMask;
if (mask == ImageOperandsMaskNone)
--numArgs; // undo speculative reservation for the mask argument
else
@@ -1901,10 +1960,9 @@
opCode = OpImageSparseFetch;
else
opCode = OpImageFetch;
-#ifdef NV_EXTENSIONS
+#ifndef GLSLANG_WEB
} else if (parameters.granularity && parameters.coarse) {
opCode = OpImageSampleFootprintNV;
-#endif
} else if (gather) {
if (parameters.Dref)
if (sparse)
@@ -1916,6 +1974,7 @@
opCode = OpImageSparseGather;
else
opCode = OpImageGather;
+#endif
} else if (explicitLod) {
if (parameters.Dref) {
if (proj)
@@ -2064,11 +2123,7 @@
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:
@@ -2086,6 +2141,7 @@
if (parameters.lod)
query->addIdOperand(parameters.lod);
buildPoint->addInstruction(std::unique_ptr<Instruction>(query));
+ addCapability(CapabilityImageQuery);
return query->getResultId();
}
@@ -2153,7 +2209,8 @@
if (constituent == 0)
resultId = subResultId;
else
- resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision);
+ resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId),
+ precision);
}
return resultId;
@@ -2162,7 +2219,8 @@
// OpCompositeConstruct
Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constituents)
{
- assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 && getNumTypeConstituents(typeId) == (int)constituents.size()));
+ assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 &&
+ getNumTypeConstituents(typeId) == (int)constituents.size()));
if (generatingOpCodeForSpecConst) {
// Sometime, even in spec-constant-op mode, the constant composite to be
@@ -2279,7 +2337,12 @@
int numRows = getTypeNumRows(resultTypeId);
Instruction* instr = module.getInstruction(componentTypeId);
- unsigned bitCount = instr->getImmediateOperand(0);
+#ifdef GLSLANG_WEB
+ const unsigned bitCount = 32;
+ assert(bitCount == instr->getImmediateOperand(0));
+#else
+ const unsigned bitCount = instr->getImmediateOperand(0);
+#endif
// Optimize matrix constructed from a bigger matrix
if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
@@ -2570,7 +2633,8 @@
}
// Comments in header
-void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
+void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
+ AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
{
accessChain.coherentFlags |= coherentFlags;
accessChain.alignment |= alignment;
@@ -2624,7 +2688,8 @@
}
// Comments in header
-Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
+Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType,
+ spv::MemoryAccessMask memoryAccess, spv::Scope scope, unsigned int alignment)
{
Id id;
@@ -2649,12 +2714,19 @@
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);
-
+ 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;
@@ -2675,7 +2747,13 @@
}
// load through the access chain
- id = createLoad(collapseAccessChain(), memoryAccess, scope, alignment);
+ id = collapseAccessChain();
+ // Apply nonuniform both to the access chain and the loaded value.
+ // Buffer accesses need the access chain decorated, and this is where
+ // loaded image types get decorated. TODO: This should maybe move to
+ // createImageTextureFunctionCall.
+ addDecoration(id, nonUniform);
+ id = createLoad(id, memoryAccess, scope, alignment);
setPrecision(id, precision);
addDecoration(id, nonUniform);
}
@@ -2956,14 +3034,14 @@
}
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
- unsigned int dependencyLength)
+ const std::vector<unsigned int>& 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<Instruction>(merge));
}
@@ -3029,7 +3107,8 @@
dumpSourceInstructions(iItr->first, *iItr->second, out);
}
-void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector<std::unique_ptr<Instruction> >& instructions) const
+void Builder::dumpInstructions(std::vector<unsigned int>& out,
+ const std::vector<std::unique_ptr<Instruction> >& instructions) const
{
for (int i = 0; i < (int)instructions.size(); ++i) {
instructions[i]->dump(out);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 52f7fba..71b90d6 100644
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -1,7 +1,8 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
-// Copyright (C) 2015-2018 Google, Inc.
+// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -61,6 +62,15 @@
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);
@@ -85,6 +95,7 @@
const char* file_c_str = str.c_str();
fileString->addStringOperand(file_c_str);
strings.push_back(std::unique_ptr<Instruction>(fileString));
+ module.mapInstruction(fileString);
stringIds[file_c_str] = strId;
return strId;
}
@@ -97,6 +108,20 @@
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<unsigned>(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);
@@ -158,7 +183,9 @@
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
// accelerationStructureNV type
- Id makeAccelerationStructureNVType();
+ Id makeAccelerationStructureType();
+ // rayQueryEXT type
+ Id makeRayQueryType();
// For querying about types.
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
@@ -173,7 +200,8 @@
Id getContainedTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId, int) const;
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
- ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
+ ImageFormat getImageTypeFormat(Id typeId) const
+ { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
@@ -183,18 +211,28 @@
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
- bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
- bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
- bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
+ bool isBoolType(Id typeId)
+ { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
+ bool isIntType(Id typeId) const
+ { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
+ bool isUintType(Id typeId) const
+ { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
- bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
+ bool isScalarType(Id typeId) const
+ { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt ||
+ getTypeClass(typeId) == OpTypeBool; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
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; }
+#ifdef GLSLANG_WEB
+ bool isCooperativeMatrixType(Id typeId)const { return false; }
+#else
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
- bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
+#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; }
@@ -206,7 +244,8 @@
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
- unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
+ unsigned int getConstantScalar(Id resultId) const
+ { return module.getInstruction(resultId)->getImmediateOperand(0); }
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
int getScalarTypeWidth(Id typeId) const
@@ -248,14 +287,22 @@
// For making new constants (will return old constant if the requested one was already made).
Id makeBoolConstant(bool b, bool specConstant = false);
- Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
- Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); }
- Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
- Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); }
- Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
- Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
- Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
- Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
+ Id makeInt8Constant(int i, bool specConstant = false)
+ { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
+ Id makeUint8Constant(unsigned u, bool specConstant = false)
+ { return makeIntConstant(makeUintType(8), u, specConstant); }
+ Id makeInt16Constant(int i, bool specConstant = false)
+ { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
+ Id makeUint16Constant(unsigned u, bool specConstant = false)
+ { return makeIntConstant(makeUintType(16), u, specConstant); }
+ Id makeIntConstant(int i, bool specConstant = false)
+ { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
+ Id makeUintConstant(unsigned u, bool specConstant = false)
+ { return makeIntConstant(makeUintType(32), u, specConstant); }
+ Id makeInt64Constant(long long i, bool specConstant = false)
+ { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
+ Id makeUint64Constant(unsigned long long u, bool specConstant = false)
+ { return makeInt64Constant(makeUintType(64), u, specConstant); }
Id makeFloatConstant(float f, bool specConstant = false);
Id makeDoubleConstant(double d, bool specConstant = false);
Id makeFloat16Constant(float f16, bool specConstant = false);
@@ -286,8 +333,8 @@
// Make a shader-style function, and create its entry block if entry is non-zero.
// Return the function, pass back the entry.
// The returned pointer is only valid for the lifetime of this builder.
- Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
- const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
+ Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
+ const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
// Create a return. An 'implicit' return is one not appearing in the source
// code. In the case of an implicit return, no post-return block is inserted.
@@ -300,16 +347,18 @@
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, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ 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, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ 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<Id>& offsets);
@@ -408,7 +457,8 @@
};
// 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.
@@ -467,7 +517,7 @@
// recursion stack can hold the memory for it.
//
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
- const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
+ const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
// Add a branch to the innermost switch's merge block.
void addSwitchBreak();
@@ -484,7 +534,7 @@
Block &head, &body, &merge, &continue_target;
private:
LoopBlocks();
- LoopBlocks& operator=(const LoopBlocks&);
+ LoopBlocks& operator=(const LoopBlocks&) = delete;
};
// Start a new loop and prepare the builder to generate code for it. Until
@@ -541,18 +591,34 @@
std::vector<Id> indexChain;
Id instr; // cache the instruction that generates this access chain
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
- 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
+ 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.
+ 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; }
+ bool anyCoherent() const {
+ return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent ||
+ subgroupcoherent || shadercallcoherent;
+ }
+
unsigned coherent : 1;
unsigned devicecoherent : 1;
unsigned queuefamilycoherent : 1;
unsigned workgroupcoherent : 1;
unsigned subgroupcoherent : 1;
+ unsigned shadercallcoherent : 1;
unsigned nonprivate : 1;
unsigned volatil : 1;
unsigned isImage : 1;
@@ -563,23 +629,25 @@
queuefamilycoherent = 0;
workgroupcoherent = 0;
subgroupcoherent = 0;
+ shadercallcoherent = 0;
nonprivate = 0;
volatil = 0;
isImage = 0;
}
- CoherentFlags() { clear(); }
CoherentFlags operator |=(const CoherentFlags &other) {
coherent |= other.coherent;
devicecoherent |= other.devicecoherent;
queuefamilycoherent |= other.queuefamilycoherent;
workgroupcoherent |= other.workgroupcoherent;
subgroupcoherent |= other.subgroupcoherent;
+ shadercallcoherent |= other.shadercallcoherent;
nonprivate |= other.nonprivate;
volatil |= other.volatil;
isImage |= other.isImage;
return *this;
}
+#endif
};
CoherentFlags coherentFlags;
};
@@ -619,11 +687,13 @@
}
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
- void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
+ void accessChainPushSwizzle(std::vector<unsigned>& 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, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
+ void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags,
+ unsigned int alignment)
{
if (accessChain.swizzle.size() != 1) {
accessChain.component = component;
@@ -635,10 +705,18 @@
}
// use accessChain and swizzle to store value
- void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ 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, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
+ Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType,
+ spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
+ unsigned int alignment = 0);
+
+ // Return whether or not the access chain can be represented in SPIR-V
+ // as an l-value.
+ // E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be.
+ bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; }
// get the direct pointer for an l-value
Id accessChainGetLValue();
@@ -647,22 +725,28 @@
// based on the type of the base and the chain of dereferences.
Id accessChainGetInferredType();
- // Add capabilities, extensions, remove unneeded decorations, etc.,
+ // 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 instruction in a reachable block in a function.
- void postProcessReachable(const 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<unsigned int>&) 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<unsigned int>& operands);
// Sets to generate opcode for specialization constants.
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
@@ -688,7 +772,8 @@
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
void dumpModuleProcesses(std::vector<unsigned int>&) const;
- spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) 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;
@@ -723,10 +808,14 @@
std::vector<std::unique_ptr<Instruction> > externals;
std::vector<std::unique_ptr<Function> > functions;
- // not output, internally used for quick & dirty canonical (unique) creation
- std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants; // map type opcodes to constant inst.
- std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
- std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; // map type opcodes to type instructions
+ // not output, internally used for quick & dirty canonical (unique) creation
+
+ // map type opcodes to constant inst.
+ std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
+ // map struct-id to constant instructions
+ std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
+ // map type opcodes to type instructions
+ std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
// stack of switches
std::stack<Block*> switchMerges;
diff --git a/SPIRV/SpvPostProcess.cpp b/SPIRV/SpvPostProcess.cpp
index 80471ca..d40174d 100644
--- a/SPIRV/SpvPostProcess.cpp
+++ b/SPIRV/SpvPostProcess.cpp
@@ -39,6 +39,7 @@
#include <cassert>
#include <cstdlib>
+#include <unordered_map>
#include <unordered_set>
#include <algorithm>
@@ -51,16 +52,13 @@
#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
}
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.
@@ -118,12 +116,48 @@
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:
-#if AMD_EXTENSIONS
switch (inst.getImmediateOperand(1)) {
case GLSLstd450Frexp:
case GLSLstd450FrexpStruct:
@@ -139,7 +173,6 @@
default:
break;
}
-#endif
break;
default:
if (basicTypeOp == OpTypeFloat && width == 16)
@@ -185,12 +218,10 @@
addCapability(CapabilityImageQuery);
break;
-#ifdef NV_EXTENSIONS
case OpGroupNonUniformPartitionNV:
addExtension(E_SPV_NV_shader_subgroup_partitioned);
addCapability(CapabilityGroupNonUniformPartitionedNV);
break;
-#endif
case OpLoad:
case OpStore:
@@ -289,17 +320,16 @@
}
}
}
-
-// Called for each instruction in a reachable block.
-void Builder::postProcessReachable(const Instruction&)
-{
- // did have code here, but questionable to do so without deleting the instructions
-}
+#endif
// comment in header
-void Builder::postProcess()
+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<const Block*> reachableBlocks;
+ std::unordered_map<Block*, Block*> headerForUnreachableContinue;
+ std::unordered_set<Block*> unreachableMerges;
std::unordered_set<Id> unreachableDefinitions;
// Collect IDs defined in unreachable blocks. For each function, label the
// reachable blocks first. Then for each unreachable block, collect the
@@ -307,16 +337,41 @@
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
Function* f = *fi;
Block* entry = f->getEntryBlock();
- inReadableOrder(entry, [&reachableBlocks](const Block* b) { reachableBlocks.insert(b); });
+ 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 (reachableBlocks.count(b) == 0) {
- for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
+ 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<Instruction>& I) -> bool {
@@ -324,14 +379,29 @@
return unreachableDefinitions.count(decoration_id) != 0;
}),
decorations.end());
+}
+#ifndef GLSLANG_WEB
+// comment in header
+void Builder::postProcessFeatures() {
// Add per-instruction capabilities, extensions, etc.,
- // process all reachable instructions...
- for (auto bi = reachableBlocks.cbegin(); bi != reachableBlocks.cend(); ++bi) {
- const Block* block = *bi;
- const auto function = [this](const std::unique_ptr<Instruction>& inst) { postProcessReachable(*inst.get()); };
- std::for_each(block->getInstructions().begin(), block->getInstructions().end(), function);
+ // 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
@@ -366,24 +436,15 @@
}
}
}
+}
+#endif
- // 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)) {
- addExtension(spv::E_SPV_KHR_8bit_storage);
- addCapability(spv::CapabilityStorageBuffer8BitAccess);
- }
- if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
- containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
- addExtension(spv::E_SPV_KHR_16bit_storage);
- addCapability(spv::CapabilityStorageBuffer16BitAccess);
- }
- }
- }
+// comment in header
+void Builder::postProcess() {
+ postProcessCFG();
+#ifndef GLSLANG_WEB
+ postProcessFeatures();
+#endif
}
}; // end spv namespace
diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp
index cce5fa7..1e968ba 100644
--- a/SPIRV/SpvTools.cpp
+++ b/SPIRV/SpvTools.cpp
@@ -1,6 +1,6 @@
//
// Copyright (C) 2014-2016 LunarG, Inc.
-// Copyright (C) 2018 Google, Inc.
+// Copyright (C) 2018-2020 Google, Inc.
//
// All rights reserved.
//
@@ -52,8 +52,23 @@
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: return spv_target_env::SPV_ENV_VULKAN_1_1;
+ 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;
}
@@ -90,7 +105,7 @@
// Apply the SPIRV-Tools validator to generated SPIR-V.
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
- spv::SpvBuildLogger* logger)
+ spv::SpvBuildLogger* logger, bool prelegalization)
{
// validate
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
@@ -98,6 +113,7 @@
spv_diagnostic diagnostic = nullptr;
spv_validator_options options = spvValidatorOptionsCreate();
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
+ spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
spvValidateWithOptions(context, options, &binary, &diagnostic);
// report
@@ -114,8 +130,8 @@
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
// legalizing HLSL SPIR-V.
-void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>& spirv,
- spv::SpvBuildLogger*, const SpvOptions* options)
+void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
+ spv::SpvBuildLogger* logger, const SpvOptions* options)
{
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
@@ -159,6 +175,7 @@
if (options->generateDebugInfo) {
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
}
+ optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
@@ -182,8 +199,6 @@
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
if (options->optimizeSize) {
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
- // TODO(greg-lunarg): Add this when AMD driver issues are resolved
- // optimizer.RegisterPass(CreateCommonUniformElimPass());
}
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
@@ -192,7 +207,8 @@
}
spvtools::OptimizerOptions spvOptOptions;
- spvOptOptions.set_run_validator(false); // The validator may run as a seperate step later on
+ optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
+ spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
}
diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h
index 7e49ae0..59c914d 100644
--- a/SPIRV/SpvTools.h
+++ b/SPIRV/SpvTools.h
@@ -41,10 +41,12 @@
#ifndef GLSLANG_SPV_TOOLS_H
#define GLSLANG_SPV_TOOLS_H
+#ifdef ENABLE_OPT
#include <vector>
#include <ostream>
+#endif
-#include "../glslang/MachineIndependent/localintermediate.h"
+#include "glslang/MachineIndependent/localintermediate.h"
#include "Logger.h"
namespace glslang {
@@ -59,14 +61,14 @@
bool validate;
};
-#if ENABLE_OPT
+#ifdef ENABLE_OPT
// Use the SPIRV-Tools disassembler to print SPIR-V.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
// Apply the SPIRV-Tools validator to generated SPIR-V.
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
- spv::SpvBuildLogger*);
+ spv::SpvBuildLogger*, bool prelegalization);
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
// legalizing HLSL SPIR-V.
diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp
index 631173c..4faa89e 100644
--- a/SPIRV/disassemble.cpp
+++ b/SPIRV/disassemble.cpp
@@ -52,26 +52,16 @@
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)
{
@@ -82,16 +72,10 @@
// used to identify the extended instruction library imported when printing
enum ExtInstSet {
GLSL450Inst,
-
-#ifdef AMD_EXTENSIONS
GLSLextAMDInst,
-#endif
-
-#ifdef NV_EXTENSIONS
GLSLextNVInst,
-#endif
-
OpenCLExtInst,
+ NonSemanticDebugPrintfExtInst,
};
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
@@ -497,39 +481,37 @@
if (opCode == OpExtInst) {
ExtInstSet extInstSet = GLSL450Inst;
const char* name = idDescriptor[stream[word - 2]].c_str();
- if (0 == memcmp("OpenCL", name, 6)) {
+ if (strcmp("OpenCL.std", name) == 0) {
extInstSet = OpenCLExtInst;
-#ifdef AMD_EXTENSIONS
+ } else if (strcmp("OpenCL.DebugInfo.100", name) == 0) {
+ extInstSet = OpenCLExtInst;
+ } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
+ extInstSet = NonSemanticDebugPrintfExtInst;
} 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_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
+ } else if (extInstSet == NonSemanticDebugPrintfExtInst) {
+ out << "(DebugPrintf)";
}
}
break;
@@ -648,9 +630,11 @@
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) {
@@ -692,18 +676,17 @@
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(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
- strcmp(name, spv::E_SPV_NV_mesh_shader) == 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) {
// NV builtins
case BuiltInViewportMaskNV: return "ViewportMaskNV";
@@ -729,6 +712,8 @@
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";
@@ -745,7 +730,6 @@
}
return "Bad";
}
-#endif
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
{
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index 76e1df8..b1f2b82 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -1,5 +1,6 @@
//
// Copyright (C) 2014-2015 LunarG, Inc.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
@@ -50,12 +51,8 @@
// 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,22 +95,17 @@
case 4: return "Fragment";
case 5: return "GLCompute";
case 6: return "Kernel";
-#ifdef NV_EXTENSIONS
case ExecutionModelTaskNV: return "TaskNV";
case ExecutionModelMeshNV: return "MeshNV";
-#endif
default: return "Bad";
-#ifdef NV_EXTENSIONS
- case ExecutionModelRayGenerationNV: return "RayGenerationNV";
- case ExecutionModelIntersectionNV: return "IntersectionNV";
- case ExecutionModelAnyHitNV: return "AnyHitNV";
- case ExecutionModelClosestHitNV: return "ClosestHitNV";
- case ExecutionModelMissNV: return "MissNV";
- case ExecutionModelCallableNV: return "CallableNV";
-#endif
-
+ case ExecutionModelRayGenerationKHR: return "RayGenerationKHR";
+ case ExecutionModelIntersectionKHR: return "IntersectionKHR";
+ case ExecutionModelAnyHitKHR: return "AnyHitKHR";
+ case ExecutionModelClosestHitKHR: return "ClosestHitKHR";
+ case ExecutionModelMissKHR: return "MissKHR";
+ case ExecutionModelCallableKHR: return "CallableKHR";
}
}
@@ -183,13 +175,18 @@
case 4446: return "PostDepthCoverage";
-#ifdef NV_EXTENSIONS
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV";
case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV";
case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV";
-#endif
+
+ 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";
@@ -213,14 +210,12 @@
case 11: return "Image";
case 12: return "StorageBuffer";
-#ifdef NV_EXTENSIONS
- case StorageClassRayPayloadNV: return "RayPayloadNV";
- case StorageClassHitAttributeNV: return "HitAttributeNV";
- case StorageClassIncomingRayPayloadNV: return "IncomingRayPayloadNV";
- case StorageClassShaderRecordBufferNV: return "ShaderRecordBufferNV";
- case StorageClassCallableDataNV: return "CallableDataNV";
- case StorageClassIncomingCallableDataNV: return "IncomingCallableDataNV";
-#endif
+ case StorageClassRayPayloadKHR: return "RayPayloadKHR";
+ case StorageClassHitAttributeKHR: return "HitAttributeKHR";
+ case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR";
+ case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR";
+ case StorageClassCallableDataKHR: return "CallableDataKHR";
+ case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR";
case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT";
@@ -282,10 +277,7 @@
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";
@@ -294,7 +286,6 @@
case DecorationPerViewNV: return "PerViewNV";
case DecorationPerTaskNV: return "PerTaskNV";
case DecorationPerVertexNV: return "PerVertexNV";
-#endif
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
@@ -364,7 +355,6 @@
case 4426: return "DrawIndex";
case 5014: return "FragStencilRefEXT";
-#ifdef AMD_EXTENSIONS
case 4992: return "BaryCoordNoPerspAMD";
case 4993: return "BaryCoordNoPerspCentroidAMD";
case 4994: return "BaryCoordNoPerspSampleAMD";
@@ -372,41 +362,36 @@
case 4996: return "BaryCoordSmoothCentroidAMD";
case 4997: return "BaryCoordSmoothSampleAMD";
case 4998: return "BaryCoordPullModelAMD";
-#endif
-
-#ifdef NV_EXTENSIONS
- 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 BuiltInLaunchIdKHR: return "LaunchIdKHR";
+ case BuiltInLaunchSizeKHR: return "LaunchSizeKHR";
+ case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR";
+ case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR";
+ case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR";
+ case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR";
+ case BuiltInRayTminKHR: return "RayTminKHR";
+ case BuiltInRayTmaxKHR: return "RayTmaxKHR";
+ case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
+ case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
+ case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
+ case BuiltInWorldToObjectKHR: return "WorldToObjectKHR";
+ case BuiltInHitTKHR: return "HitTKHR";
+ case BuiltInHitKindKHR: return "HitKindKHR";
+ case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR";
+ 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";
-#endif
+ case BuiltInBaryCoordNV: return "BaryCoordNV";
+ case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
- case BuiltInFragSizeEXT: return "FragSizeEXT";
- case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
+ case BuiltInFragSizeEXT: return "FragSizeEXT";
+ case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT";
case 5264: return "FullyCoveredEXT";
-
-#ifdef NV_EXTENSIONS
case BuiltInTaskCountNV: return "TaskCountNV";
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
@@ -415,7 +400,10 @@
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
-#endif
+ case BuiltInWarpsPerSMNV: return "WarpsPerSMNV";
+ case BuiltInSMCountNV: return "SMCountNV";
+ case BuiltInWarpIDNV: return "WarpIDNV";
+ case BuiltInSMIDNV: return "SMIDNV";
default: return "Bad";
}
@@ -575,7 +563,7 @@
}
}
-const int ImageOperandsCeiling = 12;
+const int ImageOperandsCeiling = 14;
const char* ImageOperandsString(int format)
{
@@ -592,6 +580,8 @@
case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR";
case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR";
case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR";
+ case ImageOperandsSignExtendShift: return "SignExtend";
+ case ImageOperandsZeroExtendShift: return "ZeroExtend";
case ImageOperandsCeiling:
default:
@@ -674,15 +664,20 @@
}
}
-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";
@@ -763,11 +758,9 @@
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";
}
@@ -875,26 +868,23 @@
case CapabilityStoragePushConstant16: return "StoragePushConstant16";
case CapabilityStorageInputOutput16: return "StorageInputOutput16";
- case CapabilityStorageBuffer8BitAccess: return "CapabilityStorageBuffer8BitAccess";
- case CapabilityUniformAndStorageBuffer8BitAccess: return "CapabilityUniformAndStorageBuffer8BitAccess";
- case CapabilityStoragePushConstant8: return "CapabilityStoragePushConstant8";
+ 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";
@@ -902,37 +892,51 @@
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
case CapabilityRayTracingNV: return "RayTracingNV";
+ case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
+ case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR";
+ case CapabilityRayTraversalPrimitiveCullingProvisionalKHR: return "RayTraversalPrimitiveCullingProvisionalKHR";
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityMeshShadingNV: return "MeshShadingNV";
-// case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by CapabilityFragmentDensityEXT
-#endif
+ 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 "CapabilityVulkanMemoryModelKHR";
- case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
+ case CapabilityVulkanMemoryModelKHR: return "VulkanMemoryModelKHR";
+ case CapabilityVulkanMemoryModelDeviceScopeKHR: return "VulkanMemoryModelDeviceScopeKHR";
- case CapabilityPhysicalStorageBufferAddressesEXT: return "CapabilityPhysicalStorageBufferAddressesEXT";
+ case CapabilityPhysicalStorageBufferAddressesEXT: return "PhysicalStorageBufferAddressesEXT";
- case CapabilityVariablePointers: return "CapabilityVariablePointers";
+ case CapabilityVariablePointers: return "VariablePointers";
- case CapabilityCooperativeMatrixNV: return "CapabilityCooperativeMatrixNV";
+ 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";
}
@@ -1026,6 +1030,7 @@
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";
@@ -1308,7 +1313,6 @@
case 4430: return "OpSubgroupAllEqualKHR";
case 4432: return "OpSubgroupReadInvocationKHR";
-#ifdef AMD_EXTENSIONS
case 5000: return "OpGroupIAddNonUniformAMD";
case 5001: return "OpGroupFAddNonUniformAMD";
case 5002: return "OpGroupFMinNonUniformAMD";
@@ -1320,28 +1324,57 @@
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";
- 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 OpReportIntersectionKHR: return "OpReportIntersectionKHR";
+ case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR";
+ case OpTerminateRayKHR: return "OpTerminateRayKHR";
+ case OpTraceRayKHR: return "OpTraceRayKHR";
+ case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
+ case OpExecuteCallableKHR: return "OpExecuteCallableKHR";
case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV";
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
-#endif
+
+ case OpTypeRayQueryProvisionalKHR: return "OpTypeRayQueryProvisionalKHR";
+ case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR";
+ case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR";
+ case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR";
+ case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR";
+ case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR";
+ case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR";
+ case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR";
+ case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR";
+ case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR";
+ case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR";
+ case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR";
+ case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR";
+ case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR";
+ case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR";
+ case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR";
+ case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR";
+ case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR";
+ case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR";
+ case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR";
+ case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR";
+ case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR";
+ case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR";
+ case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR";
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";
@@ -1456,6 +1489,8 @@
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
@@ -1933,6 +1968,8 @@
InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'");
+ InstructionDesc[OpCopyLogical].operands.push(OperandId, "'Operand'");
+
InstructionDesc[OpIsNan].operands.push(OperandId, "'x'");
InstructionDesc[OpIsInf].operands.push(OperandId, "'x'");
@@ -2646,7 +2683,6 @@
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'");
@@ -2685,36 +2721,128 @@
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");
- InstructionDesc[OpTypeAccelerationStructureNV].setResultAndType(true, false);
+ InstructionDesc[OpTypeAccelerationStructureKHR].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[OpTraceRayKHR].operands.push(OperandId, "'NV Acceleration Structure'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'");
+ InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'");
+ InstructionDesc[OpTraceRayKHR].setResultAndType(false, false);
- InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Parameter'");
- InstructionDesc[OpReportIntersectionNV].operands.push(OperandId, "'Hit Kind'");
+ InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'");
+ InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'");
- InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false);
+ InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false);
- InstructionDesc[OpTerminateRayNV].setResultAndType(false, false);
+ InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false);
- InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index");
- InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID");
- InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false);
+ InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index");
+ InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData ID");
+ InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false);
+
+ // Ray Query
+ InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false);
+ InstructionDesc[OpTypeRayQueryProvisionalKHR].setResultAndType(true, false);
+
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'");
+ InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'");
+ InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'");
+ InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false);
+
+ InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true);
+
+ InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'");
+ InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'");
+ InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true);
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
@@ -2725,7 +2853,6 @@
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'");
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'");
-#endif
InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Component Type'");
InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Scope'");
@@ -2752,6 +2879,10 @@
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/SPIRV/hex_float.h b/SPIRV/hex_float.h
index 905b21a..8be8e9f 100644
--- a/SPIRV/hex_float.h
+++ b/SPIRV/hex_float.h
@@ -784,8 +784,8 @@
if (val.isInfinity()) {
// Fail the parse. Emulate standard behaviour by setting the value to
// the closest normal value, and set the fail bit on the stream.
- value.set_value((value.isNegative() | negate_value) ? T::lowest()
- : T::max());
+ value.set_value((value.isNegative() || negate_value) ? T::lowest()
+ : T::max());
is.setstate(std::ios_base::failbit);
}
return is;
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index 62c2dc9..dae36cf 100644
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2019 The Khronos Group Inc.
+// Copyright (c) 2014-2020 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"),
@@ -49,12 +49,12 @@
typedef unsigned int Id;
-#define SPV_VERSION 0x10300
-#define SPV_REVISION 7
+#define SPV_VERSION 0x10500
+#define SPV_REVISION 3
static const unsigned int MagicNumber = 0x07230203;
-static const unsigned int Version = 0x00010300;
-static const unsigned int Revision = 7;
+static const unsigned int Version = 0x00010500;
+static const unsigned int Revision = 3;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@@ -78,11 +78,17 @@
ExecutionModelKernel = 6,
ExecutionModelTaskNV = 5267,
ExecutionModelMeshNV = 5268,
+ ExecutionModelRayGenerationKHR = 5313,
ExecutionModelRayGenerationNV = 5313,
+ ExecutionModelIntersectionKHR = 5314,
ExecutionModelIntersectionNV = 5314,
+ ExecutionModelAnyHitKHR = 5315,
ExecutionModelAnyHitNV = 5315,
+ ExecutionModelClosestHitKHR = 5316,
ExecutionModelClosestHitNV = 5316,
+ ExecutionModelMissKHR = 5317,
ExecutionModelMissNV = 5317,
+ ExecutionModelCallableKHR = 5318,
ExecutionModelCallableNV = 5318,
ExecutionModelMax = 0x7fffffff,
};
@@ -91,6 +97,7 @@
AddressingModelLogical = 0,
AddressingModelPhysical32 = 1,
AddressingModelPhysical64 = 2,
+ AddressingModelPhysicalStorageBuffer64 = 5348,
AddressingModelPhysicalStorageBuffer64EXT = 5348,
AddressingModelMax = 0x7fffffff,
};
@@ -99,6 +106,7 @@
MemoryModelSimple = 0,
MemoryModelGLSL450 = 1,
MemoryModelOpenCL = 2,
+ MemoryModelVulkan = 3,
MemoryModelVulkanKHR = 3,
MemoryModelMax = 0x7fffffff,
};
@@ -154,6 +162,12 @@
ExecutionModeDerivativeGroupQuadsNV = 5289,
ExecutionModeDerivativeGroupLinearNV = 5290,
ExecutionModeOutputTrianglesNV = 5298,
+ ExecutionModePixelInterlockOrderedEXT = 5366,
+ ExecutionModePixelInterlockUnorderedEXT = 5367,
+ ExecutionModeSampleInterlockOrderedEXT = 5368,
+ ExecutionModeSampleInterlockUnorderedEXT = 5369,
+ ExecutionModeShadingRateInterlockOrderedEXT = 5370,
+ ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
ExecutionModeMax = 0x7fffffff,
};
@@ -171,12 +185,19 @@
StorageClassAtomicCounter = 10,
StorageClassImage = 11,
StorageClassStorageBuffer = 12,
+ StorageClassCallableDataKHR = 5328,
StorageClassCallableDataNV = 5328,
+ StorageClassIncomingCallableDataKHR = 5329,
StorageClassIncomingCallableDataNV = 5329,
+ StorageClassRayPayloadKHR = 5338,
StorageClassRayPayloadNV = 5338,
+ StorageClassHitAttributeKHR = 5339,
StorageClassHitAttributeNV = 5339,
+ StorageClassIncomingRayPayloadKHR = 5342,
StorageClassIncomingRayPayloadNV = 5342,
+ StorageClassShaderRecordBufferKHR = 5343,
StorageClassShaderRecordBufferNV = 5343,
+ StorageClassPhysicalStorageBuffer = 5349,
StorageClassPhysicalStorageBufferEXT = 5349,
StorageClassMax = 0x7fffffff,
};
@@ -305,10 +326,16 @@
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,
};
@@ -322,10 +349,16 @@
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 {
@@ -406,6 +439,7 @@
DecorationNonWritable = 24,
DecorationNonReadable = 25,
DecorationUniform = 26,
+ DecorationUniformId = 27,
DecorationSaturatedConversion = 28,
DecorationStream = 29,
DecorationLocation = 30,
@@ -437,11 +471,17 @@
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,
};
@@ -530,20 +570,39 @@
BuiltInFragmentSizeNV = 5292,
BuiltInFragInvocationCountEXT = 5293,
BuiltInInvocationsPerPixelNV = 5293,
+ BuiltInLaunchIdKHR = 5319,
BuiltInLaunchIdNV = 5319,
+ BuiltInLaunchSizeKHR = 5320,
BuiltInLaunchSizeNV = 5320,
+ BuiltInWorldRayOriginKHR = 5321,
BuiltInWorldRayOriginNV = 5321,
+ BuiltInWorldRayDirectionKHR = 5322,
BuiltInWorldRayDirectionNV = 5322,
+ BuiltInObjectRayOriginKHR = 5323,
BuiltInObjectRayOriginNV = 5323,
+ BuiltInObjectRayDirectionKHR = 5324,
BuiltInObjectRayDirectionNV = 5324,
+ BuiltInRayTminKHR = 5325,
BuiltInRayTminNV = 5325,
+ BuiltInRayTmaxKHR = 5326,
BuiltInRayTmaxNV = 5326,
+ BuiltInInstanceCustomIndexKHR = 5327,
BuiltInInstanceCustomIndexNV = 5327,
+ BuiltInObjectToWorldKHR = 5330,
BuiltInObjectToWorldNV = 5330,
+ BuiltInWorldToObjectKHR = 5331,
BuiltInWorldToObjectNV = 5331,
+ BuiltInHitTKHR = 5332,
BuiltInHitTNV = 5332,
+ BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333,
+ BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
+ BuiltInRayGeometryIndexKHR = 5352,
+ BuiltInWarpsPerSMNV = 5374,
+ BuiltInSMCountNV = 5375,
+ BuiltInWarpIDNV = 5376,
+ BuiltInSMIDNV = 5377,
BuiltInMax = 0x7fffffff,
};
@@ -564,6 +623,11 @@
LoopControlDontUnrollShift = 1,
LoopControlDependencyInfiniteShift = 2,
LoopControlDependencyLengthShift = 3,
+ LoopControlMinIterationsShift = 4,
+ LoopControlMaxIterationsShift = 5,
+ LoopControlIterationMultipleShift = 6,
+ LoopControlPeelCountShift = 7,
+ LoopControlPartialCountShift = 8,
LoopControlMax = 0x7fffffff,
};
@@ -573,6 +637,11 @@
LoopControlDontUnrollMask = 0x00000002,
LoopControlDependencyInfiniteMask = 0x00000004,
LoopControlDependencyLengthMask = 0x00000008,
+ LoopControlMinIterationsMask = 0x00000010,
+ LoopControlMaxIterationsMask = 0x00000020,
+ LoopControlIterationMultipleMask = 0x00000040,
+ LoopControlPeelCountMask = 0x00000080,
+ LoopControlPartialCountMask = 0x00000100,
};
enum FunctionControlShift {
@@ -602,9 +671,13 @@
MemorySemanticsCrossWorkgroupMemoryShift = 9,
MemorySemanticsAtomicCounterMemoryShift = 10,
MemorySemanticsImageMemoryShift = 11,
+ MemorySemanticsOutputMemoryShift = 12,
MemorySemanticsOutputMemoryKHRShift = 12,
+ MemorySemanticsMakeAvailableShift = 13,
MemorySemanticsMakeAvailableKHRShift = 13,
+ MemorySemanticsMakeVisibleShift = 14,
MemorySemanticsMakeVisibleKHRShift = 14,
+ MemorySemanticsVolatileShift = 15,
MemorySemanticsMax = 0x7fffffff,
};
@@ -620,17 +693,24 @@
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,
};
@@ -640,8 +720,11 @@
MemoryAccessVolatileMask = 0x00000001,
MemoryAccessAlignedMask = 0x00000002,
MemoryAccessNontemporalMask = 0x00000004,
+ MemoryAccessMakePointerAvailableMask = 0x00000008,
MemoryAccessMakePointerAvailableKHRMask = 0x00000008,
+ MemoryAccessMakePointerVisibleMask = 0x00000010,
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
+ MemoryAccessNonPrivatePointerMask = 0x00000020,
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
};
@@ -651,7 +734,9 @@
ScopeWorkgroup = 2,
ScopeSubgroup = 3,
ScopeInvocation = 4,
+ ScopeQueueFamily = 5,
ScopeQueueFamilyKHR = 5,
+ ScopeShaderCallKHR = 6,
ScopeMax = 0x7fffffff,
};
@@ -751,6 +836,8 @@
CapabilityGroupNonUniformShuffleRelative = 66,
CapabilityGroupNonUniformClustered = 67,
CapabilityGroupNonUniformQuad = 68,
+ CapabilityShaderLayer = 69,
+ CapabilityShaderViewportIndex = 70,
CapabilitySubgroupBallotKHR = 4423,
CapabilityDrawParameters = 4427,
CapabilitySubgroupVoteKHR = 4431,
@@ -774,11 +861,14 @@
CapabilitySignedZeroInfNanPreserve = 4466,
CapabilityRoundingModeRTE = 4467,
CapabilityRoundingModeRTZ = 4468,
+ CapabilityRayQueryProvisionalKHR = 4471,
+ CapabilityRayTraversalPrimitiveCullingProvisionalKHR = 4478,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
CapabilityStencilExportEXT = 5013,
CapabilityImageReadWriteLodAMD = 5015,
+ CapabilityShaderClockKHR = 5055,
CapabilitySampleMaskOverrideCoverageNV = 5249,
CapabilityGeometryShaderPassthroughNV = 5251,
CapabilityShaderViewportIndexLayerEXT = 5254,
@@ -794,34 +884,103 @@
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,
+ CapabilityRayTracingProvisionalKHR = 5353,
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,
};
+enum RayFlagsShift {
+ RayFlagsOpaqueKHRShift = 0,
+ RayFlagsNoOpaqueKHRShift = 1,
+ RayFlagsTerminateOnFirstHitKHRShift = 2,
+ RayFlagsSkipClosestHitShaderKHRShift = 3,
+ RayFlagsCullBackFacingTrianglesKHRShift = 4,
+ RayFlagsCullFrontFacingTrianglesKHRShift = 5,
+ RayFlagsCullOpaqueKHRShift = 6,
+ RayFlagsCullNoOpaqueKHRShift = 7,
+ RayFlagsSkipTrianglesKHRShift = 8,
+ RayFlagsSkipAABBsKHRShift = 9,
+ RayFlagsMax = 0x7fffffff,
+};
+
+enum RayFlagsMask {
+ RayFlagsMaskNone = 0,
+ RayFlagsOpaqueKHRMask = 0x00000001,
+ RayFlagsNoOpaqueKHRMask = 0x00000002,
+ RayFlagsTerminateOnFirstHitKHRMask = 0x00000004,
+ RayFlagsSkipClosestHitShaderKHRMask = 0x00000008,
+ RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010,
+ RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020,
+ RayFlagsCullOpaqueKHRMask = 0x00000040,
+ RayFlagsCullNoOpaqueKHRMask = 0x00000080,
+ RayFlagsSkipTrianglesKHRMask = 0x00000100,
+ RayFlagsSkipAABBsKHRMask = 0x00000200,
+};
+
+enum RayQueryIntersection {
+ RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0,
+ RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1,
+ RayQueryIntersectionMax = 0x7fffffff,
+};
+
+enum RayQueryCommittedIntersectionType {
+ RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0,
+ RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1,
+ RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2,
+ RayQueryCommittedIntersectionTypeMax = 0x7fffffff,
+};
+
+enum RayQueryCandidateIntersectionType {
+ RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0,
+ RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1,
+ RayQueryCandidateIntersectionTypeMax = 0x7fffffff,
+};
+
enum Op {
OpNop = 0,
OpUndef = 1,
@@ -1163,12 +1322,23 @@
OpGroupNonUniformLogicalXor = 364,
OpGroupNonUniformQuadBroadcast = 365,
OpGroupNonUniformQuadSwap = 366,
+ OpCopyLogical = 400,
+ OpPtrEqual = 401,
+ OpPtrNotEqual = 402,
+ OpPtrDiff = 403,
OpSubgroupBallotKHR = 4421,
OpSubgroupFirstInvocationKHR = 4422,
OpSubgroupAllKHR = 4428,
OpSubgroupAnyKHR = 4429,
OpSubgroupAllEqualKHR = 4430,
OpSubgroupReadInvocationKHR = 4432,
+ OpTypeRayQueryProvisionalKHR = 4472,
+ OpRayQueryInitializeKHR = 4473,
+ OpRayQueryTerminateKHR = 4474,
+ OpRayQueryGenerateIntersectionKHR = 4475,
+ OpRayQueryConfirmIntersectionKHR = 4476,
+ OpRayQueryProceedKHR = 4477,
+ OpRayQueryGetIntersectionTypeKHR = 4479,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1179,20 +1349,31 @@
OpGroupSMaxNonUniformAMD = 5007,
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
+ OpReadClockKHR = 5056,
OpImageSampleFootprintNV = 5283,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
+ OpIgnoreIntersectionKHR = 5335,
OpIgnoreIntersectionNV = 5335,
+ OpTerminateRayKHR = 5336,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceRayKHR = 5337,
+ OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
+ OpExecuteCallableKHR = 5344,
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,
@@ -1203,7 +1384,23 @@
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,
@@ -1323,9 +1520,582 @@
OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
+ OpRayQueryGetRayTMinKHR = 6016,
+ OpRayQueryGetRayFlagsKHR = 6017,
+ OpRayQueryGetIntersectionTKHR = 6018,
+ OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019,
+ OpRayQueryGetIntersectionInstanceIdKHR = 6020,
+ OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021,
+ OpRayQueryGetIntersectionGeometryIndexKHR = 6022,
+ OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023,
+ OpRayQueryGetIntersectionBarycentricsKHR = 6024,
+ OpRayQueryGetIntersectionFrontFaceKHR = 6025,
+ OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026,
+ OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027,
+ OpRayQueryGetIntersectionObjectRayOriginKHR = 6028,
+ OpRayQueryGetWorldRayDirectionKHR = 6029,
+ OpRayQueryGetWorldRayOriginKHR = 6030,
+ OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
+ OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
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 OpTypeRayQueryProvisionalKHR: *hasResult = true; *hasResultType = false; break;
+ case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break;
+ case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionTypeKHR: *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;
+ case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
+ case OpRayQueryGetIntersectionWorldToObjectKHR: *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)); }
@@ -1336,6 +2106,7 @@
inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
+inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
} // end namespace spv
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index b3cd0b0..6523035 100755
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -226,6 +226,35 @@
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();
+ addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
+ }
+ // 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<Instruction>(branch));
+ successors.push_back(header);
+ }
+
bool isTerminated() const
{
switch (instructions.back()->getOpCode()) {
@@ -235,6 +264,7 @@
case OpKill:
case OpReturn:
case OpReturnValue:
+ case OpUnreachable:
return true;
default:
return false;
@@ -268,10 +298,24 @@
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<void(Block*)> 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<void(Block*, ReachReason, Block* header)> callback);
//
// SPIR-V IR Function.
@@ -321,7 +365,7 @@
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);
}
@@ -436,6 +480,6 @@
parent.getParent().mapInstruction(raw_instruction);
}
-}; // end spv namespace
+} // end spv namespace
#endif // spvIR_H
diff --git a/StandAlone/CMakeLists.txt b/StandAlone/CMakeLists.txt
index 5cea53d..591ac34 100644
--- a/StandAlone/CMakeLists.txt
+++ b/StandAlone/CMakeLists.txt
@@ -1,28 +1,29 @@
add_library(glslang-default-resource-limits
- ${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp)
+ ${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/resource_limits_c.cpp)
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 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
+
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,22 +33,36 @@
endif(WIN32)
target_link_libraries(glslangValidator ${LIBRARIES})
-target_link_libraries(spirv-remap ${LIBRARIES})
-target_include_directories(glslangValidator PUBLIC ../External)
+target_include_directories(glslangValidator PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
+
+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/StandAlone/ResourceLimits.cpp b/StandAlone/ResourceLimits.cpp
index 66e79af..7c7f4c4 100644
--- a/StandAlone/ResourceLimits.cpp
+++ b/StandAlone/ResourceLimits.cpp
@@ -134,6 +134,7 @@
/* .maxTaskWorkGroupSizeY_NV = */ 1,
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
/* .maxMeshViewCountNV = */ 4,
+ /* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */ {
/* .nonInductiveForLoops = */ 1,
@@ -234,7 +235,6 @@
<< "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n"
<< "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n"
<< "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n"
-#ifdef NV_EXTENSIONS
<< "MaxMeshOutputVerticesNV " << DefaultTBuiltInResource.maxMeshOutputVerticesNV << "\n"
<< "MaxMeshOutputPrimitivesNV " << DefaultTBuiltInResource.maxMeshOutputPrimitivesNV << "\n"
<< "MaxMeshWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_NV << "\n"
@@ -244,7 +244,7 @@
<< "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n"
<< "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n"
<< "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n"
-#endif
+ << "MaxDualSourceDrawBuffersEXT " << DefaultTBuiltInResource.maxDualSourceDrawBuffersEXT << "\n"
<< "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n"
<< "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n"
<< "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n"
@@ -451,7 +451,6 @@
resources->maxCombinedClipAndCullDistances = value;
else if (tokenStr == "MaxSamples")
resources->maxSamples = value;
-#ifdef NV_EXTENSIONS
else if (tokenStr == "MaxMeshOutputVerticesNV")
resources->maxMeshOutputVerticesNV = value;
else if (tokenStr == "MaxMeshOutputPrimitivesNV")
@@ -470,7 +469,6 @@
resources->maxTaskWorkGroupSizeZ_NV = value;
else if (tokenStr == "MaxMeshViewCountNV")
resources->maxMeshViewCountNV = value;
-#endif
else if (tokenStr == "nonInductiveForLoops")
resources->limits.nonInductiveForLoops = (value != 0);
else if (tokenStr == "whileLoops")
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index bb37a84..a7ce53d 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -1,6 +1,7 @@
//
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
// Copyright (C) 2013-2016 LunarG, Inc.
+// Copyright (C) 2016-2020 Google, Inc.
//
// All rights reserved.
//
@@ -104,6 +105,7 @@
bool targetHlslFunctionality1 = false;
bool SpvToolsDisassembler = false;
bool SpvToolsValidate = false;
+bool NaNClamp = false;
//
// Return codes from main/exit().
@@ -145,11 +147,13 @@
{
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;
@@ -162,6 +166,7 @@
const char* variableName = nullptr;
bool HlslEnable16BitTypes = false;
bool HlslDX9compatible = false;
+bool DumpBuiltinSymbols = false;
std::vector<std::string> IncludeDirectoryList;
// Source environment
@@ -200,7 +205,7 @@
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
@@ -218,7 +223,7 @@
text.append("#undef ");
fixLine(undef);
- Processes.push_back("U");
+ Processes.push_back("undef-macro ");
Processes.back().append(undef);
text.append(undef);
@@ -237,6 +242,7 @@
std::string text; // contents of preamble
};
+// Track the user's #define and #undef from the command line.
TPreamble UserPreamble;
//
@@ -253,16 +259,14 @@
case EShLangGeometry: name = "geom.spv"; break;
case EShLangFragment: name = "frag.spv"; break;
case EShLangCompute: name = "comp.spv"; break;
-#ifdef NV_EXTENSIONS
- 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 EShLangRayGen: name = "rgen.spv"; break;
+ case EShLangIntersect: name = "rint.spv"; break;
+ case EShLangAnyHit: name = "rahit.spv"; break;
+ case EShLangClosestHit: name = "rchit.spv"; break;
+ case EShLangMiss: name = "rmiss.spv"; break;
+ case EShLangCallable: name = "rcall.spv"; break;
case EShLangMeshNV: name = "mesh.spv"; break;
case EShLangTaskNV: name = "task.spv"; break;
-#endif
default: name = "unknown"; break;
}
} else
@@ -290,9 +294,12 @@
//
// 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);
}
@@ -480,7 +487,7 @@
Options |= EOptionAutoMapLocations;
} else if (lowerword == "uniform-base") {
if (argc <= 1)
- Error("no <base> provided for --uniform-base");
+ Error("no <base> provided", lowerword.c_str());
uniformBase = ::strtol(argv[1], NULL, 10);
bumpArg();
break;
@@ -491,13 +498,23 @@
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 <name[=def]>", argv[0]);
+ bumpArg();
+ } else if (lowerword == "dump-builtin-symbols") {
+ DumpBuiltinSymbols = true;
} else if (lowerword == "entry-point") {
entryPointName = argv[1];
if (argc <= 1)
- Error("no <name> provided for --entry-point");
+ Error("no <name> provided", lowerword.c_str());
bumpArg();
} else if (lowerword == "flatten-uniform-arrays" || // synonyms
lowerword == "flatten-uniform-array" ||
@@ -519,6 +536,8 @@
} 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;
@@ -570,7 +589,7 @@
} else if (lowerword == "source-entrypoint" || // synonyms
lowerword == "sep") {
if (argc <= 1)
- Error("no <entry-point> provided for --source-entrypoint");
+ Error("no <entry-point> provided", lowerword.c_str());
sourceEntryPointName = argv[1];
bumpArg();
break;
@@ -591,6 +610,9 @@
} else if (strcmp(argv[1], "vulkan1.1") == 0) {
setVulkanSpv();
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();
ClientVersion = glslang::EShTargetOpenGL_450;
@@ -609,22 +631,36 @@
} 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 one of: vulkan1.0, vulkan1.1, opengl, spirv1.0, spirv1.1, spirv1.2, or spirv1.3");
+ 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 <name>", argv[0]);
+ bumpArg();
} else if (lowerword == "variable-name" || // synonyms
lowerword == "vn") {
Options |= EOptionOutputHexadecimal;
if (argc <= 1)
- Error("no <C-variable-name> provided for --variable-name");
+ Error("no <C-variable-name> provided", lowerword.c_str());
variableName = argv[1];
bumpArg();
break;
} else if (lowerword == "version") {
Options |= EOptionDumpVersions;
- } else {
+ } else if (lowerword == "help") {
usage();
+ break;
+ } else {
+ Error("unrecognized command-line option", argv[0]);
}
}
break;
@@ -635,7 +671,7 @@
if (argv[0][2] == 0)
Options |= EOptionReadHlsl;
else
- UserPreamble.addDef(getStringOperand("-D<macro> macro name"));
+ UserPreamble.addDef(getStringOperand("-D<name[=def]>"));
break;
case 'u':
uniformLocationOverrides.push_back(getUniformOverride());
@@ -678,7 +714,7 @@
bumpArg();
break;
case 'U':
- UserPreamble.addUndef(getStringOperand("-U<macro>: macro name"));
+ UserPreamble.addUndef(getStringOperand("-U<name>"));
break;
case 'V':
setVulkanSpv();
@@ -750,7 +786,7 @@
Options |= EOptionOutputHexadecimal;
break;
default:
- usage();
+ Error("unrecognized command-line option", argv[0]);
break;
}
} else {
@@ -766,8 +802,17 @@
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)
@@ -788,6 +833,10 @@
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;
@@ -833,6 +882,8 @@
messages = (EShMessages)(messages | EShMsgHlslLegalization);
if (HlslDX9compatible)
messages = (EShMessages)(messages | EShMsgHlslDX9Compatible);
+ if (DumpBuiltinSymbols)
+ messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable);
}
//
@@ -960,42 +1011,47 @@
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);
- if (Options & EOptionInvertY)
- shader->setInvertY(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.
@@ -1005,8 +1061,10 @@
compUnit.stage, Client, ClientInputSemanticsVersion);
shader->setEnvClient(Client, ClientVersion);
shader->setEnvTarget(TargetLanguage, TargetVersion);
+#ifdef ENABLE_HLSL
if (targetHlslFunctionality1)
shader->setEnvTargetHlslFunctionality1();
+#endif
}
shaders.push_back(shader);
@@ -1016,6 +1074,7 @@
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)) {
@@ -1027,6 +1086,7 @@
StderrIfNonEmpty(shader->getInfoDebugLog());
continue;
}
+#endif
if (! shader->parse(&Resources, defaultVersion, false, messages, includer))
CompileFailed = true;
@@ -1049,11 +1109,13 @@
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) &&
@@ -1062,11 +1124,13 @@
PutsIfNonEmpty(program.getInfoDebugLog());
}
+#ifndef GLSLANG_WEB
// Reflect
if (Options & EOptionDumpReflection) {
program.buildReflection(ReflectOptions);
program.dumpReflection();
}
+#endif
// Dump SPIR-V
if (Options & EOptionSpv) {
@@ -1076,7 +1140,6 @@
for (int stage = 0; stage < EShLangCount; ++stage) {
if (program.getIntermediate((EShLanguage)stage)) {
std::vector<unsigned int> spirv;
- std::string warningsErrors;
spv::SpvBuildLogger logger;
glslang::SpvOptions spvOptions;
if (Options & EOptionDebug)
@@ -1096,8 +1159,10 @@
} else {
glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage));
}
+#ifndef GLSLANG_WEB
if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv))
spv::Disassemble(std::cout, spirv);
+#endif
}
}
}
@@ -1185,11 +1250,13 @@
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",
@@ -1225,7 +1292,7 @@
ProcessConfigFile();
if ((Options & EOptionReadHlsl) && !((Options & EOptionOutputPreprocessed) || (Options & EOptionSpv)))
- Error("ERROR: HLSL requires SPIR-V code generation (or preprocessing only)");
+ Error("HLSL requires SPIR-V code generation (or preprocessing only)");
//
// Two modes:
@@ -1361,24 +1428,22 @@
return EShLangFragment;
else if (stageName == "comp")
return EShLangCompute;
-#ifdef NV_EXTENSIONS
else if (stageName == "rgen")
- return EShLangRayGenNV;
+ return EShLangRayGen;
else if (stageName == "rint")
- return EShLangIntersectNV;
+ return EShLangIntersect;
else if (stageName == "rahit")
- return EShLangAnyHitNV;
+ return EShLangAnyHit;
else if (stageName == "rchit")
- return EShLangClosestHitNV;
+ return EShLangClosestHit;
else if (stageName == "rmiss")
- return EShLangMissNV;
+ return EShLangMiss;
else if (stageName == "rcall")
- return EShLangCallableNV;
+ return EShLangCallable;
else if (stageName == "mesh")
return EShLangMeshNV;
else if (stageName == "task")
return EShLangTaskNV;
-#endif
usage();
return EShLangVertex;
@@ -1448,7 +1513,6 @@
" .geom for a geometry shader\n"
" .frag for a fragment shader\n"
" .comp for a compute shader\n"
-#ifdef NV_EXTENSIONS
" .mesh for a mesh shader\n"
" .task for a task shader\n"
" .rgen for a ray generation shader\n"
@@ -1457,15 +1521,14 @@
" .rchit for a ray closest hit shader\n"
" .rmiss for a ray miss shader\n"
" .rcall for a ray callable shader\n"
-#endif
" .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 (this is the default when any suffix is .hlsl)\n"
- " -D<macro=def>\n"
- " -D<macro> define a pre-processor macro\n"
+ " -D<name[=def]> | --define-macro <name[=def]> | --D <name[=def]>\n"
+ " define a pre-processor macro\n"
" -E print pre-processed GLSL; cannot be used with -l;\n"
" errors will appear on stderr\n"
" -G[ver] create SPIR-V binary, under OpenGL semantics; turns on -l;\n"
@@ -1481,7 +1544,8 @@
" -Os optimizes SPIR-V to minimize size\n"
" -S <stage> uses specified stage rather than parsing the file extension\n"
" choices for <stage> are vert, tesc, tese, geom, frag, or comp\n"
- " -U<macro> undefine a pre-processor macro\n"
+ " -U<name> | --undef-macro <name> | --U <name>\n"
+ " undefine a pre-processor macro\n"
" -V[ver] create SPIR-V binary, under Vulkan semantics; turns on -l;\n"
" default file name is <stage>.spv (-o overrides this)\n"
" 'ver', when present, is the version of the input semantics,\n"
@@ -1503,7 +1567,7 @@
" -l link all input files together to form a single module\n"
" -m memory leak mode\n"
" -o <file> save binary to <file>, requires a binary option (e.g., -V)\n"
- " -q dump reflection query database\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"
@@ -1520,6 +1584,7 @@
" --auto-map-locations | --aml automatically locate input/output lacking\n"
" 'location' (fragile, not cross stage)\n"
" --client {vulkan<ver>|opengl<ver>} 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"
@@ -1527,9 +1592,11 @@
" 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 texture/sampler combo like DirectX9 would."
+ " --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"
@@ -1584,16 +1651,17 @@
" --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 | opengl | \n"
- " spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3}\n"
- " set execution environment that emitted code\n"
- " will execute in (versus source language\n"
- " semantics selected by --client) defaults:\n"
- " * 'vulkan1.0' under '--client vulkan<ver>'\n"
- " * 'opengl' under '--client opengl<ver>'\n"
- " * 'spirv1.0' under --target-env vulkan1.0\n"
- " * 'spirv1.3' under --target-env vulkan1.1\n"
- " multiple --targen-env can be specified.\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<ver>\n"
+ " * opengl under --client opengl<ver>\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 <name>\n"
" --vn <name> creates a C header file that contains a\n"
" uint32_t array named <name>\n"
diff --git a/StandAlone/resource_limits_c.cpp b/StandAlone/resource_limits_c.cpp
new file mode 100644
index 0000000..a1f681c
--- /dev/null
+++ b/StandAlone/resource_limits_c.cpp
@@ -0,0 +1,65 @@
+/**
+BSD 2-Clause License
+
+Copyright (c) 2020, Travis Fort
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. 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.
+
+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 HOLDER 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 "resource_limits_c.h"
+#include "ResourceLimits.h"
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+
+const glslang_resource_t* glslang_default_resource(void)
+{
+ return reinterpret_cast<const glslang_resource_t*>(&glslang::DefaultTBuiltInResource);
+}
+
+#if defined(__clang__) || defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#elif defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996)
+#endif
+
+const char* glslang_default_resource_string()
+{
+ std::string cpp_str = glslang::GetDefaultTBuiltInResourceString();
+ char* c_str = (char*)malloc(cpp_str.length() + 1);
+ strcpy(c_str, cpp_str.c_str());
+ return c_str;
+}
+
+#if defined(__clang__) || defined(__GNUC__)
+#pragma GCC diagnostic pop
+#elif defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+void glslang_decode_resource_limits(glslang_resource_t* resources, char* config)
+{
+ glslang::DecodeResourceLimits(reinterpret_cast<TBuiltInResource*>(resources), config);
+}
diff --git a/StandAlone/resource_limits_c.h b/StandAlone/resource_limits_c.h
new file mode 100644
index 0000000..108fd5e
--- /dev/null
+++ b/StandAlone/resource_limits_c.h
@@ -0,0 +1,54 @@
+/**
+BSD 2-Clause License
+
+Copyright (c) 2020, Travis Fort
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. 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.
+
+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 HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**/
+
+#ifndef _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
+#define _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
+
+#include "../glslang/Include/glslang_c_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// These are the default resources for TBuiltInResources, used for both
+// - parsing this string for the case where the user didn't supply one,
+// - dumping out a template for user construction of a config file.
+const glslang_resource_t* glslang_default_resource(void);
+
+// Returns the DefaultTBuiltInResource as a human-readable string.
+// NOTE: User is responsible for freeing this string.
+const char* glslang_default_resource_string();
+
+// Decodes the resource limits from |config| to |resources|.
+void glslang_decode_resource_limits(glslang_resource_t* resources, char* config);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
diff --git a/StandAlone/spirv-remap.cpp b/StandAlone/spirv-remap.cpp
index 998f742..48878c3 100644
--- a/StandAlone/spirv-remap.cpp
+++ b/StandAlone/spirv-remap.cpp
@@ -227,7 +227,7 @@
}
}
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
@@ -334,8 +334,6 @@
if (outputDir.empty())
usage(argv[0], "Output directory required");
- std::string errmsg;
-
// Main operations: read, remap, and write.
execute(inputFile, outputDir, opts, verbosity);
diff --git a/Test/100.frag b/Test/100.frag
index 4f0c69b..439fc6c 100644
--- a/Test/100.frag
+++ b/Test/100.frag
@@ -201,6 +201,19 @@
return fooinit();
}
+// Test extension GL_EXT_blend_func_extended
+void blendFuncFail() // Error since extension GL_EXT_blend_func_extended is disabled
+{
+ gl_SecondaryFragColorEXT = vec4(1.0);
+ gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);
+}
+#extension GL_EXT_blend_func_extended : enable
+void blendFunc()
+{
+ gl_SecondaryFragColorEXT = vec4(1.0);
+ gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);
+}
+
// Test extra-function initializers
const float fi1 = 3.0;
const float fi2 = 4.0;
@@ -219,6 +232,9 @@
int init2 = gl_FrontFacing ? 1 : 2;
+#define A__B // error
+int a__b; // error
+
#pragma STDGL invariant(all)
#line 3000
diff --git a/Test/120.vert b/Test/120.vert
index d276557..7b98492 100644
--- a/Test/120.vert
+++ b/Test/120.vert
@@ -201,3 +201,15 @@
#define macr(A,B) A ## B
int macr(qrs,tuv);
+
+layout(std140) uniform BlockName // ERROR
+{
+ int test;
+};
+
+#extension GL_ARB_uniform_buffer_object : enable
+
+layout(std140) uniform BlockName
+{
+ int test;
+};
\ No newline at end of file
diff --git a/Test/130.frag b/Test/130.frag
index 3e39411..c352df4 100644
--- a/Test/130.frag
+++ b/Test/130.frag
@@ -62,12 +62,14 @@
b3 < b3; // ERROR
uv3 > uv3; // ERROR
uvec2(2, 3) >= uvec2(3,3); // ERROR
+ int samples = gl_NumSamples; // ERROR
int(bl4) <= int(bl4); // true
int(bl4.x) > int(bl4.y); // false
}
#extension GL_ARB_texture_gather : enable
#extension GL_ARB_texture_rectangle : enable
+#extension GL_ARB_sample_shading : enable
uniform sampler2D samp2D;
uniform sampler2DShadow samp2DS;
@@ -83,6 +85,7 @@
s = textureGatherOffset(samp2DA, vec3(0.3), ivec2(1));
s = textureGatherOffset(samp2DS, vec2(0.3), 1.3, ivec2(1)); // ERROR
s = textureGatherOffset(samp2D, vec2(0.3), ivec2(1), 2); // ERROR
+ int samples = gl_NumSamples;
}
#extension GL_ARB_gpu_shader5 : enable
@@ -167,3 +170,12 @@
}
layout(early_fragment_tests) out; // ERROR
+
+#extension GL_ARB_explicit_uniform_location : enable
+
+layout(location = 3) uniform vec4 ucolor0; // ERROR: explicit attrib location is also required for version < 330
+
+#extension GL_ARB_explicit_attrib_location : enable
+
+layout(location = 4) uniform vec4 ucolor1;
+
diff --git a/Test/140.frag b/Test/140.frag
index 2bc2f59..5efdbed 100644
--- a/Test/140.frag
+++ b/Test/140.frag
@@ -17,6 +17,7 @@
#error GL_ES is not set
#endif
+
in struct S { float f; } s; // ERROR
float patch = 3.1;
@@ -51,3 +52,9 @@
{
return i1 + i2;
}
+
+uniform sampler2DMS aaa1; // ERROR
+
+#extension GL_ARB_texture_multisample : enable
+
+uniform sampler2DMS aaa2;
diff --git a/Test/140.vert b/Test/140.vert
index 914e672..8035144 100644
--- a/Test/140.vert
+++ b/Test/140.vert
@@ -68,7 +68,7 @@
#extension GL_EXT_device_group : enable
#endif
-#ifdef GL_EXT_device_group
+#ifdef GL_EXT_multiview
#extension GL_EXT_multiview : enable
#endif
diff --git a/Test/150.frag b/Test/150.frag
index 16963af..228e4f0 100644
--- a/Test/150.frag
+++ b/Test/150.frag
@@ -47,4 +47,138 @@
int primitiveID()
{
return gl_PrimitiveID;
+ gl_PerFragment; // ERROR, block name can't get reused
+}
+
+in double type1; // ERROR
+#extension GL_ARB_gpu_shader_fp64 : enable
+double type2;
+double type3 = 2.0;
+int absTest = sqrt(type3);
+double absTest2 = sqrt(type3);
+double absTest3 = sqrt(2);
+float dk = sqrt(11);
+
+#extension GL_ARB_shader_bit_encoding: enable
+
+float f;
+vec4 v4;
+ivec4 iv4a;
+uvec2 uv2c;
+void bitEncodingPass()
+{
+ int i = floatBitsToInt(f);
+ uvec4 uv11 = floatBitsToUint(v4);
+ vec4 v14 = intBitsToFloat(iv4a);
+ vec2 v15 = uintBitsToFloat(uv2c);
+}
+
+#extension GL_ARB_shader_bit_encoding: disable
+
+void bitEncodingFail()
+{
+ int i = floatBitsToInt(f); // Error, extention GL_ARB_bit_encoding is diabled
+}
+
+#extension GL_ARB_shading_language_packing : enable
+vec2 v2a;
+uint uy;
+
+void packingPass()
+{
+ uint u19 = packSnorm2x16(v2a);
+ vec2 v20 = unpackSnorm2x16(uy);
+ uint u15 = packUnorm2x16(v2a);
+ vec2 v16 = unpackUnorm2x16(uy);
+ uint u17 = packHalf2x16(v2a);
+ vec2 v18 = unpackHalf2x16(uy);
+}
+
+#extension GL_ARB_shading_language_packing : disable
+void packingFail()
+{
+ uint u19 = packSnorm2x16(v2a); // Error, extension GL_ARB_shading_language_packing is disabled
+}
+
+// Testing extension GL_ARB_texture_query_lod
+uniform sampler1D samp1D;
+uniform sampler2DShadow samp2Ds;
+
+void qlodFail()
+{
+ vec2 lod;
+ float pf;
+ vec2 pf2;
+ vec3 pf3;
+
+ lod = textureQueryLod(samp1D, pf); // ERROR, extension GL_ARB_texture_query_lod needed
+ lod = textureQueryLod(samp2Ds, pf2); // ERROR, extension GL_ARB_texture_query_lod needed
+}
+
+#extension GL_ARB_texture_query_lod : enable
+
+uniform isampler2D isamp2D;
+uniform usampler3D usamp3D;
+uniform samplerCube sampCube;
+uniform isampler1DArray isamp1DA;
+uniform usampler2DArray usamp2DA;
+
+uniform sampler1DShadow samp1Ds;
+uniform samplerCubeShadow sampCubes;
+uniform sampler1DArrayShadow samp1DAs;
+uniform sampler2DArrayShadow samp2DAs;
+
+uniform samplerBuffer sampBuf;
+uniform sampler2DRect sampRect;
+
+void qlodPass()
+{
+ vec2 lod;
+ float pf;
+ vec2 pf2;
+ vec3 pf3;
+
+ lod = textureQueryLod(samp1D, pf);
+ lod = textureQueryLod(isamp2D, pf2);
+ lod = textureQueryLod(usamp3D, pf3);
+ lod = textureQueryLod(sampCube, pf3);
+ lod = textureQueryLod(isamp1DA, pf);
+ lod = textureQueryLod(usamp2DA, pf2);
+
+ lod = textureQueryLod(samp1Ds, pf);
+ lod = textureQueryLod(samp2Ds, pf2);
+ lod = textureQueryLod(sampCubes, pf3);
+ lod = textureQueryLod(samp1DAs, pf);
+ lod = textureQueryLod(samp2DAs, pf2);
+
+ lod = textureQueryLod(sampBuf, pf); // ERROR
+ lod = textureQueryLod(sampRect, pf2); // ERROR
+}
+
+// Test extension GL_EXT_shader_integer_mix
+#extension GL_EXT_shader_integer_mix : enable
+bool b1, b2, b;
+int x,y;
+uint z,w;
+
+void testmix()
+{
+ int ival = mix(x, y, b);
+ ivec2 iv2 = mix(ivec2(x), ivec2(y), bvec2(b));
+ ivec3 iv3 = mix(ivec3(x), ivec3(y), bvec3(b));
+ ivec4 iv4 = mix(ivec4(x), ivec4(x), bvec4(b));
+ uint uiv = mix(z, w, b);
+ uvec2 uv2 = mix(uvec2(z), uvec2(z), bvec2(b));
+ uvec3 uv3 = mix(uvec3(z), uvec3(z), bvec3(b));
+ uvec4 uv4 = mix(uvec4(z), uvec4(z), bvec4(b));
+ bool bv = mix(b1, b2, b);
+ bvec2 bv2 = mix(bvec2(b1), bvec2(b2), bvec2(b));
+ bvec3 bv3 = mix(bvec3(b1), bvec3(b2), bvec3(b));
+ bvec4 bv4 = mix(bvec4(b1), bvec4(b2), bvec4(b));
+}
+
+#extension GL_EXT_shader_integer_mix : disable
+void testmixFail()
+{
+ int ival = mix(x, y, b); // Error since extenson GL_EXT_shader_integer_mix is disabled
}
diff --git a/Test/150.vert b/Test/150.vert
index 4dd9e5c..f9a920c 100644
--- a/Test/150.vert
+++ b/Test/150.vert
@@ -25,5 +25,21 @@
};
int a[5]; // ERROR, resizing user-block member
+in double dvarerr; // Error since extension GL_ARB_vertex_attrib_64bit is not enabled
+#extension GL_ARB_vertex_attrib_64bit: enable
+in double dvar;
+in dvec2 dv2var;
+in dvec3 dv3var;
+in dvec4 dv4var;
+in dmat2 dmat2var;
+in dmat3 dmat3var;
+in dmat4 dmat4var;
+in dmat2x3 dmat23var;
+in dmat2x4 dmat24var;
+in dmat3x2 dmat32var;
+in dmat3x4 dmat34var;
+in dmat4x2 dmat42var;
+in dmat4x3 dmat43var;
+
#line 3000
#error line of this error should be 3001
diff --git a/Test/300.frag b/Test/300.frag
index ca2e2cb..279864a 100644
--- a/Test/300.frag
+++ b/Test/300.frag
@@ -149,6 +149,39 @@
layout(early_fragment_tests) in; // ERROR
+// Test extension GL_EXT_shader_integer_mix
+#extension GL_EXT_shader_integer_mix : enable
+bool b1, b2, b;
+int x,y;
+uint z,w;
+
+void testmix()
+{
+ int ival = mix(x, y, b);
+ ivec2 iv2 = mix(ivec2(x), ivec2(y), bvec2(b));
+ ivec3 iv3 = mix(ivec3(x), ivec3(y), bvec3(b));
+ ivec4 iv4 = mix(ivec4(x), ivec4(x), bvec4(b));
+ uint uiv = mix(z, w, b);
+ uvec2 uv2 = mix(uvec2(z), uvec2(z), bvec2(b));
+ uvec3 uv3 = mix(uvec3(z), uvec3(z), bvec3(b));
+ uvec4 uv4 = mix(uvec4(z), uvec4(z), bvec4(b));
+ bool bv = mix(b1, b2, b);
+ bvec2 bv2 = mix(bvec2(b1), bvec2(b2), bvec2(b));
+ bvec3 bv3 = mix(bvec3(b1), bvec3(b2), bvec3(b));
+ bvec4 bv4 = mix(bvec4(b1), bvec4(b2), bvec4(b));
+}
+
+#extension GL_EXT_shader_integer_mix : disable
+void testmixFail()
+{
+ int ival = mix(x, y, b); // Error since extenson GL_EXT_shader_integer_mix is disabled
+}
+
+// Test layout qualifier "index" with extension GL_EXT_blend_func_extended
+layout(location = 0, index = 1) out vec4 outVarFail; // Error Index supported with extension GL_EXT_blend_func_extended enabled
+#extension GL_EXT_blend_func_extended : enable
+layout(location = 0, index = 2) out vec4 outVarPass;
+
#ifndef GL_FRAGMENT_PRECISION_HIGH
#error missing GL_FRAGMENT_PRECISION_HIGH
#endif
diff --git a/Test/310.comp b/Test/310.comp
index 9ca8eaa..33ecbf0 100644
--- a/Test/310.comp
+++ b/Test/310.comp
@@ -106,9 +106,9 @@
void passrc()
{
- passr(qualim1);
- passr(qualim2); // ERROR, drops restrict
- passr(iimg2D);
+ passr(qualim1); // ERROR, changing formats
+ passr(qualim2); // ERROR, drops restrict, ERROR, changing formats
+ passr(iimg2D); // ERROR, changing formats
}
highp layout(rg8i) uniform readonly uimage2D i1bad; // ERROR, type mismatch
diff --git a/Test/310.frag b/Test/310.frag
old mode 100644
new mode 100755
index 6814e6c..5cdcca7
--- a/Test/310.frag
+++ b/Test/310.frag
@@ -58,8 +58,8 @@
b1 = mix(b2, b3, b);
uvec3 um3 = mix(uvec3(i), uvec3(i), bvec3(b));
ivec4 im4 = mix(ivec4(i), ivec4(i), bvec4(b));
+ 1 << mix(1u, 1u, false); // does not require folding
}
-
layout(binding=3) uniform sampler2D s1;
layout(binding=3) uniform sampler2D s2; // ERROR: overlapping bindings? Don't see that in the 310 spec.
highp layout(binding=2) uniform writeonly image2D i2D;
@@ -440,7 +440,7 @@
#extension GL_EXT_device_group : enable
#endif
-#ifdef GL_EXT_device_group
+#ifdef GL_EXT_multiview
#extension GL_EXT_multiview : enable
#endif
@@ -448,4 +448,40 @@
{
gl_DeviceIndex;
gl_ViewIndex;
-}
+}
+
+#extension GL_EXT_shader_implicit_conversions : enable
+
+// Test function overloading
+void func(uint a, uvec4 b)
+{
+
+}
+
+int func(uint a, uvec4 b) // Error function overloading because of same signature and different return type
+{
+ return 0;
+}
+
+int b;
+
+void testimplicit() {
+
+ uint a = b; // int->uint
+ mediump vec4 col = vec4(1, 2, 3, 4); // ivec4 -> vec4
+ int b = a + 2; // ERROR: cannot convert from ' temp uint' to ' temp int'
+
+ // Test binary ops
+ uint c = b * 3;
+ uint d = b * 3u;
+ uint e = b%3;
+ uint f = (b > 3)? b : c;
+ func(b, ivec4(1,2,3,4));
+}
+
+#extension GL_EXT_shader_implicit_conversions : disable
+
+void testimplicitFail() {
+ uint a = b; // Error GL_EXT_shader_implicit_conversions is disabled
+}
+
diff --git a/Test/310.inheritMemory.frag b/Test/310.inheritMemory.frag
new file mode 100644
index 0000000..bdf1283
--- /dev/null
+++ b/Test/310.inheritMemory.frag
@@ -0,0 +1,43 @@
+#version 310 es
+precision mediump float;
+
+struct S {
+ float buff[10];
+};
+
+layout(std430, binding=2) readonly buffer RoBuff {
+ float buff_ro[10];
+ S s_ro;
+} ro_buffer;
+
+layout(std430, binding=2) buffer Buff {
+ float buff[10];
+ S s;
+} non_ro_buffer;
+
+void non_ro_fun(float[10] buff) { }
+void non_ro_funf(float el) { }
+void non_ro_funS(S s) { }
+
+out vec4 fragColor;
+
+void main()
+{
+ S s;
+
+ non_ro_fun(s.buff);
+ non_ro_funf(s.buff[3]);
+ non_ro_funS(s);
+
+ non_ro_fun(non_ro_buffer.buff);
+ non_ro_fun(non_ro_buffer.s.buff);
+ non_ro_funf(non_ro_buffer.buff[3]);
+ non_ro_funf(non_ro_buffer.s.buff[3]);
+ non_ro_funS(non_ro_buffer.s);
+
+ non_ro_fun(ro_buffer.buff_ro);
+ non_ro_fun(ro_buffer.s_ro.buff);
+ non_ro_funf(ro_buffer.buff_ro[3]);
+ non_ro_funf(ro_buffer.s_ro.buff[3]);
+ non_ro_funS(ro_buffer.s_ro);
+}
diff --git a/Test/320.comp b/Test/320.comp
index c31b047..5b38995 100644
--- a/Test/320.comp
+++ b/Test/320.comp
@@ -1,5 +1,17 @@
#version 320 es
+
+float fX;
+float fY;
void main()
{
+ dFdx(fX);
+ dFdy(fY);
+ fwidth(fX);
+ dFdxCoarse(fX);
+ dFdyCoarse(fY);
+ fwidthCoarse(fX);
+ dFdxFine(fX);
+ dFdyFine(fY);
+ fwidthFine(fX);
}
diff --git a/Test/330.frag b/Test/330.frag
index 9afa8f8..364fc0a 100644
--- a/Test/330.frag
+++ b/Test/330.frag
@@ -126,27 +126,26 @@
layout(location=0, index=0) in; // ERROR, not just on in
layout(location=0, index=0) out; // ERROR, need a variable
layout(location=26, index=0) out indexBlock { int a; } indexBlockI; // ERROR, not on a block
-
-uniform sampler1D samp1D;
-uniform sampler2DShadow samp2Ds;
-
-void qlod()
-{
- vec2 lod;
- float pf;
- vec2 pf2;
- vec3 pf3;
-
- lod = textureQueryLod(samp1D, pf); // ERROR, not until 400
- lod = textureQueryLod(samp2Ds, pf2); // ERROR, not until 400
-}
-
-int precise; // okay, not a keyword yet
-struct SKeyMem { int precise; } KeyMem; // okay, not a keyword yet
-
-void fooKeyMem()
-{
- KeyMem.precise;
-}
-
-layout(location=28, index=2) out vec4 outIndex2; // ERROR index out of range
\ No newline at end of file
+
+int precise; // okay, not a keyword yet
+struct SKeyMem { int precise; } KeyMem; // okay, not a keyword yet
+
+void fooKeyMem()
+{
+ KeyMem.precise;
+}
+
+layout(location=28, index=2) out vec4 outIndex2; // ERROR index out of range
+
+layout(location=4) uniform vec4 ucolor0; // ERROR: extension is not enabled
+
+#extension GL_ARB_explicit_uniform_location : enable
+
+layout(location=5) uniform vec4 ucolor1;
+
+layout(location=6) uniform ColorsBuffer // ERROR: location cannot be applied in uniform buffer block
+{
+ vec4 colors[128];
+} colorsBuffer;
+
+
diff --git a/Test/400.tesc b/Test/400.tesc
index 415d7f7..6d609d5 100644
--- a/Test/400.tesc
+++ b/Test/400.tesc
@@ -114,7 +114,7 @@
#extension GL_EXT_device_group : enable
#endif
-#ifdef GL_EXT_device_group
+#ifdef GL_EXT_multiview
#extension GL_EXT_multiview : enable
#endif
diff --git a/Test/400.tese b/Test/400.tese
index c110a1c..a3d30fe 100644
--- a/Test/400.tese
+++ b/Test/400.tese
@@ -114,7 +114,7 @@
#extension GL_EXT_device_group : enable
#endif
-#ifdef GL_EXT_device_group
+#ifdef GL_EXT_multiview
#extension GL_EXT_multiview : enable
#endif
diff --git a/Test/410.vert b/Test/410.vert
index 0ecf476..1891a67 100644
--- a/Test/410.vert
+++ b/Test/410.vert
@@ -6,4 +6,5 @@
void main()
{
+ int test = gl_MaxFragmentUniformVectors;
}
diff --git a/Test/420.frag b/Test/420.frag
index 1444758..d3020b3 100644
--- a/Test/420.frag
+++ b/Test/420.frag
@@ -12,3 +12,31 @@
layout(depth_any) out float gl_FragDepth; // ERROR, done after use
layout(binding=0) uniform atomic_uint a[];
+
+uniform writeonly image2D i2D;
+ivec2 iv2dim = imageSize(i2D); // ERROR: imageSize called without enabling GL_ARB_shader_image_size extension
+#extension GL_ARB_shader_image_size : enable
+ivec2 iv2dim1 = imageSize(i2D);
+
+#extension GL_ARB_shader_storage_buffer_object : enable
+
+layout(binding = 0,std430) buffer Buffer
+{
+ int atomi;
+ uint atomu;
+};
+
+void atomicOpPass()
+{
+ int origi = atomicAdd(atomi, 3);
+ uint origu = atomicAnd(atomu, 7u);
+ origi = atomicExchange(atomi, 4);
+ origu = atomicCompSwap(atomu, 10u, 8u);
+}
+
+#extension GL_ARB_shader_storage_buffer_object : disable
+
+layout(binding = 1,std430) buffer BufferFail // Error std430 and "buffer" block support disabled
+{
+ int atom1i;
+};
diff --git a/Test/420.vert b/Test/420.vert
index ab28140..c7ffa90 100644
--- a/Test/420.vert
+++ b/Test/420.vert
@@ -131,9 +131,9 @@
void passrc()
{
- passr(qualim1);
- passr(qualim2); // ERROR, drops volatile
- passr(iimg2D);
+ passr(qualim1); // ERROR, changing formats
+ passr(qualim2); // ERROR, drops volatile, ERROR, changing formats
+ passr(iimg2D); // ERROR, changing formats
}
layout(rg8i) uniform uimage2D i1bad; // ERROR, type mismatch
diff --git a/Test/430.comp b/Test/430.comp
index 0929432..178b994 100644
--- a/Test/430.comp
+++ b/Test/430.comp
@@ -48,6 +48,9 @@
layout(location = 2) shared vec4 sl; // ERROR
shared float fs = 4.2; // ERROR
+layout(local_size_y = 1) in;
+layout(local_size_y = 2) in; // ERROR, changing
+layout(local_size_y = 1) in;
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) out; // ERROR
int arrX[gl_WorkGroupSize.x];
diff --git a/Test/450.comp b/Test/450.comp
index fb2b56a..316674d 100644
--- a/Test/450.comp
+++ b/Test/450.comp
@@ -1,5 +1,8 @@
#version 450 core
layout(local_size_x = 0) in; // ERROR, 0 not allowed
+
+layout(binding=10000) uniform atomic_uint; // ERROR
+
void main()
{
shared float f; // ERROR shared must be global
diff --git a/Test/460.vert b/Test/460.vert
index fd87d8b..cf4f4ad 100644
--- a/Test/460.vert
+++ b/Test/460.vert
@@ -7,6 +7,7 @@
void main()
{
bool b1;
+ float array[int(mod(float (7.1), float (4.0)))];
b1 = anyInvocation(b1);
b1 = allInvocations(b1);
b1 = allInvocationsEqual(b1);
diff --git a/Test/atomic_uint.frag b/Test/atomic_uint.frag
index 9a95a48..4155214 100644
--- a/Test/atomic_uint.frag
+++ b/Test/atomic_uint.frag
@@ -1,6 +1,7 @@
#version 420 core
layout(binding = 0) uniform atomic_uint counter;
+layout(binding = 0, offset = 9) uniform atomic_uint counter;
uint func(atomic_uint c)
{
@@ -41,7 +42,7 @@
layout(binding=0, offset=32) uniform atomic_uint aOffset;
layout(binding=0, offset=4) uniform atomic_uint;
layout(binding=0) uniform atomic_uint bar3; // offset is 4
-layout(binding=0) uniform atomic_uint ac[3]; // offset = 8
+layout(binding=0) uniform atomic_uint ac[2]; // offset = 8
layout(binding=0) uniform atomic_uint ad; // offset = 20
layout(offset=8) uniform atomic_uint bar4; // ERROR, no binding
layout(binding = 0, offset = 12) uniform atomic_uint overlap; // ERROR, overlapping offsets
diff --git a/Test/baseLegalResults/hlsl.aliasOpaque.frag.out b/Test/baseLegalResults/hlsl.aliasOpaque.frag.out
index 2e58bdd..887e4ac 100644
--- a/Test/baseLegalResults/hlsl.aliasOpaque.frag.out
+++ b/Test/baseLegalResults/hlsl.aliasOpaque.frag.out
@@ -1,6 +1,6 @@
hlsl.aliasOpaque.frag
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 87
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.flattenOpaque.frag.out b/Test/baseLegalResults/hlsl.flattenOpaque.frag.out
index d334b7e..ad9e6c1 100644
--- a/Test/baseLegalResults/hlsl.flattenOpaque.frag.out
+++ b/Test/baseLegalResults/hlsl.flattenOpaque.frag.out
@@ -1,6 +1,6 @@
hlsl.flattenOpaque.frag
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 185
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out b/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
index 921cb96..6ed8da2 100644
--- a/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
+++ b/Test/baseLegalResults/hlsl.flattenOpaqueInit.vert.out
@@ -1,6 +1,6 @@
hlsl.flattenOpaqueInit.vert
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 134
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out b/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
index 39770f4..81ab5e6 100644
--- a/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
+++ b/Test/baseLegalResults/hlsl.flattenOpaqueInitMix.vert.out
@@ -1,6 +1,6 @@
hlsl.flattenOpaqueInitMix.vert
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 97
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.flattenSubset.frag.out b/Test/baseLegalResults/hlsl.flattenSubset.frag.out
index 4628479..562070d 100644
--- a/Test/baseLegalResults/hlsl.flattenSubset.frag.out
+++ b/Test/baseLegalResults/hlsl.flattenSubset.frag.out
@@ -1,6 +1,6 @@
hlsl.flattenSubset.frag
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 66
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.flattenSubset2.frag.out b/Test/baseLegalResults/hlsl.flattenSubset2.frag.out
index 0d7ab56..5cc280b 100644
--- a/Test/baseLegalResults/hlsl.flattenSubset2.frag.out
+++ b/Test/baseLegalResults/hlsl.flattenSubset2.frag.out
@@ -1,6 +1,6 @@
hlsl.flattenSubset2.frag
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 53
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out b/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out
index 27482b3..f4c9c5a 100644
--- a/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out
+++ b/Test/baseLegalResults/hlsl.partialFlattenLocal.vert.out
@@ -1,6 +1,6 @@
hlsl.partialFlattenLocal.vert
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 158
Capability Shader
diff --git a/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out b/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out
index e54fb7e..7be570b 100644
--- a/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out
+++ b/Test/baseLegalResults/hlsl.partialFlattenMixed.vert.out
@@ -1,6 +1,6 @@
hlsl.partialFlattenMixed.vert
// Module Version 10000
-// Generated by (magic number): 80007
+// Generated by (magic number): 80008
// Id's are bound by 36
Capability Shader
diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out
index 5e702e8..2ac6054 100644
--- a/Test/baseResults/100.frag.out
+++ b/Test/baseResults/100.frag.out
@@ -82,13 +82,19 @@
ERROR: 0:193: '.length' : not supported for this version or the enabled extensions
ERROR: 0:194: '.' : cannot apply to an array: method
ERROR: 0:194: 'a' : can't use function syntax on variable
-ERROR: 0:214: 'non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)' : not supported for this version or the enabled extensions
+ERROR: 0:207: 'gl_SecondaryFragColorEXT' : required extension not requested: GL_EXT_blend_func_extended
+ERROR: 0:208: 'gl_SecondaryFragDataEXT' : required extension not requested: GL_EXT_blend_func_extended
+ERROR: 0:208: 'gl_MaxDualSourceDrawBuffersEXT' : required extension not requested: GL_EXT_blend_func_extended
+ERROR: 0:227: 'non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)' : not supported for this version or the enabled extensions
+ERROR: 0:235: '#define' : names containing consecutive underscores are reserved, and an error if version < 300: A__B
+ERROR: 0:236: 'a__b' : identifiers containing consecutive underscores ("__") are reserved, and an error if version < 300
ERROR: 0:3000: '#error' : line of this error should be 3000
ERROR: 0:3002: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
-ERROR: 77 compilation errors. No code generated.
+ERROR: 82 compilation errors. No code generated.
Shader version: 100
+Requested GL_EXT_blend_func_extended
Requested GL_EXT_frag_depth
Requested GL_EXT_shader_non_constant_global_initializers
Requested GL_EXT_shader_texture_lod
@@ -359,36 +365,76 @@
0:201 Sequence
0:201 Branch: Return with expression
0:201 Function Call: fooinit( ( global mediump float)
-0:209 Function Definition: fooinit( ( global mediump float)
-0:209 Function Parameters:
-0:211 Sequence
-0:211 Branch: Return with expression
-0:211 Constant:
-0:211 12.000000
-0:214 Sequence
-0:214 move second child to first child ( temp mediump int)
-0:214 'init1' ( global mediump int)
-0:214 Test condition and select ( temp mediump int)
-0:214 Condition
-0:214 'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:214 true case
+0:205 Function Definition: blendFuncFail( ( global void)
+0:205 Function Parameters:
+0:207 Sequence
+0:207 move second child to first child ( temp mediump 4-component vector of float)
+0:207 'gl_SecondaryFragColorEXT' ( out mediump 4-component vector of float SecondaryFragColorEXT)
+0:207 Constant:
+0:207 1.000000
+0:207 1.000000
+0:207 1.000000
+0:207 1.000000
+0:208 move second child to first child ( temp mediump 4-component vector of float)
+0:208 direct index ( temp mediump 4-component vector of float SecondaryFragDataEXT)
+0:208 'gl_SecondaryFragDataEXT' ( out 1-element array of mediump 4-component vector of float SecondaryFragDataEXT)
+0:208 Constant:
+0:208 0 (const int)
+0:208 Constant:
+0:208 0.100000
+0:208 0.100000
+0:208 0.100000
+0:208 0.100000
+0:211 Function Definition: blendFunc( ( global void)
+0:211 Function Parameters:
+0:213 Sequence
+0:213 move second child to first child ( temp mediump 4-component vector of float)
+0:213 'gl_SecondaryFragColorEXT' ( out mediump 4-component vector of float SecondaryFragColorEXT)
+0:213 Constant:
+0:213 1.000000
+0:213 1.000000
+0:213 1.000000
+0:213 1.000000
+0:214 move second child to first child ( temp mediump 4-component vector of float)
+0:214 direct index ( temp mediump 4-component vector of float SecondaryFragDataEXT)
+0:214 'gl_SecondaryFragDataEXT' ( out 1-element array of mediump 4-component vector of float SecondaryFragDataEXT)
+0:214 Constant:
+0:214 0 (const int)
0:214 Constant:
-0:214 1 (const int)
-0:214 false case
-0:214 Constant:
-0:214 2 (const int)
-0:220 Sequence
-0:220 move second child to first child ( temp mediump int)
-0:220 'init2' ( global mediump int)
-0:220 Test condition and select ( temp mediump int)
-0:220 Condition
-0:220 'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:220 true case
-0:220 Constant:
-0:220 1 (const int)
-0:220 false case
-0:220 Constant:
-0:220 2 (const int)
+0:214 0.100000
+0:214 0.100000
+0:214 0.100000
+0:214 0.100000
+0:222 Function Definition: fooinit( ( global mediump float)
+0:222 Function Parameters:
+0:224 Sequence
+0:224 Branch: Return with expression
+0:224 Constant:
+0:224 12.000000
+0:227 Sequence
+0:227 move second child to first child ( temp mediump int)
+0:227 'init1' ( global mediump int)
+0:227 Test condition and select ( temp mediump int)
+0:227 Condition
+0:227 'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:227 true case
+0:227 Constant:
+0:227 1 (const int)
+0:227 false case
+0:227 Constant:
+0:227 2 (const int)
+0:233 Sequence
+0:233 move second child to first child ( temp mediump int)
+0:233 'init2' ( global mediump int)
+0:233 Test condition and select ( temp mediump int)
+0:233 Condition
+0:233 'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:233 true case
+0:233 Constant:
+0:233 1 (const int)
+0:233 false case
+0:233 Constant:
+0:233 2 (const int)
0:? Linker Objects
0:? 'a' ( global 3-element array of mediump int)
0:? 'uint' ( global mediump int)
@@ -421,12 +467,14 @@
0:? 5.000000
0:? 'init1' ( global mediump int)
0:? 'init2' ( global mediump int)
+0:? 'a__b' ( global mediump int)
Linked fragment stage:
Shader version: 100
+Requested GL_EXT_blend_func_extended
Requested GL_EXT_frag_depth
Requested GL_EXT_shader_non_constant_global_initializers
Requested GL_EXT_shader_texture_lod
@@ -517,30 +565,30 @@
0:152 'f124' ( global mediump float)
0:152 Constant:
0:152 50000000000.000000
-0:214 Sequence
-0:214 move second child to first child ( temp mediump int)
-0:214 'init1' ( global mediump int)
-0:214 Test condition and select ( temp mediump int)
-0:214 Condition
-0:214 'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:214 true case
-0:214 Constant:
-0:214 1 (const int)
-0:214 false case
-0:214 Constant:
-0:214 2 (const int)
-0:220 Sequence
-0:220 move second child to first child ( temp mediump int)
-0:220 'init2' ( global mediump int)
-0:220 Test condition and select ( temp mediump int)
-0:220 Condition
-0:220 'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:220 true case
-0:220 Constant:
-0:220 1 (const int)
-0:220 false case
-0:220 Constant:
-0:220 2 (const int)
+0:227 Sequence
+0:227 move second child to first child ( temp mediump int)
+0:227 'init1' ( global mediump int)
+0:227 Test condition and select ( temp mediump int)
+0:227 Condition
+0:227 'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:227 true case
+0:227 Constant:
+0:227 1 (const int)
+0:227 false case
+0:227 Constant:
+0:227 2 (const int)
+0:233 Sequence
+0:233 move second child to first child ( temp mediump int)
+0:233 'init2' ( global mediump int)
+0:233 Test condition and select ( temp mediump int)
+0:233 Condition
+0:233 'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:233 true case
+0:233 Constant:
+0:233 1 (const int)
+0:233 false case
+0:233 Constant:
+0:233 2 (const int)
0:? Linker Objects
0:? 'a' ( global 3-element array of mediump int)
0:? 'uint' ( global mediump int)
@@ -573,4 +621,5 @@
0:? 5.000000
0:? 'init1' ( global mediump int)
0:? 'init2' ( global mediump int)
+0:? 'a__b' ( global mediump int)
diff --git a/Test/baseResults/120.vert.out b/Test/baseResults/120.vert.out
index 5a91ed6..6c42b75 100644
--- a/Test/baseResults/120.vert.out
+++ b/Test/baseResults/120.vert.out
@@ -79,7 +79,8 @@
ERROR: 0:195: 'gl_ModelViewMatrix' : identifiers starting with "gl_" are reserved
ERROR: 0:200: 'token pasting (##)' : not supported for this version or the enabled extensions
ERROR: 0:203: 'token pasting (##)' : not supported for this version or the enabled extensions
-ERROR: 80 compilation errors. No code generated.
+ERROR: 0:205: '' : syntax error, unexpected IDENTIFIER
+ERROR: 81 compilation errors. No code generated.
Shader version: 120
diff --git a/Test/baseResults/130.frag.out b/Test/baseResults/130.frag.out
index 81d055b..6115f69 100644
--- a/Test/baseResults/130.frag.out
+++ b/Test/baseResults/130.frag.out
@@ -7,33 +7,38 @@
ERROR: 0:62: '<' : wrong operand types: no operation '<' exists that takes a left-hand operand of type ' temp 3-component vector of bool' and a right operand of type ' temp 3-component vector of bool' (or there is no acceptable conversion)
ERROR: 0:63: '>' : wrong operand types: no operation '>' exists that takes a left-hand operand of type ' temp 3-component vector of uint' and a right operand of type ' temp 3-component vector of uint' (or there is no acceptable conversion)
ERROR: 0:64: '>=' : wrong operand types: no operation '>=' exists that takes a left-hand operand of type ' const 2-component vector of uint' and a right operand of type ' const 2-component vector of uint' (or there is no acceptable conversion)
-ERROR: 0:80: 'textureGatherOffset' : no matching overloaded function found
-ERROR: 0:80: 'assign' : cannot convert from ' const float' to ' temp 4-component vector of float'
-ERROR: 0:81: 'textureGatherOffset(...)' : not supported for this version or the enabled extensions
-ERROR: 0:84: 'textureGatherOffset(...)' : not supported for this version or the enabled extensions
-ERROR: 0:85: 'textureGatherOffset(...)' : not supported for this version or the enabled extensions
-WARNING: 0:88: '#extension' : extension is only partially supported: GL_ARB_gpu_shader5
-ERROR: 0:120: 'line continuation' : not supported for this version or the enabled extensions
-ERROR: 0:126: 'uniform block' : not supported for this version or the enabled extensions
-ERROR: 0:140: 'length' : does not operate on this type: temp bool
-ERROR: 0:140: 'boolb' : can't use function syntax on variable
-ERROR: 0:141: 'length' : does not operate on this type: temp float
-ERROR: 0:141: '' : function call, method, or subroutine call expected
-ERROR: 0:141: '' : no matching overloaded function found
-ERROR: 0:142: 'length' : incomplete method syntax
-ERROR: 0:143: 'length' : method does not accept any arguments
-ERROR: 0:146: 'gl_FogFragCoord' : identifiers starting with "gl_" are reserved
-ERROR: 0:151: 'int' : must be qualified as flat in
-ERROR: 0:151: 'redeclaration' : cannot change the type of gl_FogFragCoord
-ERROR: 0:153: 'early_fragment_tests' : not supported for this version or the enabled extensions
-ERROR: 0:154: 'image load store' : not supported for this version or the enabled extensions
-ERROR: 0:154: 'iimage2D' : Reserved word.
-ERROR: 0:169: 'early_fragment_tests' : can only apply to 'in'
-ERROR: 28 compilation errors. No code generated.
+ERROR: 0:65: 'gl_NumSamples' : required extension not requested: GL_ARB_sample_shading
+ERROR: 0:82: 'textureGatherOffset' : no matching overloaded function found
+ERROR: 0:82: 'assign' : cannot convert from ' const float' to ' temp 4-component vector of float'
+ERROR: 0:83: 'textureGatherOffset(...)' : not supported for this version or the enabled extensions
+ERROR: 0:86: 'textureGatherOffset(...)' : not supported for this version or the enabled extensions
+ERROR: 0:87: 'textureGatherOffset(...)' : not supported for this version or the enabled extensions
+WARNING: 0:91: '#extension' : extension is only partially supported: GL_ARB_gpu_shader5
+ERROR: 0:123: 'line continuation' : not supported for this version or the enabled extensions
+ERROR: 0:129: 'uniform block' : not supported for this version or the enabled extensions
+ERROR: 0:143: 'length' : does not operate on this type: temp bool
+ERROR: 0:143: 'boolb' : can't use function syntax on variable
+ERROR: 0:144: 'length' : does not operate on this type: temp float
+ERROR: 0:144: '' : function call, method, or subroutine call expected
+ERROR: 0:144: '' : no matching overloaded function found
+ERROR: 0:145: 'length' : incomplete method syntax
+ERROR: 0:146: 'length' : method does not accept any arguments
+ERROR: 0:149: 'gl_FogFragCoord' : identifiers starting with "gl_" are reserved
+ERROR: 0:154: 'int' : must be qualified as flat in
+ERROR: 0:154: 'redeclaration' : cannot change the type of gl_FogFragCoord
+ERROR: 0:156: 'early_fragment_tests' : not supported for this version or the enabled extensions
+ERROR: 0:157: 'image load store' : not supported for this version or the enabled extensions
+ERROR: 0:157: 'iimage2D' : Reserved word.
+ERROR: 0:172: 'early_fragment_tests' : can only apply to 'in'
+ERROR: 0:176: 'location qualifier on uniform or buffer' : not supported for this version or the enabled extensions
+ERROR: 30 compilation errors. No code generated.
Shader version: 130
+Requested GL_ARB_explicit_attrib_location
+Requested GL_ARB_explicit_uniform_location
Requested GL_ARB_gpu_shader5
+Requested GL_ARB_sample_shading
Requested GL_ARB_separate_shader_objects
Requested GL_ARB_shader_image_load_store
Requested GL_ARB_shading_language_420pack
@@ -119,259 +124,267 @@
0:63 false (const bool)
0:64 Constant:
0:64 false (const bool)
-0:65 Constant:
-0:65 true (const bool)
+0:65 Sequence
+0:65 move second child to first child ( temp int)
+0:65 'samples' ( temp int)
+0:65 'gl_NumSamples' ( uniform int SampleMaskIn)
0:66 Constant:
-0:66 false (const bool)
-0:77 Function Definition: bar23( ( global void)
-0:77 Function Parameters:
+0:66 true (const bool)
+0:67 Constant:
+0:67 false (const bool)
+0:79 Function Definition: bar23( ( global void)
+0:79 Function Parameters:
0:? Sequence
-0:80 's' ( temp 4-component vector of float)
-0:81 move second child to first child ( temp 4-component vector of float)
-0:81 's' ( temp 4-component vector of float)
-0:81 textureGatherOffset ( global 4-component vector of float)
-0:81 'samp2DR' ( uniform sampler2DRect)
-0:81 Constant:
-0:81 0.300000
-0:81 0.300000
-0:81 Constant:
-0:81 1 (const int)
-0:81 1 (const int)
-0:82 move second child to first child ( temp 4-component vector of float)
-0:82 's' ( temp 4-component vector of float)
-0:82 textureGatherOffset ( global 4-component vector of float)
-0:82 'samp2D' ( uniform sampler2D)
-0:82 Constant:
-0:82 0.300000
-0:82 0.300000
-0:82 Constant:
-0:82 1 (const int)
-0:82 1 (const int)
+0:82 's' ( temp 4-component vector of float)
0:83 move second child to first child ( temp 4-component vector of float)
0:83 's' ( temp 4-component vector of float)
0:83 textureGatherOffset ( global 4-component vector of float)
-0:83 'samp2DA' ( uniform sampler2DArray)
+0:83 'samp2DR' ( uniform sampler2DRect)
0:83 Constant:
0:83 0.300000
0:83 0.300000
-0:83 0.300000
0:83 Constant:
0:83 1 (const int)
0:83 1 (const int)
0:84 move second child to first child ( temp 4-component vector of float)
0:84 's' ( temp 4-component vector of float)
0:84 textureGatherOffset ( global 4-component vector of float)
-0:84 'samp2DS' ( uniform sampler2DShadow)
+0:84 'samp2D' ( uniform sampler2D)
0:84 Constant:
0:84 0.300000
0:84 0.300000
0:84 Constant:
-0:84 1.300000
-0:84 Constant:
0:84 1 (const int)
0:84 1 (const int)
0:85 move second child to first child ( temp 4-component vector of float)
0:85 's' ( temp 4-component vector of float)
0:85 textureGatherOffset ( global 4-component vector of float)
-0:85 'samp2D' ( uniform sampler2D)
+0:85 'samp2DA' ( uniform sampler2DArray)
0:85 Constant:
0:85 0.300000
0:85 0.300000
+0:85 0.300000
0:85 Constant:
0:85 1 (const int)
0:85 1 (const int)
-0:85 Constant:
-0:85 2 (const int)
-0:90 Function Definition: bar234( ( global void)
-0:90 Function Parameters:
+0:86 move second child to first child ( temp 4-component vector of float)
+0:86 's' ( temp 4-component vector of float)
+0:86 textureGatherOffset ( global 4-component vector of float)
+0:86 'samp2DS' ( uniform sampler2DShadow)
+0:86 Constant:
+0:86 0.300000
+0:86 0.300000
+0:86 Constant:
+0:86 1.300000
+0:86 Constant:
+0:86 1 (const int)
+0:86 1 (const int)
+0:87 move second child to first child ( temp 4-component vector of float)
+0:87 's' ( temp 4-component vector of float)
+0:87 textureGatherOffset ( global 4-component vector of float)
+0:87 'samp2D' ( uniform sampler2D)
+0:87 Constant:
+0:87 0.300000
+0:87 0.300000
+0:87 Constant:
+0:87 1 (const int)
+0:87 1 (const int)
+0:87 Constant:
+0:87 2 (const int)
+0:88 Sequence
+0:88 move second child to first child ( temp int)
+0:88 'samples' ( temp int)
+0:88 'gl_NumSamples' ( uniform int SampleMaskIn)
+0:93 Function Definition: bar234( ( global void)
+0:93 Function Parameters:
0:? Sequence
-0:93 move second child to first child ( temp 4-component vector of float)
-0:93 's' ( temp 4-component vector of float)
-0:93 textureGatherOffset ( global 4-component vector of float)
-0:93 'samp2D' ( uniform sampler2D)
-0:93 Constant:
-0:93 0.300000
-0:93 0.300000
-0:93 Constant:
-0:93 1 (const int)
-0:93 1 (const int)
-0:94 move second child to first child ( temp 4-component vector of float)
-0:94 's' ( temp 4-component vector of float)
-0:94 textureGatherOffset ( global 4-component vector of float)
-0:94 'samp2DA' ( uniform sampler2DArray)
-0:94 Constant:
-0:94 0.300000
-0:94 0.300000
-0:94 0.300000
-0:94 Constant:
-0:94 1 (const int)
-0:94 1 (const int)
-0:95 move second child to first child ( temp 4-component vector of float)
-0:95 's' ( temp 4-component vector of float)
-0:95 textureGatherOffset ( global 4-component vector of float)
-0:95 'samp2DR' ( uniform sampler2DRect)
-0:95 Constant:
-0:95 0.300000
-0:95 0.300000
-0:95 Constant:
-0:95 1 (const int)
-0:95 1 (const int)
0:96 move second child to first child ( temp 4-component vector of float)
0:96 's' ( temp 4-component vector of float)
0:96 textureGatherOffset ( global 4-component vector of float)
-0:96 'samp2DS' ( uniform sampler2DShadow)
+0:96 'samp2D' ( uniform sampler2D)
0:96 Constant:
0:96 0.300000
0:96 0.300000
0:96 Constant:
-0:96 1.300000
-0:96 Constant:
0:96 1 (const int)
0:96 1 (const int)
0:97 move second child to first child ( temp 4-component vector of float)
0:97 's' ( temp 4-component vector of float)
0:97 textureGatherOffset ( global 4-component vector of float)
-0:97 'samp2D' ( uniform sampler2D)
+0:97 'samp2DA' ( uniform sampler2DArray)
0:97 Constant:
0:97 0.300000
0:97 0.300000
+0:97 0.300000
0:97 Constant:
0:97 1 (const int)
0:97 1 (const int)
-0:97 Constant:
-0:97 2 (const int)
-0:107 Function Definition: bar235( ( global void)
-0:107 Function Parameters:
-0:109 Sequence
-0:109 Sequence
-0:109 move second child to first child ( temp 3-component vector of int)
-0:109 'a' ( temp 3-component vector of int)
-0:109 textureSize ( global 3-component vector of int)
-0:109 'Sca' ( uniform samplerCubeArray)
-0:109 Constant:
-0:109 3 (const int)
-0:110 Sequence
-0:110 move second child to first child ( temp 4-component vector of float)
-0:110 'b' ( temp 4-component vector of float)
-0:110 texture ( global 4-component vector of float)
-0:110 'Sca' ( uniform samplerCubeArray)
-0:110 'i' ( smooth in 4-component vector of float)
-0:111 Sequence
-0:111 move second child to first child ( temp 4-component vector of int)
-0:111 'c' ( temp 4-component vector of int)
-0:111 texture ( global 4-component vector of int)
-0:111 'Isca' ( uniform isamplerCubeArray)
-0:111 'i' ( smooth in 4-component vector of float)
-0:111 Constant:
-0:111 0.700000
+0:98 move second child to first child ( temp 4-component vector of float)
+0:98 's' ( temp 4-component vector of float)
+0:98 textureGatherOffset ( global 4-component vector of float)
+0:98 'samp2DR' ( uniform sampler2DRect)
+0:98 Constant:
+0:98 0.300000
+0:98 0.300000
+0:98 Constant:
+0:98 1 (const int)
+0:98 1 (const int)
+0:99 move second child to first child ( temp 4-component vector of float)
+0:99 's' ( temp 4-component vector of float)
+0:99 textureGatherOffset ( global 4-component vector of float)
+0:99 'samp2DS' ( uniform sampler2DShadow)
+0:99 Constant:
+0:99 0.300000
+0:99 0.300000
+0:99 Constant:
+0:99 1.300000
+0:99 Constant:
+0:99 1 (const int)
+0:99 1 (const int)
+0:100 move second child to first child ( temp 4-component vector of float)
+0:100 's' ( temp 4-component vector of float)
+0:100 textureGatherOffset ( global 4-component vector of float)
+0:100 'samp2D' ( uniform sampler2D)
+0:100 Constant:
+0:100 0.300000
+0:100 0.300000
+0:100 Constant:
+0:100 1 (const int)
+0:100 1 (const int)
+0:100 Constant:
+0:100 2 (const int)
+0:110 Function Definition: bar235( ( global void)
+0:110 Function Parameters:
+0:112 Sequence
0:112 Sequence
-0:112 move second child to first child ( temp 4-component vector of uint)
-0:112 'd' ( temp 4-component vector of uint)
-0:112 texture ( global 4-component vector of uint)
-0:112 'Usca' ( uniform usamplerCubeArray)
-0:112 'i' ( smooth in 4-component vector of float)
-0:114 move second child to first child ( temp 4-component vector of float)
-0:114 'b' ( temp 4-component vector of float)
-0:114 textureLod ( global 4-component vector of float)
-0:114 'Sca' ( uniform samplerCubeArray)
-0:114 'i' ( smooth in 4-component vector of float)
-0:114 Constant:
-0:114 1.700000
-0:115 move second child to first child ( temp 3-component vector of int)
-0:115 'a' ( temp 3-component vector of int)
-0:115 textureSize ( global 3-component vector of int)
-0:115 'Scas' ( uniform samplerCubeArrayShadow)
-0:115 direct index ( temp int)
-0:115 'a' ( temp 3-component vector of int)
-0:115 Constant:
-0:115 0 (const int)
-0:116 Sequence
-0:116 move second child to first child ( temp float)
-0:116 'f' ( temp float)
-0:116 texture ( global float)
-0:116 'Scas' ( uniform samplerCubeArrayShadow)
-0:116 'i' ( smooth in 4-component vector of float)
-0:116 direct index ( temp float)
-0:116 'b' ( temp 4-component vector of float)
-0:116 Constant:
-0:116 1 (const int)
-0:117 move second child to first child ( temp 4-component vector of int)
-0:117 'c' ( temp 4-component vector of int)
-0:117 textureGrad ( global 4-component vector of int)
-0:117 'Isca' ( uniform isamplerCubeArray)
+0:112 move second child to first child ( temp 3-component vector of int)
+0:112 'a' ( temp 3-component vector of int)
+0:112 textureSize ( global 3-component vector of int)
+0:112 'Sca' ( uniform samplerCubeArray)
+0:112 Constant:
+0:112 3 (const int)
+0:113 Sequence
+0:113 move second child to first child ( temp 4-component vector of float)
+0:113 'b' ( temp 4-component vector of float)
+0:113 texture ( global 4-component vector of float)
+0:113 'Sca' ( uniform samplerCubeArray)
+0:113 'i' ( smooth in 4-component vector of float)
+0:114 Sequence
+0:114 move second child to first child ( temp 4-component vector of int)
+0:114 'c' ( temp 4-component vector of int)
+0:114 texture ( global 4-component vector of int)
+0:114 'Isca' ( uniform isamplerCubeArray)
+0:114 'i' ( smooth in 4-component vector of float)
+0:114 Constant:
+0:114 0.700000
+0:115 Sequence
+0:115 move second child to first child ( temp 4-component vector of uint)
+0:115 'd' ( temp 4-component vector of uint)
+0:115 texture ( global 4-component vector of uint)
+0:115 'Usca' ( uniform usamplerCubeArray)
+0:115 'i' ( smooth in 4-component vector of float)
+0:117 move second child to first child ( temp 4-component vector of float)
+0:117 'b' ( temp 4-component vector of float)
+0:117 textureLod ( global 4-component vector of float)
+0:117 'Sca' ( uniform samplerCubeArray)
0:117 'i' ( smooth in 4-component vector of float)
0:117 Constant:
-0:117 0.100000
-0:117 0.100000
-0:117 0.100000
-0:117 Constant:
-0:117 0.200000
-0:117 0.200000
-0:117 0.200000
-0:129 Function Definition: bar23444( ( global void)
-0:129 Function Parameters:
+0:117 1.700000
+0:118 move second child to first child ( temp 3-component vector of int)
+0:118 'a' ( temp 3-component vector of int)
+0:118 textureSize ( global 3-component vector of int)
+0:118 'Scas' ( uniform samplerCubeArrayShadow)
+0:118 direct index ( temp int)
+0:118 'a' ( temp 3-component vector of int)
+0:118 Constant:
+0:118 0 (const int)
+0:119 Sequence
+0:119 move second child to first child ( temp float)
+0:119 'f' ( temp float)
+0:119 texture ( global float)
+0:119 'Scas' ( uniform samplerCubeArrayShadow)
+0:119 'i' ( smooth in 4-component vector of float)
+0:119 direct index ( temp float)
+0:119 'b' ( temp 4-component vector of float)
+0:119 Constant:
+0:119 1 (const int)
+0:120 move second child to first child ( temp 4-component vector of int)
+0:120 'c' ( temp 4-component vector of int)
+0:120 textureGrad ( global 4-component vector of int)
+0:120 'Isca' ( uniform isamplerCubeArray)
+0:120 'i' ( smooth in 4-component vector of float)
+0:120 Constant:
+0:120 0.100000
+0:120 0.100000
+0:120 0.100000
+0:120 Constant:
+0:120 0.200000
+0:120 0.200000
+0:120 0.200000
+0:132 Function Definition: bar23444( ( global void)
+0:132 Function Parameters:
0:? Sequence
-0:132 Sequence
-0:132 move second child to first child ( temp float)
-0:132 'a1' ( temp float)
-0:132 direct index ( temp float)
-0:132 direct index ( temp 3-component vector of float)
-0:132 'm43' ( temp 4X3 matrix of float)
-0:132 Constant:
-0:132 3 (const int)
-0:132 Constant:
-0:132 1 (const int)
-0:134 Sequence
-0:134 move second child to first child ( temp int)
-0:134 'a2' ( temp int)
-0:134 Constant:
-0:134 4 (const int)
-0:135 add second child into first child ( temp int)
-0:135 'a2' ( temp int)
-0:135 Constant:
-0:135 3 (const int)
-0:136 add second child into first child ( temp int)
-0:136 'a2' ( temp int)
-0:136 Constant:
-0:136 3 (const int)
+0:135 Sequence
+0:135 move second child to first child ( temp float)
+0:135 'a1' ( temp float)
+0:135 direct index ( temp float)
+0:135 direct index ( temp 3-component vector of float)
+0:135 'm43' ( temp 4X3 matrix of float)
+0:135 Constant:
+0:135 3 (const int)
+0:135 Constant:
+0:135 1 (const int)
0:137 Sequence
-0:137 move second child to first child ( temp float)
-0:137 'b' ( const (read only) float)
-0:137 component-wise multiply ( temp float)
-0:137 Constant:
-0:137 2.000000
-0:137 'a1' ( temp float)
-0:138 move second child to first child ( temp float)
-0:138 direct index ( temp float)
-0:138 'a' ( global 3-component vector of float)
-0:138 Constant:
-0:138 0 (const int)
+0:137 move second child to first child ( temp int)
+0:137 'a2' ( temp int)
+0:137 Constant:
+0:137 4 (const int)
+0:138 add second child into first child ( temp int)
+0:138 'a2' ( temp int)
0:138 Constant:
-0:138 -1.000000
-0:140 Constant:
-0:140 0.000000
-0:141 Constant:
-0:141 0.000000
+0:138 3 (const int)
+0:139 add second child into first child ( temp int)
+0:139 'a2' ( temp int)
+0:139 Constant:
+0:139 3 (const int)
+0:140 Sequence
+0:140 move second child to first child ( temp float)
+0:140 'b' ( const (read only) float)
+0:140 component-wise multiply ( temp float)
+0:140 Constant:
+0:140 2.000000
+0:140 'a1' ( temp float)
+0:141 move second child to first child ( temp float)
+0:141 direct index ( temp float)
+0:141 'a' ( global 3-component vector of float)
+0:141 Constant:
+0:141 0 (const int)
+0:141 Constant:
+0:141 -1.000000
0:143 Constant:
-0:143 1 (const int)
-0:162 Function Definition: qux2( ( global void)
-0:162 Function Parameters:
+0:143 0.000000
+0:144 Constant:
+0:144 0.000000
+0:146 Constant:
+0:146 1 (const int)
+0:165 Function Definition: qux2( ( global void)
+0:165 Function Parameters:
0:? Sequence
-0:165 imageAtomicCompSwap ( global int)
-0:165 'iimg2D' (layout( r32i) uniform iimage2D)
-0:165 Construct ivec2 ( temp 2-component vector of int)
-0:165 'i' ( temp int)
-0:165 'i' ( temp int)
-0:165 'i' ( temp int)
-0:165 'i' ( temp int)
-0:166 Sequence
-0:166 move second child to first child ( temp 4-component vector of int)
-0:166 'pos' ( temp 4-component vector of int)
-0:166 imageLoad ( global 4-component vector of int)
-0:166 'iimg2D' (layout( r32i) uniform iimage2D)
-0:166 Construct ivec2 ( temp 2-component vector of int)
-0:166 'i' ( temp int)
-0:166 'i' ( temp int)
+0:168 imageAtomicCompSwap ( global int)
+0:168 'iimg2D' (layout( r32i) uniform iimage2D)
+0:168 Construct ivec2 ( temp 2-component vector of int)
+0:168 'i' ( temp int)
+0:168 'i' ( temp int)
+0:168 'i' ( temp int)
+0:168 'i' ( temp int)
+0:169 Sequence
+0:169 move second child to first child ( temp 4-component vector of int)
+0:169 'pos' ( temp 4-component vector of int)
+0:169 imageLoad ( global 4-component vector of int)
+0:169 'iimg2D' (layout( r32i) uniform iimage2D)
+0:169 Construct ivec2 ( temp 2-component vector of int)
+0:169 'i' ( temp int)
+0:169 'i' ( temp int)
0:? Linker Objects
0:? 'a' ( global 3-component vector of float)
0:? 'b' ( global float)
@@ -402,13 +415,18 @@
0:? 'gl_FogFragCoord' ( smooth in float)
0:? 'iimg2Dbad' (layout( r32i) uniform iimage2D)
0:? 'iimg2D' (layout( r32i) uniform iimage2D)
+0:? 'ucolor0' (layout( location=3) uniform 4-component vector of float)
+0:? 'ucolor1' (layout( location=4) uniform 4-component vector of float)
Linked fragment stage:
Shader version: 130
+Requested GL_ARB_explicit_attrib_location
+Requested GL_ARB_explicit_uniform_location
Requested GL_ARB_gpu_shader5
+Requested GL_ARB_sample_shading
Requested GL_ARB_separate_shader_objects
Requested GL_ARB_shader_image_load_store
Requested GL_ARB_shading_language_420pack
@@ -457,4 +475,6 @@
0:? 'gl_FogFragCoord' ( smooth in float)
0:? 'iimg2Dbad' (layout( r32i) uniform iimage2D)
0:? 'iimg2D' (layout( r32i) uniform iimage2D)
+0:? 'ucolor0' (layout( location=3) uniform 4-component vector of float)
+0:? 'ucolor1' (layout( location=4) uniform 4-component vector of float)
diff --git a/Test/baseResults/140.frag.out b/Test/baseResults/140.frag.out
index 7ce2170..702718a 100644
--- a/Test/baseResults/140.frag.out
+++ b/Test/baseResults/140.frag.out
@@ -1,14 +1,15 @@
140.frag
WARNING: 0:3: varying deprecated in version 130; may be removed in future release
ERROR: 0:17: '#error' : GL_ES is not set
-ERROR: 0:20: 'fragment-shader struct input' : not supported for this version or the enabled extensions
-ERROR: 0:24: 'location' : not supported for this version or the enabled extensions
-ERROR: 0:24: 'location qualifier on input' : not supported for this version or the enabled extensions
-ERROR: 0:26: 'location' : not supported for this version or the enabled extensions
-ERROR: 0:26: 'location qualifier on output' : not supported for this version or the enabled extensions
-ERROR: 0:40: 'assign' : l-value required "v" (can't modify shader input)
-ERROR: 0:40: 'out' : Non-L-value cannot be passed for 'out' or 'inout' parameters.
-ERROR: 8 compilation errors. No code generated.
+ERROR: 0:21: 'fragment-shader struct input' : not supported for this version or the enabled extensions
+ERROR: 0:25: 'location' : not supported for this version or the enabled extensions
+ERROR: 0:25: 'location qualifier on input' : not supported for this version or the enabled extensions
+ERROR: 0:27: 'location' : not supported for this version or the enabled extensions
+ERROR: 0:27: 'location qualifier on output' : not supported for this version or the enabled extensions
+ERROR: 0:41: 'assign' : l-value required "v" (can't modify shader input)
+ERROR: 0:41: 'out' : Non-L-value cannot be passed for 'out' or 'inout' parameters.
+ERROR: 0:56: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
+ERROR: 9 compilation errors. No code generated.
Shader version: 140
@@ -25,80 +26,80 @@
0:12 'gl_ClipDistance' ( smooth in 5-element array of float ClipDistance)
0:12 Constant:
0:12 2 (const int)
-0:22 Sequence
-0:22 move second child to first child ( temp float)
-0:22 'patch' ( global float)
-0:22 Constant:
-0:22 3.100000
-0:38 Function Definition: foo( ( global void)
-0:38 Function Parameters:
-0:40 Sequence
-0:40 Sequence
-0:40 move second child to first child ( temp 2-component vector of float)
-0:40 'r1' ( temp 2-component vector of float)
-0:40 modf ( global 2-component vector of float)
-0:40 vector swizzle ( temp 2-component vector of float)
-0:40 'v' ( smooth in 4-component vector of float)
-0:40 Sequence
-0:40 Constant:
-0:40 0 (const int)
-0:40 Constant:
-0:40 1 (const int)
-0:40 vector swizzle ( temp 2-component vector of float)
-0:40 'v' ( smooth in 4-component vector of float)
-0:40 Sequence
-0:40 Constant:
-0:40 2 (const int)
-0:40 Constant:
-0:40 3 (const int)
+0:23 Sequence
+0:23 move second child to first child ( temp float)
+0:23 'patch' ( global float)
+0:23 Constant:
+0:23 3.100000
+0:39 Function Definition: foo( ( global void)
+0:39 Function Parameters:
+0:41 Sequence
0:41 Sequence
0:41 move second child to first child ( temp 2-component vector of float)
-0:41 'r2' ( temp 2-component vector of float)
+0:41 'r1' ( temp 2-component vector of float)
0:41 modf ( global 2-component vector of float)
0:41 vector swizzle ( temp 2-component vector of float)
-0:41 'o' ( out 4-component vector of float)
+0:41 'v' ( smooth in 4-component vector of float)
0:41 Sequence
0:41 Constant:
0:41 0 (const int)
0:41 Constant:
0:41 1 (const int)
0:41 vector swizzle ( temp 2-component vector of float)
-0:41 'o' ( out 4-component vector of float)
+0:41 'v' ( smooth in 4-component vector of float)
0:41 Sequence
0:41 Constant:
0:41 2 (const int)
0:41 Constant:
0:41 3 (const int)
-0:42 move second child to first child ( temp float)
-0:42 direct index ( temp float)
-0:42 'o' ( out 4-component vector of float)
-0:42 Constant:
-0:42 2 (const int)
-0:42 Function Call: fooi( ( global float)
-0:47 Sequence
-0:47 move second child to first child ( temp float)
-0:47 'i1' ( global float)
-0:47 Test condition and select ( temp float)
-0:47 Condition
-0:47 'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:47 true case
-0:47 Constant:
-0:47 -2.000000
-0:47 false case
-0:47 Constant:
-0:47 2.000000
+0:42 Sequence
+0:42 move second child to first child ( temp 2-component vector of float)
+0:42 'r2' ( temp 2-component vector of float)
+0:42 modf ( global 2-component vector of float)
+0:42 vector swizzle ( temp 2-component vector of float)
+0:42 'o' ( out 4-component vector of float)
+0:42 Sequence
+0:42 Constant:
+0:42 0 (const int)
+0:42 Constant:
+0:42 1 (const int)
+0:42 vector swizzle ( temp 2-component vector of float)
+0:42 'o' ( out 4-component vector of float)
+0:42 Sequence
+0:42 Constant:
+0:42 2 (const int)
+0:42 Constant:
+0:42 3 (const int)
+0:43 move second child to first child ( temp float)
+0:43 direct index ( temp float)
+0:43 'o' ( out 4-component vector of float)
+0:43 Constant:
+0:43 2 (const int)
+0:43 Function Call: fooi( ( global float)
0:48 Sequence
0:48 move second child to first child ( temp float)
-0:48 'i2' ( global float)
-0:48 Constant:
-0:48 102.000000
-0:50 Function Definition: fooi( ( global float)
-0:50 Function Parameters:
-0:52 Sequence
-0:52 Branch: Return with expression
-0:52 add ( temp float)
-0:52 'i1' ( global float)
-0:52 'i2' ( global float)
+0:48 'i1' ( global float)
+0:48 Test condition and select ( temp float)
+0:48 Condition
+0:48 'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:48 true case
+0:48 Constant:
+0:48 -2.000000
+0:48 false case
+0:48 Constant:
+0:48 2.000000
+0:49 Sequence
+0:49 move second child to first child ( temp float)
+0:49 'i2' ( global float)
+0:49 Constant:
+0:49 102.000000
+0:51 Function Definition: fooi( ( global float)
+0:51 Function Parameters:
+0:53 Sequence
+0:53 Branch: Return with expression
+0:53 add ( temp float)
+0:53 'i1' ( global float)
+0:53 'i2' ( global float)
0:? Linker Objects
0:? 'v' ( smooth in 4-component vector of float)
0:? 'i' ( smooth in 4-component vector of float)
@@ -131,28 +132,28 @@
0:12 'gl_ClipDistance' ( smooth in 5-element array of float ClipDistance)
0:12 Constant:
0:12 2 (const int)
-0:22 Sequence
-0:22 move second child to first child ( temp float)
-0:22 'patch' ( global float)
-0:22 Constant:
-0:22 3.100000
-0:47 Sequence
-0:47 move second child to first child ( temp float)
-0:47 'i1' ( global float)
-0:47 Test condition and select ( temp float)
-0:47 Condition
-0:47 'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:47 true case
-0:47 Constant:
-0:47 -2.000000
-0:47 false case
-0:47 Constant:
-0:47 2.000000
+0:23 Sequence
+0:23 move second child to first child ( temp float)
+0:23 'patch' ( global float)
+0:23 Constant:
+0:23 3.100000
0:48 Sequence
0:48 move second child to first child ( temp float)
-0:48 'i2' ( global float)
-0:48 Constant:
-0:48 102.000000
+0:48 'i1' ( global float)
+0:48 Test condition and select ( temp float)
+0:48 Condition
+0:48 'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:48 true case
+0:48 Constant:
+0:48 -2.000000
+0:48 false case
+0:48 Constant:
+0:48 2.000000
+0:49 Sequence
+0:49 move second child to first child ( temp float)
+0:49 'i2' ( global float)
+0:49 Constant:
+0:49 102.000000
0:? Linker Objects
0:? 'v' ( smooth in 4-component vector of float)
0:? 'i' ( smooth in 4-component vector of float)
diff --git a/Test/baseResults/150.frag.out b/Test/baseResults/150.frag.out
index 1454b55..7672b58 100644
--- a/Test/baseResults/150.frag.out
+++ b/Test/baseResults/150.frag.out
@@ -3,10 +3,30 @@
ERROR: 0:5: 'redeclaration' : cannot redeclare with different qualification: gl_FragCoord
ERROR: 0:6: 'layout qualifier' : can only apply origin_upper_left and pixel_center_origin to gl_FragCoord
ERROR: 0:14: 'gl_FragCoord' : cannot redeclare after use
-ERROR: 4 compilation errors. No code generated.
+ERROR: 0:50: 'gl_PerFragment' : cannot be used (maybe an instance name is needed)
+ERROR: 0:50: 'gl_PerFragment' : undeclared identifier
+ERROR: 0:53: 'double' : Reserved word.
+ERROR: 0:53: 'double' : not supported for this version or the enabled extensions
+ERROR: 0:53: 'double' : must be qualified as flat in
+ERROR: 0:57: '=' : cannot convert from ' global double' to ' global int'
+ERROR: 0:80: 'floatBitsToInt' : required extension not requested: GL_ARB_shader_bit_encoding
+ERROR: 0:100: 'packSnorm2x16' : required extension not requested: GL_ARB_shading_language_packing
+ERROR: 0:114: 'textureQueryLod' : required extension not requested: GL_ARB_texture_query_lod
+ERROR: 0:115: 'textureQueryLod' : required extension not requested: GL_ARB_texture_query_lod
+ERROR: 0:154: 'textureQueryLod' : no matching overloaded function found
+ERROR: 0:154: 'assign' : cannot convert from ' const float' to ' temp 2-component vector of float'
+ERROR: 0:155: 'textureQueryLod' : no matching overloaded function found
+ERROR: 0:155: 'assign' : cannot convert from ' const float' to ' temp 2-component vector of float'
+ERROR: 0:183: 'mix' : required extension not requested: GL_EXT_shader_integer_mix
+ERROR: 19 compilation errors. No code generated.
Shader version: 150
+Requested GL_ARB_gpu_shader_fp64
+Requested GL_ARB_shader_bit_encoding
+Requested GL_ARB_shading_language_packing
+Requested GL_ARB_texture_query_lod
+Requested GL_EXT_shader_integer_mix
gl_FragCoord pixel center is integer
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
@@ -106,6 +126,296 @@
0:49 Sequence
0:49 Branch: Return with expression
0:49 'gl_PrimitiveID' ( flat in int PrimitiveID)
+0:50 'gl_PerFragment' ( temp float)
+0:56 Sequence
+0:56 move second child to first child ( temp double)
+0:56 'type3' ( global double)
+0:56 Constant:
+0:56 2.000000
+0:58 Sequence
+0:58 move second child to first child ( temp double)
+0:58 'absTest2' ( global double)
+0:58 sqrt ( global double)
+0:58 'type3' ( global double)
+0:59 Sequence
+0:59 move second child to first child ( temp double)
+0:59 'absTest3' ( global double)
+0:59 Constant:
+0:59 1.414214
+0:60 Sequence
+0:60 move second child to first child ( temp float)
+0:60 'dk' ( global float)
+0:60 Constant:
+0:60 3.316625
+0:68 Function Definition: bitEncodingPass( ( global void)
+0:68 Function Parameters:
+0:70 Sequence
+0:70 Sequence
+0:70 move second child to first child ( temp int)
+0:70 'i' ( temp int)
+0:70 floatBitsToInt ( global int)
+0:70 'f' ( global float)
+0:71 Sequence
+0:71 move second child to first child ( temp 4-component vector of uint)
+0:71 'uv11' ( temp 4-component vector of uint)
+0:71 floatBitsToUint ( global 4-component vector of uint)
+0:71 'v4' ( global 4-component vector of float)
+0:72 Sequence
+0:72 move second child to first child ( temp 4-component vector of float)
+0:72 'v14' ( temp 4-component vector of float)
+0:72 intBitsToFloat ( global 4-component vector of float)
+0:72 'iv4a' ( global 4-component vector of int)
+0:73 Sequence
+0:73 move second child to first child ( temp 2-component vector of float)
+0:73 'v15' ( temp 2-component vector of float)
+0:73 uintBitsToFloat ( global 2-component vector of float)
+0:73 'uv2c' ( global 2-component vector of uint)
+0:78 Function Definition: bitEncodingFail( ( global void)
+0:78 Function Parameters:
+0:80 Sequence
+0:80 Sequence
+0:80 move second child to first child ( temp int)
+0:80 'i' ( temp int)
+0:80 floatBitsToInt ( global int)
+0:80 'f' ( global float)
+0:87 Function Definition: packingPass( ( global void)
+0:87 Function Parameters:
+0:89 Sequence
+0:89 Sequence
+0:89 move second child to first child ( temp uint)
+0:89 'u19' ( temp uint)
+0:89 packSnorm2x16 ( global uint)
+0:89 'v2a' ( global 2-component vector of float)
+0:90 Sequence
+0:90 move second child to first child ( temp 2-component vector of float)
+0:90 'v20' ( temp 2-component vector of float)
+0:90 unpackSnorm2x16 ( global 2-component vector of float)
+0:90 'uy' ( global uint)
+0:91 Sequence
+0:91 move second child to first child ( temp uint)
+0:91 'u15' ( temp uint)
+0:91 packUnorm2x16 ( global uint)
+0:91 'v2a' ( global 2-component vector of float)
+0:92 Sequence
+0:92 move second child to first child ( temp 2-component vector of float)
+0:92 'v16' ( temp 2-component vector of float)
+0:92 unpackUnorm2x16 ( global 2-component vector of float)
+0:92 'uy' ( global uint)
+0:93 Sequence
+0:93 move second child to first child ( temp uint)
+0:93 'u17' ( temp uint)
+0:93 packHalf2x16 ( global uint)
+0:93 'v2a' ( global 2-component vector of float)
+0:94 Sequence
+0:94 move second child to first child ( temp 2-component vector of float)
+0:94 'v18' ( temp 2-component vector of float)
+0:94 unpackHalf2x16 ( global 2-component vector of float)
+0:94 'uy' ( global uint)
+0:98 Function Definition: packingFail( ( global void)
+0:98 Function Parameters:
+0:100 Sequence
+0:100 Sequence
+0:100 move second child to first child ( temp uint)
+0:100 'u19' ( temp uint)
+0:100 packSnorm2x16 ( global uint)
+0:100 'v2a' ( global 2-component vector of float)
+0:107 Function Definition: qlodFail( ( global void)
+0:107 Function Parameters:
+0:? Sequence
+0:114 move second child to first child ( temp 2-component vector of float)
+0:114 'lod' ( temp 2-component vector of float)
+0:114 textureQueryLod ( global 2-component vector of float)
+0:114 'samp1D' ( uniform sampler1D)
+0:114 'pf' ( temp float)
+0:115 move second child to first child ( temp 2-component vector of float)
+0:115 'lod' ( temp 2-component vector of float)
+0:115 textureQueryLod ( global 2-component vector of float)
+0:115 'samp2Ds' ( uniform sampler2DShadow)
+0:115 'pf2' ( temp 2-component vector of float)
+0:134 Function Definition: qlodPass( ( global void)
+0:134 Function Parameters:
+0:? Sequence
+0:141 move second child to first child ( temp 2-component vector of float)
+0:141 'lod' ( temp 2-component vector of float)
+0:141 textureQueryLod ( global 2-component vector of float)
+0:141 'samp1D' ( uniform sampler1D)
+0:141 'pf' ( temp float)
+0:142 move second child to first child ( temp 2-component vector of float)
+0:142 'lod' ( temp 2-component vector of float)
+0:142 textureQueryLod ( global 2-component vector of float)
+0:142 'isamp2D' ( uniform isampler2D)
+0:142 'pf2' ( temp 2-component vector of float)
+0:143 move second child to first child ( temp 2-component vector of float)
+0:143 'lod' ( temp 2-component vector of float)
+0:143 textureQueryLod ( global 2-component vector of float)
+0:143 'usamp3D' ( uniform usampler3D)
+0:143 'pf3' ( temp 3-component vector of float)
+0:144 move second child to first child ( temp 2-component vector of float)
+0:144 'lod' ( temp 2-component vector of float)
+0:144 textureQueryLod ( global 2-component vector of float)
+0:144 'sampCube' ( uniform samplerCube)
+0:144 'pf3' ( temp 3-component vector of float)
+0:145 move second child to first child ( temp 2-component vector of float)
+0:145 'lod' ( temp 2-component vector of float)
+0:145 textureQueryLod ( global 2-component vector of float)
+0:145 'isamp1DA' ( uniform isampler1DArray)
+0:145 'pf' ( temp float)
+0:146 move second child to first child ( temp 2-component vector of float)
+0:146 'lod' ( temp 2-component vector of float)
+0:146 textureQueryLod ( global 2-component vector of float)
+0:146 'usamp2DA' ( uniform usampler2DArray)
+0:146 'pf2' ( temp 2-component vector of float)
+0:148 move second child to first child ( temp 2-component vector of float)
+0:148 'lod' ( temp 2-component vector of float)
+0:148 textureQueryLod ( global 2-component vector of float)
+0:148 'samp1Ds' ( uniform sampler1DShadow)
+0:148 'pf' ( temp float)
+0:149 move second child to first child ( temp 2-component vector of float)
+0:149 'lod' ( temp 2-component vector of float)
+0:149 textureQueryLod ( global 2-component vector of float)
+0:149 'samp2Ds' ( uniform sampler2DShadow)
+0:149 'pf2' ( temp 2-component vector of float)
+0:150 move second child to first child ( temp 2-component vector of float)
+0:150 'lod' ( temp 2-component vector of float)
+0:150 textureQueryLod ( global 2-component vector of float)
+0:150 'sampCubes' ( uniform samplerCubeShadow)
+0:150 'pf3' ( temp 3-component vector of float)
+0:151 move second child to first child ( temp 2-component vector of float)
+0:151 'lod' ( temp 2-component vector of float)
+0:151 textureQueryLod ( global 2-component vector of float)
+0:151 'samp1DAs' ( uniform sampler1DArrayShadow)
+0:151 'pf' ( temp float)
+0:152 move second child to first child ( temp 2-component vector of float)
+0:152 'lod' ( temp 2-component vector of float)
+0:152 textureQueryLod ( global 2-component vector of float)
+0:152 'samp2DAs' ( uniform sampler2DArrayShadow)
+0:152 'pf2' ( temp 2-component vector of float)
+0:154 'lod' ( temp 2-component vector of float)
+0:155 'lod' ( temp 2-component vector of float)
+0:164 Function Definition: testmix( ( global void)
+0:164 Function Parameters:
+0:166 Sequence
+0:166 Sequence
+0:166 move second child to first child ( temp int)
+0:166 'ival' ( temp int)
+0:166 mix ( global int)
+0:166 'x' ( global int)
+0:166 'y' ( global int)
+0:166 'b' ( global bool)
+0:167 Sequence
+0:167 move second child to first child ( temp 2-component vector of int)
+0:167 'iv2' ( temp 2-component vector of int)
+0:167 mix ( global 2-component vector of int)
+0:167 Construct ivec2 ( temp 2-component vector of int)
+0:167 'x' ( global int)
+0:167 Construct ivec2 ( temp 2-component vector of int)
+0:167 'y' ( global int)
+0:167 Construct bvec2 ( temp 2-component vector of bool)
+0:167 'b' ( global bool)
+0:168 Sequence
+0:168 move second child to first child ( temp 3-component vector of int)
+0:168 'iv3' ( temp 3-component vector of int)
+0:168 mix ( global 3-component vector of int)
+0:168 Construct ivec3 ( temp 3-component vector of int)
+0:168 'x' ( global int)
+0:168 Construct ivec3 ( temp 3-component vector of int)
+0:168 'y' ( global int)
+0:168 Construct bvec3 ( temp 3-component vector of bool)
+0:168 'b' ( global bool)
+0:169 Sequence
+0:169 move second child to first child ( temp 4-component vector of int)
+0:169 'iv4' ( temp 4-component vector of int)
+0:169 mix ( global 4-component vector of int)
+0:169 Construct ivec4 ( temp 4-component vector of int)
+0:169 'x' ( global int)
+0:169 Construct ivec4 ( temp 4-component vector of int)
+0:169 'x' ( global int)
+0:169 Construct bvec4 ( temp 4-component vector of bool)
+0:169 'b' ( global bool)
+0:170 Sequence
+0:170 move second child to first child ( temp uint)
+0:170 'uiv' ( temp uint)
+0:170 mix ( global uint)
+0:170 'z' ( global uint)
+0:170 'w' ( global uint)
+0:170 'b' ( global bool)
+0:171 Sequence
+0:171 move second child to first child ( temp 2-component vector of uint)
+0:171 'uv2' ( temp 2-component vector of uint)
+0:171 mix ( global 2-component vector of uint)
+0:171 Construct uvec2 ( temp 2-component vector of uint)
+0:171 'z' ( global uint)
+0:171 Construct uvec2 ( temp 2-component vector of uint)
+0:171 'z' ( global uint)
+0:171 Construct bvec2 ( temp 2-component vector of bool)
+0:171 'b' ( global bool)
+0:172 Sequence
+0:172 move second child to first child ( temp 3-component vector of uint)
+0:172 'uv3' ( temp 3-component vector of uint)
+0:172 mix ( global 3-component vector of uint)
+0:172 Construct uvec3 ( temp 3-component vector of uint)
+0:172 'z' ( global uint)
+0:172 Construct uvec3 ( temp 3-component vector of uint)
+0:172 'z' ( global uint)
+0:172 Construct bvec3 ( temp 3-component vector of bool)
+0:172 'b' ( global bool)
+0:173 Sequence
+0:173 move second child to first child ( temp 4-component vector of uint)
+0:173 'uv4' ( temp 4-component vector of uint)
+0:173 mix ( global 4-component vector of uint)
+0:173 Construct uvec4 ( temp 4-component vector of uint)
+0:173 'z' ( global uint)
+0:173 Construct uvec4 ( temp 4-component vector of uint)
+0:173 'z' ( global uint)
+0:173 Construct bvec4 ( temp 4-component vector of bool)
+0:173 'b' ( global bool)
+0:174 Sequence
+0:174 move second child to first child ( temp bool)
+0:174 'bv' ( temp bool)
+0:174 mix ( global bool)
+0:174 'b1' ( global bool)
+0:174 'b2' ( global bool)
+0:174 'b' ( global bool)
+0:175 Sequence
+0:175 move second child to first child ( temp 2-component vector of bool)
+0:175 'bv2' ( temp 2-component vector of bool)
+0:175 mix ( global 2-component vector of bool)
+0:175 Construct bvec2 ( temp 2-component vector of bool)
+0:175 'b1' ( global bool)
+0:175 Construct bvec2 ( temp 2-component vector of bool)
+0:175 'b2' ( global bool)
+0:175 Construct bvec2 ( temp 2-component vector of bool)
+0:175 'b' ( global bool)
+0:176 Sequence
+0:176 move second child to first child ( temp 3-component vector of bool)
+0:176 'bv3' ( temp 3-component vector of bool)
+0:176 mix ( global 3-component vector of bool)
+0:176 Construct bvec3 ( temp 3-component vector of bool)
+0:176 'b1' ( global bool)
+0:176 Construct bvec3 ( temp 3-component vector of bool)
+0:176 'b2' ( global bool)
+0:176 Construct bvec3 ( temp 3-component vector of bool)
+0:176 'b' ( global bool)
+0:177 Sequence
+0:177 move second child to first child ( temp 4-component vector of bool)
+0:177 'bv4' ( temp 4-component vector of bool)
+0:177 mix ( global 4-component vector of bool)
+0:177 Construct bvec4 ( temp 4-component vector of bool)
+0:177 'b1' ( global bool)
+0:177 Construct bvec4 ( temp 4-component vector of bool)
+0:177 'b2' ( global bool)
+0:177 Construct bvec4 ( temp 4-component vector of bool)
+0:177 'b' ( global bool)
+0:181 Function Definition: testmixFail( ( global void)
+0:181 Function Parameters:
+0:183 Sequence
+0:183 Sequence
+0:183 move second child to first child ( temp int)
+0:183 'ival' ( temp int)
+0:183 mix ( global int)
+0:183 'x' ( global int)
+0:183 'y' ( global int)
+0:183 'b' ( global bool)
0:? Linker Objects
0:? 'gl_FragCoord' ( gl_FragCoord 4-component vector of float FragCoord)
0:? 'foo' ( smooth in 4-component vector of float)
@@ -120,12 +430,50 @@
0:? 'p2' ( flat in 2-component vector of int)
0:? 'p3' ( flat in 3-component vector of int)
0:? 'samp' ( flat in int)
+0:? 'type1' ( smooth in double)
+0:? 'type2' ( global double)
+0:? 'type3' ( global double)
+0:? 'absTest' ( global int)
+0:? 'absTest2' ( global double)
+0:? 'absTest3' ( global double)
+0:? 'dk' ( global float)
+0:? 'f' ( global float)
+0:? 'v4' ( global 4-component vector of float)
+0:? 'iv4a' ( global 4-component vector of int)
+0:? 'uv2c' ( global 2-component vector of uint)
+0:? 'v2a' ( global 2-component vector of float)
+0:? 'uy' ( global uint)
+0:? 'samp1D' ( uniform sampler1D)
+0:? 'samp2Ds' ( uniform sampler2DShadow)
+0:? 'isamp2D' ( uniform isampler2D)
+0:? 'usamp3D' ( uniform usampler3D)
+0:? 'sampCube' ( uniform samplerCube)
+0:? 'isamp1DA' ( uniform isampler1DArray)
+0:? 'usamp2DA' ( uniform usampler2DArray)
+0:? 'samp1Ds' ( uniform sampler1DShadow)
+0:? 'sampCubes' ( uniform samplerCubeShadow)
+0:? 'samp1DAs' ( uniform sampler1DArrayShadow)
+0:? 'samp2DAs' ( uniform sampler2DArrayShadow)
+0:? 'sampBuf' ( uniform samplerBuffer)
+0:? 'sampRect' ( uniform sampler2DRect)
+0:? 'b1' ( global bool)
+0:? 'b2' ( global bool)
+0:? 'b' ( global bool)
+0:? 'x' ( global int)
+0:? 'y' ( global int)
+0:? 'z' ( global uint)
+0:? 'w' ( global uint)
Linked fragment stage:
Shader version: 150
+Requested GL_ARB_gpu_shader_fp64
+Requested GL_ARB_shader_bit_encoding
+Requested GL_ARB_shading_language_packing
+Requested GL_ARB_texture_query_lod
+Requested GL_EXT_shader_integer_mix
gl_FragCoord pixel center is integer
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
@@ -141,6 +489,26 @@
0:18 'patch' ( global float)
0:18 Constant:
0:18 3.100000
+0:56 Sequence
+0:56 move second child to first child ( temp double)
+0:56 'type3' ( global double)
+0:56 Constant:
+0:56 2.000000
+0:58 Sequence
+0:58 move second child to first child ( temp double)
+0:58 'absTest2' ( global double)
+0:58 sqrt ( global double)
+0:58 'type3' ( global double)
+0:59 Sequence
+0:59 move second child to first child ( temp double)
+0:59 'absTest3' ( global double)
+0:59 Constant:
+0:59 1.414214
+0:60 Sequence
+0:60 move second child to first child ( temp float)
+0:60 'dk' ( global float)
+0:60 Constant:
+0:60 3.316625
0:? Linker Objects
0:? 'gl_FragCoord' ( gl_FragCoord 4-component vector of float FragCoord)
0:? 'foo' ( smooth in 4-component vector of float)
@@ -155,4 +523,37 @@
0:? 'p2' ( flat in 2-component vector of int)
0:? 'p3' ( flat in 3-component vector of int)
0:? 'samp' ( flat in int)
+0:? 'type1' ( smooth in double)
+0:? 'type2' ( global double)
+0:? 'type3' ( global double)
+0:? 'absTest' ( global int)
+0:? 'absTest2' ( global double)
+0:? 'absTest3' ( global double)
+0:? 'dk' ( global float)
+0:? 'f' ( global float)
+0:? 'v4' ( global 4-component vector of float)
+0:? 'iv4a' ( global 4-component vector of int)
+0:? 'uv2c' ( global 2-component vector of uint)
+0:? 'v2a' ( global 2-component vector of float)
+0:? 'uy' ( global uint)
+0:? 'samp1D' ( uniform sampler1D)
+0:? 'samp2Ds' ( uniform sampler2DShadow)
+0:? 'isamp2D' ( uniform isampler2D)
+0:? 'usamp3D' ( uniform usampler3D)
+0:? 'sampCube' ( uniform samplerCube)
+0:? 'isamp1DA' ( uniform isampler1DArray)
+0:? 'usamp2DA' ( uniform usampler2DArray)
+0:? 'samp1Ds' ( uniform sampler1DShadow)
+0:? 'sampCubes' ( uniform samplerCubeShadow)
+0:? 'samp1DAs' ( uniform sampler1DArrayShadow)
+0:? 'samp2DAs' ( uniform sampler2DArrayShadow)
+0:? 'sampBuf' ( uniform samplerBuffer)
+0:? 'sampRect' ( uniform sampler2DRect)
+0:? 'b1' ( global bool)
+0:? 'b2' ( global bool)
+0:? 'b' ( global bool)
+0:? 'x' ( global int)
+0:? 'y' ( global int)
+0:? 'z' ( global uint)
+0:? 'w' ( global uint)
diff --git a/Test/baseResults/150.vert.out b/Test/baseResults/150.vert.out
index 504160d..05a1db9 100644
--- a/Test/baseResults/150.vert.out
+++ b/Test/baseResults/150.vert.out
@@ -1,10 +1,14 @@
150.vert
ERROR: 0:26: 'a' : cannot redeclare a user-block member array
+ERROR: 0:28: 'double' : Reserved word.
+ERROR: 0:28: 'double' : not supported for this version or the enabled extensions
+ERROR: 0:28: 'vertex-shader `double` type input' : not supported for this version or the enabled extensions
ERROR: 0:3001: '#error' : line of this error should be 3001
-ERROR: 2 compilation errors. No code generated.
+ERROR: 5 compilation errors. No code generated.
Shader version: 150
+Requested GL_ARB_vertex_attrib_64bit
ERROR: node is still EOpNull!
0:13 Function Definition: main( ( global void)
0:13 Function Parameters:
@@ -43,6 +47,20 @@
0:? 'iv4' ( in 4-component vector of float)
0:? 'ps' ( uniform float)
0:? 'anon@1' (layout( column_major shared) uniform block{layout( column_major shared) uniform unsized 1-element array of int a})
+0:? 'dvarerr' ( in double)
+0:? 'dvar' ( in double)
+0:? 'dv2var' ( in 2-component vector of double)
+0:? 'dv3var' ( in 3-component vector of double)
+0:? 'dv4var' ( in 4-component vector of double)
+0:? 'dmat2var' ( in 2X2 matrix of double)
+0:? 'dmat3var' ( in 3X3 matrix of double)
+0:? 'dmat4var' ( in 4X4 matrix of double)
+0:? 'dmat23var' ( in 2X3 matrix of double)
+0:? 'dmat24var' ( in 2X4 matrix of double)
+0:? 'dmat32var' ( in 3X2 matrix of double)
+0:? 'dmat34var' ( in 3X4 matrix of double)
+0:? 'dmat42var' ( in 4X2 matrix of double)
+0:? 'dmat43var' ( in 4X3 matrix of double)
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
@@ -52,6 +70,7 @@
ERROR: Linking vertex stage: Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)
Shader version: 150
+Requested GL_ARB_vertex_attrib_64bit
ERROR: node is still EOpNull!
0:13 Function Definition: main( ( global void)
0:13 Function Parameters:
@@ -90,6 +109,20 @@
0:? 'iv4' ( in 4-component vector of float)
0:? 'ps' ( uniform float)
0:? 'anon@1' (layout( column_major shared) uniform block{layout( column_major shared) uniform 1-element array of int a})
+0:? 'dvarerr' ( in double)
+0:? 'dvar' ( in double)
+0:? 'dv2var' ( in 2-component vector of double)
+0:? 'dv3var' ( in 3-component vector of double)
+0:? 'dv4var' ( in 4-component vector of double)
+0:? 'dmat2var' ( in 2X2 matrix of double)
+0:? 'dmat3var' ( in 3X3 matrix of double)
+0:? 'dmat4var' ( in 4X4 matrix of double)
+0:? 'dmat23var' ( in 2X3 matrix of double)
+0:? 'dmat24var' ( in 2X4 matrix of double)
+0:? 'dmat32var' ( in 3X2 matrix of double)
+0:? 'dmat34var' ( in 3X4 matrix of double)
+0:? 'dmat42var' ( in 4X2 matrix of double)
+0:? 'dmat43var' ( in 4X3 matrix of double)
0:? 'gl_VertexID' ( gl_VertexId int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId)
diff --git a/Test/baseResults/300.frag.out b/Test/baseResults/300.frag.out
index ee1b8a5..50a6b07 100644
--- a/Test/baseResults/300.frag.out
+++ b/Test/baseResults/300.frag.out
@@ -40,15 +40,20 @@
ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]
ERROR: 0:148: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)
ERROR: 0:150: 'early_fragment_tests' : not supported for this version or the enabled extensions
-ERROR: 0:156: 'invariant' : can only apply to an output
-ERROR: 0:157: 'invariant' : can only apply to an output
-ERROR: 0:158: 'invariant' : can only apply to an output
-ERROR: 0:160: 'imageBuffer' : Reserved word.
-ERROR: 0:160: '' : syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON
-ERROR: 46 compilation errors. No code generated.
+ERROR: 0:177: 'specific signature of builtin mix' : required extension not requested: GL_EXT_shader_integer_mix
+ERROR: 0:181: 'index layout qualifier on fragment output' : not supported for this version or the enabled extensions
+ERROR: 0:183: 'index' : value must be 0 or 1
+ERROR: 0:189: 'invariant' : can only apply to an output
+ERROR: 0:190: 'invariant' : can only apply to an output
+ERROR: 0:191: 'invariant' : can only apply to an output
+ERROR: 0:193: 'imageBuffer' : Reserved word.
+ERROR: 0:193: '' : syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON
+ERROR: 49 compilation errors. No code generated.
Shader version: 300
+Requested GL_EXT_blend_func_extended
+Requested GL_EXT_shader_integer_mix
using early_fragment_tests
ERROR: node is still EOpNull!
0:53 Function Definition: main( ( global void)
@@ -362,6 +367,130 @@
0:145 21.000000
0:145 22.000000
0:145 33.000000
+0:158 Function Definition: testmix( ( global void)
+0:158 Function Parameters:
+0:160 Sequence
+0:160 Sequence
+0:160 move second child to first child ( temp mediump int)
+0:160 'ival' ( temp mediump int)
+0:160 mix ( global mediump int)
+0:160 'x' ( global mediump int)
+0:160 'y' ( global mediump int)
+0:160 'b' ( global bool)
+0:161 Sequence
+0:161 move second child to first child ( temp mediump 2-component vector of int)
+0:161 'iv2' ( temp mediump 2-component vector of int)
+0:161 mix ( global mediump 2-component vector of int)
+0:161 Construct ivec2 ( temp mediump 2-component vector of int)
+0:161 'x' ( global mediump int)
+0:161 Construct ivec2 ( temp mediump 2-component vector of int)
+0:161 'y' ( global mediump int)
+0:161 Construct bvec2 ( temp 2-component vector of bool)
+0:161 'b' ( global bool)
+0:162 Sequence
+0:162 move second child to first child ( temp mediump 3-component vector of int)
+0:162 'iv3' ( temp mediump 3-component vector of int)
+0:162 mix ( global mediump 3-component vector of int)
+0:162 Construct ivec3 ( temp mediump 3-component vector of int)
+0:162 'x' ( global mediump int)
+0:162 Construct ivec3 ( temp mediump 3-component vector of int)
+0:162 'y' ( global mediump int)
+0:162 Construct bvec3 ( temp 3-component vector of bool)
+0:162 'b' ( global bool)
+0:163 Sequence
+0:163 move second child to first child ( temp mediump 4-component vector of int)
+0:163 'iv4' ( temp mediump 4-component vector of int)
+0:163 mix ( global mediump 4-component vector of int)
+0:163 Construct ivec4 ( temp mediump 4-component vector of int)
+0:163 'x' ( global mediump int)
+0:163 Construct ivec4 ( temp mediump 4-component vector of int)
+0:163 'x' ( global mediump int)
+0:163 Construct bvec4 ( temp 4-component vector of bool)
+0:163 'b' ( global bool)
+0:164 Sequence
+0:164 move second child to first child ( temp mediump uint)
+0:164 'uiv' ( temp mediump uint)
+0:164 mix ( global mediump uint)
+0:164 'z' ( global mediump uint)
+0:164 'w' ( global mediump uint)
+0:164 'b' ( global bool)
+0:165 Sequence
+0:165 move second child to first child ( temp mediump 2-component vector of uint)
+0:165 'uv2' ( temp mediump 2-component vector of uint)
+0:165 mix ( global mediump 2-component vector of uint)
+0:165 Construct uvec2 ( temp mediump 2-component vector of uint)
+0:165 'z' ( global mediump uint)
+0:165 Construct uvec2 ( temp mediump 2-component vector of uint)
+0:165 'z' ( global mediump uint)
+0:165 Construct bvec2 ( temp 2-component vector of bool)
+0:165 'b' ( global bool)
+0:166 Sequence
+0:166 move second child to first child ( temp mediump 3-component vector of uint)
+0:166 'uv3' ( temp mediump 3-component vector of uint)
+0:166 mix ( global mediump 3-component vector of uint)
+0:166 Construct uvec3 ( temp mediump 3-component vector of uint)
+0:166 'z' ( global mediump uint)
+0:166 Construct uvec3 ( temp mediump 3-component vector of uint)
+0:166 'z' ( global mediump uint)
+0:166 Construct bvec3 ( temp 3-component vector of bool)
+0:166 'b' ( global bool)
+0:167 Sequence
+0:167 move second child to first child ( temp mediump 4-component vector of uint)
+0:167 'uv4' ( temp mediump 4-component vector of uint)
+0:167 mix ( global mediump 4-component vector of uint)
+0:167 Construct uvec4 ( temp mediump 4-component vector of uint)
+0:167 'z' ( global mediump uint)
+0:167 Construct uvec4 ( temp mediump 4-component vector of uint)
+0:167 'z' ( global mediump uint)
+0:167 Construct bvec4 ( temp 4-component vector of bool)
+0:167 'b' ( global bool)
+0:168 Sequence
+0:168 move second child to first child ( temp bool)
+0:168 'bv' ( temp bool)
+0:168 mix ( global bool)
+0:168 'b1' ( global bool)
+0:168 'b2' ( global bool)
+0:168 'b' ( global bool)
+0:169 Sequence
+0:169 move second child to first child ( temp 2-component vector of bool)
+0:169 'bv2' ( temp 2-component vector of bool)
+0:169 mix ( global 2-component vector of bool)
+0:169 Construct bvec2 ( temp 2-component vector of bool)
+0:169 'b1' ( global bool)
+0:169 Construct bvec2 ( temp 2-component vector of bool)
+0:169 'b2' ( global bool)
+0:169 Construct bvec2 ( temp 2-component vector of bool)
+0:169 'b' ( global bool)
+0:170 Sequence
+0:170 move second child to first child ( temp 3-component vector of bool)
+0:170 'bv3' ( temp 3-component vector of bool)
+0:170 mix ( global 3-component vector of bool)
+0:170 Construct bvec3 ( temp 3-component vector of bool)
+0:170 'b1' ( global bool)
+0:170 Construct bvec3 ( temp 3-component vector of bool)
+0:170 'b2' ( global bool)
+0:170 Construct bvec3 ( temp 3-component vector of bool)
+0:170 'b' ( global bool)
+0:171 Sequence
+0:171 move second child to first child ( temp 4-component vector of bool)
+0:171 'bv4' ( temp 4-component vector of bool)
+0:171 mix ( global 4-component vector of bool)
+0:171 Construct bvec4 ( temp 4-component vector of bool)
+0:171 'b1' ( global bool)
+0:171 Construct bvec4 ( temp 4-component vector of bool)
+0:171 'b2' ( global bool)
+0:171 Construct bvec4 ( temp 4-component vector of bool)
+0:171 'b' ( global bool)
+0:175 Function Definition: testmixFail( ( global void)
+0:175 Function Parameters:
+0:177 Sequence
+0:177 Sequence
+0:177 move second child to first child ( temp mediump int)
+0:177 'ival' ( temp mediump int)
+0:177 mix ( global mediump int)
+0:177 'x' ( global mediump int)
+0:177 'y' ( global mediump int)
+0:177 'b' ( global bool)
0:? Linker Objects
0:? 's2D' ( uniform lowp sampler2D)
0:? 's3D' ( uniform lowp sampler3D)
@@ -397,6 +526,15 @@
0:? 'colors' ( out 4-element array of lowp 4-component vector of float)
0:? 'st1' ( uniform structure{ global mediump int i, global lowp sampler2D s})
0:? 'st2' ( uniform structure{ global mediump int i, global lowp sampler2D s})
+0:? 'b1' ( global bool)
+0:? 'b2' ( global bool)
+0:? 'b' ( global bool)
+0:? 'x' ( global mediump int)
+0:? 'y' ( global mediump int)
+0:? 'z' ( global mediump uint)
+0:? 'w' ( global mediump uint)
+0:? 'outVarFail' (layout( location=0 index=1) out lowp 4-component vector of float)
+0:? 'outVarPass' (layout( location=0 index=0) out lowp 4-component vector of float)
0:? 'fooinv' ( invariant smooth in lowp 4-component vector of float)
@@ -405,6 +543,8 @@
ERROR: Linking fragment stage: when more than one fragment shader output, all must have location qualifiers
Shader version: 300
+Requested GL_EXT_blend_func_extended
+Requested GL_EXT_shader_integer_mix
using early_fragment_tests
ERROR: node is still EOpNull!
0:53 Function Definition: main( ( global void)
@@ -628,5 +768,14 @@
0:? 'colors' ( out 4-element array of lowp 4-component vector of float)
0:? 'st1' ( uniform structure{ global mediump int i, global lowp sampler2D s})
0:? 'st2' ( uniform structure{ global mediump int i, global lowp sampler2D s})
+0:? 'b1' ( global bool)
+0:? 'b2' ( global bool)
+0:? 'b' ( global bool)
+0:? 'x' ( global mediump int)
+0:? 'y' ( global mediump int)
+0:? 'z' ( global mediump uint)
+0:? 'w' ( global mediump uint)
+0:? 'outVarFail' (layout( location=0 index=1) out lowp 4-component vector of float)
+0:? 'outVarPass' (layout( location=0 index=0) out lowp 4-component vector of float)
0:? 'fooinv' ( invariant smooth in lowp 4-component vector of float)
diff --git a/Test/baseResults/300BuiltIns.frag.out b/Test/baseResults/300