diff --git a/.travis.yml b/.travis.yml index 1fa3fc01cd..746ac46047 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,18 +46,18 @@ addons: install: # Make sure that clang-3.6 is selected on Linux. - if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "clang" ]]; then - export CC=clang-3.6 CXX=clang++-3.6; + export CC=clang-3.6 CXX=clang++-3.6; fi # Download a recent Android NDK and use its android.toolchain.cmake file. - if [[ "$BUILD_NDK" == "ON" ]]; then - export ANDROID_NDK=$HOME/android-ndk; - git init $ANDROID_NDK; - pushd $ANDROID_NDK; - git remote add dneto0 https://github.com/dneto0/android-ndk.git; - git fetch --depth=1 dneto0 r17b-strip; - git checkout FETCH_HEAD; - popd; - export TOOLCHAIN_PATH=$ANDROID_NDK/build/cmake/android.toolchain.cmake; + export ANDROID_NDK=$HOME/android-ndk; + git init $ANDROID_NDK; + pushd $ANDROID_NDK; + git remote add dneto0 https://github.com/dneto0/android-ndk.git; + git fetch --depth=1 dneto0 r17b-strip; + git checkout FETCH_HEAD; + popd; + export TOOLCHAIN_PATH=$ANDROID_NDK/build/cmake/android.toolchain.cmake; fi before_script: @@ -71,42 +71,42 @@ script: # We can use newer API levels if we want. # For Linux and macOS, do debug/release building with testing. - if [[ "$BUILD_NDK" == "ON" ]]; then - cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_PATH} - -DANDROID_NATIVE_API_LEVEL=android-14 - -DCMAKE_BUILD_TYPE=Release - -DANDROID_ABI="armeabi-v7a with NEON" - -DBUILD_TESTING=OFF ..; - make -j4; + cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_PATH} + -DANDROID_NATIVE_API_LEVEL=android-14 + -DCMAKE_BUILD_TYPE=Release + -DANDROID_ABI="armeabi-v7a with NEON" + -DGLSLANG_BUILD_TESTING=OFF ..; + make -j4; else - cmake -DCMAKE_BUILD_TYPE=${GLSLANG_BUILD_TYPE} - -DCMAKE_INSTALL_PREFIX=`pwd`/install ..; - make -j4 install; - ctest --output-on-failure && - cd ../Test && ./runtests; + cmake -DCMAKE_BUILD_TYPE=${GLSLANG_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX=`pwd`/install ..; + make -j4 install; + ctest --output-on-failure && + cd ../Test && ./runtests; fi after_success: # For debug build, the generated dll has a postfix "d" in its name. - if [[ "${GLSLANG_BUILD_TYPE}" == "Debug" ]]; then - export SUFFIX="d"; + export SUFFIX="d"; else - export SUFFIX=""; + export SUFFIX=""; fi # Create tarball for deployment - if [[ ${CC} == clang* && "${BUILD_NDK}" != "ON" ]]; then - cd ../build/install; - export TARBALL=glslang-master-${TRAVIS_OS_NAME}-${GLSLANG_BUILD_TYPE}.zip; - zip ${TARBALL} - bin/glslangValidator - include/glslang/* - lib/libglslang${SUFFIX}.a - lib/libHLSL${SUFFIX}.a - lib/libOGLCompiler${SUFFIX}.a - lib/libOSDependent${SUFFIX}.a - lib/libSPIRV${SUFFIX}.a - lib/libSPVRemapper${SUFFIX}.a - lib/libSPIRV-Tools${SUFFIX}.a - lib/libSPIRV-Tools-opt${SUFFIX}.a; + cd ../build/install; + export TARBALL=glslang-master-${TRAVIS_OS_NAME}-${GLSLANG_BUILD_TYPE}.zip; + zip ${TARBALL} + bin/glslangValidator + include/glslang/* + lib/libglslang${SUFFIX}.a + lib/libHLSL${SUFFIX}.a + lib/libOGLCompiler${SUFFIX}.a + lib/libOSDependent${SUFFIX}.a + lib/libSPIRV${SUFFIX}.a + lib/libSPVRemapper${SUFFIX}.a + lib/libSPIRV-Tools${SUFFIX}.a + lib/libSPIRV-Tools-opt${SUFFIX}.a; fi before_deploy: diff --git a/Android.mk b/Android.mk index fda81a7cf2..a4d95be604 100644 --- a/Android.mk +++ b/Android.mk @@ -2,7 +2,7 @@ LOCAL_PATH := $(call my-dir) GLSLANG_OS_FLAGS := -DGLSLANG_OSINCLUDE_UNIX # AMD and NV extensions are turned on by default in upstream Glslang. -GLSLANG_DEFINES:= -DAMD_EXTENSIONS -DNV_EXTENSIONS -DENABLE_HLSL $(GLSLANG_OS_FLAGS) +GLSLANG_DEFINES:= -DAMD_EXTENSIONS -DNV_EXTENSIONS -DGLSLANG_ENABLE_HLSL $(GLSLANG_OS_FLAGS) include $(CLEAR_VARS) LOCAL_MODULE:=OSDependent diff --git a/BUILD.bazel b/BUILD.bazel index d70bc7f653..3c152615d2 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -66,8 +66,8 @@ cc_library( copts = COMMON_COPTS, defines = [ "AMD_EXTENSIONS", - "ENABLE_HLSL=0", - "ENABLE_OPT=0", + "GLSLANG_ENABLE_HLSL=0", + "GLSLANG_ENABLE_OPT=0", "NV_EXTENSIONS", ], linkopts = select({ @@ -85,7 +85,7 @@ genrule( "SPIRV/GLSL.ext.KHR.h", "SPIRV/GLSL.ext.NV.h", "SPIRV/GLSL.std.450.h", - "SPIRV/NonSemanticDebugPrintf.h", + "SPIRV/NonSemanticDebugPrintf.h", "SPIRV/spirv.hpp", ], outs = [ @@ -94,7 +94,7 @@ genrule( "include/SPIRV/GLSL.ext.KHR.h", "include/SPIRV/GLSL.ext.NV.h", "include/SPIRV/GLSL.std.450.h", - "include/SPIRV/NonSemanticDebugPrintf.h", + "include/SPIRV/NonSemanticDebugPrintf.h", "include/SPIRV/spirv.hpp", ], cmd = "mkdir -p $(@D)/include/SPIRV && cp $(SRCS) $(@D)/include/SPIRV/", diff --git a/BUILD.gn b/BUILD.gn index 87c28e9de6..c4eacba87a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -51,7 +51,7 @@ spirv_tools_dir = glslang_spirv_tools_dir config("glslang_public") { include_dirs = [ "." ] - defines = [ "ENABLE_HLSL=1" ] + defines = [ "GLSLANG_ENABLE_HLSL=1" ] } source_set("glslang_sources") { @@ -70,7 +70,7 @@ source_set("glslang_sources") { "SPIRV/InReadableOrder.cpp", "SPIRV/Logger.cpp", "SPIRV/Logger.h", - "SPIRV/NonSemanticDebugPrintf.h", + "SPIRV/NonSemanticDebugPrintf.h", "SPIRV/SPVRemapper.cpp", "SPIRV/SPVRemapper.h", "SPIRV/SpvBuilder.cpp", @@ -164,7 +164,7 @@ source_set("glslang_sources") { "hlsl/hlslTokens.h", ] - defines = [ "ENABLE_OPT=1" ] + defines = [ "GLSLANG_ENABLE_OPT=1" ] if (is_win) { sources += [ "glslang/OSDependent/Windows/ossource.cpp" ] @@ -224,7 +224,7 @@ executable("glslang_validator") { if (!is_win) { cflags = [ "-Woverflow" ] } - defines = [ "ENABLE_OPT=1" ] + defines = [ "GLSLANG_ENABLE_OPT=1" ] deps = [ ":glslang_default_resource_limits_sources", ":glslang_sources", @@ -238,7 +238,7 @@ executable("spirv-remap") { sources = [ "StandAlone/spirv-remap.cpp", ] - defines = [ "ENABLE_OPT=1" ] + defines = [ "GLSLANG_ENABLE_OPT=1" ] deps = [ ":glslang_sources", ] diff --git a/CMakeLists.txt b/CMakeLists.txt index a80cd5f92f..d63b4f226a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,12 +15,12 @@ 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) +option(GLSLANG_BUILD_SHARED_LIBS "Build Shared Libraries" OFF) +option(GLSLANG_BUILD_EXTERNAL "Build external dependencies in /External" ON) set(LIB_TYPE STATIC) -if(BUILD_SHARED_LIBS) +if(GLSLANG_BUILD_SHARED_LIBS) set(LIB_TYPE SHARED) endif() @@ -51,22 +51,23 @@ CMAKE_DEPENDENT_OPTION(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN" OFF) -CMAKE_DEPENDENT_OPTION(ENABLE_HLSL +CMAKE_DEPENDENT_OPTION(GLSLANG_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) +option(GLSLANG_ENABLE_RTTI "Enables RTTI" OFF) +option(GLSLANG_ENABLE_OPT "Enables spirv-opt capability if present" ON) +option(GLSLANG_ENABLE_PCH "Enables Precompiled header" ON) +option(GLSLANG_ENABLE_CTEST "Enables testing" ON) +option(GLSLANG_BUILD_TESTING "Builds tests" ON) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND WIN32) set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "..." FORCE) endif() -option(USE_CCACHE "Use ccache" OFF) -if(USE_CCACHE) +option(GLSLANG_USE_CCACHE "Use ccache" OFF) +if(GLSLANG_USE_CCACHE) find_program(CCACHE_FOUND ccache) if(CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) @@ -75,7 +76,7 @@ endif() # Precompiled header macro. Parameters are source file list and filename for pch cpp file. macro(glslang_pch SRCS PCHCPP) - if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio" AND ENABLE_PCH) + if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio" AND GLSLANG_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}") @@ -87,13 +88,13 @@ endmacro(glslang_pch) project(glslang) -if(ENABLE_CTEST) +if(GLSLANG_ENABLE_CTEST) include(CTest) endif() -if(ENABLE_HLSL) - add_definitions(-DENABLE_HLSL) -endif(ENABLE_HLSL) +if(GLSLANG_ENABLE_HLSL) + add_definitions(-DGLSLANG_ENABLE_HLSL) +endif(GLSLANG_ENABLE_HLSL) if(ENABLE_GLSLANG_WEBMIN) add_definitions(-DGLSLANG_WEB) @@ -118,7 +119,7 @@ if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") add_compile_options(-Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions) add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over. - if(NOT ENABLE_RTTI) + if(NOT GLSLANG_ENABLE_RTTI) add_compile_options(-fno-rtti) endif() if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0") @@ -128,11 +129,11 @@ elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") add_compile_options(-Wall -Wuninitialized -Wunused -Wunused-local-typedefs -Wunused-parameter -Wunused-value -Wunused-variable) add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over. - if(NOT ENABLE_RTTI) + if(NOT GLSLANG_ENABLE_RTTI) add_compile_options(-fno-rtti) endif() elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "MSVC") - if(NOT ENABLE_RTTI) + if(NOT GLSLANG_ENABLE_RTTI) add_compile_options(/GR-) # Disable RTTI endif() endif() @@ -168,7 +169,7 @@ endfunction(glslang_set_link_args) # 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) +if(GLSLANG_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. @@ -176,17 +177,17 @@ if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External) endif() if(NOT TARGET SPIRV-Tools-opt) - set(ENABLE_OPT OFF) + set(GLSLANG_ENABLE_OPT OFF) endif() -if(ENABLE_OPT) +if(GLSLANG_ENABLE_OPT) message(STATUS "optimizer enabled") - add_definitions(-DENABLE_OPT=1) + add_definitions(-DGLSLANG_ENABLE_OPT=1) else() - if(ENABLE_HLSL) + if(GLSLANG_ENABLE_HLSL) message(STATUS "spirv-tools not linked - illegal SPIRV may be generated for HLSL") endif() - add_definitions(-DENABLE_OPT=0) + add_definitions(-DGLSLANG_ENABLE_OPT=0) endif() add_subdirectory(glslang) @@ -195,14 +196,14 @@ if(ENABLE_GLSLANG_BINARIES) add_subdirectory(StandAlone) endif() add_subdirectory(SPIRV) -if(ENABLE_HLSL) +if(GLSLANG_ENABLE_HLSL) add_subdirectory(hlsl) -endif(ENABLE_HLSL) -if(ENABLE_CTEST) +endif(GLSLANG_ENABLE_HLSL) +if(GLSLANG_ENABLE_CTEST) add_subdirectory(gtests) endif() -if(BUILD_TESTING) +if(GLSLANG_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 "") @@ -223,4 +224,4 @@ if(BUILD_TESTING) 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) +endif(GLSLANG_BUILD_TESTING) diff --git a/External/CMakeLists.txt b/External/CMakeLists.txt index 6ff4f47acd..8fbc96c781 100644 --- a/External/CMakeLists.txt +++ b/External/CMakeLists.txt @@ -1,7 +1,7 @@ # Suppress all warnings from external projects. set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -w) -if(BUILD_TESTING) +if(GLSLANG_BUILD_TESTING) if(TARGET gmock) message(STATUS "Google Mock already configured - use it") elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest) @@ -23,7 +23,7 @@ if(BUILD_TESTING) mark_as_advanced(gmock_build_tests BUILD_GMOCK BUILD_GTEST - BUILD_SHARED_LIBS + GLSLANG_BUILD_SHARED_LIBS gtest_build_samples gtest_build_tests gtest_disable_pthreads @@ -35,7 +35,7 @@ if(BUILD_TESTING) endif() endif() -if(ENABLE_OPT AND NOT TARGET SPIRV-Tools-opt) +if(GLSLANG_ENABLE_OPT AND NOT TARGET SPIRV-Tools-opt) if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/spirv-tools) set(SPIRV_SKIP_TESTS ON CACHE BOOL "Skip building SPIRV-Tools tests") add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/spirv-tools spirv-tools) diff --git a/README.md b/README.md index 5188ab4646..95abd308d8 100755 --- a/README.md +++ b/README.md @@ -6,14 +6,14 @@ ## 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. + 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. + a goal as of July 20, 2020, the fifth anniversary of the release of Visual Studio 2015. # Glslang Components and Status @@ -44,7 +44,7 @@ Translates glslang's AST to the Khronos-specified SPIR-V intermediate language. 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. +**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 @@ -67,19 +67,21 @@ The above page, while not kept up to date, includes additional information regar ## 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, +a usage statement. Basic operation is to give it a file containing a shader, and it will print out warnings/errors and optionally an AST. The applied stage-specific rules are based on the file extension: -* `.vert` for a vertex shader -* `.tesc` for a tessellation control shader -* `.tese` for a tessellation evaluation shader -* `.geom` for a geometry shader -* `.frag` for a fragment shader -* `.comp` for a compute shader + +- `.vert` for a vertex shader +- `.tesc` for a tessellation control shader +- `.tese` for a tessellation evaluation shader +- `.geom` for a geometry shader +- `.frag` for a fragment shader +- `.comp` for a compute shader There is also a non-shader extension -* `.conf` for a configuration file of limits, see usage statement for example + +- `.conf` for a configuration file of limits, see usage statement for example ## Building @@ -91,13 +93,13 @@ branch. ### Dependencies -* A C++11 compiler. +- A C++11 compiler. (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 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. +- [CMake][cmake]: for generating compilation targets. +- make: _Linux_, ninja is an alternative, if configured. +- [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. ### Build steps @@ -153,6 +155,7 @@ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE ``` 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 @@ -211,26 +214,27 @@ the web grammar subset (see more about the web subset in the next section). ### Building to WASM for the Web and Node Use the steps in [Build Steps](#build-steps), with the following notes/exceptions: -* For building the web subset of core glslang: - + execute `updateGrammar web` from the glslang subdirectory + +- For building the web subset of core glslang: + - execute `updateGrammar web` from the glslang subdirectory (or if using your own scripts, `m4` needs a `-DGLSLANG_WEB` argument) - + set `-DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF` - + turn on `-DENABLE_GLSLANG_JS=ON` - + optionally, for a minimum-size binary, turn on `-DENABLE_GLSLANG_WEBMIN=ON` - + optionally, for GLSL compilation error messages, turn on `-DENABLE_GLSLANG_WEB_DEVEL=ON` -* `emsdk` needs to be present in your executable search path, *PATH* for + - set `-DGLSLANG_ENABLE_HLSL=OFF -DGLSLANG_BUILD_TESTING=OFF -DGLSLANG_ENABLE_OPT=OFF -DINSTALL_GTEST=OFF` + - turn on `-DENABLE_GLSLANG_JS=ON` + - optionally, for a minimum-size binary, turn on `-DENABLE_GLSLANG_WEBMIN=ON` + - optionally, for GLSL compilation error messages, turn on `-DENABLE_GLSLANG_WEB_DEVEL=ON` +- `emsdk` needs to be present in your executable search path, _PATH_ for Bash-like environments - + [Instructions located + - [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install) -* Wrap cmake call: `emcmake cmake` -* To get a fully minimized build, make sure to use `brotli` to compress the .js +- Wrap cmake call: `emcmake cmake` +- To get a fully minimized build, make sure to use `brotli` to compress the .js and .wasm files Example: ```sh emcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_WEB=ON \ - -DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF .. + -DGLSLANG_ENABLE_HLSL=OFF -DGLSLANG_BUILD_TESTING=OFF -DGLSLANG_ENABLE_OPT=OFF -DINSTALL_GTEST=OFF .. ``` ## Building glslang - Using vcpkg @@ -282,8 +286,8 @@ 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 +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 @@ -296,7 +300,7 @@ place the tests under the `gtests/` directory. Integration tests are placed in the `Test/` directory. It contains test input and a subdirectory `baseResults/` that contains the expected results of the -tests. Both the tests and `baseResults/` are under source-code control. +tests. Both the tests and `baseResults/` are under source-code control. Google Test runs those integration tests by reading the test input, compiling them, and then compare against the expected results in `baseResults/`. The @@ -310,25 +314,26 @@ For more information, please check `gtests/` directory's For the `runtests` script, it will generate current results in the `localResults/` directory and `diff` them against the `baseResults/`. When you want to update the tracked test results, they need to be -copied from `localResults/` to `baseResults/`. This can be done by +copied from `localResults/` to `baseResults/`. This can be done by the `bump` shell script. You can add your own private list of tests, not tracked publicly, by using -`localtestlist` to list non-tracked tests. This is automatically read +`localtestlist` to list non-tracked tests. This is automatically read by `runtests` and included in the `diff` and `bump` process. ## Programmatic Interfaces Another piece of software can programmatically translate shaders to an AST using one of two different interfaces: -* A new C++ class-oriented interface, or -* The original C functional interface + +- A new C++ class-oriented interface, or +- The original C functional interface The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles. ### C++ Class Interface (new, preferred) -This interface is in roughly the last 1/3 of `ShaderLang.h`. It is in the +This interface is in roughly the last 1/3 of `ShaderLang.h`. It is in the glslang namespace and contains the following, here with suggested calls for generating SPIR-V: @@ -384,37 +389,37 @@ warning/error and other options for controlling compilation. ## Basic Internal Operation -* Initial lexical analysis is done by the preprocessor in +- Initial lexical analysis is done by the preprocessor in `MachineIndependent/Preprocessor`, and then refined by a GLSL scanner - in `MachineIndependent/Scan.cpp`. There is currently no use of flex. + in `MachineIndependent/Scan.cpp`. There is currently no use of flex. -* Code is parsed using bison on `MachineIndependent/glslang.y` with the - aid of a symbol table and an AST. The symbol table is not passed on to +- Code is parsed using bison on `MachineIndependent/glslang.y` with the + aid of a symbol table and an AST. The symbol table is not passed on to the back-end; the intermediate representation stands on its own. The tree is built by the grammar productions, many of which are offloaded into `ParseHelper.cpp`, and by `Intermediate.cpp`. -* The intermediate representation is very high-level, and represented - as an in-memory tree. This serves to lose no information from the +- 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 propagated 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 lists all global symbols. -* The primary algorithm of the back-end compiler is to traverse the +- The primary algorithm of the back-end compiler is to traverse the tree (high-level intermediate representation), and create an internal - object code representation. There is an example of how to do this + object code representation. There is an example of how to do this in `MachineIndependent/intermOut.cpp`. -* Reduction of the tree to a linear byte-code style low-level intermediate +- Reduction of the tree to a linear byte-code style low-level intermediate representation is likely a good way to generate fully optimized code. -* There is currently some dead old-style linker-type code still lying around. +- There is currently some dead old-style linker-type code still lying around. -* Memory pool: parsing uses types derived from C++ `std` types, using a - custom allocator that puts them in a memory pool. This makes allocation +- Memory pool: parsing uses types derived from C++ `std` types, using a + custom allocator that puts them in a memory pool. This makes allocation of individual container/contents just few cycles and deallocation free. This pool is popped after the AST is made and processed. @@ -429,7 +434,7 @@ warning/error and other options for controlling compilation. - 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: +- Features can be protected by version/extension/stage/profile: See the comment in `glslang/MachineIndependent/Versions.cpp`. [cmake]: https://cmake.org/ diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt index 90406099a0..2806fe4b1c 100644 --- a/SPIRV/CMakeLists.txt +++ b/SPIRV/CMakeLists.txt @@ -47,14 +47,14 @@ if (ENABLE_SPVREMAPPER) set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON) endif() -if(WIN32 AND BUILD_SHARED_LIBS) +if(WIN32 AND GLSLANG_BUILD_SHARED_LIBS) set_target_properties(SPIRV PROPERTIES PREFIX "") if (ENABLE_SPVREMAPPER) set_target_properties(SPVRemapper PROPERTIES PREFIX "") endif() endif() -if(ENABLE_OPT) +if(GLSLANG_ENABLE_OPT) target_include_directories(SPIRV PRIVATE ${spirv-tools_SOURCE_DIR}/include PRIVATE ${spirv-tools_SOURCE_DIR}/source @@ -65,7 +65,7 @@ if(ENABLE_OPT) $) else() target_link_libraries(SPIRV glslang) -endif(ENABLE_OPT) +endif(GLSLANG_ENABLE_OPT) if(WIN32) source_group("Source" FILES ${SOURCES} ${HEADERS}) @@ -73,7 +73,7 @@ if(WIN32) endif(WIN32) if(ENABLE_GLSLANG_INSTALL) - if(BUILD_SHARED_LIBS) + if(GLSLANG_BUILD_SHARED_LIBS) if (ENABLE_SPVREMAPPER) install(TARGETS SPVRemapper EXPORT SPVRemapperTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 5787e3d526..e3a6efb2b1 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -39,23 +39,23 @@ // translate them to SPIR-V. // -#include "spirv.hpp" #include "GlslangToSpv.h" #include "SpvBuilder.h" +#include "spirv.hpp" namespace spv { - #include "GLSL.std.450.h" - #include "GLSL.ext.KHR.h" - #include "GLSL.ext.EXT.h" - #include "GLSL.ext.AMD.h" - #include "GLSL.ext.NV.h" - #include "NonSemanticDebugPrintf.h" -} +#include "GLSL.ext.AMD.h" +#include "GLSL.ext.EXT.h" +#include "GLSL.ext.KHR.h" +#include "GLSL.ext.NV.h" +#include "GLSL.std.450.h" +#include "NonSemanticDebugPrintf.h" +} // namespace spv // Glslang includes -#include "../glslang/MachineIndependent/localintermediate.h" -#include "../glslang/MachineIndependent/SymbolTable.h" #include "../glslang/Include/Common.h" #include "../glslang/Include/revision.h" +#include "../glslang/MachineIndependent/SymbolTable.h" +#include "../glslang/MachineIndependent/localintermediate.h" #include #include @@ -70,17 +70,15 @@ namespace { namespace { class SpecConstantOpModeGuard { public: - SpecConstantOpModeGuard(spv::Builder* builder) - : builder_(builder) { + SpecConstantOpModeGuard(spv::Builder* builder) : builder_(builder) + { previous_flag_ = builder->isInSpecConstCodeGenMode(); } - ~SpecConstantOpModeGuard() { - previous_flag_ ? builder_->setToSpecConstCodeGenMode() - : builder_->setToNormalCodeGenMode(); - } - void turnOnSpecConstantOpMode() { - builder_->setToSpecConstCodeGenMode(); + ~SpecConstantOpModeGuard() + { + previous_flag_ ? builder_->setToSpecConstCodeGenMode() : builder_->setToNormalCodeGenMode(); } + void turnOnSpecConstantOpMode() { builder_->setToSpecConstCodeGenMode(); } private: spv::Builder* builder_; @@ -88,29 +86,29 @@ class SpecConstantOpModeGuard { }; struct OpDecorations { - public: - OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) : - precision(precision) +public: + OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) + : precision(precision) #ifndef GLSLANG_WEB - , - noContraction(noContraction), - nonUniform(nonUniform) + , + noContraction(noContraction), nonUniform(nonUniform) #endif - { } + { + } spv::Decoration precision; #ifdef GLSLANG_WEB - void addNoContraction(spv::Builder&, spv::Id) const { } - void addNonUniform(spv::Builder&, spv::Id) const { } + 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 + 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 @@ -123,8 +121,8 @@ struct OpDecorations { class TGlslangToSpvTraverser : public glslang::TIntermTraverser { public: TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate*, spv::SpvBuildLogger* logger, - glslang::SpvOptions& options); - virtual ~TGlslangToSpvTraverser() { } + glslang::SpvOptions& options); + virtual ~TGlslangToSpvTraverser() {} bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*); bool visitBinary(glslang::TVisit, glslang::TIntermBinary*); @@ -147,9 +145,9 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier); spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier); spv::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type); - spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); - spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); - spv::Scope TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags); + spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags& coherentFlags); + spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags& coherentFlags); + spv::Scope TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags& coherentFlags); spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration); spv::ImageFormat TranslateImageFormat(const glslang::TType& type); spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const; @@ -164,7 +162,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { void convertSwizzle(const glslang::TIntermAggregate&, std::vector& swizzle); spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&, - bool lastBufferBlockMember, bool forwardReferenceOnly = false); + bool lastBufferBlockMember, bool forwardReferenceOnly = false); bool filterMember(const glslang::TType& member); spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking, const glslang::TQualifier&); @@ -172,7 +170,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { const glslang::TQualifier&, spv::Id); spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim); spv::Id accessChainLoad(const glslang::TType& type); - void accessChainStore(const glslang::TType& type, spv::Id rvalue); + void accessChainStore(const glslang::TType& type, spv::Id rvalue); void multiTypeStore(const glslang::TType&, spv::Id rValue); glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const; int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix); @@ -189,7 +187,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { void visitFunctions(const glslang::TIntermSequence&); void handleFunctionEntry(const glslang::TIntermAggregate* node); void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, - spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + spv::Builder::AccessChain::CoherentFlags& lvalueCoherentFlags); void translateArguments(glslang::TIntermUnary& node, std::vector& arguments); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); @@ -199,7 +197,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { 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, - const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + 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, @@ -207,22 +205,22 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, - std::vector& operands, glslang::TBasicType typeProxy, - const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); + std::vector& operands, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags& lvalueCoherentFlags); spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, - glslang::TBasicType typeProxy); - spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, - spv::Id typeId, std::vector& operands); + glslang::TBasicType typeProxy); + spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, + std::vector& operands); spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, - glslang::TBasicType typeProxy); + glslang::TBasicType typeProxy); spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, - std::vector& operands, glslang::TBasicType typeProxy); + std::vector& operands, glslang::TBasicType typeProxy); spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId); spv::Id getSymbolId(const glslang::TIntermSymbol* node); - void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier); + void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier); spv::Id createSpvConstant(const glslang::TIntermTyped&); spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, - int& nextConst, bool specConstant); + 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); @@ -243,28 +241,28 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { 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 - std::set iOSet; // all input/output variables from either static use or declaration of interface + bool linkageOnly; // true when visiting the set of objects in the AST present only for + // establishing interface, whether or not they were statically used + std::set iOSet; // all input/output variables from either static use or declaration of interface const glslang::TIntermediate* glslangIntermediate; - bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp + bool nanMinMaxClamp; // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp spv::Id stdBuiltins; spv::Id nonSemanticDebugPrintf; std::unordered_map extBuiltinMap; std::unordered_map symbolValues; - std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, - // rather than a pointer + std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, + // rather than a pointer std::unordered_map functionMap; std::unordered_map structMap[glslang::ElpCount][glslang::ElmCount]; // for mapping glslang block indices to spv indices (e.g., due to hidden members): std::unordered_map> memberRemapper; // for mapping glslang symbol struct to symbol Id std::unordered_map glslangTypeToIdMap; - std::stack breakForLoop; // false means break for switch + std::stack breakForLoop; // false means break for switch std::unordered_map counterOriginator; // Map pointee types for EbtReference to their forward pointers - std::map forwardPointers; + std::map forwardPointers; // Type forcing, for when SPIR-V wants a different type than the AST, // requiring local translation to and from SPIR-V type on every access. // Maps AST-required-type-id> @@ -305,21 +303,35 @@ spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) { switch (stage) { - case EShLangVertex: return spv::ExecutionModelVertex; - case EShLangFragment: return spv::ExecutionModelFragment; - case EShLangCompute: return spv::ExecutionModelGLCompute; + 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 EShLangRayGenNV: return spv::ExecutionModelRayGenerationNV; - case EShLangIntersectNV: return spv::ExecutionModelIntersectionNV; - case EShLangAnyHitNV: return spv::ExecutionModelAnyHitNV; - case EShLangClosestHitNV: return spv::ExecutionModelClosestHitNV; - case EShLangMissNV: return spv::ExecutionModelMissNV; - case EShLangCallableNV: return spv::ExecutionModelCallableNV; - case EShLangTaskNV: return spv::ExecutionModelTaskNV; - case EShLangMeshNV: return spv::ExecutionModelMeshNV; + case EShLangTessControl: + return spv::ExecutionModelTessellationControl; + case EShLangTessEvaluation: + return spv::ExecutionModelTessellationEvaluation; + case EShLangGeometry: + return spv::ExecutionModelGeometry; + case EShLangRayGenNV: + return spv::ExecutionModelRayGenerationNV; + case EShLangIntersectNV: + return spv::ExecutionModelIntersectionNV; + case EShLangAnyHitNV: + return spv::ExecutionModelAnyHitNV; + case EShLangClosestHitNV: + return spv::ExecutionModelClosestHitNV; + case EShLangMissNV: + return spv::ExecutionModelMissNV; + case EShLangCallableNV: + return spv::ExecutionModelCallableNV; + case EShLangTaskNV: + return spv::ExecutionModelTaskNV; + case EShLangMeshNV: + return spv::ExecutionModelMeshNV; #endif default: assert(0); @@ -331,13 +343,20 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) spv::Dim TranslateDimensionality(const glslang::TSampler& sampler) { switch (sampler.dim) { - case glslang::Esd1D: return spv::Dim1D; - case glslang::Esd2D: return spv::Dim2D; - case glslang::Esd3D: return spv::Dim3D; - case glslang::EsdCube: return spv::DimCube; - case glslang::EsdRect: return spv::DimRect; - case glslang::EsdBuffer: return spv::DimBuffer; - case glslang::EsdSubpass: return spv::DimSubpassData; + case glslang::Esd1D: + return spv::Dim1D; + case glslang::Esd2D: + return spv::Dim2D; + case glslang::Esd3D: + return spv::Dim3D; + case glslang::EsdCube: + return spv::DimCube; + case glslang::EsdRect: + return spv::DimRect; + case glslang::EsdBuffer: + return spv::DimBuffer; + case glslang::EsdSubpass: + return spv::DimSubpassData; default: assert(0); return spv::Dim2D; @@ -348,8 +367,10 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler) spv::Decoration TranslatePrecisionDecoration(glslang::TPrecisionQualifier glslangPrecision) { switch (glslangPrecision) { - case glslang::EpqLow: return spv::DecorationRelaxedPrecision; - case glslang::EpqMedium: return spv::DecorationRelaxedPrecision; + case glslang::EpqLow: + return spv::DecorationRelaxedPrecision; + case glslang::EpqMedium: + return spv::DecorationRelaxedPrecision; default: return spv::NoPrecision; } @@ -366,16 +387,25 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto { if (type.getBasicType() == glslang::EbtBlock) { switch (type.getQualifier().storage) { - case glslang::EvqUniform: return spv::DecorationBlock; - case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; - case glslang::EvqVaryingIn: return spv::DecorationBlock; - case glslang::EvqVaryingOut: return spv::DecorationBlock; + case glslang::EvqUniform: + return spv::DecorationBlock; + case glslang::EvqBuffer: + return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; + case glslang::EvqVaryingIn: + return spv::DecorationBlock; + case glslang::EvqVaryingOut: + return spv::DecorationBlock; #ifndef GLSLANG_WEB - case glslang::EvqPayloadNV: return spv::DecorationBlock; - case glslang::EvqPayloadInNV: return spv::DecorationBlock; - case glslang::EvqHitAttrNV: return spv::DecorationBlock; - case glslang::EvqCallableDataNV: return spv::DecorationBlock; - case glslang::EvqCallableDataInNV: return spv::DecorationBlock; + case glslang::EvqPayloadNV: + return spv::DecorationBlock; + case glslang::EvqPayloadInNV: + return spv::DecorationBlock; + case glslang::EvqHitAttrNV: + return spv::DecorationBlock; + case glslang::EvqCallableDataNV: + return spv::DecorationBlock; + case glslang::EvqCallableDataInNV: + return spv::DecorationBlock; #endif default: assert(0); @@ -388,7 +418,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto // Translate glslang type to SPIR-V memory decorations. void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector& memory, - bool useVulkanMemoryModel) + bool useVulkanMemoryModel) { if (!useVulkanMemoryModel) { if (qualifier.isCoherent()) @@ -403,7 +433,7 @@ void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector if (qualifier.isReadOnly()) memory.push_back(spv::DecorationNonWritable); if (qualifier.isWriteOnly()) - memory.push_back(spv::DecorationNonReadable); + memory.push_back(spv::DecorationNonReadable); } // Translate glslang type to SPIR-V layout decorations. @@ -429,8 +459,10 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T case glslang::EvqUniform: case glslang::EvqBuffer: switch (type.getQualifier().layoutPacking) { - case glslang::ElpShared: return spv::DecorationGLSLShared; - case glslang::ElpPacked: return spv::DecorationGLSLPacked; + case glslang::ElpShared: + return spv::DecorationGLSLShared; + case glslang::ElpPacked: + return spv::DecorationGLSLPacked; default: return spv::DecorationMax; } @@ -438,9 +470,12 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T case glslang::EvqVaryingOut: if (type.getQualifier().isTaskMemory()) { switch (type.getQualifier().layoutPacking) { - case glslang::ElpShared: return spv::DecorationGLSLShared; - case glslang::ElpPacked: return spv::DecorationGLSLPacked; - default: break; + case glslang::ElpShared: + return spv::DecorationGLSLShared; + case glslang::ElpPacked: + return spv::DecorationGLSLPacked; + default: + break; } } else { assert(type.getQualifier().layoutPacking == glslang::ElpNone); @@ -477,8 +512,7 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g else if (qualifier.isExplicitInterpolation()) { builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter); return spv::DecorationExplicitInterpAMD; - } - else + } else return spv::DecorationMax; } @@ -534,8 +568,8 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl return spv::DecorationMax; } -spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( - const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +spv::MemoryAccessMask +TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags& coherentFlags) { spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone; @@ -543,14 +577,9 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) return mask; - if (coherentFlags.volatil || - coherentFlags.coherent || - coherentFlags.devicecoherent || - coherentFlags.queuefamilycoherent || - coherentFlags.workgroupcoherent || - coherentFlags.subgroupcoherent) { - mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask | - spv::MemoryAccessMakePointerVisibleKHRMask; + if (coherentFlags.volatil || coherentFlags.coherent || coherentFlags.devicecoherent || + coherentFlags.queuefamilycoherent || coherentFlags.workgroupcoherent || coherentFlags.subgroupcoherent) { + mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask; } if (coherentFlags.nonprivate) { mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask; @@ -566,8 +595,8 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( return mask; } -spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( - const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +spv::ImageOperandsMask +TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags& coherentFlags) { spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; @@ -575,14 +604,9 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( if (!glslangIntermediate->usingVulkanMemoryModel()) return mask; - if (coherentFlags.volatil || - coherentFlags.coherent || - coherentFlags.devicecoherent || - coherentFlags.queuefamilycoherent || - coherentFlags.workgroupcoherent || - coherentFlags.subgroupcoherent) { - mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask | - spv::ImageOperandsMakeTexelVisibleKHRMask; + if (coherentFlags.volatil || coherentFlags.coherent || coherentFlags.devicecoherent || + coherentFlags.queuefamilycoherent || coherentFlags.workgroupcoherent || coherentFlags.subgroupcoherent) { + mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask | spv::ImageOperandsMakeTexelVisibleKHRMask; } if (coherentFlags.nonprivate) { mask = mask | spv::ImageOperandsNonPrivateTexelKHRMask; @@ -606,25 +630,19 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere flags.devicecoherent = type.getQualifier().devicecoherent; flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent; // shared variables are implicitly workgroupcoherent in GLSL. - flags.workgroupcoherent = type.getQualifier().workgroupcoherent || - type.getQualifier().storage == glslang::EvqShared; + flags.workgroupcoherent = + type.getQualifier().workgroupcoherent || type.getQualifier().storage == glslang::EvqShared; flags.subgroupcoherent = type.getQualifier().subgroupcoherent; flags.volatil = type.getQualifier().volatil; // *coherent variables are implicitly nonprivate in GLSL - flags.nonprivate = type.getQualifier().nonprivate || - flags.subgroupcoherent || - flags.workgroupcoherent || - flags.queuefamilycoherent || - flags.devicecoherent || - flags.coherent || - flags.volatil; + flags.nonprivate = type.getQualifier().nonprivate || flags.subgroupcoherent || flags.workgroupcoherent || + flags.queuefamilycoherent || flags.devicecoherent || flags.coherent || flags.volatil; flags.isImage = type.getBasicType() == glslang::EbtSampler; #endif return flags; } -spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( - const spv::Builder::AccessChain::CoherentFlags &coherentFlags) +spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags& coherentFlags) { spv::Scope scope = spv::ScopeMax; @@ -655,13 +673,13 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( // 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) + bool memberDeclaration) { switch (builtIn) { case glslang::EbvPointSize: #ifndef GLSLANG_WEB // Defer adding the capability until the built-in is actually used. - if (! memberDeclaration) { + if (!memberDeclaration) { switch (glslangIntermediate->getStage()) { case EShLangGeometry: builder.addCapability(spv::CapabilityGeometryPointSize); @@ -677,23 +695,38 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI #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; + 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 @@ -714,8 +747,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvViewportIndex: builder.addCapability(spv::CapabilityMultiViewport); - if (glslangIntermediate->getStage() == EShLangVertex || - glslangIntermediate->getStage() == EShLangTessControl || + if (glslangIntermediate->getStage() == EShLangVertex || glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessEvaluation) { builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5); @@ -739,8 +771,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInLayer; } builder.addCapability(spv::CapabilityGeometry); - if (glslangIntermediate->getStage() == EShLangVertex || - glslangIntermediate->getStage() == EShLangTessControl || + if (glslangIntermediate->getStage() == EShLangVertex || glslangIntermediate->getStage() == EShLangTessControl || glslangIntermediate->getStage() == EShLangTessEvaluation) { builder.addIncorporatedExtension(spv::E_SPV_EXT_shader_viewport_index_layer, spv::Spv_1_5); @@ -773,12 +804,18 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityStencilExportEXT); return spv::BuiltInFragStencilRefEXT; - case glslang::EbvInvocationId: return spv::BuiltInInvocationId; - case glslang::EbvTessLevelInner: return spv::BuiltInTessLevelInner; - case glslang::EbvTessLevelOuter: return spv::BuiltInTessLevelOuter; - case glslang::EbvTessCoord: return spv::BuiltInTessCoord; - case glslang::EbvPatchVertices: return spv::BuiltInPatchVertices; - case glslang::EbvHelperInvocation: return spv::BuiltInHelperInvocation; + case glslang::EbvInvocationId: + return spv::BuiltInInvocationId; + case glslang::EbvTessLevelInner: + return spv::BuiltInTessLevelInner; + case glslang::EbvTessLevelOuter: + return spv::BuiltInTessLevelOuter; + case glslang::EbvTessCoord: + return spv::BuiltInTessCoord; + case glslang::EbvPatchVertices: + return spv::BuiltInPatchVertices; + case glslang::EbvHelperInvocation: + return spv::BuiltInHelperInvocation; case glslang::EbvSubGroupSize: builder.addExtension(spv::E_SPV_KHR_shader_ballot); @@ -1077,52 +1114,93 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy // do the translation switch (type.getQualifier().getFormat()) { - case glslang::ElfNone: return spv::ImageFormatUnknown; - case glslang::ElfRgba32f: return spv::ImageFormatRgba32f; - case glslang::ElfRgba16f: return spv::ImageFormatRgba16f; - case glslang::ElfR32f: return spv::ImageFormatR32f; - case glslang::ElfRgba8: return spv::ImageFormatRgba8; - case glslang::ElfRgba8Snorm: return spv::ImageFormatRgba8Snorm; - case glslang::ElfRg32f: return spv::ImageFormatRg32f; - case glslang::ElfRg16f: return spv::ImageFormatRg16f; - case glslang::ElfR11fG11fB10f: return spv::ImageFormatR11fG11fB10f; - case glslang::ElfR16f: return spv::ImageFormatR16f; - case glslang::ElfRgba16: return spv::ImageFormatRgba16; - case glslang::ElfRgb10A2: return spv::ImageFormatRgb10A2; - case glslang::ElfRg16: return spv::ImageFormatRg16; - case glslang::ElfRg8: return spv::ImageFormatRg8; - case glslang::ElfR16: return spv::ImageFormatR16; - case glslang::ElfR8: return spv::ImageFormatR8; - case glslang::ElfRgba16Snorm: return spv::ImageFormatRgba16Snorm; - case glslang::ElfRg16Snorm: return spv::ImageFormatRg16Snorm; - case glslang::ElfRg8Snorm: return spv::ImageFormatRg8Snorm; - case glslang::ElfR16Snorm: return spv::ImageFormatR16Snorm; - case glslang::ElfR8Snorm: return spv::ImageFormatR8Snorm; - case glslang::ElfRgba32i: return spv::ImageFormatRgba32i; - case glslang::ElfRgba16i: return spv::ImageFormatRgba16i; - case glslang::ElfRgba8i: return spv::ImageFormatRgba8i; - case glslang::ElfR32i: return spv::ImageFormatR32i; - case glslang::ElfRg32i: return spv::ImageFormatRg32i; - case glslang::ElfRg16i: return spv::ImageFormatRg16i; - case glslang::ElfRg8i: return spv::ImageFormatRg8i; - case glslang::ElfR16i: return spv::ImageFormatR16i; - case glslang::ElfR8i: return spv::ImageFormatR8i; - case glslang::ElfRgba32ui: return spv::ImageFormatRgba32ui; - case glslang::ElfRgba16ui: return spv::ImageFormatRgba16ui; - case glslang::ElfRgba8ui: return spv::ImageFormatRgba8ui; - case glslang::ElfR32ui: return spv::ImageFormatR32ui; - case glslang::ElfRg32ui: return spv::ImageFormatRg32ui; - case glslang::ElfRg16ui: return spv::ImageFormatRg16ui; - case glslang::ElfRgb10a2ui: return spv::ImageFormatRgb10a2ui; - case glslang::ElfRg8ui: return spv::ImageFormatRg8ui; - case glslang::ElfR16ui: return spv::ImageFormatR16ui; - case glslang::ElfR8ui: return spv::ImageFormatR8ui; - default: return spv::ImageFormatMax; + case glslang::ElfNone: + return spv::ImageFormatUnknown; + case glslang::ElfRgba32f: + return spv::ImageFormatRgba32f; + case glslang::ElfRgba16f: + return spv::ImageFormatRgba16f; + case glslang::ElfR32f: + return spv::ImageFormatR32f; + case glslang::ElfRgba8: + return spv::ImageFormatRgba8; + case glslang::ElfRgba8Snorm: + return spv::ImageFormatRgba8Snorm; + case glslang::ElfRg32f: + return spv::ImageFormatRg32f; + case glslang::ElfRg16f: + return spv::ImageFormatRg16f; + case glslang::ElfR11fG11fB10f: + return spv::ImageFormatR11fG11fB10f; + case glslang::ElfR16f: + return spv::ImageFormatR16f; + case glslang::ElfRgba16: + return spv::ImageFormatRgba16; + case glslang::ElfRgb10A2: + return spv::ImageFormatRgb10A2; + case glslang::ElfRg16: + return spv::ImageFormatRg16; + case glslang::ElfRg8: + return spv::ImageFormatRg8; + case glslang::ElfR16: + return spv::ImageFormatR16; + case glslang::ElfR8: + return spv::ImageFormatR8; + case glslang::ElfRgba16Snorm: + return spv::ImageFormatRgba16Snorm; + case glslang::ElfRg16Snorm: + return spv::ImageFormatRg16Snorm; + case glslang::ElfRg8Snorm: + return spv::ImageFormatRg8Snorm; + case glslang::ElfR16Snorm: + return spv::ImageFormatR16Snorm; + case glslang::ElfR8Snorm: + return spv::ImageFormatR8Snorm; + case glslang::ElfRgba32i: + return spv::ImageFormatRgba32i; + case glslang::ElfRgba16i: + return spv::ImageFormatRgba16i; + case glslang::ElfRgba8i: + return spv::ImageFormatRgba8i; + case glslang::ElfR32i: + return spv::ImageFormatR32i; + case glslang::ElfRg32i: + return spv::ImageFormatRg32i; + case glslang::ElfRg16i: + return spv::ImageFormatRg16i; + case glslang::ElfRg8i: + return spv::ImageFormatRg8i; + case glslang::ElfR16i: + return spv::ImageFormatR16i; + case glslang::ElfR8i: + return spv::ImageFormatR8i; + case glslang::ElfRgba32ui: + return spv::ImageFormatRgba32ui; + case glslang::ElfRgba16ui: + return spv::ImageFormatRgba16ui; + case glslang::ElfRgba8ui: + return spv::ImageFormatRgba8ui; + case glslang::ElfR32ui: + return spv::ImageFormatR32ui; + case glslang::ElfRg32ui: + return spv::ImageFormatRg32ui; + case glslang::ElfRg16ui: + return spv::ImageFormatRg16ui; + case glslang::ElfRgb10a2ui: + return spv::ImageFormatRgb10a2ui; + case glslang::ElfRg8ui: + return spv::ImageFormatRg8ui; + case glslang::ElfR16ui: + return spv::ImageFormatR16ui; + case glslang::ElfR8ui: + return spv::ImageFormatR8ui; + default: + return spv::ImageFormatMax; } } -spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl( - const glslang::TIntermSelection& selectionNode) const +spv::SelectionControlMask +TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const { if (selectionNode.getFlatten()) return spv::SelectionControlFlattenMask; @@ -1131,8 +1209,7 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl( 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; @@ -1143,7 +1220,7 @@ spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const g // return a non-0 dependency if the dependency argument must be set spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode, - std::vector& operands) const + std::vector& operands) const { spv::LoopControlMask control = spv::LoopControlMaskNone; @@ -1192,15 +1269,14 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T return spv::StorageClassOutput; if (glslangIntermediate->getSource() != glslang::EShSourceHlsl || - type.getQualifier().storage == glslang::EvqUniform) { + type.getQualifier().storage == glslang::EvqUniform) { if (type.isAtomic()) return spv::StorageClassAtomicCounter; if (type.containsOpaque()) return spv::StorageClassUniformConstant; } - if (type.getQualifier().isUniformOrBuffer() && - type.getQualifier().isShaderRecordNV()) { + if (type.getQualifier().isUniformOrBuffer() && type.getQualifier().isShaderRecordNV()) { return spv::StorageClassShaderRecordBufferNV; } @@ -1218,16 +1294,25 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T } switch (type.getQualifier().storage) { - case glslang::EvqGlobal: return spv::StorageClassPrivate; - case glslang::EvqConstReadOnly: return spv::StorageClassFunction; - case glslang::EvqTemporary: return spv::StorageClassFunction; - case glslang::EvqShared: return spv::StorageClassWorkgroup; + case glslang::EvqGlobal: + return spv::StorageClassPrivate; + case glslang::EvqConstReadOnly: + return spv::StorageClassFunction; + case glslang::EvqTemporary: + return spv::StorageClassFunction; + case glslang::EvqShared: + return spv::StorageClassWorkgroup; #ifndef GLSLANG_WEB - case glslang::EvqPayloadNV: return spv::StorageClassRayPayloadNV; - case glslang::EvqPayloadInNV: return spv::StorageClassIncomingRayPayloadNV; - case glslang::EvqHitAttrNV: return spv::StorageClassHitAttributeNV; - case glslang::EvqCallableDataNV: return spv::StorageClassCallableDataNV; - case glslang::EvqCallableDataInNV: return spv::StorageClassIncomingCallableDataNV; + case glslang::EvqPayloadNV: + return spv::StorageClassRayPayloadNV; + case glslang::EvqPayloadInNV: + return spv::StorageClassIncomingRayPayloadNV; + case glslang::EvqHitAttrNV: + return spv::StorageClassHitAttributeNV; + case glslang::EvqCallableDataNV: + return spv::StorageClassCallableDataNV; + case glslang::EvqCallableDataInNV: + return spv::StorageClassIncomingCallableDataNV; #endif default: assert(0); @@ -1286,9 +1371,8 @@ bool IsDescriptorResource(const glslang::TType& type) { // uniform and buffer blocks are included, unless it is a push_constant if (type.getBasicType() == glslang::EbtBlock) - return type.getQualifier().isUniformOrBuffer() && - ! type.getQualifier().isShaderRecordNV() && - ! type.getQualifier().isPushConstant(); + return type.getQualifier().isUniformOrBuffer() && !type.getQualifier().isShaderRecordNV() && + !type.getQualifier().isPushConstant(); // non block... // basically samplerXXX/subpass/sampler/texture are all included @@ -1368,17 +1452,13 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie // 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) + 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()); @@ -1477,27 +1557,40 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, 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; + 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; + case glslang::EioPixelInterlockOrdered: + mode = spv::ExecutionModePixelInterlockOrderedEXT; break; - case glslang::EioPixelInterlockUnordered: mode = spv::ExecutionModePixelInterlockUnorderedEXT; + case glslang::EioPixelInterlockUnordered: + mode = spv::ExecutionModePixelInterlockUnorderedEXT; break; - case glslang::EioSampleInterlockOrdered: mode = spv::ExecutionModeSampleInterlockOrderedEXT; + case glslang::EioSampleInterlockOrdered: + mode = spv::ExecutionModeSampleInterlockOrderedEXT; break; - case glslang::EioSampleInterlockUnordered: mode = spv::ExecutionModeSampleInterlockUnorderedEXT; + case glslang::EioSampleInterlockUnordered: + mode = spv::ExecutionModeSampleInterlockUnorderedEXT; break; - case glslang::EioShadingRateInterlockOrdered: mode = spv::ExecutionModeShadingRateInterlockOrderedEXT; + case glslang::EioShadingRateInterlockOrdered: + mode = spv::ExecutionModeShadingRateInterlockOrderedEXT; break; - case glslang::EioShadingRateInterlockUnordered: mode = spv::ExecutionModeShadingRateInterlockUnorderedEXT; + case glslang::EioShadingRateInterlockUnordered: + mode = spv::ExecutionModeShadingRateInterlockUnorderedEXT; break; - default: mode = spv::ExecutionModeMax; + default: + mode = spv::ExecutionModeMax; break; } if (mode != spv::ExecutionModeMax) { @@ -1519,8 +1612,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, case EShLangCompute: builder.addCapability(spv::CapabilityShader); builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), - glslangIntermediate->getLocalSize(1), - glslangIntermediate->getLocalSize(2)); + glslangIntermediate->getLocalSize(1), glslangIntermediate->getLocalSize(2)); if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) { builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV); builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV); @@ -1539,35 +1631,56 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, 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(); } switch (primitive) { - case glslang::ElgTriangles: mode = spv::ExecutionModeTriangles; break; - case glslang::ElgQuads: mode = spv::ExecutionModeQuads; break; - case glslang::ElgIsolines: mode = spv::ExecutionModeIsolines; break; - default: mode = spv::ExecutionModeMax; break; + case glslang::ElgTriangles: + mode = spv::ExecutionModeTriangles; + break; + case glslang::ElgQuads: + mode = spv::ExecutionModeQuads; + break; + case glslang::ElgIsolines: + mode = spv::ExecutionModeIsolines; + break; + default: + mode = spv::ExecutionModeMax; + break; } if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); switch (glslangIntermediate->getVertexSpacing()) { - case glslang::EvsEqual: mode = spv::ExecutionModeSpacingEqual; break; - case glslang::EvsFractionalEven: mode = spv::ExecutionModeSpacingFractionalEven; break; - case glslang::EvsFractionalOdd: mode = spv::ExecutionModeSpacingFractionalOdd; break; - default: mode = spv::ExecutionModeMax; break; + case glslang::EvsEqual: + mode = spv::ExecutionModeSpacingEqual; + break; + case glslang::EvsFractionalEven: + mode = spv::ExecutionModeSpacingFractionalEven; + break; + case glslang::EvsFractionalOdd: + mode = spv::ExecutionModeSpacingFractionalOdd; + break; + default: + mode = spv::ExecutionModeMax; + break; } if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); switch (glslangIntermediate->getVertexOrder()) { - case glslang::EvoCw: mode = spv::ExecutionModeVertexOrderCw; break; - case glslang::EvoCcw: mode = spv::ExecutionModeVertexOrderCcw; break; - default: mode = spv::ExecutionModeMax; break; + case glslang::EvoCw: + mode = spv::ExecutionModeVertexOrderCw; + break; + case glslang::EvoCcw: + mode = spv::ExecutionModeVertexOrderCcw; + break; + default: + mode = spv::ExecutionModeMax; + break; } if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); @@ -1579,12 +1692,24 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, case EShLangGeometry: builder.addCapability(spv::CapabilityGeometry); switch (glslangIntermediate->getInputPrimitive()) { - case glslang::ElgPoints: mode = spv::ExecutionModeInputPoints; break; - case glslang::ElgLines: mode = spv::ExecutionModeInputLines; break; - case glslang::ElgLinesAdjacency: mode = spv::ExecutionModeInputLinesAdjacency; break; - case glslang::ElgTriangles: mode = spv::ExecutionModeTriangles; break; - case glslang::ElgTrianglesAdjacency: mode = spv::ExecutionModeInputTrianglesAdjacency; break; - default: mode = spv::ExecutionModeMax; break; + case glslang::ElgPoints: + mode = spv::ExecutionModeInputPoints; + break; + case glslang::ElgLines: + mode = spv::ExecutionModeInputLines; + break; + case glslang::ElgLinesAdjacency: + mode = spv::ExecutionModeInputLinesAdjacency; + break; + case glslang::ElgTriangles: + mode = spv::ExecutionModeTriangles; + break; + case glslang::ElgTrianglesAdjacency: + mode = spv::ExecutionModeInputTrianglesAdjacency; + break; + default: + mode = spv::ExecutionModeMax; + break; } if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); @@ -1592,10 +1717,18 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addExecutionMode(shaderEntry, spv::ExecutionModeInvocations, glslangIntermediate->getInvocations()); switch (glslangIntermediate->getOutputPrimitive()) { - case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break; - case glslang::ElgLineStrip: mode = spv::ExecutionModeOutputLineStrip; break; - case glslang::ElgTriangleStrip: mode = spv::ExecutionModeOutputTriangleStrip; break; - default: mode = spv::ExecutionModeMax; break; + case glslang::ElgPoints: + mode = spv::ExecutionModeOutputPoints; + break; + case glslang::ElgLineStrip: + mode = spv::ExecutionModeOutputLineStrip; + break; + case glslang::ElgTriangleStrip: + mode = spv::ExecutionModeOutputTriangleStrip; + break; + default: + mode = spv::ExecutionModeMax; + break; } if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); @@ -1616,19 +1749,25 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addCapability(spv::CapabilityMeshShadingNV); builder.addExtension(spv::E_SPV_NV_mesh_shader); builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), - glslangIntermediate->getLocalSize(1), - glslangIntermediate->getLocalSize(2)); + glslangIntermediate->getLocalSize(1), glslangIntermediate->getLocalSize(2)); if (glslangIntermediate->getStage() == EShLangMeshNV) { - builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, - glslangIntermediate->getVertices()); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, - glslangIntermediate->getPrimitives()); + glslangIntermediate->getPrimitives()); switch (glslangIntermediate->getOutputPrimitive()) { - case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break; - case glslang::ElgLines: mode = spv::ExecutionModeOutputLinesNV; break; - case glslang::ElgTriangles: mode = spv::ExecutionModeOutputTrianglesNV; break; - default: mode = spv::ExecutionModeMax; break; + case glslang::ElgPoints: + mode = spv::ExecutionModeOutputPoints; + break; + case glslang::ElgLines: + mode = spv::ExecutionModeOutputLinesNV; + break; + case glslang::ElgTriangles: + mode = spv::ExecutionModeOutputTrianglesNV; + break; + default: + mode = spv::ExecutionModeMax; + break; } if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); @@ -1645,7 +1784,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, void TGlslangToSpvTraverser::finishSpv() { // Finish the entry point function - if (! entryPointTerminated) { + if (!entryPointTerminated) { builder.setBuildPoint(shaderEntry->getLastBlock()); builder.leaveFunction(); } @@ -1662,10 +1801,7 @@ void TGlslangToSpvTraverser::finishSpv() } // Write the SPV into 'out'. -void TGlslangToSpvTraverser::dumpSpv(std::vector& out) -{ - builder.dump(out); -} +void TGlslangToSpvTraverser::dumpSpv(std::vector& out) { builder.dump(out); } // // Implement the traversal functions. @@ -1719,7 +1855,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) } // Only process non-linkage-only nodes for generating actual static uses - if (! linkageOnly || symbol->getQualifier().isSpecConstant()) { + if (!linkageOnly || symbol->getQualifier().isSpecConstant()) { // Prepare to generate code for the access // L-value chains will be computed left to right. We're on the symbol now, @@ -1742,7 +1878,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) builder.setAccessChainLValue(id); } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL // Process linkage-only nodes for any special additional interface work. if (linkageOnly) { if (glslangIntermediate->getHlslFunctionality1()) { @@ -1829,12 +1965,11 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T spv::Id leftRValue = accessChainLoad(node->getLeft()->getType()); // do the operation - OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), - TranslateNoContractionDecoration(node->getType().getQualifier()), - TranslateNonUniformDecoration(node->getType().getQualifier()) }; - rValue = createBinaryOperation(node->getOp(), decorations, - convertGlslangToSpvType(node->getType()), leftRValue, rValue, - node->getType().getBasicType()); + OpDecorations decorations = {TranslatePrecisionDecoration(node->getOperationPrecision()), + TranslateNoContractionDecoration(node->getType().getQualifier()), + TranslateNonUniformDecoration(node->getType().getQualifier())}; + rValue = createBinaryOperation(node->getOp(), decorations, convertGlslangToSpvType(node->getType()), + leftRValue, rValue, node->getType().getBasicType()); // these all need their counterparts in createBinaryOperation() assert(rValue != spv::NoResult); @@ -1850,132 +1985,122 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T } return false; 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); - - // Add the next element in the chain - - const int glslangIndex = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); - if (! node->getLeft()->getType().isArray() && - node->getLeft()->getType().isVector() && - node->getOp() == glslang::EOpIndexDirect) { - // This is essentially a hard-coded vector swizzle of size 1, - // so short circuit the access-chain stuff with a swizzle. - std::vector swizzle; - swizzle.push_back(glslangIndex); - int dummySize; - builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), - TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar( - node->getLeft()->getType(), dummySize)); - } else { + 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); + + // Add the next element in the chain + + const int glslangIndex = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); + if (!node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector() && + node->getOp() == glslang::EOpIndexDirect) { + // This is essentially a hard-coded vector swizzle of size 1, + // so short circuit the access-chain stuff with a swizzle. + std::vector swizzle; + swizzle.push_back(glslangIndex); + int dummySize; + builder.accessChainPushSwizzle( + swizzle, convertGlslangToSpvType(node->getLeft()->getType()), + TranslateCoherent(node->getLeft()->getType()), + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + } else { - // Load through a block reference is performed with a dot operator that - // is mapped to EOpIndexDirectStruct. When we get to the actual reference, - // do a load and reset the access chain. - if (node->getLeft()->isReference() && - !node->getLeft()->getType().isArray() && - node->getOp() == glslang::EOpIndexDirectStruct) - { - spv::Id left = accessChainLoad(node->getLeft()->getType()); - builder.clearAccessChain(); - builder.setAccessChainLValue(left); - } + // Load through a block reference is performed with a dot operator that + // is mapped to EOpIndexDirectStruct. When we get to the actual reference, + // do a load and reset the access chain. + if (node->getLeft()->isReference() && !node->getLeft()->getType().isArray() && + node->getOp() == glslang::EOpIndexDirectStruct) { + spv::Id left = accessChainLoad(node->getLeft()->getType()); + builder.clearAccessChain(); + builder.setAccessChainLValue(left); + } - int spvIndex = glslangIndex; - if (node->getLeft()->getBasicType() == glslang::EbtBlock && - node->getOp() == glslang::EOpIndexDirectStruct) - { - // This may be, e.g., an anonymous block-member selection, which generally need - // index remapping due to hidden members in anonymous blocks. - int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; - if (memberRemapper.find(glslangId) != memberRemapper.end()) { - std::vector& remapper = memberRemapper[glslangId]; - assert(remapper.size() > 0); - spvIndex = remapper[glslangIndex]; - } + int spvIndex = glslangIndex; + if (node->getLeft()->getBasicType() == glslang::EbtBlock && + node->getOp() == glslang::EOpIndexDirectStruct) { + // This may be, e.g., an anonymous block-member selection, which generally need + // index remapping due to hidden members in anonymous blocks. + int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; + if (memberRemapper.find(glslangId) != memberRemapper.end()) { + std::vector& remapper = memberRemapper[glslangId]; + assert(remapper.size() > 0); + spvIndex = remapper[glslangIndex]; } + } - // normal case for indexing array or structure or block - builder.accessChainPush(builder.makeIntConstant(spvIndex), - TranslateCoherent(node->getLeft()->getType()), - node->getLeft()->getType().getBufferReferenceAlignment()); + // normal case for indexing array or structure or block + 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. - if (node->getLeft()->getType().isStruct() && ! node->getLeft()->getType().isArray()) - declareUseOfStructMember(*(node->getLeft()->getType().getStruct()), glslangIndex); - } + // Add capabilities here for accessing PointSize and clip/cull distance. + // We have deferred generation of associated capabilities until now. + if (node->getLeft()->getType().isStruct() && !node->getLeft()->getType().isArray()) + declareUseOfStructMember(*(node->getLeft()->getType().getStruct()), glslangIndex); } + } return false; - case glslang::EOpIndexIndirect: - { - // 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. + case glslang::EOpIndexIndirect: { + // 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. - // This adapter is building access chains left to right. - // Set up the access chain to the left. - node->getLeft()->traverse(this); + // This adapter is building access chains left to right. + // Set up the access chain to the left. + node->getLeft()->traverse(this); - // save it so that computing the right side doesn't trash it - spv::Builder::AccessChain partial = builder.getAccessChain(); + // save it so that computing the right side doesn't trash it + spv::Builder::AccessChain partial = builder.getAccessChain(); - // compute the next index in the chain - builder.clearAccessChain(); - node->getRight()->traverse(this); - spv::Id index = accessChainLoad(node->getRight()->getType()); + // compute the next index in the chain + builder.clearAccessChain(); + node->getRight()->traverse(this); + spv::Id index = accessChainLoad(node->getRight()->getType()); - addIndirectionIndexCapabilities(node->getLeft()->getType(), node->getRight()->getType()); + addIndirectionIndexCapabilities(node->getLeft()->getType(), node->getRight()->getType()); - // restore the saved access chain - builder.setAccessChain(partial); + // restore the saved access chain + builder.setAccessChain(partial); - if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) { - int dummySize; - builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()), - TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), - dummySize)); - } else - builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), - node->getLeft()->getType().getBufferReferenceAlignment()); - } - return false; - case glslang::EOpVectorSwizzle: - { - node->getLeft()->traverse(this); - std::vector swizzle; - convertSwizzle(*node->getRight()->getAsAggregate(), swizzle); + if (!node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector()) { int dummySize; - builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()), - TranslateCoherent(node->getLeft()->getType()), - glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), - dummySize)); - } + builder.accessChainPushComponent( + index, convertGlslangToSpvType(node->getLeft()->getType()), + TranslateCoherent(node->getLeft()->getType()), + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + } else + builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()), + node->getLeft()->getType().getBufferReferenceAlignment()); + } + return false; + case glslang::EOpVectorSwizzle: { + node->getLeft()->traverse(this); + std::vector swizzle; + convertSwizzle(*node->getRight()->getAsAggregate(), swizzle); + int dummySize; + builder.accessChainPushSwizzle( + swizzle, convertGlslangToSpvType(node->getLeft()->getType()), TranslateCoherent(node->getLeft()->getType()), + glslangIntermediate->getBaseAlignmentScalar(node->getLeft()->getType(), dummySize)); + } return false; case glslang::EOpMatrixSwizzle: logger->missingFunctionality("matrix swizzle"); return true; case glslang::EOpLogicalOr: - case glslang::EOpLogicalAnd: - { - - // These may require short circuiting, but can sometimes be done as straight - // binary operations. The right operand must be short circuited if it has - // side effects, and should probably be if it is complex. - 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()); - builder.clearAccessChain(); - builder.setAccessChainRValue(result); - } + case glslang::EOpLogicalAnd: { + + // These may require short circuiting, but can sometimes be done as straight + // binary operations. The right operand must be short circuited if it has + // side effects, and should probably be if it is complex. + 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()); + builder.clearAccessChain(); + builder.setAccessChainRValue(result); + } return false; default: break; @@ -1994,17 +2119,16 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T spv::Id right = accessChainLoad(node->getRight()->getType()); // get result - OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), - TranslateNoContractionDecoration(node->getType().getQualifier()), - TranslateNonUniformDecoration(node->getType().getQualifier()) }; - spv::Id result = createBinaryOperation(node->getOp(), decorations, - convertGlslangToSpvType(node->getType()), left, right, - node->getLeft()->getType().getBasicType()); + OpDecorations decorations = {TranslatePrecisionDecoration(node->getOperationPrecision()), + TranslateNoContractionDecoration(node->getType().getQualifier()), + TranslateNonUniformDecoration(node->getType().getQualifier())}; + spv::Id result = createBinaryOperation(node->getOp(), decorations, convertGlslangToSpvType(node->getType()), left, + right, node->getLeft()->getType().getBasicType()); builder.clearAccessChain(); - if (! result) { + if (!result) { logger->missingFunctionality("unknown glslang binary operation"); - return true; // pick up a child as the place-holder result + return true; // pick up a child as the place-holder result } else { builder.setAccessChainRValue(result); return false; @@ -2015,24 +2139,22 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // Returns . // Also see comment for 'forceType', regarding tracking SPIR-V-required types. std::pair TGlslangToSpvTraverser::getForcedType(spv::BuiltIn builtIn, - const glslang::TType& glslangType) + const glslang::TType& glslangType) { - switch(builtIn) - { - case spv::BuiltInSubgroupEqMask: - case spv::BuiltInSubgroupGeMask: - case spv::BuiltInSubgroupGtMask: - case spv::BuiltInSubgroupLeMask: - case spv::BuiltInSubgroupLtMask: { - // these require changing a 64-bit scaler -> a vector of 32-bit components - if (glslangType.isVector()) - break; - std::pair ret(builder.makeVectorType(builder.makeUintType(32), 4), - builder.makeUintType(64)); - return ret; - } - default: + switch (builtIn) { + case spv::BuiltInSubgroupEqMask: + case spv::BuiltInSubgroupGeMask: + case spv::BuiltInSubgroupGtMask: + case spv::BuiltInSubgroupLeMask: + case spv::BuiltInSubgroupLtMask: { + // these require changing a 64-bit scaler -> a vector of 32-bit components + if (glslangType.isVector()) break; + std::pair ret(builder.makeVectorType(builder.makeUintType(32), 4), builder.makeUintType(64)); + return ret; + } + default: + break; } std::pair ret(spv::NoType, spv::NoType); @@ -2120,8 +2242,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI } 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); } @@ -2147,18 +2269,19 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // 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; + TIntermNode* operandNode; if (invertedType != spv::NoType) operandNode = node->getOperand()->getAsBinaryNode()->getLeft(); else operandNode = node->getOperand(); - + operandNode->traverse(this); spv::Id operand = spv::NoResult; @@ -2166,10 +2289,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI 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) { + if (node->getOp() == glslang::EOpAtomicCounterIncrement || node->getOp() == glslang::EOpAtomicCounterDecrement || + node->getOp() == glslang::EOpAtomicCounter || node->getOp() == glslang::EOpInterpolateAtCentroid) { operand = builder.accessChainGetLValue(); // Special case l-value operands lvalueCoherentFlags = builder.getAccessChain().coherentFlags; lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); @@ -2179,19 +2300,19 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI operand = accessChainLoad(node->getOperand()->getType()); } - OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), - TranslateNoContractionDecoration(node->getType().getQualifier()), - TranslateNonUniformDecoration(node->getType().getQualifier()) }; + OpDecorations decorations = {TranslatePrecisionDecoration(node->getOperationPrecision()), + TranslateNoContractionDecoration(node->getType().getQualifier()), + TranslateNonUniformDecoration(node->getType().getQualifier())}; // it could be a conversion - if (! result) - result = createConversion(node->getOp(), decorations, resultType(), operand, - node->getOperand()->getBasicType()); + if (!result) + result = + createConversion(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType()); // if not, then possibly an operation - if (! result) + if (!result) result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, - node->getOperand()->getBasicType(), lvalueCoherentFlags); + node->getOperand()->getBasicType(), lvalueCoherentFlags); if (result) { if (invertedType) { @@ -2210,48 +2331,44 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI case glslang::EOpPostIncrement: case glslang::EOpPostDecrement: case glslang::EOpPreIncrement: - case glslang::EOpPreDecrement: - { - // we need the integer value "1" or the floating point "1.0" to add/subtract - spv::Id one = 0; - if (node->getBasicType() == glslang::EbtFloat) - one = builder.makeFloatConstant(1.0F); + case glslang::EOpPreDecrement: { + // we need the integer value "1" or the floating point "1.0" to add/subtract + 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) - one = builder.makeFloat16Constant(1.0F); - else if (node->getBasicType() == glslang::EbtInt8 || node->getBasicType() == glslang::EbtUint8) - one = builder.makeInt8Constant(1); - else if (node->getBasicType() == glslang::EbtInt16 || node->getBasicType() == glslang::EbtUint16) - one = builder.makeInt16Constant(1); - else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64) - one = builder.makeInt64Constant(1); + else if (node->getBasicType() == glslang::EbtDouble) + one = builder.makeDoubleConstant(1.0); + else if (node->getBasicType() == glslang::EbtFloat16) + one = builder.makeFloat16Constant(1.0F); + else if (node->getBasicType() == glslang::EbtInt8 || node->getBasicType() == glslang::EbtUint8) + one = builder.makeInt8Constant(1); + else if (node->getBasicType() == glslang::EbtInt16 || node->getBasicType() == glslang::EbtUint16) + 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; - if (node->getOp() == glslang::EOpPreIncrement || - node->getOp() == glslang::EOpPostIncrement) - op = glslang::EOpAdd; - else - op = glslang::EOpSub; + else + one = builder.makeIntConstant(1); + glslang::TOperator op; + if (node->getOp() == glslang::EOpPreIncrement || node->getOp() == glslang::EOpPostIncrement) + op = glslang::EOpAdd; + else + op = glslang::EOpSub; - spv::Id result = createBinaryOperation(op, decorations, - convertGlslangToSpvType(node->getType()), operand, one, - node->getType().getBasicType()); - assert(result != spv::NoResult); + spv::Id result = createBinaryOperation(op, decorations, convertGlslangToSpvType(node->getType()), operand, one, + node->getType().getBasicType()); + assert(result != spv::NoResult); - // The result of operation is always stored, but conditionally the - // consumed result. The consumed result is always an r-value. - builder.accessChainStore(result); - builder.clearAccessChain(); - if (node->getOp() == glslang::EOpPreIncrement || - node->getOp() == glslang::EOpPreDecrement) - builder.setAccessChainRValue(result); - else - builder.setAccessChainRValue(operand); - } + // The result of operation is always stored, but conditionally the + // consumed result. The consumed result is always an r-value. + builder.accessChainStore(result); + builder.clearAccessChain(); + if (node->getOp() == glslang::EOpPreIncrement || node->getOp() == glslang::EOpPreDecrement) + builder.setAccessChainRValue(result); + else + builder.setAccessChainRValue(operand); + } return false; @@ -2266,7 +2383,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI default: logger->missingFunctionality("unknown glslang unary"); - return true; // pick up operand as placeholder result + return true; // pick up operand as placeholder result } } @@ -2284,8 +2401,8 @@ spv::Id TGlslangToSpvTraverser::createCompositeConstruct(spv::Id resultTypeId, s std::vector rTypeConstituents; int numrTypeConstituents = builder.getNumTypeConstituents(rType); for (int i = 0; i < numrTypeConstituents; ++i) { - rTypeConstituents.push_back(builder.createCompositeExtract(constituent, - builder.getContainedTypeId(rType, i), i)); + rTypeConstituents.push_back( + builder.createCompositeExtract(constituent, builder.getContainedTypeId(rType, i), i)); } constituents[c] = createCompositeConstruct(lType, rTypeConstituents); } else { @@ -2311,14 +2428,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt 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 - spv::Builder::AccessChain complexLvalue; // for holding swizzling l-values too complex for SPIR-V, - // for at out parameter - spv::Id temporaryLvalue = spv::NoResult; // temporary to pass, as proxy for complexLValue + spv::Id invertedType = spv::NoType; // to use to override the natural type of the node + spv::Builder::AccessChain complexLvalue; // for holding swizzling l-values too complex for SPIR-V, + // for at out parameter + spv::Id temporaryLvalue = spv::NoResult; // temporary to pass, as proxy for complexLValue - 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()); + }; // try texturing result = createImageTextureFunctionCall(node); @@ -2329,9 +2446,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt return false; } #ifndef GLSLANG_WEB - else if (node->getOp() == glslang::EOpImageStore || - node->getOp() == glslang::EOpImageStoreLod || - node->getOp() == glslang::EOpImageAtomicStore) { + else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod || + node->getOp() == glslang::EOpImageAtomicStore) { // "imageStore" is a special case, which has no result return false; } @@ -2350,8 +2466,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); switch (node->getOp()) { - case glslang::EOpSequence: - { + case glslang::EOpSequence: { if (preVisit) ++sequenceDepth; else @@ -2376,8 +2491,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt return true; } - case glslang::EOpLinkerObjects: - { + case glslang::EOpLinkerObjects: { if (visit == glslang::EvPreVisit) linkageOnly = true; else @@ -2385,8 +2499,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt return true; } - case glslang::EOpComma: - { + case glslang::EOpComma: { // processing from left to right naturally leaves the right-most // lying around in the access chain glslang::TIntermSequence& glslangOperands = node->getSequence(); @@ -2417,8 +2530,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // the body, so we still visited the function node's children, making this // child redundant. return false; - case glslang::EOpFunctionCall: - { + case glslang::EOpFunctionCall: { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); if (node->isUserDefined()) result = handleUserFunctionCall(node); @@ -2537,8 +2649,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpConstructStruct: case glslang::EOpConstructTextureSampler: case glslang::EOpConstructReference: - case glslang::EOpConstructCooperativeMatrix: - { + case glslang::EOpConstructCooperativeMatrix: { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); std::vector arguments; translateArguments(*node, arguments, lvalueCoherentFlags); @@ -2546,8 +2657,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (node->getOp() == glslang::EOpConstructTextureSampler) constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments); else if (node->getOp() == glslang::EOpConstructStruct || - node->getOp() == glslang::EOpConstructCooperativeMatrix || - node->getType().isArray()) { + node->getOp() == glslang::EOpConstructCooperativeMatrix || node->getType().isArray()) { std::vector constituents; for (int c = 0; c < (int)arguments.size(); ++c) constituents.push_back(arguments[c]); @@ -2570,15 +2680,20 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpLessThanEqual: case glslang::EOpGreaterThanEqual: case glslang::EOpVectorEqual: - case glslang::EOpVectorNotEqual: - { + case glslang::EOpVectorNotEqual: { // Map the operation to a binary binOp = node->getOp(); reduceComparison = false; switch (node->getOp()) { - case glslang::EOpVectorEqual: binOp = glslang::EOpVectorEqual; break; - case glslang::EOpVectorNotEqual: binOp = glslang::EOpVectorNotEqual; break; - default: binOp = node->getOp(); break; + case glslang::EOpVectorEqual: + binOp = glslang::EOpVectorEqual; + break; + case glslang::EOpVectorNotEqual: + binOp = glslang::EOpVectorNotEqual; + break; + default: + binOp = node->getOp(); + break; } break; @@ -2591,8 +2706,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // two vectors multiplied to make a matrix binOp = glslang::EOpOuterProduct; break; - case glslang::EOpDot: - { + case glslang::EOpDot: { // for scalar dot product, use multiply glslang::TIntermSequence& glslangOperands = node->getSequence(); if (glslangOperands[0]->getAsTyped()->getVectorSize() == 1) @@ -2715,11 +2829,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spv::Id rightId = accessChainLoad(right->getType()); builder.setLine(node->getLoc().line, node->getLoc().getFilename()); - OpDecorations decorations = { precision, - TranslateNoContractionDecoration(node->getType().getQualifier()), - TranslateNonUniformDecoration(node->getType().getQualifier()) }; - result = createBinaryOperation(binOp, decorations, - resultType(), leftId, rightId, + OpDecorations decorations = {precision, TranslateNoContractionDecoration(node->getType().getQualifier()), + TranslateNonUniformDecoration(node->getType().getQualifier())}; + result = createBinaryOperation(binOp, decorations, resultType(), leftId, rightId, left->getType().getBasicType(), reduceComparison); // code above should only make binOp that exists in createBinaryOperation @@ -2776,8 +2888,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // if (glslangOperands[0]->getAsOperator() && glslangOperands[0]->getAsOperator()->getOp() == glslang::EOpVectorSwizzle) - invertedType = convertGlslangToSpvType( - glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); + invertedType = convertGlslangToSpvType(glslangOperands[0]->getAsBinaryNode()->getLeft()->getType()); } break; case glslang::EOpAtomicLoad: @@ -2823,8 +2934,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt glslangOperands[arg]->traverse(this); #ifndef GLSLANG_WEB - if (node->getOp() == glslang::EOpCooperativeMatrixLoad || - node->getOp() == glslang::EOpCooperativeMatrixStore) { + if (node->getOp() == glslang::EOpCooperativeMatrixLoad || node->getOp() == glslang::EOpCooperativeMatrixStore) { if (arg == 1) { // fold "element" parameter into the access chain @@ -2837,9 +2947,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt 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; @@ -2862,8 +2971,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (memoryAccess & (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) { - memoryAccessOperands.push_back(spv::IdImmediate(true, - builder.makeUintConstant(TranslateMemoryScope(coherentFlags)))); + memoryAccessOperands.push_back( + spv::IdImmediate(true, builder.makeUintConstant(TranslateMemoryScope(coherentFlags)))); } } else if (arg == 2) { continue; @@ -2880,7 +2989,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt // l-value. complexLvalue = builder.getAccessChain(); temporaryLvalue = builder.createVariable(spv::StorageClassFunction, - builder.accessChainGetInferredType(), "swizzleTemp"); + builder.accessChainGetInferredType(), "swizzleTemp"); operands.push_back(temporaryLvalue); } else { operands.push_back(builder.accessChainGetLValue()); @@ -2923,15 +3032,16 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = 0; } else #endif - if (atomic) { + if (atomic) { // Handle all atomics result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), - lvalueCoherentFlags); + lvalueCoherentFlags); } else if (node->getOp() == glslang::EOpDebugPrintf) { if (!nonSemanticDebugPrintf) { nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf"); } - result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, spv::NonSemanticDebugPrintfDebugPrintf, operands); + result = builder.createBuiltinCall(builder.makeVoidType(), nonSemanticDebugPrintf, + spv::NonSemanticDebugPrintfDebugPrintf, operands); builder.addExtension(spv::E_SPV_KHR_non_semantic_info); } else { // Pass through to generic operations. @@ -2939,17 +3049,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case 0: result = createNoArgOperation(node->getOp(), precision, resultType()); break; - case 1: - { - OpDecorations decorations = { precision, - TranslateNoContractionDecoration(node->getType().getQualifier()), - TranslateNonUniformDecoration(node->getType().getQualifier()) }; - result = createUnaryOperation( - node->getOp(), decorations, - resultType(), operands.front(), - glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags); - } - break; + case 1: { + OpDecorations decorations = {precision, TranslateNoContractionDecoration(node->getType().getQualifier()), + TranslateNonUniformDecoration(node->getType().getQualifier())}; + result = createUnaryOperation(node->getOp(), decorations, resultType(), operands.front(), + glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags); + } break; default: result = createMiscOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); break; @@ -2965,9 +3070,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (noReturnValue) return false; - if (! result) { + if (!result) { logger->missingFunctionality("unknown glslang aggregate"); - return true; // pick up a child as a placeholder operand + return true; // pick up a child as a placeholder operand } else { builder.clearAccessChain(); builder.setAccessChainRValue(result); @@ -3006,8 +3111,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // false otherwise. const auto bothSidesPolicy = [&]() -> bool { // do we have both sides? - if (node->getTrueBlock() == nullptr || - node->getFalseBlock() == nullptr) + if (node->getTrueBlock() == nullptr || node->getFalseBlock() == nullptr) return false; // required? (unless we write additional code to look for side effects @@ -3020,7 +3124,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang if (!isOpSelectable()) return false; - assert(node->getType() == node->getTrueBlock() ->getAsTyped()->getType() && + assert(node->getType() == node->getTrueBlock()->getAsTyped()->getType() && node->getType() == node->getFalseBlock()->getAsTyped()->getType()); // return true if a single operand to ? : is okay for OpSelect @@ -3028,8 +3132,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang return node->getAsSymbolNode() || node->getType().getQualifier().isConstant(); }; - return operandOkay(node->getTrueBlock() ->getAsTyped()) && - operandOkay(node->getFalseBlock()->getAsTyped()); + return operandOkay(node->getTrueBlock()->getAsTyped()) && operandOkay(node->getFalseBlock()->getAsTyped()); }; spv::Id result = spv::NoResult; // upcoming result selecting between trueValue and falseValue @@ -3060,15 +3163,14 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // smear condition to vector, if necessary (AST is always scalar) // 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))); + condition = builder.smearScalar( + spv::NoPrecision, condition, + builder.makeVectorType(builder.makeBoolType(), builder.getNumComponents(trueValue))); } // OpSelect - result = builder.createTriOp(spv::OpSelect, - convertGlslangToSpvType(node->getType()), condition, - trueValue, falseValue); + result = builder.createTriOp(spv::OpSelect, convertGlslangToSpvType(node->getType()), condition, trueValue, + falseValue); builder.clearAccessChain(); builder.setAccessChainRValue(result); @@ -3159,15 +3261,15 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T std::vector codeSegments; glslang::TIntermSequence& sequence = node->getBody()->getSequence(); std::vector caseValues; - std::vector valueIndexToSegment(sequence.size()); // note: probably not all are used, it is an overestimate + std::vector valueIndexToSegment(sequence.size()); // note: probably not all are used, it is an overestimate for (glslang::TIntermSequence::iterator c = sequence.begin(); c != sequence.end(); ++c) { TIntermNode* child = *c; if (child->getAsBranchNode() && child->getAsBranchNode()->getFlowOp() == glslang::EOpDefault) 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); } @@ -3181,7 +3283,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T // make the switch statement std::vector segmentBlocks; // returned, as the blocks allocated in the call builder.makeSwitch(selector, control, (int)codeSegments.size(), caseValues, valueIndexToSegment, defaultSegment, - segmentBlocks); + segmentBlocks); // emit all the code in the segments breakForLoop.push(false); @@ -3262,8 +3364,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn node->getTerminal()->traverse(this); if (node->getTest()) { node->getTest()->traverse(this); - spv::Id condition = - accessChainLoad(node->getTest()->getType()); + spv::Id condition = accessChainLoad(node->getTest()->getType()); builder.createConditionalBranch(condition, &blocks.head, &blocks.merge); } else { // TODO: unless there was a break/return/discard instruction @@ -3344,11 +3445,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* // Now, handle actual variables spv::StorageClass storageClass = TranslateStorageClass(node->getType()); - spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType()) - : forcedType; + spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType()) : forcedType; - const bool contains16BitType = node->getType().contains16BitFloat() || - node->getType().contains16BitInt(); + const bool contains16BitType = node->getType().contains16BitFloat() || node->getType().contains16BitInt(); if (contains16BitType) { switch (storageClass) { case spv::StorageClassInput: @@ -3409,18 +3508,21 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) { switch (sampler.type) { - case glslang::EbtInt: return builder.makeIntType(32); - case glslang::EbtUint: return builder.makeUintType(32); - case glslang::EbtFloat: return builder.makeFloatType(32); + case glslang::EbtInt: + return builder.makeIntType(32); + case glslang::EbtUint: + return builder.makeUintType(32); + case glslang::EbtFloat: + return builder.makeFloatType(32); #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); + case glslang::EbtFloat16: + builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch); + builder.addCapability(spv::CapabilityFloat16ImageAMD); + return builder.makeFloatType(16); #endif - default: - assert(0); - return builder.makeFloatType(32); + default: + assert(0); + return builder.makeFloatType(32); } } @@ -3429,8 +3531,7 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) // is applied. spv::Id TGlslangToSpvTraverser::getInvertedSwizzleType(const glslang::TIntermTyped& node) { - if (node.getAsOperator() && - node.getAsOperator()->getOp() == glslang::EOpVectorSwizzle) + if (node.getAsOperator() && node.getAsOperator()->getOp() == glslang::EOpVectorSwizzle) return convertGlslangToSpvType(node.getAsBinaryNode()->getLeft()->getType()); else return spv::NoType; @@ -3439,7 +3540,7 @@ spv::Id TGlslangToSpvTraverser::getInvertedSwizzleType(const glslang::TIntermTyp // 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 parentResult) { std::vector swizzle; convertSwizzle(*node.getAsBinaryNode()->getRight()->getAsAggregate(), swizzle); @@ -3466,15 +3567,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // explicitLayout can be kept the same throughout the hierarchical recursive walk. // Mutually recursive with convertGlslangStructToSpvType(). spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, - glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, - bool lastBufferBlockMember, bool forwardReferenceOnly) + glslang::TLayoutPacking explicitLayout, + const glslang::TQualifier& qualifier, + bool lastBufferBlockMember, bool forwardReferenceOnly) { spv::Id spvType = spv::NoResult; switch (type.getBasicType()) { case glslang::EbtVoid: spvType = builder.makeVoidType(); - assert (! type.isArray()); + assert(!type.isArray()); break; case glslang::EbtBool: // "transparent" bool doesn't exist in SPIR-V. The GLSL convention is @@ -3525,60 +3627,53 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty case glslang::EbtAccStructNV: spvType = builder.makeAccelerationStructureNVType(); break; - case glslang::EbtReference: - { - // Make the forward pointer, then recurse to convert the structure type, then - // patch up the forward pointer with a real pointer type. - if (forwardPointers.find(type.getReferentType()) == forwardPointers.end()) { - spv::Id forwardId = builder.makeForwardPointer(spv::StorageClassPhysicalStorageBufferEXT); - forwardPointers[type.getReferentType()] = forwardId; - } - spvType = forwardPointers[type.getReferentType()]; - if (!forwardReferenceOnly) { - spv::Id referentType = convertGlslangToSpvType(*type.getReferentType()); - builder.makePointerFromForwardPointer(spv::StorageClassPhysicalStorageBufferEXT, - forwardPointers[type.getReferentType()], - referentType); - } + 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; } - break; + 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.isPureSampler()) { - spvType = builder.makeSamplerType(); - } else { - // an image is present, make its type - 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); - } + case glslang::EbtSampler: { + const glslang::TSampler& sampler = type.getSampler(); + if (sampler.isPureSampler()) { + spvType = builder.makeSamplerType(); + } else { + // an image is present, make its type + 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); } } - break; + } break; case glslang::EbtStruct: - case glslang::EbtBlock: - { - // If we've seen this struct type, return it - const glslang::TTypeList* glslangMembers = type.getStruct(); - - // Try to share structs for different layouts, but not yet for other - // kinds of qualification (primarily not yet including interpolant qualification). - if (! HasNonLayoutQualifiers(type, qualifier)) - spvType = structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers]; - if (spvType != spv::NoResult) - break; + case glslang::EbtBlock: { + // If we've seen this struct type, return it + const glslang::TTypeList* glslangMembers = type.getStruct(); + + // Try to share structs for different layouts, but not yet for other + // kinds of qualification (primarily not yet including interpolant qualification). + if (!HasNonLayoutQualifiers(type, qualifier)) + spvType = structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers]; + if (spvType != spv::NoResult) + break; - // else, we haven't seen it... - if (type.getBasicType() == glslang::EbtBlock) - memberRemapper[glslangTypeToIdMap[glslangMembers]].resize(glslangMembers->size()); - spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier); - } - break; + // else, we haven't seen it... + if (type.getBasicType() == glslang::EbtBlock) + memberRemapper[glslangTypeToIdMap[glslangMembers]].resize(glslangMembers->size()); + spvType = convertGlslangStructToSpvType(type, glslangMembers, explicitLayout, qualifier); + } break; case glslang::EbtString: // no type used for OpString return 0; @@ -3600,8 +3695,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty 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) { + if (type.getBasicType() == glslang::EbtUint8 || type.getBasicType() == glslang::EbtInt8) { builder.addCapability(spv::CapabilityInt8); } @@ -3613,7 +3707,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty } if (type.isArray()) { - int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride + int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride // Do all but the outer dimension if (type.getArraySizes()->getNumDims() > 1) { @@ -3682,8 +3776,7 @@ bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member) return true; if (glslangIntermediate->getStage() != EShLangMeshNV) { - if (member.getFieldName() == "gl_ViewportMask" && - extensions.find("GL_NV_viewport_array2") == extensions.end()) + if (member.getFieldName() == "gl_ViewportMask" && extensions.find("GL_NV_viewport_array2") == extensions.end()) return true; if (member.getFieldName() == "gl_PositionPerViewNV" && extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end()) @@ -3707,9 +3800,9 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy { // Create a vector of struct types for SPIR-V to consume std::vector spvMembers; - int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, - // except sometimes for blocks - std::vector > deferredForwardPointers; + int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, + // except sometimes for blocks + std::vector> deferredForwardPointers; for (int i = 0; i < (int)glslangMembers->size(); i++) { glslang::TType& glslangMember = *(*glslangMembers)[i].type; if (glslangMember.hiddenMember()) { @@ -3730,12 +3823,12 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy InheritQualifiers(memberQualifier, qualifier); // manually inherit location - if (! memberQualifier.hasLocation() && qualifier.hasLocation()) + if (!memberQualifier.hasLocation() && qualifier.hasLocation()) memberQualifier.layoutLocation = qualifier.layoutLocation; // recurse - bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer && - i == (int)glslangMembers->size() - 1; + bool lastBufferBlockMember = + qualifier.storage == glslang::EvqBuffer && i == (int)glslangMembers->size() - 1; // Make forward pointers for any pointer members, and create a list of members to // convert to spirv types after creating the struct. @@ -3743,20 +3836,18 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy if (forwardPointers.find(glslangMember.getReferentType()) == forwardPointers.end()) { deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier)); } - spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, - true)); + spvMembers.push_back(convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, + lastBufferBlockMember, true)); } else { - spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, - false)); + spvMembers.push_back(convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, + lastBufferBlockMember, false)); } } } // Make the SPIR-V type spv::Id spvType = builder.makeStructType(spvMembers, type.getTypeName().c_str()); - if (! HasNonLayoutQualifiers(type, qualifier)) + if (!HasNonLayoutQualifiers(type, qualifier)) structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers] = spvType; // Decorate it @@ -3770,15 +3861,13 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy return spvType; } -void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, - const glslang::TTypeList* glslangMembers, +void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, const glslang::TTypeList* glslangMembers, glslang::TLayoutPacking explicitLayout, - const glslang::TQualifier& qualifier, - spv::Id spvType) + const glslang::TQualifier& qualifier, spv::Id spvType) { // Name and decorate the non-hidden members int offset = -1; - int locationOffset = 0; // for use within the members of this struct + int locationOffset = 0; // for use within the members of this struct for (int i = 0; i < (int)glslangMembers->size(); i++) { glslang::TType& glslangMember = *(*glslangMembers)[i].type; int member = i; @@ -3816,8 +3905,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier)); #ifndef GLSLANG_WEB - if (type.getBasicType() == glslang::EbtBlock && - qualifier.storage == glslang::EvqBuffer) { + if (type.getBasicType() == glslang::EbtBlock && qualifier.storage == glslang::EvqBuffer) { // Add memory decorations only to top-level members of shader storage block std::vector memory; TranslateMemoryDecoration(memberQualifier, memory, glslangIntermediate->usingVulkanMemoryModel()); @@ -3831,12 +3919,12 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, // just track whether a member needs to be decorated. // Ignore member locations if the container is an array, as that's // ill-specified and decisions have been made to not allow this. - if (! type.isArray() && memberQualifier.hasLocation()) + if (!type.isArray() && memberQualifier.hasLocation()) builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation); - if (qualifier.hasLocation()) // track for upcoming inheritance - locationOffset += glslangIntermediate->computeTypeLocationSize( - glslangMember, glslangIntermediate->getStage()); + if (qualifier.hasLocation()) // track for upcoming inheritance + locationOffset += + glslangIntermediate->computeTypeLocationSize(glslangMember, glslangIntermediate->getStage()); // component, XFB, others if (glslangMember.getQualifier().hasComponent()) @@ -3875,12 +3963,12 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, if (builtIn == spv::BuiltInLayer) { // SPV_NV_viewport_array2 extension - if (glslangMember.getQualifier().layoutViewportRelative){ + if (glslangMember.getQualifier().layoutViewportRelative) { builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV); builder.addCapability(spv::CapabilityShaderViewportMaskNV); builder.addExtension(spv::E_SPV_NV_viewport_array2); } - if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){ + if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048) { builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset); @@ -3936,12 +4024,10 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) unsigned int alignment = builder.getAccessChain().alignment; alignment |= type.getBufferReferenceAlignment(); - spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type), - TranslateNonUniformDecoration(type.getQualifier()), - nominalTypeId, + spv::Id loadedId = builder.accessChainLoad( + TranslatePrecisionDecoration(type), TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId, spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), - TranslateMemoryScope(coherentFlags), - alignment); + TranslateMemoryScope(coherentFlags), alignment); // Need to convert to abstract types when necessary if (type.getBasicType() == glslang::EbtBool) { @@ -3956,7 +4042,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize); if (nominalTypeId != bvecType) loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId, - makeSmearedConstant(builder.makeUintConstant(0), vecSize)); + makeSmearedConstant(builder.makeUintConstant(0), vecSize)); } } @@ -4004,10 +4090,10 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I unsigned int alignment = builder.getAccessChain().alignment; alignment |= type.getBufferReferenceAlignment(); - builder.accessChainStore(rvalue, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & - ~spv::MemoryAccessMakePointerVisibleKHRMask), - TranslateMemoryScope(coherentFlags), alignment); + builder.accessChainStore( + rvalue, + spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask), + TranslateMemoryScope(coherentFlags), alignment); } // For storing when types match at the glslang level, but not might match at the @@ -4024,7 +4110,7 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id rValue) { // we only do the complex path here if it's an aggregate - if (! type.isStruct() && ! type.isArray()) { + if (!type.isStruct() && !type.isArray()) { accessChainStore(type, rValue); return; } @@ -4068,7 +4154,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id builder.clearAccessChain(); builder.setAccessChainLValue(lValue); builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type), - type.getBufferReferenceAlignment()); + type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangElementType, elementRValue); @@ -4089,7 +4175,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id builder.clearAccessChain(); builder.setAccessChainLValue(lValue); builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type), - type.getBufferReferenceAlignment()); + type.getBufferReferenceAlignment()); // store the member multiTypeStore(glslangMemberType, memberRValue); @@ -4107,8 +4193,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang: return glslang::ElpNone; // has to be a uniform or buffer block or task in/out blocks - if (type.getQualifier().storage != glslang::EvqUniform && - type.getQualifier().storage != glslang::EvqBuffer && + if (type.getQualifier().storage != glslang::EvqUniform && type.getQualifier().storage != glslang::EvqBuffer && !type.getQualifier().isTaskMemory()) return glslang::ElpNone; @@ -4125,12 +4210,12 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang: // 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) + glslang::TLayoutMatrix matrixLayout) { int size; int stride; glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, - matrixLayout == glslang::ElmRowMajor); + matrixLayout == glslang::ElmRowMajor); return stride; } @@ -4138,7 +4223,7 @@ int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glsl // 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) + glslang::TLayoutMatrix matrixLayout) { glslang::TType elementType; elementType.shallowCopy(matrixType); @@ -4147,7 +4232,7 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl int size; int stride; glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, - matrixLayout == glslang::ElmRowMajor); + matrixLayout == glslang::ElmRowMajor); return stride; } @@ -4159,7 +4244,9 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl // 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) + int& currentOffset, int& nextOffset, + glslang::TLayoutPacking explicitLayout, + glslang::TLayoutMatrix matrixLayout) { // this will get a positive value when deemed necessary nextOffset = -1; @@ -4174,7 +4261,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType // settings are needed in layoutOffset, and then the following will come into play. if (explicitLayout == glslang::ElpNone) { - if (! memberType.getQualifier().hasOffset()) + if (!memberType.getQualifier().hasOffset()) currentOffset = -1; return; @@ -4190,15 +4277,15 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType int memberSize; int dummyStride; int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, - matrixLayout == glslang::ElmRowMajor); + matrixLayout == glslang::ElmRowMajor); // Adjust alignment for HLSL rules // TODO: make this consistent in early phases of code: // adjusting this late means inconsistencies with earlier code, which for reflection is an issue // Until reflection is brought in sync with these adjustments, don't apply to $Global, // which is the most likely to rely on reflection, and least likely to rely implicit layouts - if (glslangIntermediate->usingHlslOffsets() && - ! memberType.isArray() && memberType.isVector() && structType.getTypeName().compare("$Global") != 0) { + if (glslangIntermediate->usingHlslOffsets() && !memberType.isArray() && memberType.isVector() && + structType.getTypeName().compare("$Global") != 0) { int dummySize; int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, dummySize); if (componentAlignment <= 4) @@ -4209,8 +4296,8 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType 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; @@ -4219,8 +4306,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember) { const glslang::TBuiltInVariable glslangBuiltIn = members[glslangMember].type->getQualifier().builtIn; - switch (glslangBuiltIn) - { + switch (glslangBuiltIn) { case glslang::EbvPointSize: #ifndef GLSLANG_WEB case glslang::EbvClipDistance: @@ -4260,9 +4346,7 @@ bool TGlslangToSpvTraverser::isShaderEntryPoint(const glslang::TIntermAggregate* // qualifiers such that we should have only in/out/inout/constreadonly here. bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier) const { - assert(qualifier == glslang::EvqIn || - qualifier == glslang::EvqOut || - qualifier == glslang::EvqInOut || + assert(qualifier == glslang::EvqIn || qualifier == glslang::EvqOut || qualifier == glslang::EvqInOut || qualifier == glslang::EvqConstReadOnly); return qualifier != glslang::EvqConstReadOnly; } @@ -4271,7 +4355,7 @@ bool TGlslangToSpvTraverser::writableParam(glslang::TStorageQualifier qualifier) bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier, const glslang::TType& paramType, bool implicitThisParam) { - if (implicitThisParam) // implicit this + if (implicitThisParam) // implicit this return true; if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) return paramType.getBasicType() == glslang::EbtBlock; @@ -4283,7 +4367,7 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier, void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions) { const auto getParamDecorations = [&](std::vector& decorations, const glslang::TType& type, - bool useVulkanMemoryModel) { + bool useVulkanMemoryModel) { spv::Decoration paramPrecision = TranslatePrecisionDecoration(type); if (paramPrecision != spv::NoPrecision) decorations.push_back(paramPrecision); @@ -4294,18 +4378,18 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF // memory and use RestrictPointer/AliasedPointer. if (originalParam(type.getQualifier().storage, type, false) || !writableParam(type.getQualifier().storage)) { - decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict : - spv::DecorationAliased); + decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict + : spv::DecorationAliased); } else { - decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT : - spv::DecorationAliasedPointerEXT); + decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT + : spv::DecorationAliasedPointerEXT); } } }; for (int f = 0; f < (int)glslFunctions.size(); ++f) { glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate(); - if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntryPoint(glslFunction)) + if (!glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntryPoint(glslFunction)) continue; // We're on a user function. Set up the basic interface for the function now, @@ -4326,9 +4410,9 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF std::vector> paramDecorations; // list of decorations per parameter glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); -#ifdef ENABLE_HLSL - bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == - glslangIntermediate->implicitThisName; +#ifdef GLSLANG_ENABLE_HLSL + bool implicitThis = (int)parameters.size() > 0 && + parameters[0]->getAsSymbolNode()->getName() == glslangIntermediate->implicitThisName; #else bool implicitThis = false; #endif @@ -4348,10 +4432,9 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF } spv::Block* functionBlock; - spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()), - convertGlslangToSpvType(glslFunction->getType()), - glslFunction->getName().c_str(), paramTypes, - paramDecorations, &functionBlock); + spv::Function* function = builder.makeFunctionEntry( + TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()), + glslFunction->getName().c_str(), paramTypes, paramDecorations, &functionBlock); if (implicitThis) function->setImplicitThis(); @@ -4381,8 +4464,8 @@ void TGlslangToSpvTraverser::makeGlobalInitializers(const glslang::TIntermSequen 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. @@ -4411,7 +4494,7 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate } void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, - spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) + spv::Builder::AccessChain::CoherentFlags& lvalueCoherentFlags) { const glslang::TIntermSequence& glslangArguments = node.getSequence(); @@ -4424,8 +4507,8 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& sampler = glslangArguments[0]->getAsTyped()->getType().getSampler(); cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; #ifndef GLSLANG_WEB - f16ShadowCompare = sampler.shadow && - glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; + f16ShadowCompare = + sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; #endif } @@ -4451,20 +4534,20 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& lvalue = true; break; case glslang::EOpSparseImageLoad: - if ((sampler.ms && i == 3) || (! sampler.ms && i == 2)) + if ((sampler.ms && i == 3) || (!sampler.ms && i == 2)) lvalue = true; break; case glslang::EOpSparseTexture: - if (((cubeCompare || f16ShadowCompare) && i == 3) || (! (cubeCompare || f16ShadowCompare) && i == 2)) + if (((cubeCompare || f16ShadowCompare) && i == 3) || (!(cubeCompare || f16ShadowCompare) && i == 2)) lvalue = true; break; case glslang::EOpSparseTextureClamp: - if (((cubeCompare || f16ShadowCompare) && i == 4) || (! (cubeCompare || f16ShadowCompare) && i == 3)) + if (((cubeCompare || f16ShadowCompare) && i == 4) || (!(cubeCompare || f16ShadowCompare) && i == 3)) lvalue = true; break; case glslang::EOpSparseTextureLod: case glslang::EOpSparseTextureOffset: - if ((f16ShadowCompare && i == 4) || (! f16ShadowCompare && i == 3)) + if ((f16ShadowCompare && i == 4) || (!f16ShadowCompare && i == 3)) lvalue = true; break; case glslang::EOpSparseTextureFetch: @@ -4478,25 +4561,25 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& case glslang::EOpSparseTextureLodOffset: case glslang::EOpSparseTextureGrad: case glslang::EOpSparseTextureOffsetClamp: - if ((f16ShadowCompare && i == 5) || (! f16ShadowCompare && i == 4)) + if ((f16ShadowCompare && i == 5) || (!f16ShadowCompare && i == 4)) lvalue = true; break; case glslang::EOpSparseTextureGradOffset: case glslang::EOpSparseTextureGradClamp: - if ((f16ShadowCompare && i == 6) || (! f16ShadowCompare && i == 5)) + if ((f16ShadowCompare && i == 6) || (!f16ShadowCompare && i == 5)) lvalue = true; break; case glslang::EOpSparseTextureGradOffsetClamp: - if ((f16ShadowCompare && i == 7) || (! f16ShadowCompare && i == 6)) + if ((f16ShadowCompare && i == 7) || (!f16ShadowCompare && i == 6)) lvalue = true; break; case glslang::EOpSparseTextureGather: - if ((sampler.shadow && i == 3) || (! sampler.shadow && i == 2)) + if ((sampler.shadow && i == 3) || (!sampler.shadow && i == 2)) lvalue = true; break; case glslang::EOpSparseTextureGatherOffset: case glslang::EOpSparseTextureGatherOffsets: - if ((sampler.shadow && i == 4) || (! sampler.shadow && i == 3)) + if ((sampler.shadow && i == 4) || (!sampler.shadow && i == 3)) lvalue = true; break; case glslang::EOpSparseTextureGatherLod: @@ -4552,21 +4635,22 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node) { - if (! node->isImage() && ! node->isTexture()) + if (!node->isImage() && !node->isTexture()) return spv::NoResult; builder.setLine(node->getLoc().line, node->getLoc().getFilename()); // 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 GLSLANG_WEB const bool f16ShadowCompare = false; #else - bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate()) + bool f16ShadowCompare = + (sampler.shadow && node->getAsAggregate()) ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16 : false; #endif @@ -4590,7 +4674,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO translateArguments(*node->getAsUnaryNode(), arguments); spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); - spv::Builder::TextureParameters params = { }; + spv::Builder::TextureParameters params = {}; params.sampler = arguments[0]; glslang::TCrackedTextureOp cracked; @@ -4642,13 +4726,13 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO glslang::TType returnType(node->getType().getBasicType(), glslang::EvqTemporary, components); - auto resultType = [&returnType,this]{ return convertGlslangToSpvType(returnType); }; + auto resultType = [&returnType, this] { return convertGlslangToSpvType(returnType); }; // Check for image functions other than queries if (node->isImage()) { std::vector operands; auto opIt = arguments.begin(); - spv::IdImmediate image = { true, *(opIt++) }; + spv::IdImmediate image = {true, *(opIt++)}; operands.push_back(image); // Handle subpass operations @@ -4660,10 +4744,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO std::vector comps; comps.push_back(zero); comps.push_back(zero); - spv::IdImmediate coord = { true, - builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) }; + spv::IdImmediate coord = { + true, builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps)}; operands.push_back(coord); - spv::IdImmediate imageOperands = { false, spv::ImageOperandsMaskNone }; + spv::IdImmediate imageOperands = {false, spv::ImageOperandsMaskNone}; imageOperands.word = imageOperands.word | signExtensionMask(); if (sampler.isMultiSample()) { imageOperands.word = imageOperands.word | spv::ImageOperandsSampleMask; @@ -4671,7 +4755,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (imageOperands.word != spv::ImageOperandsMaskNone) { operands.push_back(imageOperands); if (sampler.isMultiSample()) { - spv::IdImmediate imageOperand = { true, *(opIt++) }; + spv::IdImmediate imageOperand = {true, *(opIt++)}; operands.push_back(imageOperand); } } @@ -4680,7 +4764,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return result; } - spv::IdImmediate coord = { true, *(opIt++) }; + spv::IdImmediate coord = {true, *(opIt++)}; operands.push_back(coord); if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) { spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; @@ -4696,20 +4780,20 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask); mask = mask | signExtensionMask(); if (mask != spv::ImageOperandsMaskNone) { - spv::IdImmediate imageOperands = { false, (unsigned int)mask }; + spv::IdImmediate imageOperands = {false, (unsigned int)mask}; operands.push_back(imageOperands); } if (mask & spv::ImageOperandsSampleMask) { - spv::IdImmediate imageOperand = { true, *opIt++ }; + spv::IdImmediate imageOperand = {true, *opIt++}; operands.push_back(imageOperand); } if (mask & spv::ImageOperandsLodMask) { - spv::IdImmediate imageOperand = { true, *opIt++ }; + spv::IdImmediate imageOperand = {true, *opIt++}; operands.push_back(imageOperand); } 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); } @@ -4728,10 +4812,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // Push the texel value before the operands if (sampler.isMultiSample() || cracked.lod) { - spv::IdImmediate texel = { true, *(opIt + 1) }; + spv::IdImmediate texel = {true, *(opIt + 1)}; operands.push_back(texel); } else { - spv::IdImmediate texel = { true, *opIt }; + spv::IdImmediate texel = {true, *opIt}; operands.push_back(texel); } @@ -4748,20 +4832,20 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask); mask = mask | signExtensionMask(); if (mask != spv::ImageOperandsMaskNone) { - spv::IdImmediate imageOperands = { false, (unsigned int)mask }; + spv::IdImmediate imageOperands = {false, (unsigned int)mask}; operands.push_back(imageOperands); } if (mask & spv::ImageOperandsSampleMask) { - spv::IdImmediate imageOperand = { true, *opIt++ }; + spv::IdImmediate imageOperand = {true, *opIt++}; operands.push_back(imageOperand); } if (mask & spv::ImageOperandsLodMask) { - spv::IdImmediate imageOperand = { true, *opIt++ }; + spv::IdImmediate imageOperand = {true, *opIt++}; operands.push_back(imageOperand); } 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); } @@ -4769,8 +4853,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown) builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat); return spv::NoResult; - } else if (node->getOp() == glslang::EOpSparseImageLoad || - node->getOp() == glslang::EOpSparseImageLoadLod) { + } 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); @@ -4789,20 +4872,20 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask); mask = mask | signExtensionMask(); if (mask != spv::ImageOperandsMaskNone) { - spv::IdImmediate imageOperands = { false, (unsigned int)mask }; + spv::IdImmediate imageOperands = {false, (unsigned int)mask}; operands.push_back(imageOperands); } if (mask & spv::ImageOperandsSampleMask) { - spv::IdImmediate imageOperand = { true, *opIt++ }; + spv::IdImmediate imageOperand = {true, *opIt++}; operands.push_back(imageOperand); } if (mask & spv::ImageOperandsLodMask) { - spv::IdImmediate imageOperand = { true, *opIt++ }; + spv::IdImmediate imageOperand = {true, *opIt++}; operands.push_back(imageOperand); } 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); } @@ -4823,7 +4906,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer, // as the first source operand, is required by SPIR-V atomic operations. // For non-MS, the sample value should be 0 - spv::IdImmediate sample = { true, sampler.isMultiSample() ? *(opIt++) : builder.makeUintConstant(0) }; + spv::IdImmediate sample = {true, sampler.isMultiSample() ? *(opIt++) : builder.makeUintConstant(0)}; operands.push_back(sample); spv::Id resultTypeId; @@ -4845,7 +4928,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO operands.push_back(*opIt); return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), - lvalueCoherentFlags); + lvalueCoherentFlags); } } @@ -4870,8 +4953,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO std::vector comps; comps.push_back(zero); comps.push_back(zero); - operands.push_back(builder.makeCompositeConstant( - builder.makeVectorType(builder.makeIntType(32), 2), comps)); + operands.push_back( + builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps)); } for (; opIt != arguments.end(); ++opIt) @@ -4896,7 +4979,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO // check for bias argument bool bias = false; - if (! cracked.lod && ! cracked.grad && ! cracked.fetch && ! cubeCompare) { + if (!cracked.lod && !cracked.grad && !cracked.fetch && !cubeCompare) { int nonBiasArgCount = 2; if (cracked.gather) ++nonBiasArgCount; // comp argument should be present when bias argument is present @@ -4956,12 +5039,12 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO std::vector indexes; int dRefComp; if (cracked.proj) - dRefComp = 2; // "The resulting 3rd component of P in the shadow forms is used as Dref" + dRefComp = 2; // "The resulting 3rd component of P in the shadow forms is used as Dref" 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 @@ -5009,7 +5092,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ++extraArgs; } // gather component - if (cracked.gather && ! sampler.shadow) { + if (cracked.gather && !sampler.shadow) { // default component is 0, if missing, otherwise an argument if (2 + extraArgs < (int)arguments.size()) { params.component = arguments[2 + extraArgs]; @@ -5017,7 +5100,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } else params.component = builder.makeIntConstant(0); } - spv::Id resultStruct = spv::NoResult; + spv::Id resultStruct = spv::NoResult; if (imageFootprint) { //Following three extra arguments // int granularity, bool coarse, out gl_TextureFootprint2DNV footprint @@ -5038,7 +5121,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO builder.addExtension(spv::E_SPV_NV_shader_image_footprint); builder.addCapability(spv::CapabilityImageFootprintNV); - //resultStructType(OpenGL type) contains 5 elements: //struct gl_TextureFootprint2DNV { // uvec2 anchor; @@ -5059,10 +5141,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO assert(builder.isStructType(resultStructType)); //resType (SPIR-V type) contains 6 elements: - //Member 0 must be a Boolean type scalar(LOD), - //Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor), - //Member 2 must be a vector of integer type, whose Signedness operand is 0(offset), - //Member 3 must be a vector of integer type, whose Signedness operand is 0(mask), + //Member 0 must be a Boolean type scalar(LOD), + //Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor), + //Member 2 must be a vector of integer type, whose Signedness operand is 0(offset), + //Member 3 must be a vector of integer type, whose Signedness operand is 0(mask), //Member 4 must be a scalar of integer type, whose Signedness operand is 0(lod), //Member 5 must be a scalar of integer type, whose Signedness operand is 0(granularity). std::vector members; @@ -5073,9 +5155,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO spv::Id resType = builder.makeStructType(members, "ResType"); //call ImageFootprintNV - spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, - cracked.gather, noImplicitLod, params, signExtensionMask()); - + spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, cracked.gather, + noImplicitLod, params, signExtensionMask()); + //copy resType (SPIR-V type) to resultStructType(OpenGL type) for (int i = 0; i < 5; i++) { builder.clearAccessChain(); @@ -5086,8 +5168,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO 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); } @@ -5102,17 +5184,25 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO int projSourceComp = builder.getNumComponents(params.coords) - 1; int projTargetComp; switch (sampler.dim) { - case glslang::Esd1D: projTargetComp = 1; break; - case glslang::Esd2D: projTargetComp = 2; break; - case glslang::EsdRect: projTargetComp = 2; break; - default: projTargetComp = projSourceComp; break; + case glslang::Esd1D: + projTargetComp = 1; + break; + case glslang::Esd2D: + projTargetComp = 2; + break; + case glslang::EsdRect: + projTargetComp = 2; + break; + default: + projTargetComp = projSourceComp; + break; } // 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); - params.coords = builder.createCompositeInsert(projComp, params.coords, - builder.getTypeId(params.coords), projTargetComp); + spv::Id projComp = builder.createCompositeExtract( + params.coords, builder.getScalarTypeId(builder.getTypeId(params.coords)), projSourceComp); + params.coords = builder.createCompositeInsert(projComp, params.coords, builder.getTypeId(params.coords), + projTargetComp); } } @@ -5128,10 +5218,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } #endif - std::vector result( 1, - builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, - noImplicitLod, params, signExtensionMask()) - ); + std::vector result(1, + builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, + cracked.gather, noImplicitLod, params, signExtensionMask())); if (components != node->getType().getVectorSize()) result[0] = builder.createConstructor(precision, result, convertGlslangToSpvType(node->getType())); @@ -5143,7 +5232,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg { // Grab the function's pointer from the previously created function spv::Function* function = functionMap[node->getName().c_str()]; - if (! function) + if (!function) return 0; const glslang::TIntermSequence& glslangArgs = node->getSequence(); @@ -5193,7 +5282,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg } else if (writableParam(qualifiers[a])) { // need space to hold the copy arg = builder.createVariable(spv::StorageClassFunction, - builder.getContainedTypeId(function->getParamType(a)), "param"); + 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]); @@ -5241,16 +5330,16 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg } // Translate AST operation to SPV operation, already having SPV-based operands/types. -spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpDecorations& decorations, - spv::Id typeId, spv::Id left, spv::Id right, - glslang::TBasicType typeProxy, bool reduceComparison) +spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, + spv::Id left, spv::Id right, glslang::TBasicType typeProxy, + bool reduceComparison) { bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); bool isBool = typeProxy == glslang::EbtBool; spv::Op binOp = spv::OpNop; - bool needMatchingVectors = true; // for non-matrix ops, would a scalar need to smear to match a vector? + bool needMatchingVectors = true; // for non-matrix ops, would a scalar need to smear to match a vector? bool comparison = false; switch (op) { @@ -5285,7 +5374,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD binOp = spv::OpVectorTimesScalar; } else if (isFloat) binOp = spv::OpFMul; - else + else binOp = spv::OpIMul; break; case glslang::EOpVectorTimesMatrix: @@ -5403,8 +5492,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD // handle mapped binary operations (should be non-comparison) if (binOp != spv::OpNop) { assert(comparison == false); - if (builder.isMatrix(left) || builder.isMatrix(right) || - builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right)) + if (builder.isMatrix(left) || builder.isMatrix(right) || builder.isCooperativeMatrix(left) || + builder.isCooperativeMatrix(right)) return createBinaryMatrixOperation(binOp, decorations, typeId, left, right); // No matrix involved; make both operands be the same number of components, if needed @@ -5417,13 +5506,13 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD return builder.setPrecision(result, decorations.precision); } - if (! comparison) + if (!comparison) return 0; // Handle comparison instructions - if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual) - && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) { + 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); decorations.addNonUniform(builder, result); return result; @@ -5568,10 +5657,9 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora case spv::OpFSub: case spv::OpFDiv: case spv::OpFMod: - case spv::OpFMul: - { + case spv::OpFMul: { // one time set up... - bool leftMat = builder.isMatrix(left); + bool leftMat = builder.isMatrix(left); bool rightMat = builder.isMatrix(right); unsigned int numCols = leftMat ? builder.getNumColumns(left) : builder.getNumColumns(right); int numRows = leftMat ? builder.getNumRows(left) : builder.getNumRows(right); @@ -5588,7 +5676,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora for (unsigned int c = 0; c < numCols; ++c) { std::vector indexes; indexes.push_back(c); - spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec; + 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); decorations.addNoContraction(builder, result); @@ -5607,8 +5695,10 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora } } -spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, - spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) +spv::Id +TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, + spv::Id operand, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags& lvalueCoherentFlags) { spv::Op unaryOp = spv::OpNop; int extBuiltins = -1; @@ -5876,8 +5966,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe break; case glslang::EOpAtomicCounterIncrement: case glslang::EOpAtomicCounterDecrement: - case glslang::EOpAtomicCounter: - { + case glslang::EOpAtomicCounter: { // Handle all of the atomics in one place, in createAtomicOperation() std::vector operands; operands.push_back(operand); @@ -5934,8 +6023,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpAddInvocationsExclusiveScan: case glslang::EOpMinInvocationsExclusiveScanNonUniform: case glslang::EOpMaxInvocationsExclusiveScanNonUniform: - case glslang::EOpAddInvocationsExclusiveScanNonUniform: - { + case glslang::EOpAddInvocationsExclusiveScanNonUniform: { std::vector operands; operands.push_back(operand); return createInvocationsOperation(op, typeId, operands, typeProxy); @@ -6037,7 +6125,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat // get the types sorted out int numCols = builder.getNumColumns(operand); int numRows = builder.getNumRows(operand); - spv::Id srcVecType = builder.makeVectorType(builder.getScalarTypeId(builder.getTypeId(operand)), numRows); + spv::Id srcVecType = builder.makeVectorType(builder.getScalarTypeId(builder.getTypeId(operand)), numRows); spv::Id destVecType = builder.makeVectorType(builder.getScalarTypeId(typeId), numRows); std::vector results; @@ -6045,7 +6133,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat for (int c = 0; c < numCols; ++c) { std::vector indexes; indexes.push_back(c); - spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes); + spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes); spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec); decorations.addNoContraction(builder, destVec); decorations.addNonUniform(builder, destVec); @@ -6065,7 +6153,7 @@ spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, { // Get the result type width, based on the type to convert to. int width = 32; - switch(op) { + switch (op) { case glslang::EOpConvInt16ToUint8: case glslang::EOpConvIntToUint8: case glslang::EOpConvInt64ToUint8: @@ -6108,7 +6196,7 @@ spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, // based on the target width, but the source type. spv::Id type = spv::NoType; spv::Op convOp = spv::OpNop; - switch(op) { + switch (op) { case glslang::EOpConvInt8ToUint16: case glslang::EOpConvInt8ToUint: case glslang::EOpConvInt8ToUint64: @@ -6158,7 +6246,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvBoolToFloat: convOp = spv::OpSelect; zero = builder.makeFloatConstant(0.0F); - one = builder.makeFloatConstant(1.0F); + one = builder.makeFloatConstant(1.0F); break; case glslang::EOpConvBoolToInt: @@ -6249,7 +6337,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. #ifndef GLSLANG_WEB - if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) { + if (op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) { zero = builder.makeUint8Constant(0); } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) { zero = builder.makeUint16Constant(0); @@ -6311,7 +6399,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvBoolToDouble: convOp = spv::OpSelect; zero = builder.makeDoubleConstant(0.0); - one = builder.makeDoubleConstant(1.0); + one = builder.makeDoubleConstant(1.0); break; case glslang::EOpConvBoolToFloat16: convOp = spv::OpSelect; @@ -6320,22 +6408,22 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora break; case glslang::EOpConvBoolToInt8: zero = builder.makeInt8Constant(0); - one = builder.makeInt8Constant(1); + one = builder.makeInt8Constant(1); convOp = spv::OpSelect; break; case glslang::EOpConvBoolToUint8: zero = builder.makeUint8Constant(0); - one = builder.makeUint8Constant(1); + one = builder.makeUint8Constant(1); convOp = spv::OpSelect; break; case glslang::EOpConvBoolToInt16: zero = builder.makeInt16Constant(0); - one = builder.makeInt16Constant(1); + one = builder.makeInt16Constant(1); convOp = spv::OpSelect; break; case glslang::EOpConvBoolToUint16: zero = builder.makeUint16Constant(0); - one = builder.makeUint16Constant(1); + one = builder.makeUint16Constant(1); convOp = spv::OpSelect; break; case glslang::EOpConvDoubleToFloat: @@ -6408,7 +6496,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. - switch(op) { + switch (op) { case glslang::EOpConvInt16ToUint8: case glslang::EOpConvIntToUint8: case glslang::EOpConvInt64ToUint8: @@ -6478,7 +6566,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora if (convOp == spv::OpSelect) { zero = makeSmearedConstant(zero, vectorSize); - one = makeSmearedConstant(one, vectorSize); + one = makeSmearedConstant(one, vectorSize); result = builder.createTriOp(convOp, destType, operand, one, zero); } else result = builder.createUnaryOp(convOp, destType, operand); @@ -6501,9 +6589,10 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector } // For glslang ops that map to SPV atomic opCodes -spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, - spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, - const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) +spv::Id +TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy, + const spv::Builder::AccessChain::CoherentFlags& lvalueCoherentFlags) { spv::Op opCode = spv::OpNop; @@ -6519,14 +6608,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv 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: @@ -6590,11 +6679,11 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv } else { scopeId = builder.makeUintConstant(spv::ScopeDevice); } - // semantics default to relaxed - spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && - glslangIntermediate->usingVulkanMemoryModel() ? - spv::MemorySemanticsVolatileMask : - spv::MemorySemanticsMaskNone); + // semantics default to relaxed + spv::Id semanticsId = + builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && glslangIntermediate->usingVulkanMemoryModel() + ? spv::MemorySemanticsVolatileMask + : spv::MemorySemanticsMaskNone); spv::Id semanticsId2 = semanticsId; pointerId = operands[0]; @@ -6605,33 +6694,31 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv 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 | - spv::MemorySemanticsVolatileMask)) { + if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | spv::MemorySemanticsVolatileMask)) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } @@ -6639,7 +6726,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); } - std::vector spvAtomicOperands; // hold the spv operands + std::vector spvAtomicOperands; // hold the spv operands spvAtomicOperands.push_back(pointerId); spvAtomicOperands.push_back(scopeId); spvAtomicOperands.push_back(semanticsId); @@ -6668,7 +6755,8 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv // Create group invocation operations. spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, - std::vector& operands, glslang::TBasicType typeProxy) + std::vector& operands, + glslang::TBasicType typeProxy) { bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); @@ -6677,21 +6765,17 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op std::vector spvGroupOperands; spv::GroupOperation groupOperation = spv::GroupOperationMax; - if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation || - op == glslang::EOpReadInvocation) { + if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation || op == glslang::EOpReadInvocation) { builder.addExtension(spv::E_SPV_KHR_shader_ballot); builder.addCapability(spv::CapabilitySubgroupBallotKHR); - } else if (op == glslang::EOpAnyInvocation || - op == glslang::EOpAllInvocations || - op == glslang::EOpAllInvocationsEqual) { + } else if (op == glslang::EOpAnyInvocation || op == glslang::EOpAllInvocations || + op == glslang::EOpAllInvocationsEqual) { builder.addExtension(spv::E_SPV_KHR_subgroup_vote); builder.addCapability(spv::CapabilitySubgroupVoteKHR); } else { builder.addCapability(spv::CapabilityGroups); - if (op == glslang::EOpMinInvocationsNonUniform || - op == glslang::EOpMaxInvocationsNonUniform || - op == glslang::EOpAddInvocationsNonUniform || - op == glslang::EOpMinInvocationsInclusiveScanNonUniform || + if (op == glslang::EOpMinInvocationsNonUniform || op == glslang::EOpMaxInvocationsNonUniform || + op == glslang::EOpAddInvocationsNonUniform || op == glslang::EOpMinInvocationsInclusiveScanNonUniform || op == glslang::EOpMaxInvocationsInclusiveScanNonUniform || op == glslang::EOpAddInvocationsInclusiveScanNonUniform || op == glslang::EOpMinInvocationsExclusiveScanNonUniform || @@ -6727,16 +6811,16 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op default: break; } - spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spv::IdImmediate scope = {true, builder.makeUintConstant(spv::ScopeSubgroup)}; spvGroupOperands.push_back(scope); if (groupOperation != spv::GroupOperationMax) { - spv::IdImmediate groupOp = { false, (unsigned)groupOperation }; + spv::IdImmediate groupOp = {false, (unsigned)groupOperation}; spvGroupOperands.push_back(groupOp); } } for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) { - spv::IdImmediate op = { true, *opIt }; + spv::IdImmediate op = {true, *opIt}; spvGroupOperands.push_back(op); } @@ -6758,15 +6842,14 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op case glslang::EOpReadFirstInvocation: opCode = spv::OpSubgroupFirstInvocationKHR; break; - case glslang::EOpBallot: - { + case glslang::EOpBallot: { // NOTE: According to the spec, the result type of "OpSubgroupBallotKHR" must be a 4 component vector of 32 // bit integer types. The GLSL built-in function "ballotARB()" assumes the maximum number of invocations in // a subgroup is 64. Thus, we have to convert uvec4.xy to uint64_t as follow: // // result = Bitcast(SubgroupBallotKHR(Predicate).xy) // - spv::Id uintType = builder.makeUintType(32); + spv::Id uintType = builder.makeUintType(32); spv::Id uvec4Type = builder.makeVectorType(uintType, 4); spv::Id result = builder.createOp(spv::OpSubgroupBallotKHR, uvec4Type, spvGroupOperands); @@ -6775,8 +6858,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op components.push_back(builder.createCompositeExtract(result, uintType, 1)); spv::Id uvec2Type = builder.makeVectorType(uintType, 2); - return builder.createUnaryOp(spv::OpBitcast, typeId, - builder.createCompositeConstruct(uvec2Type, components)); + return builder.createUnaryOp(spv::OpBitcast, typeId, builder.createCompositeConstruct(uvec2Type, components)); } case glslang::EOpMinInvocations: @@ -6788,8 +6870,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op case glslang::EOpMinInvocationsExclusiveScan: case glslang::EOpMaxInvocationsExclusiveScan: case glslang::EOpAddInvocationsExclusiveScan: - if (op == glslang::EOpMinInvocations || - op == glslang::EOpMinInvocationsInclusiveScan || + if (op == glslang::EOpMinInvocations || op == glslang::EOpMinInvocationsInclusiveScan || op == glslang::EOpMinInvocationsExclusiveScan) { if (isFloat) opCode = spv::OpGroupFMin; @@ -6799,8 +6880,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op else opCode = spv::OpGroupSMin; } - } else if (op == glslang::EOpMaxInvocations || - op == glslang::EOpMaxInvocationsInclusiveScan || + } else if (op == glslang::EOpMaxInvocations || op == glslang::EOpMaxInvocationsInclusiveScan || op == glslang::EOpMaxInvocationsExclusiveScan) { if (isFloat) opCode = spv::OpGroupFMax; @@ -6830,8 +6910,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op case glslang::EOpMinInvocationsExclusiveScanNonUniform: case glslang::EOpMaxInvocationsExclusiveScanNonUniform: case glslang::EOpAddInvocationsExclusiveScanNonUniform: - if (op == glslang::EOpMinInvocationsNonUniform || - op == glslang::EOpMinInvocationsInclusiveScanNonUniform || + if (op == glslang::EOpMinInvocationsNonUniform || op == glslang::EOpMinInvocationsInclusiveScanNonUniform || op == glslang::EOpMinInvocationsExclusiveScanNonUniform) { if (isFloat) opCode = spv::OpGroupFMinNonUniformAMD; @@ -6841,10 +6920,9 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op else opCode = spv::OpGroupSMinNonUniformAMD; } - } - else if (op == glslang::EOpMaxInvocationsNonUniform || - op == glslang::EOpMaxInvocationsInclusiveScanNonUniform || - op == glslang::EOpMaxInvocationsExclusiveScanNonUniform) { + } else if (op == glslang::EOpMaxInvocationsNonUniform || + op == glslang::EOpMaxInvocationsInclusiveScanNonUniform || + op == glslang::EOpMaxInvocationsExclusiveScanNonUniform) { if (isFloat) opCode = spv::OpGroupFMaxNonUniformAMD; else { @@ -6853,8 +6931,7 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op else opCode = spv::OpGroupSMaxNonUniformAMD; } - } - else { + } else { if (isFloat) opCode = spv::OpGroupFAddNonUniformAMD; else @@ -6876,16 +6953,14 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op // Create group invocation operations on a vector spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, - spv::Id typeId, std::vector& operands) + spv::Id typeId, std::vector& operands) { - 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 || + 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::OpGroupSMinNonUniformAMD || op == spv::OpGroupFMaxNonUniformAMD || + op == spv::OpGroupUMaxNonUniformAMD || op == spv::OpGroupSMaxNonUniformAMD || op == spv::OpGroupFAddNonUniformAMD || op == spv::OpGroupIAddNonUniformAMD); // Handle group invocation operations scalar by scalar. @@ -6904,22 +6979,22 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv for (int comp = 0; comp < numComponents; ++comp) { std::vector indexes; indexes.push_back(comp); - spv::IdImmediate scalar = { true, builder.createCompositeExtract(operands[0], scalarType, indexes) }; + spv::IdImmediate scalar = {true, builder.createCompositeExtract(operands[0], scalarType, indexes)}; std::vector spvGroupOperands; if (op == spv::OpSubgroupReadInvocationKHR) { spvGroupOperands.push_back(scalar); - spv::IdImmediate operand = { true, operands[1] }; + spv::IdImmediate operand = {true, operands[1]}; spvGroupOperands.push_back(operand); } else if (op == spv::OpGroupBroadcast) { - spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spv::IdImmediate scope = {true, builder.makeUintConstant(spv::ScopeSubgroup)}; spvGroupOperands.push_back(scope); spvGroupOperands.push_back(scalar); - spv::IdImmediate operand = { true, operands[1] }; + spv::IdImmediate operand = {true, operands[1]}; spvGroupOperands.push_back(operand); } else { - spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spv::IdImmediate scope = {true, builder.makeUintConstant(spv::ScopeSubgroup)}; spvGroupOperands.push_back(scope); - spv::IdImmediate groupOp = { false, (unsigned)groupOperation }; + spv::IdImmediate groupOp = {false, (unsigned)groupOperation}; spvGroupOperands.push_back(groupOp); spvGroupOperands.push_back(scalar); } @@ -6933,7 +7008,7 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv // Create subgroup invocation operations. spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, - std::vector& operands, glslang::TBasicType typeProxy) + std::vector& operands, glslang::TBasicType typeProxy) { // Add the required capabilities. switch (op) { @@ -7034,10 +7109,10 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s builder.addExtension(spv::E_SPV_NV_shader_subgroup_partitioned); builder.addCapability(spv::CapabilityGroupNonUniformPartitionedNV); break; - default: assert(0 && "Unhandled subgroup operation!"); + default: + assert(0 && "Unhandled subgroup operation!"); } - const bool isUnsigned = isTypeUnsignedInt(typeProxy); const bool isFloat = isTypeFloat(typeProxy); const bool isBool = typeProxy == glslang::EbtBool; @@ -7046,24 +7121,56 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s // Figure out which opcode to use. switch (op) { - case glslang::EOpSubgroupElect: opCode = spv::OpGroupNonUniformElect; break; - case glslang::EOpSubgroupAll: opCode = spv::OpGroupNonUniformAll; break; - case glslang::EOpSubgroupAny: opCode = spv::OpGroupNonUniformAny; break; - case glslang::EOpSubgroupAllEqual: opCode = spv::OpGroupNonUniformAllEqual; break; - case glslang::EOpSubgroupBroadcast: opCode = spv::OpGroupNonUniformBroadcast; break; - case glslang::EOpSubgroupBroadcastFirst: opCode = spv::OpGroupNonUniformBroadcastFirst; break; - case glslang::EOpSubgroupBallot: opCode = spv::OpGroupNonUniformBallot; break; - case glslang::EOpSubgroupInverseBallot: opCode = spv::OpGroupNonUniformInverseBallot; break; - case glslang::EOpSubgroupBallotBitExtract: opCode = spv::OpGroupNonUniformBallotBitExtract; break; + case glslang::EOpSubgroupElect: + opCode = spv::OpGroupNonUniformElect; + break; + case glslang::EOpSubgroupAll: + opCode = spv::OpGroupNonUniformAll; + break; + case glslang::EOpSubgroupAny: + opCode = spv::OpGroupNonUniformAny; + break; + case glslang::EOpSubgroupAllEqual: + opCode = spv::OpGroupNonUniformAllEqual; + break; + case glslang::EOpSubgroupBroadcast: + opCode = spv::OpGroupNonUniformBroadcast; + break; + case glslang::EOpSubgroupBroadcastFirst: + opCode = spv::OpGroupNonUniformBroadcastFirst; + break; + case glslang::EOpSubgroupBallot: + opCode = spv::OpGroupNonUniformBallot; + break; + case glslang::EOpSubgroupInverseBallot: + opCode = spv::OpGroupNonUniformInverseBallot; + break; + case glslang::EOpSubgroupBallotBitExtract: + opCode = spv::OpGroupNonUniformBallotBitExtract; + break; case glslang::EOpSubgroupBallotBitCount: case glslang::EOpSubgroupBallotInclusiveBitCount: - case glslang::EOpSubgroupBallotExclusiveBitCount: opCode = spv::OpGroupNonUniformBallotBitCount; break; - case glslang::EOpSubgroupBallotFindLSB: opCode = spv::OpGroupNonUniformBallotFindLSB; break; - case glslang::EOpSubgroupBallotFindMSB: opCode = spv::OpGroupNonUniformBallotFindMSB; break; - case glslang::EOpSubgroupShuffle: opCode = spv::OpGroupNonUniformShuffle; break; - case glslang::EOpSubgroupShuffleXor: opCode = spv::OpGroupNonUniformShuffleXor; break; - case glslang::EOpSubgroupShuffleUp: opCode = spv::OpGroupNonUniformShuffleUp; break; - case glslang::EOpSubgroupShuffleDown: opCode = spv::OpGroupNonUniformShuffleDown; break; + case glslang::EOpSubgroupBallotExclusiveBitCount: + opCode = spv::OpGroupNonUniformBallotBitCount; + break; + case glslang::EOpSubgroupBallotFindLSB: + opCode = spv::OpGroupNonUniformBallotFindLSB; + break; + case glslang::EOpSubgroupBallotFindMSB: + opCode = spv::OpGroupNonUniformBallotFindMSB; + break; + case glslang::EOpSubgroupShuffle: + opCode = spv::OpGroupNonUniformShuffle; + break; + case glslang::EOpSubgroupShuffleXor: + opCode = spv::OpGroupNonUniformShuffleXor; + break; + case glslang::EOpSubgroupShuffleUp: + opCode = spv::OpGroupNonUniformShuffleUp; + break; + case glslang::EOpSubgroupShuffleDown: + opCode = spv::OpGroupNonUniformShuffleDown; + break; case glslang::EOpSubgroupAdd: case glslang::EOpSubgroupInclusiveAdd: case glslang::EOpSubgroupExclusiveAdd: @@ -7159,11 +7266,16 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s opCode = spv::OpGroupNonUniformBitwiseXor; } break; - case glslang::EOpSubgroupQuadBroadcast: opCode = spv::OpGroupNonUniformQuadBroadcast; break; + case glslang::EOpSubgroupQuadBroadcast: + opCode = spv::OpGroupNonUniformQuadBroadcast; + break; case glslang::EOpSubgroupQuadSwapHorizontal: case glslang::EOpSubgroupQuadSwapVertical: - case glslang::EOpSubgroupQuadSwapDiagonal: opCode = spv::OpGroupNonUniformQuadSwap; break; - default: assert(0 && "Unhandled subgroup operation!"); + case glslang::EOpSubgroupQuadSwapDiagonal: + opCode = spv::OpGroupNonUniformQuadSwap; + break; + default: + assert(0 && "Unhandled subgroup operation!"); } // get the right Group Operation @@ -7243,39 +7355,46 @@ spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, s std::vector spvGroupOperands; // Every operation begins with the Execution Scope operand. - spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) }; + spv::IdImmediate executionScope = {true, builder.makeUintConstant(spv::ScopeSubgroup)}; spvGroupOperands.push_back(executionScope); // Next, for all operations that use a Group Operation, push that as an operand. if (groupOperation != spv::GroupOperationMax) { - spv::IdImmediate groupOperand = { false, (unsigned)groupOperation }; + spv::IdImmediate groupOperand = {false, (unsigned)groupOperation}; spvGroupOperands.push_back(groupOperand); } // Push back the operands next. for (auto opIt = operands.cbegin(); opIt != operands.cend(); ++opIt) { - spv::IdImmediate operand = { true, *opIt }; + spv::IdImmediate operand = {true, *opIt}; spvGroupOperands.push_back(operand); } // Some opcodes have additional operands. spv::Id directionId = spv::NoResult; switch (op) { - default: break; - case glslang::EOpSubgroupQuadSwapHorizontal: directionId = builder.makeUintConstant(0); break; - case glslang::EOpSubgroupQuadSwapVertical: directionId = builder.makeUintConstant(1); break; - case glslang::EOpSubgroupQuadSwapDiagonal: directionId = builder.makeUintConstant(2); break; + default: + break; + case glslang::EOpSubgroupQuadSwapHorizontal: + directionId = builder.makeUintConstant(0); + break; + case glslang::EOpSubgroupQuadSwapVertical: + directionId = builder.makeUintConstant(1); + break; + case glslang::EOpSubgroupQuadSwapDiagonal: + directionId = builder.makeUintConstant(2); + break; } if (directionId != spv::NoResult) { - spv::IdImmediate direction = { true, directionId }; + spv::IdImmediate direction = {true, directionId}; spvGroupOperands.push_back(direction); } return builder.createOp(opCode, typeId, spvGroupOperands); } -spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, - spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, + std::vector& operands, glslang::TBasicType typeProxy) { bool isUnsigned = isTypeUnsignedInt(typeProxy); bool isFloat = isTypeFloat(typeProxy); @@ -7335,7 +7454,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: builder.promoteScalar(precision, operands.front(), operands[2]); break; case glslang::EOpMix: - if (! builder.isBoolType(builder.getScalarTypeId(builder.getTypeId(operands.back())))) { + if (!builder.isBoolType(builder.getScalarTypeId(builder.getTypeId(operands.back())))) { assert(isFloat); libCall = spv::GLSLstd450FMix; } else { @@ -7369,49 +7488,41 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpRefract: libCall = spv::GLSLstd450Refract; break; - case glslang::EOpBarrier: - { - // This is for the extended controlBarrier function, with four operands. - // The unextended barrier() goes through createNoArgOperation. - assert(operands.size() == 4); - unsigned int executionScope = builder.getConstantScalar(operands[0]); - unsigned int memoryScope = builder.getConstantScalar(operands[1]); - unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]); - builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, - (spv::MemorySemanticsMask)semantics); - if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | - spv::MemorySemanticsMakeVisibleKHRMask | - spv::MemorySemanticsOutputMemoryKHRMask | - spv::MemorySemanticsVolatileMask)) { - builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); - } - if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || - memoryScope == spv::ScopeDevice)) { - builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); - } - return 0; + 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); } - 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; + 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); } - break; + return 0; + } break; #ifndef GLSLANG_WEB case glslang::EOpInterpolateAtSample: @@ -7457,24 +7568,22 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpFma: libCall = spv::GLSLstd450Fma; break; - case glslang::EOpFrexp: - { - libCall = spv::GLSLstd450FrexpStruct; - assert(builder.isPointerType(typeId1)); - typeId1 = builder.getContainedTypeId(typeId1); - int width = builder.getScalarTypeWidth(typeId1); - if (width == 16) - // Using 16-bit exp operand, enable extension SPV_AMD_gpu_shader_int16 - builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16); - if (builder.getNumComponents(operands[0]) == 1) - frexpIntType = builder.makeIntegerType(width, true); - else - frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true), - builder.getNumComponents(operands[0])); - typeId = builder.makeStructResultType(typeId0, frexpIntType); - consumedOperands = 1; - } - break; + case glslang::EOpFrexp: { + libCall = spv::GLSLstd450FrexpStruct; + assert(builder.isPointerType(typeId1)); + typeId1 = builder.getContainedTypeId(typeId1); + int width = builder.getScalarTypeWidth(typeId1); + if (width == 16) + // Using 16-bit exp operand, enable extension SPV_AMD_gpu_shader_int16 + builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16); + if (builder.getNumComponents(operands[0]) == 1) + frexpIntType = builder.makeIntegerType(width, true); + else + frexpIntType = + builder.makeVectorType(builder.makeIntegerType(width, true), builder.getNumComponents(operands[0])); + typeId = builder.makeStructResultType(typeId0, frexpIntType); + consumedOperands = 1; + } break; case glslang::EOpLdexp: libCall = spv::GLSLstd450Ldexp; break; @@ -7573,24 +7682,18 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: libCall = spv::InterpolateAtVertexAMD; break; - case glslang::EOpReportIntersectionNV: - { + case glslang::EOpReportIntersectionNV: { typeId = builder.makeBoolType(); opCode = spv::OpReportIntersectionNV; - } - break; - case glslang::EOpTraceNV: - { + } break; + case glslang::EOpTraceNV: { builder.createNoResultOp(spv::OpTraceNV, operands); return 0; - } - break; - case glslang::EOpExecuteCallableNV: - { + } break; + case glslang::EOpExecuteCallableNV: { builder.createNoResultOp(spv::OpExecuteCallableNV, operands); return 0; - } - break; + } break; case glslang::EOpWritePackedPrimitiveIndices4x8NV: builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands); return 0; @@ -7654,20 +7757,18 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: builder.createStore(builder.createCompositeExtract(id, typeId0, 0), operands[3]); builder.createStore(builder.createCompositeExtract(id, typeId0, 1), operands[2]); break; - case glslang::EOpFrexp: - { - assert(operands.size() == 2); - if (builder.isFloatType(builder.getScalarTypeId(typeId1))) { - // "exp" is floating-point type (from HLSL intrinsic) - spv::Id member1 = builder.createCompositeExtract(id, frexpIntType, 1); - member1 = builder.createUnaryOp(spv::OpConvertSToF, typeId1, member1); - builder.createStore(member1, operands[1]); - } else - // "exp" is integer type (from GLSL built-in function) - builder.createStore(builder.createCompositeExtract(id, frexpIntType, 1), operands[1]); - id = builder.createCompositeExtract(id, typeId0, 0); - } - break; + case glslang::EOpFrexp: { + assert(operands.size() == 2); + if (builder.isFloatType(builder.getScalarTypeId(typeId1))) { + // "exp" is floating-point type (from HLSL intrinsic) + spv::Id member1 = builder.createCompositeExtract(id, frexpIntType, 1); + member1 = builder.createUnaryOp(spv::OpConvertSToF, typeId1, member1); + builder.createStore(member1, operands[1]); + } else + // "exp" is integer type (from GLSL built-in function) + builder.createStore(builder.createCompositeExtract(id, frexpIntType, 1), operands[1]); + id = builder.createCompositeExtract(id, typeId0, 0); + } break; default: break; } @@ -7680,8 +7781,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: 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::EOpBarrier: @@ -7689,85 +7790,83 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: if (glslangIntermediate->usingVulkanMemoryModel()) { builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, spv::MemorySemanticsOutputMemoryKHRMask | - spv::MemorySemanticsAcquireReleaseMask); + spv::MemorySemanticsAcquireReleaseMask); builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } else { builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone); } } else { builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, - spv::MemorySemanticsWorkgroupMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + spv::MemorySemanticsWorkgroupMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); } return 0; case glslang::EOpMemoryBarrier: - builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAllMemory | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, + spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpMemoryBarrierBuffer: - builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsUniformMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, + spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpMemoryBarrierShared: - builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsWorkgroupMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, + spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpGroupMemoryBarrier: - builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(spv::ScopeWorkgroup, + spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; #ifndef GLSLANG_WEB case glslang::EOpMemoryBarrierAtomicCounter: builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpMemoryBarrierImage: - builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(memoryBarrierScope, + spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpAllMemoryBarrierWithGroupSync: builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, - spv::MemorySemanticsAllMemory | - spv::MemorySemanticsAcquireReleaseMask); + spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpDeviceMemoryBarrier: builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask | - spv::MemorySemanticsImageMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + spv::MemorySemanticsImageMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpDeviceMemoryBarrierWithGroupSync: - builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask | - spv::MemorySemanticsImageMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeDevice, + spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsImageMemoryMask | + spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpWorkgroupMemoryBarrier: - builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsWorkgroupMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(spv::ScopeWorkgroup, + spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpWorkgroupMemoryBarrierWithGroupSync: builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup, - spv::MemorySemanticsWorkgroupMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return 0; case glslang::EOpSubgroupBarrier: - builder.createControlBarrier(spv::ScopeSubgroup, spv::ScopeSubgroup, spv::MemorySemanticsAllMemory | - spv::MemorySemanticsAcquireReleaseMask); + builder.createControlBarrier(spv::ScopeSubgroup, spv::ScopeSubgroup, + spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; case glslang::EOpSubgroupMemoryBarrier: - builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAllMemory | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(spv::ScopeSubgroup, + spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; case glslang::EOpSubgroupMemoryBarrierBuffer: - builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsUniformMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(spv::ScopeSubgroup, + spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; case glslang::EOpSubgroupMemoryBarrierImage: - builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsImageMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(spv::ScopeSubgroup, + spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; case glslang::EOpSubgroupMemoryBarrierShared: - builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsWorkgroupMemoryMask | - spv::MemorySemanticsAcquireReleaseMask); + builder.createMemoryBarrier(spv::ScopeSubgroup, + spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask); return spv::NoResult; case glslang::EOpEmitVertex: @@ -7781,8 +7880,7 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: std::vector operands; return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid); } - case glslang::EOpTime: - { + case glslang::EOpTime: { std::vector args; // Dummy arguments spv::Id id = builder.createBuiltinCall(typeId, getExtBuiltins(spv::E_SPV_AMD_gcn_shader), spv::TimeAMD, args); return builder.setPrecision(id, precision); @@ -7801,8 +7899,7 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.createNoResultOp(spv::OpEndInvocationInterlockEXT); return 0; - case glslang::EOpIsHelperInvocation: - { + case glslang::EOpIsHelperInvocation: { std::vector args; // Dummy arguments builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT); @@ -7911,7 +8008,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol if (symbol->getType().isImage()) { std::vector memory; TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, - glslangIntermediate->usingVulkanMemoryModel()); + glslangIntermediate->usingVulkanMemoryModel()); for (unsigned int i = 0; i < memory.size(); ++i) builder.addDecoration(id, memory[i]); } @@ -7920,19 +8017,18 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier())); if (builtIn == spv::BuiltInSampleMask) { - spv::Decoration decoration; - // GL_NV_sample_mask_override_coverage extension - if (glslangIntermediate->getLayoutOverrideCoverage()) - decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV; - else - decoration = (spv::Decoration)spv::DecorationMax; + spv::Decoration decoration; + // GL_NV_sample_mask_override_coverage extension + if (glslangIntermediate->getLayoutOverrideCoverage()) + decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV; + else + 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); } - } - else if (builtIn == spv::BuiltInLayer) { + } else if (builtIn == spv::BuiltInLayer) { // SPV_NV_viewport_array2 extension if (symbol->getQualifier().layoutViewportRelative) { builder.addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV); @@ -7965,8 +8061,8 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol } if (symbol->isReference()) { - builder.addDecoration(id, symbol->getType().getQualifier().restrict ? - spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); + builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT + : spv::DecorationAliasedPointerEXT); } #endif @@ -8024,13 +8120,15 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n assert(node.getQualifier().isConstant()); // Handle front-end constants first (non-specialization constants). - if (! node.getQualifier().specConstant) { + if (!node.getQualifier().specConstant) { // 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 @@ -8084,7 +8182,8 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n // 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) + const glslang::TConstUnionArray& consts, + int& nextConst, bool specConstant) { // vector of constants for SPIR-V std::vector spvConsts; @@ -8257,7 +8356,7 @@ bool TGlslangToSpvTraverser::isTrivial(const glslang::TIntermTyped* node) return false; // count non scalars as trivial, as well as anything coming from HLSL - if (! node->getType().isScalarOrVec1() || glslangIntermediate->getSource() == glslang::EShSourceHlsl) + if (!node->getType().isScalarOrVec1() || glslangIntermediate->getSource() == glslang::EShSourceHlsl) return true; // symbols and constants are trivial @@ -8273,10 +8372,10 @@ bool TGlslangToSpvTraverser::isTrivial(const glslang::TIntermTyped* node) return false; // not on leaf nodes - if (binaryNode && (! isTrivialLeaf(binaryNode->getLeft()) || ! isTrivialLeaf(binaryNode->getRight()))) + if (binaryNode && (!isTrivialLeaf(binaryNode->getLeft()) || !isTrivialLeaf(binaryNode->getRight()))) return false; - if (unaryNode && ! isTrivialLeaf(unaryNode->getOperand())) { + if (unaryNode && !isTrivialLeaf(unaryNode->getOperand())) { return false; } @@ -8306,7 +8405,7 @@ bool TGlslangToSpvTraverser::isTrivial(const glslang::TIntermTyped* node) // 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) + glslang::TIntermTyped& right) { spv::Id boolTypeId = builder.makeBoolType(); @@ -8365,7 +8464,7 @@ spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name) } #endif -}; // end anonymous namespace +}; // end anonymous namespace namespace glslang { @@ -8388,7 +8487,7 @@ int GetSpirvGeneratorVersion() // return 4; // some deeper access chains: for dynamic vector component, and local Boolean component // return 5; // make OpArrayLength result type be an int with signedness of 0 // return 6; // revert version 5 change, which makes a different (new) kind of incorrect code, - // versions 4 and 6 each generate OpArrayLength as it has long been done + // versions 4 and 6 each generate OpArrayLength as it has long been done // return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent return 8; // switch to new dead block eliminator; use OpUnreachable } @@ -8415,9 +8514,8 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, out.open(baseName, std::ios::binary | std::ios::out); if (out.fail()) printf("ERROR: Failed to open file: %s\n", baseName); - out << "\t// " << - GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL << - std::endl; + out << "\t// " << GetSpirvGeneratorVersion() << "." << GLSLANG_MINOR_VERSION << "." << GLSLANG_PATCH_LEVEL + << std::endl; if (varName != nullptr) { out << "\t #pragma once" << std::endl; out << "const uint32_t " << varName << "[] = {" << std::endl; @@ -8450,8 +8548,8 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector& GlslangToSpv(intermediate, spirv, &logger, options); } -void GlslangToSpv(const TIntermediate& intermediate, std::vector& spirv, - spv::SpvBuildLogger* logger, SpvOptions* options) +void GlslangToSpv(const TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger* logger, + SpvOptions* options) { TIntermNode* root = intermediate.getTreeRoot(); @@ -8469,7 +8567,7 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector& it.finishSpv(); it.dumpSpv(spirv); -#if ENABLE_OPT +#if GLSLANG_ENABLE_OPT // If from HLSL, run spirv-opt to "legalize" the SPIR-V for Vulkan // eg. forward and remove memory writes of opaque types. bool prelegalization = intermediate.getSource() == EShSourceHlsl; diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp index 1e968ba542..d655fd59a2 100644 --- a/SPIRV/SpvTools.cpp +++ b/SPIRV/SpvTools.cpp @@ -37,14 +37,14 @@ // Call into SPIRV-Tools to disassemble, validate, and optimize. // -#if ENABLE_OPT +#if GLSLANG_ENABLE_OPT #include #include #include "SpvTools.h" -#include "spirv-tools/optimizer.hpp" #include "spirv-tools/libspirv.h" +#include "spirv-tools/optimizer.hpp" namespace glslang { @@ -80,7 +80,6 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog return spv_target_env::SPV_ENV_UNIVERSAL_1_0; } - // Use the SPIRV-Tools disassembler to print SPIR-V. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv) { @@ -89,8 +88,7 @@ void SpirvToolsDisassemble(std::ostream& out, const std::vector& s spv_text text; spv_diagnostic diagnostic = nullptr; spvBinaryToText(context, spirv.data(), spirv.size(), - SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT, - &text, &diagnostic); + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT, &text, &diagnostic); // dump if (diagnostic == nullptr) @@ -109,7 +107,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< { // validate spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger)); - spv_const_binary_t binary = { spirv.data(), spirv.size() }; + spv_const_binary_t binary = {spirv.data(), spirv.size()}; spv_diagnostic diagnostic = nullptr; spv_validator_options options = spvValidatorOptionsCreate(); spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); @@ -137,10 +135,9 @@ void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector< spvtools::Optimizer optimizer(target_env); optimizer.SetMessageConsumer( - [](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) { - auto &out = std::cerr; - switch (level) - { + [](spv_message_level_t level, const char* source, const spv_position_t& position, const char* message) { + auto& out = std::cerr; + switch (level) { case SPV_MSG_FATAL: case SPV_MSG_INTERNAL_ERROR: case SPV_MSG_ERROR: @@ -156,13 +153,11 @@ void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector< default: break; } - if (source) - { + if (source) { out << source << ":"; } out << position.line << ":" << position.column << ":" << position.index << ":"; - if (message) - { + if (message) { out << " " << message; } out << std::endl; diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h index 59c914da0b..ac7e881222 100644 --- a/SPIRV/SpvTools.h +++ b/SPIRV/SpvTools.h @@ -41,7 +41,7 @@ #ifndef GLSLANG_SPV_TOOLS_H #define GLSLANG_SPV_TOOLS_H -#ifdef ENABLE_OPT +#ifdef GLSLANG_ENABLE_OPT #include #include #endif @@ -61,7 +61,7 @@ struct SpvOptions { bool validate; }; -#ifdef ENABLE_OPT +#ifdef GLSLANG_ENABLE_OPT // Use the SPIRV-Tools disassembler to print SPIR-V. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); diff --git a/StandAlone/CMakeLists.txt b/StandAlone/CMakeLists.txt index 591ac340aa..41ee4adc3e 100644 --- a/StandAlone/CMakeLists.txt +++ b/StandAlone/CMakeLists.txt @@ -60,7 +60,7 @@ if(ENABLE_GLSLANG_INSTALL) install(EXPORT spirv-remapTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) endif() - if(BUILD_SHARED_LIBS) + if(GLSLANG_BUILD_SHARED_LIBS) 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) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 81aca3be69..cfaad80895 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -40,22 +40,22 @@ #define _CRT_SECURE_NO_WARNINGS #endif -#include "ResourceLimits.h" -#include "Worklist.h" -#include "DirStackFileIncluder.h" +#include "../SPIRV/GLSL.std.450.h" +#include "../SPIRV/GlslangToSpv.h" +#include "../SPIRV/disassemble.h" +#include "../SPIRV/doc.h" #include "./../glslang/Include/ShHandle.h" #include "./../glslang/Include/revision.h" #include "./../glslang/Public/ShaderLang.h" -#include "../SPIRV/GlslangToSpv.h" -#include "../SPIRV/GLSL.std.450.h" -#include "../SPIRV/doc.h" -#include "../SPIRV/disassemble.h" +#include "DirStackFileIncluder.h" +#include "ResourceLimits.h" +#include "Worklist.h" -#include -#include +#include #include #include -#include +#include +#include #include #include #include @@ -63,44 +63,44 @@ #include "../glslang/OSDependent/osinclude.h" extern "C" { - SH_IMPORT_EXPORT void ShOutputHtml(); +SH_IMPORT_EXPORT void ShOutputHtml(); } // Command-line options enum TOptions { - EOptionNone = 0, - EOptionIntermediate = (1 << 0), - EOptionSuppressInfolog = (1 << 1), - EOptionMemoryLeakMode = (1 << 2), - EOptionRelaxedErrors = (1 << 3), - EOptionGiveWarnings = (1 << 4), - EOptionLinkProgram = (1 << 5), - EOptionMultiThreaded = (1 << 6), - EOptionDumpConfig = (1 << 7), - EOptionDumpReflection = (1 << 8), - EOptionSuppressWarnings = (1 << 9), - EOptionDumpVersions = (1 << 10), - EOptionSpv = (1 << 11), - EOptionHumanReadableSpv = (1 << 12), - EOptionVulkanRules = (1 << 13), - EOptionDefaultDesktop = (1 << 14), - EOptionOutputPreprocessed = (1 << 15), - EOptionOutputHexadecimal = (1 << 16), - EOptionReadHlsl = (1 << 17), - EOptionCascadingErrors = (1 << 18), - EOptionAutoMapBindings = (1 << 19), + EOptionNone = 0, + EOptionIntermediate = (1 << 0), + EOptionSuppressInfolog = (1 << 1), + EOptionMemoryLeakMode = (1 << 2), + EOptionRelaxedErrors = (1 << 3), + EOptionGiveWarnings = (1 << 4), + EOptionLinkProgram = (1 << 5), + EOptionMultiThreaded = (1 << 6), + EOptionDumpConfig = (1 << 7), + EOptionDumpReflection = (1 << 8), + EOptionSuppressWarnings = (1 << 9), + EOptionDumpVersions = (1 << 10), + EOptionSpv = (1 << 11), + EOptionHumanReadableSpv = (1 << 12), + EOptionVulkanRules = (1 << 13), + EOptionDefaultDesktop = (1 << 14), + EOptionOutputPreprocessed = (1 << 15), + EOptionOutputHexadecimal = (1 << 16), + EOptionReadHlsl = (1 << 17), + EOptionCascadingErrors = (1 << 18), + EOptionAutoMapBindings = (1 << 19), EOptionFlattenUniformArrays = (1 << 20), - EOptionNoStorageFormat = (1 << 21), - EOptionKeepUncalled = (1 << 22), - EOptionHlslOffsets = (1 << 23), - EOptionHlslIoMapping = (1 << 24), - EOptionAutoMapLocations = (1 << 25), - EOptionDebug = (1 << 26), - EOptionStdin = (1 << 27), - EOptionOptimizeDisable = (1 << 28), - EOptionOptimizeSize = (1 << 29), - EOptionInvertY = (1 << 30), - EOptionDumpBareVersion = (1 << 31), + EOptionNoStorageFormat = (1 << 21), + EOptionKeepUncalled = (1 << 22), + EOptionHlslOffsets = (1 << 23), + EOptionHlslIoMapping = (1 << 24), + EOptionAutoMapLocations = (1 << 25), + EOptionDebug = (1 << 26), + EOptionStdin = (1 << 27), + EOptionOptimizeDisable = (1 << 28), + EOptionOptimizeSize = (1 << 29), + EOptionInvertY = (1 << 30), + EOptionDumpBareVersion = (1 << 31), }; bool targetHlslFunctionality1 = false; bool SpvToolsDisassembler = false; @@ -123,7 +123,7 @@ enum TFailCode { // // Forward declarations. // -EShLanguage FindLanguage(const std::string& name, bool parseSuffix=true); +EShLanguage FindLanguage(const std::string& name, bool parseSuffix = true); void CompileFile(const char* fileName, ShHandle); void usage(); char* ReadFileData(const char* fileName); @@ -150,7 +150,7 @@ void ProcessConfigFile() #ifndef GLSLANG_WEB else { char* configString = ReadFileData(ConfigFile.c_str()); - glslang::DecodeResourceLimits(&Resources, configString); + glslang::DecodeResourceLimits(&Resources, configString); FreeFileData(configString); } #endif @@ -174,12 +174,12 @@ std::vector IncludeDirectoryList; int ClientInputSemanticsVersion = 100; // Target environment -glslang::EShClient Client = glslang::EShClientNone; // will stay EShClientNone if only validating -glslang::EShTargetClientVersion ClientVersion; // not valid until Client is set +glslang::EShClient Client = glslang::EShClientNone; // will stay EShClientNone if only validating +glslang::EShTargetClientVersion ClientVersion; // not valid until Client is set glslang::EShTargetLanguage TargetLanguage = glslang::EShTargetNone; -glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set +glslang::EShTargetLanguageVersion TargetVersion; // not valid until TargetLanguage is set -std::vector Processes; // what should be recorded by OpModuleProcessed, or equivalent +std::vector Processes; // what should be recorded by OpModuleProcessed, or equivalent // Per descriptor-set binding base data typedef std::map TPerSetBaseBinding; @@ -194,7 +194,7 @@ std::array, EShLangCount> baseResourceSetBinding; // Add things like "#define ..." to a preamble to use in the beginning of the shader. class TPreamble { public: - TPreamble() { } + TPreamble() {} bool isSet() const { return text.size() > 0; } const char* get() const { return text.c_str(); } @@ -239,7 +239,7 @@ class TPreamble { line = line.substr(0, end); } - std::string text; // contents of preamble + std::string text; // contents of preamble }; TPreamble UserPreamble; @@ -252,21 +252,51 @@ const char* GetBinaryName(EShLanguage stage) const char* name; if (binaryFileName == nullptr) { switch (stage) { - case EShLangVertex: name = "vert.spv"; break; - case EShLangTessControl: name = "tesc.spv"; break; - case EShLangTessEvaluation: name = "tese.spv"; break; - case EShLangGeometry: name = "geom.spv"; break; - case EShLangFragment: name = "frag.spv"; break; - case EShLangCompute: name = "comp.spv"; break; - case EShLangRayGenNV: name = "rgen.spv"; break; - case EShLangIntersectNV: name = "rint.spv"; break; - case EShLangAnyHitNV: name = "rahit.spv"; break; - case EShLangClosestHitNV: name = "rchit.spv"; break; - case EShLangMissNV: name = "rmiss.spv"; break; - case EShLangCallableNV: name = "rcall.spv"; break; - case EShLangMeshNV: name = "mesh.spv"; break; - case EShLangTaskNV: name = "task.spv"; break; - default: name = "unknown"; break; + case EShLangVertex: + name = "vert.spv"; + break; + case EShLangTessControl: + name = "tesc.spv"; + break; + case EShLangTessEvaluation: + name = "tese.spv"; + break; + case EShLangGeometry: + name = "geom.spv"; + break; + case EShLangFragment: + name = "frag.spv"; + break; + case EShLangCompute: + name = "comp.spv"; + break; + case EShLangRayGenNV: + name = "rgen.spv"; + break; + case EShLangIntersectNV: + name = "rint.spv"; + break; + case EShLangAnyHitNV: + name = "rahit.spv"; + break; + case EShLangClosestHitNV: + name = "rchit.spv"; + break; + case EShLangMissNV: + name = "rmiss.spv"; + break; + case EShLangCallableNV: + name = "rcall.spv"; + break; + case EShLangMeshNV: + name = "mesh.spv"; + break; + case EShLangTaskNV: + name = "task.spv"; + break; + default: + name = "unknown"; + break; } } else name = binaryFileName; @@ -327,9 +357,9 @@ void ProcessBindingBase(int& argc, char**& argv, glslang::TResourceType res) lang = FindLanguage(argv[arg++], false); } - if ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) { + if ((argc - arg) > 2 && isdigit(argv[arg + 0][0]) && isdigit(argv[arg + 1][0])) { // Parse a per-set binding base - while ((argc - arg) > 2 && isdigit(argv[arg+0][0]) && isdigit(argv[arg+1][0])) { + while ((argc - arg) > 2 && isdigit(argv[arg + 0][0]) && isdigit(argv[arg + 1][0])) { const int baseNum = atoi(argv[arg++]); const int setNum = atoi(argv[arg++]); perSetBase[setNum] = baseNum; @@ -339,12 +369,12 @@ void ProcessBindingBase(int& argc, char**& argv, glslang::TResourceType res) singleBase = atoi(argv[arg++]); } - argc -= (arg-1); - argv += (arg-1); + argc -= (arg - 1); + argv += (arg - 1); // Set one or all languages - const int langMin = (lang < EShLangCount) ? lang+0 : 0; - const int langMax = (lang < EShLangCount) ? lang+1 : EShLangCount; + const int langMin = (lang < EShLangCount) ? lang + 0 : 0; + const int langMax = (lang < EShLangCount) ? lang + 1 : EShLangCount; for (int lang = langMin; lang < langMax; ++lang) { if (!perSetBase.empty()) @@ -383,7 +413,7 @@ void ProcessResourceSetBindingBase(int& argc, char**& argv, std::array>& workItem }; const auto getUniformOverride = [getStringOperand]() { - const char *arg = getStringOperand("-u:"); - const char *split = strchr(arg, ':'); + const char* arg = getStringOperand("-u:"); + const char* split = strchr(arg, ':'); if (split == NULL) { printf("%s: missing location\n", arg); exit(EFailUsage); @@ -471,198 +501,181 @@ void ProcessArguments(std::vector>& workItem for (bumpArg(); argc >= 1; bumpArg()) { if (argv[0][0] == '-') { switch (argv[0][1]) { - case '-': - { - std::string lowerword(argv[0]+2); - std::transform(lowerword.begin(), lowerword.end(), lowerword.begin(), ::tolower); - - // handle --word style options - if (lowerword == "auto-map-bindings" || // synonyms - lowerword == "auto-map-binding" || - lowerword == "amb") { - Options |= EOptionAutoMapBindings; - } else if (lowerword == "auto-map-locations" || // synonyms - lowerword == "aml") { - Options |= EOptionAutoMapLocations; - } else if (lowerword == "uniform-base") { - if (argc <= 1) - Error("no provided", lowerword.c_str()); - uniformBase = ::strtol(argv[1], NULL, 10); - bumpArg(); - break; - } else if (lowerword == "client") { - if (argc > 1) { - if (strcmp(argv[1], "vulkan100") == 0) - setVulkanSpv(); - else if (strcmp(argv[1], "opengl100") == 0) - setOpenGlSpv(); - else - Error("expects vulkan100 or opengl100", lowerword.c_str()); - } else - Error("expects vulkan100 or opengl100", lowerword.c_str()); - bumpArg(); - } else if (lowerword == "define-macro" || - lowerword == "d") { - if (argc > 1) - UserPreamble.addDef(argv[1]); - else - Error("expects ", argv[0]); - bumpArg(); - } else if (lowerword == "dump-builtin-symbols") { - DumpBuiltinSymbols = true; - } else if (lowerword == "entry-point") { - entryPointName = argv[1]; - if (argc <= 1) - Error("no provided", lowerword.c_str()); - bumpArg(); - } else if (lowerword == "flatten-uniform-arrays" || // synonyms - lowerword == "flatten-uniform-array" || - lowerword == "fua") { - Options |= EOptionFlattenUniformArrays; - } else if (lowerword == "hlsl-offsets") { - Options |= EOptionHlslOffsets; - } else if (lowerword == "hlsl-iomap" || - lowerword == "hlsl-iomapper" || - lowerword == "hlsl-iomapping") { - Options |= EOptionHlslIoMapping; - } else if (lowerword == "hlsl-enable-16bit-types") { - HlslEnable16BitTypes = true; - } else if (lowerword == "hlsl-dx9-compatible") { - HlslDX9compatible = true; - } else if (lowerword == "invert-y" || // synonyms - lowerword == "iy") { - Options |= EOptionInvertY; - } else if (lowerword == "keep-uncalled" || // synonyms - lowerword == "ku") { - Options |= EOptionKeepUncalled; - } else if (lowerword == "nan-clamp") { - NaNClamp = true; - } else if (lowerword == "no-storage-format" || // synonyms - lowerword == "nsf") { - Options |= EOptionNoStorageFormat; - } else if (lowerword == "relaxed-errors") { - Options |= EOptionRelaxedErrors; - } else if (lowerword == "reflect-strict-array-suffix") { - ReflectOptions |= EShReflectionStrictArraySuffix; - } else if (lowerword == "reflect-basic-array-suffix") { - ReflectOptions |= EShReflectionBasicArraySuffix; - } else if (lowerword == "reflect-intermediate-io") { - ReflectOptions |= EShReflectionIntermediateIO; - } else if (lowerword == "reflect-separate-buffers") { - ReflectOptions |= EShReflectionSeparateBuffers; - } else if (lowerword == "reflect-all-block-variables") { - ReflectOptions |= EShReflectionAllBlockVariables; - } else if (lowerword == "reflect-unwrap-io-blocks") { - ReflectOptions |= EShReflectionUnwrapIOBlocks; - } else if (lowerword == "resource-set-bindings" || // synonyms - lowerword == "resource-set-binding" || - lowerword == "rsb") { - ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding); - } else if (lowerword == "shift-image-bindings" || // synonyms - lowerword == "shift-image-binding" || - lowerword == "sib") { - ProcessBindingBase(argc, argv, glslang::EResImage); - } else if (lowerword == "shift-sampler-bindings" || // synonyms - lowerword == "shift-sampler-binding" || - lowerword == "ssb") { - ProcessBindingBase(argc, argv, glslang::EResSampler); - } else if (lowerword == "shift-uav-bindings" || // synonyms - lowerword == "shift-uav-binding" || - lowerword == "suavb") { - ProcessBindingBase(argc, argv, glslang::EResUav); - } else if (lowerword == "shift-texture-bindings" || // synonyms - lowerword == "shift-texture-binding" || - lowerword == "stb") { - ProcessBindingBase(argc, argv, glslang::EResTexture); - } else if (lowerword == "shift-ubo-bindings" || // synonyms - lowerword == "shift-ubo-binding" || - lowerword == "shift-cbuffer-bindings" || - lowerword == "shift-cbuffer-binding" || - lowerword == "sub" || - lowerword == "scb") { - ProcessBindingBase(argc, argv, glslang::EResUbo); - } else if (lowerword == "shift-ssbo-bindings" || // synonyms - lowerword == "shift-ssbo-binding" || - lowerword == "sbb") { - ProcessBindingBase(argc, argv, glslang::EResSsbo); - } else if (lowerword == "source-entrypoint" || // synonyms - lowerword == "sep") { - if (argc <= 1) - Error("no provided", lowerword.c_str()); - sourceEntryPointName = argv[1]; - bumpArg(); - break; - } else if (lowerword == "spirv-dis") { - SpvToolsDisassembler = true; - } else if (lowerword == "spirv-val") { - SpvToolsValidate = true; - } else if (lowerword == "stdin") { - Options |= EOptionStdin; - shaderStageName = argv[1]; - } else if (lowerword == "suppress-warnings") { - Options |= EOptionSuppressWarnings; - } else if (lowerword == "target-env") { - if (argc > 1) { - if (strcmp(argv[1], "vulkan1.0") == 0) { - setVulkanSpv(); - ClientVersion = glslang::EShTargetVulkan_1_0; - } 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; - } else if (strcmp(argv[1], "spirv1.0") == 0) { - TargetLanguage = glslang::EShTargetSpv; - TargetVersion = glslang::EShTargetSpv_1_0; - } else if (strcmp(argv[1], "spirv1.1") == 0) { - TargetLanguage = glslang::EShTargetSpv; - TargetVersion = glslang::EShTargetSpv_1_1; - } else if (strcmp(argv[1], "spirv1.2") == 0) { - TargetLanguage = glslang::EShTargetSpv; - TargetVersion = glslang::EShTargetSpv_1_2; - } else if (strcmp(argv[1], "spirv1.3") == 0) { - TargetLanguage = glslang::EShTargetSpv; - TargetVersion = glslang::EShTargetSpv_1_3; - } else if (strcmp(argv[1], "spirv1.4") == 0) { - TargetLanguage = glslang::EShTargetSpv; - TargetVersion = glslang::EShTargetSpv_1_4; - } else if (strcmp(argv[1], "spirv1.5") == 0) { - TargetLanguage = glslang::EShTargetSpv; - TargetVersion = glslang::EShTargetSpv_1_5; - } else - Error("--target-env expected 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]); + case '-': { + std::string lowerword(argv[0] + 2); + std::transform(lowerword.begin(), lowerword.end(), lowerword.begin(), ::tolower); + + // handle --word style options + if (lowerword == "auto-map-bindings" || // synonyms + lowerword == "auto-map-binding" || lowerword == "amb") { + Options |= EOptionAutoMapBindings; + } else if (lowerword == "auto-map-locations" || // synonyms + lowerword == "aml") { + Options |= EOptionAutoMapLocations; + } else if (lowerword == "uniform-base") { + if (argc <= 1) + Error("no provided", lowerword.c_str()); + uniformBase = ::strtol(argv[1], NULL, 10); + bumpArg(); + break; + } else if (lowerword == "client") { + if (argc > 1) { + if (strcmp(argv[1], "vulkan100") == 0) + setVulkanSpv(); + else if (strcmp(argv[1], "opengl100") == 0) + setOpenGlSpv(); else - Error("expects ", argv[0]); - bumpArg(); - } else if (lowerword == "variable-name" || // synonyms - lowerword == "vn") { - Options |= EOptionOutputHexadecimal; - if (argc <= 1) - Error("no provided", lowerword.c_str()); - variableName = argv[1]; - bumpArg(); - break; - } else if (lowerword == "version") { - Options |= EOptionDumpVersions; - } else if (lowerword == "help") { - usage(); - break; - } else { - Error("unrecognized command-line option", argv[0]); + Error("expects vulkan100 or opengl100", lowerword.c_str()); + } else + Error("expects vulkan100 or opengl100", lowerword.c_str()); + bumpArg(); + } else if (lowerword == "define-macro" || lowerword == "d") { + if (argc > 1) + UserPreamble.addDef(argv[1]); + else + Error("expects ", argv[0]); + bumpArg(); + } else if (lowerword == "dump-builtin-symbols") { + DumpBuiltinSymbols = true; + } else if (lowerword == "entry-point") { + entryPointName = argv[1]; + if (argc <= 1) + Error("no provided", lowerword.c_str()); + bumpArg(); + } else if (lowerword == "flatten-uniform-arrays" || // synonyms + lowerword == "flatten-uniform-array" || lowerword == "fua") { + Options |= EOptionFlattenUniformArrays; + } else if (lowerword == "hlsl-offsets") { + Options |= EOptionHlslOffsets; + } else if (lowerword == "hlsl-iomap" || lowerword == "hlsl-iomapper" || lowerword == "hlsl-iomapping") { + Options |= EOptionHlslIoMapping; + } else if (lowerword == "hlsl-enable-16bit-types") { + HlslEnable16BitTypes = true; + } else if (lowerword == "hlsl-dx9-compatible") { + HlslDX9compatible = true; + } else if (lowerword == "invert-y" || // synonyms + lowerword == "iy") { + Options |= EOptionInvertY; + } else if (lowerword == "keep-uncalled" || // synonyms + lowerword == "ku") { + Options |= EOptionKeepUncalled; + } else if (lowerword == "nan-clamp") { + NaNClamp = true; + } else if (lowerword == "no-storage-format" || // synonyms + lowerword == "nsf") { + Options |= EOptionNoStorageFormat; + } else if (lowerword == "relaxed-errors") { + Options |= EOptionRelaxedErrors; + } else if (lowerword == "reflect-strict-array-suffix") { + ReflectOptions |= EShReflectionStrictArraySuffix; + } else if (lowerword == "reflect-basic-array-suffix") { + ReflectOptions |= EShReflectionBasicArraySuffix; + } else if (lowerword == "reflect-intermediate-io") { + ReflectOptions |= EShReflectionIntermediateIO; + } else if (lowerword == "reflect-separate-buffers") { + ReflectOptions |= EShReflectionSeparateBuffers; + } else if (lowerword == "reflect-all-block-variables") { + ReflectOptions |= EShReflectionAllBlockVariables; + } else if (lowerword == "reflect-unwrap-io-blocks") { + ReflectOptions |= EShReflectionUnwrapIOBlocks; + } else if (lowerword == "resource-set-bindings" || // synonyms + lowerword == "resource-set-binding" || lowerword == "rsb") { + ProcessResourceSetBindingBase(argc, argv, baseResourceSetBinding); + } else if (lowerword == "shift-image-bindings" || // synonyms + lowerword == "shift-image-binding" || lowerword == "sib") { + ProcessBindingBase(argc, argv, glslang::EResImage); + } else if (lowerword == "shift-sampler-bindings" || // synonyms + lowerword == "shift-sampler-binding" || lowerword == "ssb") { + ProcessBindingBase(argc, argv, glslang::EResSampler); + } else if (lowerword == "shift-uav-bindings" || // synonyms + lowerword == "shift-uav-binding" || lowerword == "suavb") { + ProcessBindingBase(argc, argv, glslang::EResUav); + } else if (lowerword == "shift-texture-bindings" || // synonyms + lowerword == "shift-texture-binding" || lowerword == "stb") { + ProcessBindingBase(argc, argv, glslang::EResTexture); + } else if (lowerword == "shift-ubo-bindings" || // synonyms + lowerword == "shift-ubo-binding" || lowerword == "shift-cbuffer-bindings" || + lowerword == "shift-cbuffer-binding" || lowerword == "sub" || lowerword == "scb") { + ProcessBindingBase(argc, argv, glslang::EResUbo); + } else if (lowerword == "shift-ssbo-bindings" || // synonyms + lowerword == "shift-ssbo-binding" || lowerword == "sbb") { + ProcessBindingBase(argc, argv, glslang::EResSsbo); + } else if (lowerword == "source-entrypoint" || // synonyms + lowerword == "sep") { + if (argc <= 1) + Error("no provided", lowerword.c_str()); + sourceEntryPointName = argv[1]; + bumpArg(); + break; + } else if (lowerword == "spirv-dis") { + SpvToolsDisassembler = true; + } else if (lowerword == "spirv-val") { + SpvToolsValidate = true; + } else if (lowerword == "stdin") { + Options |= EOptionStdin; + shaderStageName = argv[1]; + } else if (lowerword == "suppress-warnings") { + Options |= EOptionSuppressWarnings; + } else if (lowerword == "target-env") { + if (argc > 1) { + if (strcmp(argv[1], "vulkan1.0") == 0) { + setVulkanSpv(); + ClientVersion = glslang::EShTargetVulkan_1_0; + } 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; + } else if (strcmp(argv[1], "spirv1.0") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_0; + } else if (strcmp(argv[1], "spirv1.1") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_1; + } else if (strcmp(argv[1], "spirv1.2") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_2; + } else if (strcmp(argv[1], "spirv1.3") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_3; + } else if (strcmp(argv[1], "spirv1.4") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_4; + } else if (strcmp(argv[1], "spirv1.5") == 0) { + TargetLanguage = glslang::EShTargetSpv; + TargetVersion = glslang::EShTargetSpv_1_5; + } else + Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2, opengl,\n" + "spirv1.0, spirv1.1, spirv1.2, spirv1.3, spirv1.4, or spirv1.5"); } + bumpArg(); + } else if (lowerword == "undef-macro" || lowerword == "u") { + if (argc > 1) + UserPreamble.addUndef(argv[1]); + else + Error("expects ", argv[0]); + bumpArg(); + } else if (lowerword == "variable-name" || // synonyms + lowerword == "vn") { + Options |= EOptionOutputHexadecimal; + if (argc <= 1) + Error("no provided", lowerword.c_str()); + variableName = argv[1]; + bumpArg(); + break; + } else if (lowerword == "version") { + Options |= EOptionDumpVersions; + } else if (lowerword == "help") { + usage(); + break; + } else { + Error("unrecognized command-line option", argv[0]); } - break; + } break; case 'C': Options |= EOptionCascadingErrors; break; @@ -698,7 +711,7 @@ void ProcessArguments(std::vector>& workItem if (argv[0][2] == 'd') Options |= EOptionOptimizeDisable; else if (argv[0][2] == 's') -#if ENABLE_OPT +#if GLSLANG_ENABLE_OPT Options |= EOptionOptimizeSize; #else Error("-Os not available; optimizer not linked"); @@ -790,7 +803,7 @@ void ProcessArguments(std::vector>& workItem } } else { std::string name(argv[0]); - if (! SetConfigFile(name)) { + if (!SetConfigFile(name)) { workItems.push_back(std::unique_ptr(new glslang::TWorkItem(name))); } } @@ -817,8 +830,7 @@ void ProcessArguments(std::vector>& workItem if (binaryFileName && (Options & EOptionSpv) == 0) Error("no binary generation requested (e.g., -V)"); - if ((Options & EOptionFlattenUniformArrays) != 0 && - (Options & EOptionReadHlsl) == 0) + if ((Options & EOptionFlattenUniformArrays) != 0 && (Options & EOptionReadHlsl) == 0) Error("uniform array flattening only valid when compiling HLSL source."); // rationalize client and target language @@ -877,7 +889,7 @@ void SetMessageOptions(EShMessages& messages) messages = (EShMessages)(messages | EShMsgDebugInfo); if (HlslEnable16BitTypes) messages = (EShMessages)(messages | EShMsgHlslEnable16BitTypes); - if ((Options & EOptionOptimizeDisable) || !ENABLE_OPT) + if ((Options & EOptionOptimizeDisable) || !GLSLANG_ENABLE_OPT) messages = (EShMessages)(messages | EShMsgHlslLegalization); if (HlslDX9compatible) messages = (EShMessages)(messages | EShMsgHlslDX9Compatible); @@ -902,7 +914,7 @@ void CompileShaders(glslang::TWorklist& worklist) CompileFile("stdin", compiler); - if (! (Options & EOptionSuppressInfolog)) + if (!(Options & EOptionSuppressInfolog)) workItem->results = ShGetInfoLog(compiler); ShDestruct(compiler); @@ -915,7 +927,7 @@ void CompileShaders(glslang::TWorklist& worklist) CompileFile(workItem->name.c_str(), compiler); - if (! (Options & EOptionSuppressInfolog)) + if (!(Options & EOptionSuppressInfolog)) workItem->results = ShGetInfoLog(compiler); ShDestruct(compiler); @@ -950,7 +962,7 @@ struct ShaderCompUnit { std::string fileName[maxCount]; // hold's the memory, but... const char* fileNameList[maxCount]; // downstream interface wants pointers - ShaderCompUnit(EShLanguage stage) : stage(stage), count(0) { } + ShaderCompUnit(EShLanguage stage) : stage(stage), count(0) {} ShaderCompUnit(const ShaderCompUnit& rhs) { @@ -995,7 +1007,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) glslang::TProgram& program = *new glslang::TProgram; for (auto it = compUnits.cbegin(); it != compUnits.cend(); ++it) { - const auto &compUnit = *it; + const auto& compUnit = *it; glslang::TShader* shader = new glslang::TShader(compUnit.stage); shader->setStringsWithLengthsAndNames(compUnit.text, NULL, compUnit.fileNameList, compUnit.count); if (entryPointName) @@ -1034,8 +1046,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) shader->setAutoMapLocations(true); for (auto& uniOverride : uniformLocationOverrides) { - shader->addUniformLocationOverride(uniOverride.first.c_str(), - uniOverride.second); + shader->addUniformLocationOverride(uniOverride.first.c_str(), uniOverride.second); } shader->setUniformLocationBase(uniformBase); @@ -1043,7 +1054,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) shader->setNanMinMaxClamp(NaNClamp); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0); if (Options & EOptionHlslIoMapping) shader->setHlslIoMapping(true); @@ -1055,12 +1066,11 @@ void CompileAndLinkShaderUnits(std::vector compUnits) // Set up the environment, some subsettings take precedence over earlier // ways of setting things. if (Options & EOptionSpv) { - shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl - : glslang::EShSourceGlsl, + shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl : glslang::EShSourceGlsl, compUnit.stage, Client, ClientInputSemanticsVersion); shader->setEnvClient(Client, ClientVersion); shader->setEnvTarget(TargetLanguage, TargetVersion); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL if (targetHlslFunctionality1) shader->setEnvTargetHlslFunctionality1(); #endif @@ -1071,8 +1081,8 @@ void CompileAndLinkShaderUnits(std::vector compUnits) const int defaultVersion = Options & EOptionDefaultDesktop ? 110 : 100; DirStackFileIncluder includer; - std::for_each(IncludeDirectoryList.rbegin(), IncludeDirectoryList.rend(), [&includer](const std::string& dir) { - includer.pushExternalLocalDirectory(dir); }); + std::for_each(IncludeDirectoryList.rbegin(), IncludeDirectoryList.rend(), + [&includer](const std::string& dir) { includer.pushExternalLocalDirectory(dir); }); #ifndef GLSLANG_WEB if (Options & EOptionOutputPreprocessed) { std::string str; @@ -1087,13 +1097,12 @@ void CompileAndLinkShaderUnits(std::vector compUnits) } #endif - if (! shader->parse(&Resources, defaultVersion, false, messages, includer)) + if (!shader->parse(&Resources, defaultVersion, false, messages, includer)) CompileFailed = true; program.addShader(shader); - if (! (Options & EOptionSuppressInfolog) && - ! (Options & EOptionMemoryLeakMode)) { + if (!(Options & EOptionSuppressInfolog) && !(Options & EOptionMemoryLeakMode)) { PutsIfNonEmpty(compUnit.fileName[0].c_str()); PutsIfNonEmpty(shader->getInfoLog()); PutsIfNonEmpty(shader->getInfoDebugLog()); @@ -1105,7 +1114,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) // // Link - if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages)) + if (!(Options & EOptionOutputPreprocessed) && !program.link(messages)) LinkFailed = true; #ifndef GLSLANG_WEB @@ -1117,8 +1126,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) #endif // Report - if (! (Options & EOptionSuppressInfolog) && - ! (Options & EOptionMemoryLeakMode)) { + if (!(Options & EOptionSuppressInfolog) && !(Options & EOptionMemoryLeakMode)) { PutsIfNonEmpty(program.getInfoLog()); PutsIfNonEmpty(program.getInfoDebugLog()); } @@ -1152,7 +1160,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) // Dump the spv to a file or stdout, etc., but only if not doing // memory/perf testing, as it's not internal to programmatic use. - if (! (Options & EOptionMemoryLeakMode)) { + if (!(Options & EOptionMemoryLeakMode)) { printf("%s", logger.getAllMessages().c_str()); if (Options & EOptionOutputHexadecimal) { glslang::OutputSpvHex(spirv, GetBinaryName((EShLanguage)stage), variableName); @@ -1230,7 +1238,7 @@ void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist) // all the perf/memory that a programmatic consumer will care about. for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) { for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) - CompileAndLinkShaderUnits(compUnits); + CompileAndLinkShaderUnits(compUnits); if (Options & EOptionMemoryLeakMode) glslang::OS_DumpMemoryCounters(); @@ -1259,13 +1267,12 @@ int singleMain() #endif if (Options & EOptionDumpBareVersion) { - printf("%d.%d.%d\n", - glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL); + printf("%d.%d.%d\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL); if (workList.empty()) return ESuccess; } else if (Options & EOptionDumpVersions) { - printf("Glslang Version: %d.%d.%d\n", - glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, GLSLANG_PATCH_LEVEL); + printf("Glslang Version: %d.%d.%d\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_MINOR_VERSION, + GLSLANG_PATCH_LEVEL); printf("ESSL Version: %s\n", glslang::GetEsslVersionString()); printf("GLSL Version: %s\n", glslang::GetGlslVersionString()); std::string spirvVersion; @@ -1301,16 +1308,16 @@ int singleMain() // if (Options & (EOptionLinkProgram | EOptionOutputPreprocessed)) { glslang::InitializeProcess(); - glslang::InitializeProcess(); // also test reference counting of users - glslang::InitializeProcess(); // also test reference counting of users - glslang::FinalizeProcess(); // also test reference counting of users - glslang::FinalizeProcess(); // also test reference counting of users + glslang::InitializeProcess(); // also test reference counting of users + glslang::InitializeProcess(); // also test reference counting of users + glslang::FinalizeProcess(); // also test reference counting of users + glslang::FinalizeProcess(); // also test reference counting of users CompileAndLinkShaderFiles(workList); glslang::FinalizeProcess(); } else { ShInitialize(); - ShInitialize(); // also test reference counting of users - ShFinalize(); // also test reference counting of users + ShInitialize(); // also test reference counting of users + ShFinalize(); // also test reference counting of users bool printShaderNames = workList.size() > 1; @@ -1478,7 +1485,8 @@ void CompileFile(const char* fileName, ShHandle compiler) for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) { for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) { // ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages); - ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages); + ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, &Resources, Options, + (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages); // const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err", // "or should be l", "ine 1", "string 5\n", "float glo", "bal", // ";\n#error should be line 2\n void main() {", "global = 2.3;}" }; @@ -1490,7 +1498,7 @@ void CompileFile(const char* fileName, ShHandle compiler) glslang::OS_DumpMemoryCounters(); } - delete [] lengths; + delete[] lengths; FreeFileData(shaderString); if (ret == 0) @@ -1665,8 +1673,7 @@ void usage() " --variable-name \n" " --vn creates a C header file that contains a\n" " uint32_t array named \n" - " initialized with the shader binary code\n" - ); + " initialized with the shader binary code\n"); exit(EFailUsage); } @@ -1675,27 +1682,23 @@ void usage() #include -int fopen_s( - FILE** pFile, - const char* filename, - const char* mode -) +int fopen_s(FILE** pFile, const char* filename, const char* mode) { - if (!pFile || !filename || !mode) { - return EINVAL; - } - - FILE* f = fopen(filename, mode); - if (! f) { - if (errno != 0) { - return errno; - } else { - return ENOENT; - } - } - *pFile = f; - - return 0; + if (!pFile || !filename || !mode) { + return EINVAL; + } + + FILE* f = fopen(filename, mode); + if (!f) { + if (errno != 0) { + return errno; + } else { + return ENOENT; + } + } + *pFile = f; + + return 0; } #endif @@ -1705,7 +1708,7 @@ int fopen_s( // char* ReadFileData(const char* fileName) { - FILE *in = nullptr; + FILE* in = nullptr; int errorCode = fopen_s(&in, fileName, "r"); if (errorCode || in == nullptr) Error("unable to open input file"); @@ -1716,7 +1719,7 @@ char* ReadFileData(const char* fileName) fseek(in, 0, SEEK_SET); - char* return_data = (char*)malloc(count + 1); // freed in FreeFileData() + char* return_data = (char*)malloc(count + 1); // freed in FreeFileData() if ((int)fread(return_data, 1, count, in) != count) { free(return_data); Error("can't read input file"); @@ -1728,14 +1731,11 @@ char* ReadFileData(const char* fileName) return return_data; } -void FreeFileData(char* data) -{ - free(data); -} +void FreeFileData(char* data) { free(data); } void InfoLogMsg(const char* msg, const char* name, const int num) { - if (num >= 0 ) + if (num >= 0) printf("#### %s %s %d INFO LOG ####\n", msg, name, num); else printf("#### %s %s INFO LOG ####\n", msg, name); diff --git a/glslang/CMakeLists.txt b/glslang/CMakeLists.txt index a0259a3def..8909267818 100644 --- a/glslang/CMakeLists.txt +++ b/glslang/CMakeLists.txt @@ -90,11 +90,11 @@ target_include_directories(glslang PUBLIC $ $) -if(WIN32 AND BUILD_SHARED_LIBS) +if(WIN32 AND GLSLANG_BUILD_SHARED_LIBS) set_target_properties(glslang PROPERTIES PREFIX "") endif() -if(ENABLE_HLSL) +if(GLSLANG_ENABLE_HLSL) target_link_libraries(glslang HLSL) endif() @@ -107,7 +107,7 @@ if(WIN32) endif(WIN32) if(ENABLE_GLSLANG_INSTALL) - if(BUILD_SHARED_LIBS) + if(GLSLANG_BUILD_SHARED_LIBS) install(TARGETS glslang EXPORT glslangTargets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 3572099e3d..0341c431f3 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -106,7 +106,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler, bool external : 1; // GL_OES_EGL_image_external bool yuv : 1; // GL_EXT_YUV_target -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL unsigned int getVectorSize() const { return vectorSize; } void clearReturnStruct() { structReturnIndex = noReturnStruct; } bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; } @@ -149,7 +149,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler, yuv = false; #endif -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL clearReturnStruct(); // by default, returns a single vec4; vectorSize = 4; @@ -223,7 +223,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler, isPureSampler() == right.isPureSampler() && isExternal() == right.isExternal() && isYuv() == right.isYuv() -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL && getVectorSize() == right.getVectorSize() && getStructReturnIndex() == right.getStructReturnIndex() #endif diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index 282ecca0e0..504ce93c24 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -576,7 +576,7 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin selector.push_back(0); } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL // // Make the passed-in variable information become a member of the // global uniform block. If this doesn't exist yet, make it. diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 39363f1a2a..49eaa3d5b0 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -152,7 +152,7 @@ class TParseContextBase : public TParseVersions { extensionCallback(line, extension, behavior); } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr); #endif diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index f50c80532d..ef3ad61788 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -41,31 +41,31 @@ // This is the platform independent interface between an OGL driver // and the shading language compiler/linker. // -#include -#include -#include -#include -#include "SymbolTable.h" #include "ParseHelper.h" #include "Scan.h" #include "ScanContext.h" +#include "SymbolTable.h" +#include +#include +#include +#include -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL #include "../../hlsl/hlslParseHelper.h" #include "../../hlsl/hlslParseables.h" #include "../../hlsl/hlslScanContext.h" #endif -#include "../Include/ShHandle.h" #include "../../OGLCompilersDLL/InitializeDll.h" +#include "../Include/ShHandle.h" #include "preprocessor/PpContext.h" #define SH_EXPORTING #include "../Public/ShaderLang.h" -#include "reflection.h" -#include "iomapper.h" #include "Initialize.h" +#include "iomapper.h" +#include "reflection.h" // TODO: this really shouldn't be here, it is only because of the trial addition // of printing pre-processed tokens, which requires knowing the string literal @@ -84,9 +84,11 @@ using namespace glslang; TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource source) { switch (source) { - case EShSourceGlsl: return new TBuiltIns(); // GLSL builtIns -#ifdef ENABLE_HLSL - case EShSourceHlsl: return new TBuiltInParseablesHlsl(); // HLSL intrinsics + case EShSourceGlsl: + return new TBuiltIns(); // GLSL builtIns +#ifdef GLSLANG_ENABLE_HLSL + case EShSourceHlsl: + return new TBuiltInParseablesHlsl(); // HLSL intrinsics #endif default: @@ -96,9 +98,8 @@ TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource sourc } // Create a language specific version of a parse context. -TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate, - int version, EProfile profile, EShSource source, - EShLanguage language, TInfoSink& infoSink, +TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate, int version, + EProfile profile, EShSource source, EShLanguage language, TInfoSink& infoSink, SpvVersion spvVersion, bool forwardCompatible, EShMessages messages, bool parsingBuiltIns, std::string sourceEntryPointName = "") { @@ -107,13 +108,13 @@ TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& if (sourceEntryPointName.size() == 0) intermediate.setEntryPointName("main"); TString entryPoint = sourceEntryPointName.c_str(); - return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, - language, infoSink, forwardCompatible, messages, &entryPoint); + return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, language, + infoSink, forwardCompatible, messages, &entryPoint); } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL case EShSourceHlsl: - return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, - language, infoSink, sourceEntryPointName.c_str(), forwardCompatible, messages); + return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion, language, + infoSink, sourceEntryPointName.c_str(), forwardCompatible, messages); #endif default: infoSink.info.message(EPrefixInternalError, "Unable to determine source language"); @@ -123,32 +124,70 @@ TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& // Local mapping functions for making arrays of symbol tables.... -const int VersionCount = 17; // index range in MapVersionToIndex +const int VersionCount = 17; // index range in MapVersionToIndex int MapVersionToIndex(int version) { int index = 0; switch (version) { - case 100: index = 0; break; - case 110: index = 1; break; - case 120: index = 2; break; - case 130: index = 3; break; - case 140: index = 4; break; - case 150: index = 5; break; - case 300: index = 6; break; - case 330: index = 7; break; - case 400: index = 8; break; - case 410: index = 9; break; - case 420: index = 10; break; - case 430: index = 11; break; - case 440: index = 12; break; - case 310: index = 13; break; - case 450: index = 14; break; - case 500: index = 0; break; // HLSL - case 320: index = 15; break; - case 460: index = 16; break; - default: assert(0); break; + case 100: + index = 0; + break; + case 110: + index = 1; + break; + case 120: + index = 2; + break; + case 130: + index = 3; + break; + case 140: + index = 4; + break; + case 150: + index = 5; + break; + case 300: + index = 6; + break; + case 330: + index = 7; + break; + case 400: + index = 8; + break; + case 410: + index = 9; + break; + case 420: + index = 10; + break; + case 430: + index = 11; + break; + case 440: + index = 12; + break; + case 310: + index = 13; + break; + case 450: + index = 14; + break; + case 500: + index = 0; + break; // HLSL + case 320: + index = 15; + break; + case 460: + index = 16; + break; + default: + assert(0); + break; } assert(index < VersionCount); @@ -156,7 +195,7 @@ int MapVersionToIndex(int version) return index; } -const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex +const int SpvVersionCount = 3; // index range in MapSpvVersionToIndex int MapSpvVersionToIndex(const SpvVersion& spvVersion) { @@ -172,18 +211,27 @@ int MapSpvVersionToIndex(const SpvVersion& spvVersion) return index; } -const int ProfileCount = 4; // index range in MapProfileToIndex +const int ProfileCount = 4; // index range in MapProfileToIndex int MapProfileToIndex(EProfile profile) { int index = 0; switch (profile) { - case ENoProfile: index = 0; break; - case ECoreProfile: index = 1; break; - case ECompatibilityProfile: index = 2; break; - case EEsProfile: index = 3; break; - default: break; + case ENoProfile: + index = 0; + break; + case ECoreProfile: + index = 1; + break; + case ECompatibilityProfile: + index = 2; + break; + case EEsProfile: + index = 3; + break; + default: + break; } assert(index < ProfileCount); @@ -198,9 +246,14 @@ int MapSourceToIndex(EShSource source) int index = 0; switch (source) { - case EShSourceGlsl: index = 0; break; - case EShSourceHlsl: index = 1; break; - default: break; + case EShSourceGlsl: + index = 0; + break; + case EShSourceHlsl: + index = 1; + break; + default: + break; } assert(index < SourceCount); @@ -209,11 +262,7 @@ int MapSourceToIndex(EShSource source) } // only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins -enum EPrecisionClass { - EPcGeneral, - EPcFragment, - EPcCount -}; +enum EPrecisionClass { EPcGeneral, EPcFragment, EPcCount }; // A process-global symbol table per version per profile for built-ins common // to multiple stages (languages), and a process-global symbol table per version @@ -231,16 +280,16 @@ TPoolAllocator* PerProcessGPA = nullptr; // // Parse and add to the given symbol table the content of the given shader string. // -bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, - EShSource source, TInfoSink& infoSink, TSymbolTable& symbolTable) +bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, const SpvVersion& spvVersion, + EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable& symbolTable) { TIntermediate intermediate(language, version, profile); intermediate.setSource(source); - std::unique_ptr parseContext(CreateParseContext(symbolTable, intermediate, version, profile, source, - language, infoSink, spvVersion, true, EShMsgDefault, - true)); + std::unique_ptr parseContext(CreateParseContext(symbolTable, intermediate, version, profile, + source, language, infoSink, spvVersion, true, + EShMsgDefault, true)); TShader::ForbidIncluder includer; TPpContext ppContext(*parseContext, "", includer); @@ -265,7 +314,7 @@ bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profil return true; TInputScanner input(1, builtInShaders, builtInLengths); - if (! parseContext->parseShaderStrings(ppContext, input) != 0) { + if (!parseContext->parseShaderStrings(ppContext, input) != 0) { infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); printf("Unable to parse built-ins\n%s\n", infoSink.info.c_str()); printf("%s\n", builtInShaders[0]); @@ -284,9 +333,9 @@ int CommonIndex(EProfile profile, EShLanguage language) // // To initialize per-stage shared tables, with the common table already complete. // -void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion, - EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable, - TSymbolTable** symbolTables) +void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, + const SpvVersion& spvVersion, EShLanguage language, EShSource source, + TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables) { #ifdef GLSLANG_WEB profile = EEsProfile; @@ -307,7 +356,8 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi // Initialize the full set of shareable symbol tables; // The common (cross-stage) and those shareable per-stage. // -bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source) +bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, + EProfile profile, const SpvVersion& spvVersion, EShSource source) { #ifdef GLSLANG_WEB profile = EEsProfile; @@ -325,21 +375,20 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source, infoSink, *commonTable[EPcGeneral]); if (profile == EEsProfile) - InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source, - infoSink, *commonTable[EPcFragment]); + InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, + source, infoSink, *commonTable[EPcFragment]); // do the per-stage tables // always have vertex and fragment - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source, - infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source, - infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source, infoSink, + commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source, infoSink, + commonTable, symbolTables); #ifndef GLSLANG_WEB // check for tessellation - if ((profile != EEsProfile && version >= 150) || - (profile == EEsProfile && version >= 310)) { + if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source, infoSink, commonTable, symbolTables); InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source, @@ -347,51 +396,48 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS } // check for geometry - if ((profile != EEsProfile && version >= 150) || - (profile == EEsProfile && version >= 310)) - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source, - infoSink, commonTable, symbolTables); + if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source, infoSink, + commonTable, symbolTables); #endif // check for compute - if ((profile != EEsProfile && version >= 420) || - (profile == EEsProfile && version >= 310)) - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, - infoSink, commonTable, symbolTables); + if ((profile != EEsProfile && version >= 420) || (profile == EEsProfile && version >= 310)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, infoSink, + commonTable, symbolTables); // check for ray tracing stages if (profile != EEsProfile && version >= 450) { - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source, - infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source, infoSink, + commonTable, symbolTables); InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source, - infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source, - infoSink, commonTable, symbolTables); + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source, infoSink, + commonTable, symbolTables); InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source, - infoSink, commonTable, symbolTables); - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source, - infoSink, commonTable, symbolTables); + infoSink, commonTable, symbolTables); + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source, infoSink, + commonTable, symbolTables); InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source, - infoSink, commonTable, symbolTables); + infoSink, commonTable, symbolTables); } // check for mesh - if ((profile != EEsProfile && version >= 450) || - (profile == EEsProfile && version >= 320)) - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source, - infoSink, commonTable, symbolTables); + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source, infoSink, + commonTable, symbolTables); // check for task - if ((profile != EEsProfile && version >= 450) || - (profile == EEsProfile && version >= 320)) - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source, - infoSink, commonTable, symbolTables); + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source, infoSink, + commonTable, symbolTables); return true; } -bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version, - EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EShSource source) +bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, + int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, + EShSource source) { std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); @@ -399,7 +445,8 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf return false; builtInParseables->initialize(*resources, version, profile, spvVersion, language); - InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable); + InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, + infoSink, symbolTable); builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources); return true; @@ -456,18 +503,21 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp // Copy the local symbol tables from the new pool to the global tables using the process-global pool for (int precClass = 0; precClass < EPcCount; ++precClass) { - if (! commonTable[precClass]->isEmpty()) { + if (!commonTable[precClass]->isEmpty()) { CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass] = new TSymbolTable; - CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->copyTable(*commonTable[precClass]); + CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->copyTable( + *commonTable[precClass]); CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->readOnly(); } } for (int stage = 0; stage < EShLangCount; ++stage) { - if (! stageTables[stage]->isEmpty()) { + if (!stageTables[stage]->isEmpty()) { SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage] = new TSymbolTable; - SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->adoptLevels(*CommonSymbolTable - [versionIndex][spvVersionIndex][profileIndex][sourceIndex][CommonIndex(profile, (EShLanguage)stage)]); - SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->copyTable(*stageTables[stage]); + SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->adoptLevels( + *CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex] + [CommonIndex(profile, (EShLanguage)stage)]); + SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->copyTable( + *stageTables[stage]); SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly(); } } @@ -519,7 +569,8 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo if (profile == ENoProfile) { if (version == 300 || version == 310 || version == 320) { correct = false; - infoSink.info.message(EPrefixError, "#version: versions 300, 310, and 320 require specifying the 'es' profile"); + infoSink.info.message(EPrefixError, + "#version: versions 300, 310, and 320 require specifying the 'es' profile"); profile = EEsProfile; } else if (version == 100) profile = EEsProfile; @@ -558,25 +609,42 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo // Fix version... switch (version) { // ES versions - case 100: break; - case 300: break; - case 310: break; - case 320: break; + case 100: + break; + case 300: + break; + case 310: + break; + case 320: + break; // desktop versions - case 110: break; - case 120: break; - case 130: break; - case 140: break; - case 150: break; - case 330: break; - case 400: break; - case 410: break; - case 420: break; - case 430: break; - case 440: break; - case 450: break; - case 460: break; + case 110: + break; + case 120: + break; + case 130: + break; + case 140: + break; + case 150: + break; + case 330: + break; + case 400: + break; + case 410: + break; + case 420: + break; + case 430: + break; + case 440: + break; + case 450: + break; + case 460: + break; // unknown version default: @@ -595,10 +663,10 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo // Correct for stage type... switch (stage) { case EShLangGeometry: - if ((profile == EEsProfile && version < 310) || - (profile != EEsProfile && version < 150)) { + if ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 150)) { correct = false; - infoSink.info.message(EPrefixError, "#version: geometry shaders require es profile with version 310 or non-es profile with version 150 or above"); + infoSink.info.message(EPrefixError, "#version: geometry shaders require es profile with version 310 or " + "non-es profile with version 150 or above"); version = (profile == EEsProfile) ? 310 : 150; if (profile == EEsProfile || profile == ENoProfile) profile = ECoreProfile; @@ -606,20 +674,21 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; case EShLangTessControl: case EShLangTessEvaluation: - if ((profile == EEsProfile && version < 310) || - (profile != EEsProfile && version < 150)) { + if ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 150)) { correct = false; - infoSink.info.message(EPrefixError, "#version: tessellation shaders require es profile with version 310 or non-es profile with version 150 or above"); - version = (profile == EEsProfile) ? 310 : 400; // 150 supports the extension, correction is to 400 which does not + infoSink.info.message(EPrefixError, "#version: tessellation shaders require es profile with version 310 or " + "non-es profile with version 150 or above"); + version = + (profile == EEsProfile) ? 310 : 400; // 150 supports the extension, correction is to 400 which does not if (profile == EEsProfile || profile == ENoProfile) profile = ECoreProfile; } break; case EShLangCompute: - if ((profile == EEsProfile && version < 310) || - (profile != EEsProfile && version < 420)) { + if ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 420)) { correct = false; - infoSink.info.message(EPrefixError, "#version: compute shaders require es profile with version 310 or above, or non-es profile with version 420 or above"); + infoSink.info.message(EPrefixError, "#version: compute shaders require es profile with version 310 or " + "above, or non-es profile with version 420 or above"); version = profile == EEsProfile ? 310 : 420; } break; @@ -631,16 +700,17 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo case EShLangCallableNV: if (profile == EEsProfile || version < 460) { correct = false; - infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above"); + infoSink.info.message(EPrefixError, + "#version: ray tracing shaders require non-es profile with version 460 or above"); version = 460; } break; case EShLangMeshNV: case EShLangTaskNV: - if ((profile == EEsProfile && version < 320) || - (profile != EEsProfile && version < 450)) { + if ((profile == EEsProfile && version < 320) || (profile != EEsProfile && version < 450)) { correct = false; - infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above"); + infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or " + "above, or non-es profile with version 450 or above"); version = profile == EEsProfile ? 320 : 450; } default: @@ -649,7 +719,8 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo if (profile == EEsProfile && version >= 300 && versionNotFirst) { correct = false; - infoSink.info.message(EPrefixError, "#version: statement must appear first in es-profile shader; before comments or newlines"); + infoSink.info.message( + EPrefixError, "#version: statement must appear first in es-profile shader; before comments or newlines"); } // Check for SPIR-V compatibility @@ -663,17 +734,20 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo } break; case ECompatibilityProfile: - infoSink.info.message(EPrefixError, "#version: compilation for SPIR-V does not support the compatibility profile"); + infoSink.info.message(EPrefixError, + "#version: compilation for SPIR-V does not support the compatibility profile"); break; default: if (spvVersion.vulkan > 0 && version < 140) { correct = false; - infoSink.info.message(EPrefixError, "#version: Desktop shaders for Vulkan SPIR-V require version 140 or higher"); + infoSink.info.message(EPrefixError, + "#version: Desktop shaders for Vulkan SPIR-V require version 140 or higher"); version = 140; } if (spvVersion.openGl >= 100 && version < 330) { correct = false; - infoSink.info.message(EPrefixError, "#version: Desktop shaders for OpenGL SPIR-V require version 330 or higher"); + infoSink.info.message(EPrefixError, + "#version: Desktop shaders for OpenGL SPIR-V require version 330 or higher"); version = 330; } break; @@ -688,8 +762,8 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo // TEnvironment takes precedence, for what it sets, so sort all this out. // Ideally, the internal code could be made to use TEnvironment, but for // now, translate it to the historically used parameters. -void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages, EShSource& source, - EShLanguage& stage, SpvVersion& spvVersion) +void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages, EShSource& source, EShLanguage& stage, + SpvVersion& spvVersion) { // Set up environmental defaults, first ignoring 'environment'. if (messages & EShMsgSpvRules) @@ -782,29 +856,22 @@ void RecordProcesses(TIntermediate& intermediate, EShMessages messages, const st // EShOptimizationLevel , EShMessages ); // Which returns false if a failure was detected and true otherwise. // -template +template bool ProcessDeferred( - TCompiler* compiler, - const char* const shaderStrings[], - const int numStrings, - const int* inputLengths, - const char* const stringNames[], - const char* customPreamble, - const EShOptimizationLevel optLevel, + TCompiler* compiler, const char* const shaderStrings[], const int numStrings, const int* inputLengths, + const char* const stringNames[], const char* customPreamble, const EShOptimizationLevel optLevel, const TBuiltInResource* resources, - int defaultVersion, // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan + int defaultVersion, // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan EProfile defaultProfile, // set version/profile to defaultVersion/defaultProfile regardless of the #version // directive in the source code bool forceDefaultVersionAndProfile, - bool forwardCompatible, // give errors for use of deprecated features - EShMessages messages, // warnings/errors/AST; things to print out + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages, // warnings/errors/AST; things to print out TIntermediate& intermediate, // returned tree, etc. - ProcessingContext& processingContext, - bool requireNonempty, - TShader::Includer& includer, + ProcessingContext& processingContext, bool requireNonempty, TShader::Includer& includer, const std::string sourceEntryPointName = "", - const TEnvironment* environment = nullptr) // optional way of fully setting all versions, overriding the above + const TEnvironment* environment = nullptr) // optional way of fully setting all versions, overriding the above { // This must be undone (.pop()) by the caller, after it finishes consuming the created tree. GetThreadPoolAllocator().push(); @@ -822,11 +889,11 @@ bool ProcessDeferred( // string 2...numStrings+1: user's shader // string numStrings+2: "int;" const int numPre = 2; - const int numPost = requireNonempty? 1 : 0; + const int numPost = requireNonempty ? 1 : 0; const int numTotal = numPre + numStrings + numPost; std::unique_ptr lengths(new size_t[numTotal]); - std::unique_ptr strings(new const char*[numTotal]); - std::unique_ptr names(new const char*[numTotal]); + std::unique_ptr strings(new const char*[numTotal]); + std::unique_ptr names(new const char*[numTotal]); for (int s = 0; s < numStrings; ++s) { strings[s + numPre] = shaderStrings[s]; if (inputLengths == nullptr || inputLengths[s] < 0) @@ -848,7 +915,7 @@ bool ProcessDeferred( SpvVersion spvVersion; EShLanguage stage = compiler->getLanguage(); TranslateEnvironment(environment, messages, sourceGuess, stage, spvVersion); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL EShSource source = sourceGuess; if (environment != nullptr && environment->target.hlslFunctionality1) intermediate.setHlslFunctionality1(); @@ -862,18 +929,16 @@ bool ProcessDeferred( int version = 0; EProfile profile = ENoProfile; bool versionNotFirstToken = false; - bool versionNotFirst = (source == EShSourceHlsl) - ? true - : userInput.scanVersion(version, profile, versionNotFirstToken); + bool versionNotFirst = + (source == EShSourceHlsl) ? true : userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { #ifndef GLSLANG_WEB - if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && + if (!(messages & EShMsgSuppressWarnings) && !versionNotFound && (version != defaultVersion || profile != defaultProfile)) { - compiler->infoSink.info << "Warning, (version, profile) forced to be (" - << defaultVersion << ", " << ProfileName(defaultProfile) - << "), while in source code it is (" - << version << ", " << ProfileName(profile) << ")\n"; + compiler->infoSink.info << "Warning, (version, profile) forced to be (" << defaultVersion << ", " + << ProfileName(defaultProfile) << "), while in source code it is (" << version + << ", " << ProfileName(profile) << ")\n"; } #endif if (versionNotFound) { @@ -885,8 +950,8 @@ bool ProcessDeferred( profile = defaultProfile; } - bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, - versionNotFirst, defaultVersion, source, version, profile, spvVersion); + bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, versionNotFirst, defaultVersion, source, version, + profile, spvVersion); #ifdef GLSLANG_WEB profile = EEsProfile; version = 310; @@ -895,7 +960,7 @@ bool ProcessDeferred( bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); #ifndef GLSLANG_WEB bool warnVersionNotFirst = false; - if (! versionWillBeError && versionNotFirstToken) { + if (!versionWillBeError && versionNotFirstToken) { if (messages & EShMsgRelaxedErrors) warnVersionNotFirst = true; else @@ -910,7 +975,7 @@ bool ProcessDeferred( RecordProcesses(intermediate, messages, sourceEntryPointName); if (spvVersion.vulkan > 0) intermediate.setOriginUpperLeft(); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl) intermediate.setHlslOffsets(); #endif @@ -924,11 +989,8 @@ bool ProcessDeferred( } SetupBuiltinSymbolTable(version, profile, spvVersion, source); - TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)] - [MapSpvVersionToIndex(spvVersion)] - [MapProfileToIndex(profile)] - [MapSourceToIndex(source)] - [stage]; + TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)][MapSpvVersionToIndex(spvVersion)] + [MapProfileToIndex(profile)][MapSourceToIndex(source)][stage]; // Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool. std::unique_ptr symbolTable(new TSymbolTable); @@ -937,8 +999,8 @@ bool ProcessDeferred( // Add built-in symbols that are potentially context dependent; // they get popped again further down. - if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, - stage, source)) { + if (!AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, stage, + source)) { return false; } @@ -949,9 +1011,9 @@ bool ProcessDeferred( // Now we can process the full shader under proper symbols and rules. // - std::unique_ptr parseContext(CreateParseContext(*symbolTable, intermediate, version, profile, source, - stage, compiler->infoSink, - spvVersion, forwardCompatible, messages, false, sourceEntryPointName)); + std::unique_ptr parseContext( + CreateParseContext(*symbolTable, intermediate, version, profile, source, stage, compiler->infoSink, spvVersion, + forwardCompatible, messages, false, sourceEntryPointName)); TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer); // only GLSL (bison triggered, really) needs an externally set scan context @@ -961,7 +1023,7 @@ bool ProcessDeferred( parseContext->setPpContext(&ppContext); parseContext->setLimits(*resources); - if (! goodVersion) + if (!goodVersion) parseContext->addError(); #ifndef GLSLANG_WEB if (warnVersionNotFirst) { @@ -994,8 +1056,7 @@ bool ProcessDeferred( // Push a new symbol allocation scope that will get used for the shader's globals. symbolTable->push(); - bool success = processingContext(*parseContext, ppContext, fullInput, - versionWillBeError, *symbolTable, + bool success = processingContext(*parseContext, ppContext, fullInput, versionWillBeError, *symbolTable, intermediate, optLevel, messages); return success; } @@ -1007,16 +1068,18 @@ bool ProcessDeferred( // or line changes. class SourceLineSynchronizer { public: - SourceLineSynchronizer(const std::function& lastSourceIndex, - std::string* output) - : getLastSourceIndex(lastSourceIndex), output(output), lastSource(-1), lastLine(0) {} -// SourceLineSynchronizer(const SourceLineSynchronizer&) = delete; -// SourceLineSynchronizer& operator=(const SourceLineSynchronizer&) = delete; + SourceLineSynchronizer(const std::function& lastSourceIndex, std::string* output) + : getLastSourceIndex(lastSourceIndex), output(output), lastSource(-1), lastLine(0) + { + } + // SourceLineSynchronizer(const SourceLineSynchronizer&) = delete; + // SourceLineSynchronizer& operator=(const SourceLineSynchronizer&) = delete; // Sets the internally tracked source string index to that of the most // recently read token. If we switched to a new source string, returns // true and inserts a newline. Otherwise, returns false and outputs nothing. - bool syncToMostRecentString() { + bool syncToMostRecentString() + { if (getLastSourceIndex() != lastSource) { // After switching to a new source string, we need to reset lastLine // because line number resets every time a new source string is @@ -1034,11 +1097,13 @@ class SourceLineSynchronizer { // Calls syncToMostRecentString() and then sets the internally tracked line // number to tokenLine. If we switched to a new line, returns true and inserts // newlines appropriately. Otherwise, returns false and outputs nothing. - bool syncToLine(int tokenLine) { + bool syncToLine(int tokenLine) + { syncToMostRecentString(); const bool newLineStarted = lastLine < tokenLine; for (; lastLine < tokenLine; ++lastLine) { - if (lastLine > 0) *output += '\n'; + if (lastLine > 0) + *output += '\n'; } return newLineStarted; } @@ -1072,11 +1137,9 @@ class SourceLineSynchronizer { // // This is not an officially supported or fully working path. struct DoPreprocessing { - explicit DoPreprocessing(std::string* string): outputString(string) {} - bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, - TInputScanner& input, bool versionWillBeError, - TSymbolTable&, TIntermediate&, - EShOptimizationLevel, EShMessages) + explicit DoPreprocessing(std::string* string) : outputString(string) {} + bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, TInputScanner& input, + bool versionWillBeError, TSymbolTable&, TIntermediate&, EShOptimizationLevel, EShMessages) { // This is a list of tokens that do not require a space before or after. static const std::string unNeededSpaceTokens = ";()[]"; @@ -1087,20 +1150,20 @@ struct DoPreprocessing { ppContext.setInput(input, versionWillBeError); std::string outputBuffer; - SourceLineSynchronizer lineSync( - std::bind(&TInputScanner::getLastValidSourceIndex, &input), &outputBuffer); + SourceLineSynchronizer lineSync(std::bind(&TInputScanner::getLastValidSourceIndex, &input), &outputBuffer); - parseContext.setExtensionCallback([&lineSync, &outputBuffer]( - int line, const char* extension, const char* behavior) { + parseContext.setExtensionCallback( + [&lineSync, &outputBuffer](int line, const char* extension, const char* behavior) { lineSync.syncToLine(line); outputBuffer += "#extension "; outputBuffer += extension; outputBuffer += " : "; outputBuffer += behavior; - }); + }); - parseContext.setLineCallback([&lineSync, &outputBuffer, &parseContext]( - int curLineNum, int newLineNum, bool hasSource, int sourceNum, const char* sourceName) { + parseContext.setLineCallback([&lineSync, &outputBuffer, &parseContext](int curLineNum, int newLineNum, + bool hasSource, int sourceNum, + const char* sourceName) { // SourceNum is the number of the source-string that is being parsed. lineSync.syncToLine(curLineNum); outputBuffer += "#line "; @@ -1125,31 +1188,29 @@ struct DoPreprocessing { lineSync.setLineNum(newLineNum + 1); }); - parseContext.setVersionCallback( - [&lineSync, &outputBuffer](int line, int version, const char* str) { - lineSync.syncToLine(line); - outputBuffer += "#version "; - outputBuffer += std::to_string(version); - if (str) { - outputBuffer += ' '; - outputBuffer += str; - } - }); + parseContext.setVersionCallback([&lineSync, &outputBuffer](int line, int version, const char* str) { + lineSync.syncToLine(line); + outputBuffer += "#version "; + outputBuffer += std::to_string(version); + if (str) { + outputBuffer += ' '; + outputBuffer += str; + } + }); - parseContext.setPragmaCallback([&lineSync, &outputBuffer]( - int line, const glslang::TVector& ops) { + parseContext.setPragmaCallback( + [&lineSync, &outputBuffer](int line, const glslang::TVector& ops) { lineSync.syncToLine(line); outputBuffer += "#pragma "; - for(size_t i = 0; i < ops.size(); ++i) { + for (size_t i = 0; i < ops.size(); ++i) { outputBuffer += ops[i].c_str(); } - }); + }); - parseContext.setErrorCallback([&lineSync, &outputBuffer]( - int line, const char* errorMessage) { - lineSync.syncToLine(line); - outputBuffer += "#error "; - outputBuffer += errorMessage; + parseContext.setErrorCallback([&lineSync, &outputBuffer](int line, const char* errorMessage) { + lineSync.syncToLine(line); + outputBuffer += "#error "; + outputBuffer += errorMessage; }); int lastToken = EndOfInput; // lastToken records the last token processed. @@ -1202,23 +1263,23 @@ struct DoPreprocessing { // DoFullParse is a valid ProcessingConext template argument for fully // parsing the shader. It populates the "intermediate" with the AST. -struct DoFullParse{ - bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, - TInputScanner& fullInput, bool versionWillBeError, - TSymbolTable&, TIntermediate& intermediate, - EShOptimizationLevel optLevel, EShMessages messages) +struct DoFullParse { + bool operator()(TParseContextBase& parseContext, TPpContext& ppContext, TInputScanner& fullInput, + bool versionWillBeError, TSymbolTable&, TIntermediate& intermediate, EShOptimizationLevel optLevel, + EShMessages messages) { bool success = true; // Parse the full shader. - if (! parseContext.parseShaderStrings(ppContext, fullInput, versionWillBeError)) + if (!parseContext.parseShaderStrings(ppContext, fullInput, versionWillBeError)) success = false; if (success && intermediate.getTreeRoot()) { if (optLevel == EShOptNoGeneration) - parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested."); + parseContext.infoSink.info.message(EPrefixNone, + "No errors. No code generation or linking was requested."); else success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.getLanguage()); - } else if (! success) { + } else if (!success) { parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; } @@ -1238,30 +1299,21 @@ struct DoFullParse{ // // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string // is not an officially supported or fully working path. -bool PreprocessDeferred( - TCompiler* compiler, - const char* const shaderStrings[], - const int numStrings, - const int* inputLengths, - const char* const stringNames[], - const char* preamble, - const EShOptimizationLevel optLevel, - const TBuiltInResource* resources, - int defaultVersion, // use 100 for ES environment, 110 for desktop - EProfile defaultProfile, - bool forceDefaultVersionAndProfile, - bool forwardCompatible, // give errors for use of deprecated features - EShMessages messages, // warnings/errors/AST; things to print out - TShader::Includer& includer, - TIntermediate& intermediate, // returned tree, etc. - std::string* outputString) +bool PreprocessDeferred(TCompiler* compiler, const char* const shaderStrings[], const int numStrings, + const int* inputLengths, const char* const stringNames[], const char* preamble, + const EShOptimizationLevel optLevel, const TBuiltInResource* resources, + int defaultVersion, // use 100 for ES environment, 110 for desktop + EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages, // warnings/errors/AST; things to print out + TShader::Includer& includer, + TIntermediate& intermediate, // returned tree, etc. + std::string* outputString) { DoPreprocessing parser(outputString); - return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, - preamble, optLevel, resources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, - forwardCompatible, messages, intermediate, parser, - false, includer); + return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, preamble, optLevel, + resources, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, + messages, intermediate, parser, false, includer); } #endif @@ -1276,34 +1328,24 @@ bool PreprocessDeferred( // return: the tree and other information is filled into the intermediate argument, // and true is returned by the function for success. // -bool CompileDeferred( - TCompiler* compiler, - const char* const shaderStrings[], - const int numStrings, - const int* inputLengths, - const char* const stringNames[], - const char* preamble, - const EShOptimizationLevel optLevel, - const TBuiltInResource* resources, - int defaultVersion, // use 100 for ES environment, 110 for desktop - EProfile defaultProfile, - bool forceDefaultVersionAndProfile, - bool forwardCompatible, // give errors for use of deprecated features - EShMessages messages, // warnings/errors/AST; things to print out - TIntermediate& intermediate,// returned tree, etc. - TShader::Includer& includer, - const std::string sourceEntryPointName = "", - TEnvironment* environment = nullptr) +bool CompileDeferred(TCompiler* compiler, const char* const shaderStrings[], const int numStrings, + const int* inputLengths, const char* const stringNames[], const char* preamble, + const EShOptimizationLevel optLevel, const TBuiltInResource* resources, + int defaultVersion, // use 100 for ES environment, 110 for desktop + EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages, // warnings/errors/AST; things to print out + TIntermediate& intermediate, // returned tree, etc. + TShader::Includer& includer, const std::string sourceEntryPointName = "", + TEnvironment* environment = nullptr) { DoFullParse parser; - return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, - preamble, optLevel, resources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, - forwardCompatible, messages, intermediate, parser, - true, includer, sourceEntryPointName, environment); + return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, preamble, optLevel, + resources, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, + messages, intermediate, parser, true, includer, sourceEntryPointName, environment); } -} // end anonymous namespace for local functions +} // namespace // // ShInitialize() should be called exactly once per process, not per thread. @@ -1312,7 +1354,7 @@ int ShInitialize() { glslang::InitGlobalLock(); - if (! InitProcess()) + if (!InitProcess()) return 0; glslang::GetGlobalLock(); @@ -1323,7 +1365,7 @@ int ShInitialize() PerProcessGPA = new TPoolAllocator(); glslang::TScanContext::fillInKeywordMap(); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL glslang::HlslScanContext::fillInKeywordMap(); #endif @@ -1390,7 +1432,7 @@ int ShFinalize() assert(NumberOfClients >= 0); bool finalize = NumberOfClients == 0; glslang::ReleaseGlobalLock(); - if (! finalize) + if (!finalize) return 1; for (int version = 0; version < VersionCount; ++version) { @@ -1425,7 +1467,7 @@ int ShFinalize() } glslang::TScanContext::deleteKeywordMap(); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL glslang::HlslScanContext::deleteKeywordMap(); #endif @@ -1440,18 +1482,12 @@ int ShFinalize() // Return: The return value is really boolean, indicating // success (1) or failure (0). // -int ShCompile( - const ShHandle handle, - const char* const shaderStrings[], - const int numStrings, - const int* inputLengths, - const EShOptimizationLevel optLevel, - const TBuiltInResource* resources, - int /*debugOptions*/, - int defaultVersion, // use 100 for ES environment, 110 for desktop - bool forwardCompatible, // give errors for use of deprecated features - EShMessages messages // warnings/errors/AST; things to print out - ) +int ShCompile(const ShHandle handle, const char* const shaderStrings[], const int numStrings, const int* inputLengths, + const EShOptimizationLevel optLevel, const TBuiltInResource* resources, int /*debugOptions*/, + int defaultVersion, // use 100 for ES environment, 110 for desktop + bool forwardCompatible, // give errors for use of deprecated features + EShMessages messages // warnings/errors/AST; things to print out +) { // Map the generic handle to the C++ object if (handle == 0) @@ -1469,9 +1505,9 @@ int ShCompile( TIntermediate intermediate(compiler->getLanguage()); TShader::ForbidIncluder includer; - bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr, - "", optLevel, resources, defaultVersion, ENoProfile, false, - forwardCompatible, messages, intermediate, includer); + bool success = + CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr, "", optLevel, resources, + defaultVersion, ENoProfile, false, forwardCompatible, messages, intermediate, includer); // // Call the machine dependent compiler @@ -1494,10 +1530,7 @@ int ShCompile( // Return: The return value of is really boolean, indicating // success or failure. // -int ShLinkExt( - const ShHandle linkHandle, - const ShHandle compHandles[], - const int numHandles) +int ShLinkExt(const ShHandle linkHandle, const ShHandle compHandles[], const int numHandles) { if (linkHandle == 0 || numHandles == 0) return 0; @@ -1530,7 +1563,7 @@ int ShLinkExt( for (int i = 0; i < numHandles; ++i) { if (cObjects[i]->getAsCompiler()) { - if (! cObjects[i]->getAsCompiler()->linkable()) { + if (!cObjects[i]->getAsCompiler()->linkable()) { linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code."); return 0; } @@ -1637,7 +1670,7 @@ int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* tab // // Some attribute locations are off-limits to the linker... // -int ShExcludeAttributes(const ShHandle handle, int *attributes, int count) +int ShExcludeAttributes(const ShHandle handle, int* attributes, int count) { if (handle == 0) return 0; @@ -1664,7 +1697,7 @@ int ShGetUniformLocation(const ShHandle handle, const char* name) return -1; TShHandleBase* base = reinterpret_cast(handle); - TUniformMap* uniformMap= base->getAsUniformMap(); + TUniformMap* uniformMap = base->getAsUniformMap(); if (uniformMap == 0) return -1; @@ -1699,29 +1732,19 @@ const char* GetGlslVersionString() return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL); } -int GetKhronosToolId() -{ - return 8; -} +int GetKhronosToolId() { return 8; } -bool InitializeProcess() -{ - return ShInitialize() != 0; -} +bool InitializeProcess() { return ShInitialize() != 0; } -void FinalizeProcess() -{ - ShFinalize(); -} +void FinalizeProcess() { ShFinalize(); } class TDeferredCompiler : public TCompiler { public: - TDeferredCompiler(EShLanguage s, TInfoSink& i) : TCompiler(s, i) { } + TDeferredCompiler(EShLanguage s, TInfoSink& i) : TCompiler(s, i) {} virtual bool compile(TIntermNode*, int = 0, EProfile = ENoProfile) { return true; } }; -TShader::TShader(EShLanguage s) - : stage(s), lengths(nullptr), stringNames(nullptr), preamble("") +TShader::TShader(EShLanguage s) : stage(s), lengths(nullptr), stringNames(nullptr), preamble("") { pool = new TPoolAllocator; infoSink = new TInfoSink; @@ -1758,8 +1781,7 @@ void TShader::setStringsWithLengths(const char* const* s, const int* l, int n) lengths = l; } -void TShader::setStringsWithLengthsAndNames( - const char* const* s, const int* l, const char* const* names, int n) +void TShader::setStringsWithLengthsAndNames(const char* const* s, const int* l, const char* const* names, int n) { strings = s; numStrings = n; @@ -1767,33 +1789,23 @@ void TShader::setStringsWithLengthsAndNames( stringNames = names; } -void TShader::setEntryPoint(const char* entryPoint) -{ - intermediate->setEntryPointName(entryPoint); -} +void TShader::setEntryPoint(const char* entryPoint) { intermediate->setEntryPointName(entryPoint); } -void TShader::setSourceEntryPoint(const char* name) -{ - sourceEntryPointName = name; -} +void TShader::setSourceEntryPoint(const char* name) { sourceEntryPointName = name; } -void TShader::addProcesses(const std::vector& p) -{ - intermediate->addProcesses(p); -} +void TShader::addProcesses(const std::vector& p) { intermediate->addProcesses(p); } -void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } -void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } +void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } +void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } #ifndef GLSLANG_WEB // Set binding base for given resource type -void TShader::setShiftBinding(TResourceType res, unsigned int base) { - intermediate->setShiftBinding(res, base); -} +void TShader::setShiftBinding(TResourceType res, unsigned int base) { intermediate->setShiftBinding(res, base); } // Set binding base for given resource type for a given binding set. -void TShader::setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set) { +void TShader::setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set) +{ intermediate->setShiftBindingForSet(res, base, set); } @@ -1802,38 +1814,38 @@ void TShader::setShiftSamplerBinding(unsigned int base) { setShiftBinding(EResSa // Set binding base for texture types (SRV) void TShader::setShiftTextureBinding(unsigned int base) { setShiftBinding(EResTexture, base); } // Set binding base for image types -void TShader::setShiftImageBinding(unsigned int base) { setShiftBinding(EResImage, base); } +void TShader::setShiftImageBinding(unsigned int base) { setShiftBinding(EResImage, base); } // Set binding base for uniform buffer objects (CBV) -void TShader::setShiftUboBinding(unsigned int base) { setShiftBinding(EResUbo, base); } +void TShader::setShiftUboBinding(unsigned int base) { setShiftBinding(EResUbo, base); } // Synonym for setShiftUboBinding, to match HLSL language. void TShader::setShiftCbufferBinding(unsigned int base) { setShiftBinding(EResUbo, base); } // Set binding base for UAV (unordered access view) -void TShader::setShiftUavBinding(unsigned int base) { setShiftBinding(EResUav, base); } +void TShader::setShiftUavBinding(unsigned int base) { setShiftBinding(EResUav, base); } // Set binding base for SSBOs -void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSsbo, base); } +void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSsbo, base); } // Enables binding automapping using TIoMapper -void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } +void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } // Enables position.Y output negation in vertex shader // Fragile: currently within one stage: simple auto-assignment of location -void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } +void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } void TShader::addUniformLocationOverride(const char* name, int loc) { intermediate->addUniformLocationOverride(name, loc); } -void TShader::setUniformLocationBase(int base) +void TShader::setUniformLocationBase(int base) { intermediate->setUniformLocationBase(base); } +void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } +void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } +void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { - intermediate->setUniformLocationBase(base); + intermediate->setTextureSamplerTransformMode(mode); } -void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } -void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } -void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } #endif -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL // See comment above TDefaultHlslIoMapper in iomapper.cpp: -void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } -void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } +void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } +void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } #endif // @@ -1841,21 +1853,20 @@ void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlatt // // Returns true for success. // -bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, - bool forwardCompatible, EShMessages messages, Includer& includer) +bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, + bool forceDefaultVersionAndProfile, bool forwardCompatible, EShMessages messages, + Includer& includer) { - if (! InitThread()) + if (!InitThread()) return false; SetThreadPoolAllocator(pool); - if (! preamble) + if (!preamble) preamble = ""; - return CompileDeferred(compiler, strings, numStrings, lengths, stringNames, - preamble, EShOptNone, builtInResources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, - forwardCompatible, messages, *intermediate, includer, sourceEntryPointName, - &environment); + return CompileDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, EShOptNone, builtInResources, + defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, + *intermediate, includer, sourceEntryPointName, &environment); } #ifndef GLSLANG_WEB @@ -1864,42 +1875,33 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion // // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string // is not an officially supported or fully working path. -bool TShader::preprocess(const TBuiltInResource* builtInResources, - int defaultVersion, EProfile defaultProfile, - bool forceDefaultVersionAndProfile, - bool forwardCompatible, EShMessages message, - std::string* output_string, - Includer& includer) +bool TShader::preprocess(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, + bool forceDefaultVersionAndProfile, bool forwardCompatible, EShMessages message, + std::string* output_string, Includer& includer) { - if (! InitThread()) + if (!InitThread()) return false; SetThreadPoolAllocator(pool); - if (! preamble) + if (!preamble) preamble = ""; - return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, - EShOptNone, builtInResources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, + return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, EShOptNone, + builtInResources, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, message, includer, *intermediate, output_string); } #endif -const char* TShader::getInfoLog() -{ - return infoSink->info.c_str(); -} +const char* TShader::getInfoLog() { return infoSink->info.c_str(); } -const char* TShader::getInfoDebugLog() -{ - return infoSink->debug.c_str(); -} +const char* TShader::getInfoDebugLog() { return infoSink->debug.c_str(); } -TProgram::TProgram() : +TProgram::TProgram() + : #ifndef GLSLANG_WEB - reflection(0), + reflection(0), #endif - linked(false) + linked(false) { pool = new TPoolAllocator; infoSink = new TInfoSink; @@ -1940,13 +1942,13 @@ bool TProgram::link(EShMessages messages) SetThreadPoolAllocator(pool); for (int s = 0; s < EShLangCount; ++s) { - if (! linkStage((EShLanguage)s, messages)) + if (!linkStage((EShLanguage)s, messages)) error = true; } // TODO: Link: cross-stage error checking - return ! error; + return !error; } // @@ -1981,14 +1983,12 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) // Be efficient for the common single compilation unit per stage case, // reusing it's TIntermediate instead of merging into a new one. // - TIntermediate *firstIntermediate = stages[stage].front()->intermediate; + TIntermediate* firstIntermediate = stages[stage].front()->intermediate; if (stages[stage].size() == 1) intermediate[stage] = firstIntermediate; else { - intermediate[stage] = new TIntermediate(stage, - firstIntermediate->getVersion(), - firstIntermediate->getProfile()); - + intermediate[stage] = + new TIntermediate(stage, firstIntermediate->getVersion(), firstIntermediate->getProfile()); // The new TIntermediate must use the same origin as the original TIntermediates. // Otherwise linking will fail due to different coordinate systems. @@ -2019,15 +2019,9 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) return intermediate[stage]->getNumErrors() == 0; } -const char* TProgram::getInfoLog() -{ - return infoSink->info.c_str(); -} +const char* TProgram::getInfoLog() { return infoSink->info.c_str(); } -const char* TProgram::getInfoDebugLog() -{ - return infoSink->debug.c_str(); -} +const char* TProgram::getInfoDebugLog() { return infoSink->debug.c_str(); } #ifndef GLSLANG_WEB @@ -2037,7 +2031,7 @@ const char* TProgram::getInfoDebugLog() bool TProgram::buildReflection(int opts) { - if (! linked || reflection != nullptr) + if (!linked || reflection != nullptr) return false; int firstStage = EShLangVertex, lastStage = EShLangFragment; @@ -2059,7 +2053,7 @@ bool TProgram::buildReflection(int opts) for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { - if (! reflection->addStage((EShLanguage)s, *intermediate[s])) + if (!reflection->addStage((EShLanguage)s, *intermediate[s])) return false; } } @@ -2067,33 +2061,39 @@ bool TProgram::buildReflection(int opts) return true; } -unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } -int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); } +unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } +int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); } int TProgram::getReflectionPipeIOIndex(const char* name, const bool inOrOut) const - { return reflection->getPipeIOIndex(name, inOrOut); } - -int TProgram::getNumUniformVariables() const { return reflection->getNumUniforms(); } -const TObjectReflection& TProgram::getUniform(int index) const { return reflection->getUniform(index); } -int TProgram::getNumUniformBlocks() const { return reflection->getNumUniformBlocks(); } -const TObjectReflection& TProgram::getUniformBlock(int index) const { return reflection->getUniformBlock(index); } -int TProgram::getNumPipeInputs() const { return reflection->getNumPipeInputs(); } -const TObjectReflection& TProgram::getPipeInput(int index) const { return reflection->getPipeInput(index); } -int TProgram::getNumPipeOutputs() const { return reflection->getNumPipeOutputs(); } -const TObjectReflection& TProgram::getPipeOutput(int index) const { return reflection->getPipeOutput(index); } -int TProgram::getNumBufferVariables() const { return reflection->getNumBufferVariables(); } +{ + return reflection->getPipeIOIndex(name, inOrOut); +} + +int TProgram::getNumUniformVariables() const { return reflection->getNumUniforms(); } +const TObjectReflection& TProgram::getUniform(int index) const { return reflection->getUniform(index); } +int TProgram::getNumUniformBlocks() const { return reflection->getNumUniformBlocks(); } +const TObjectReflection& TProgram::getUniformBlock(int index) const { return reflection->getUniformBlock(index); } +int TProgram::getNumPipeInputs() const { return reflection->getNumPipeInputs(); } +const TObjectReflection& TProgram::getPipeInput(int index) const { return reflection->getPipeInput(index); } +int TProgram::getNumPipeOutputs() const { return reflection->getNumPipeOutputs(); } +const TObjectReflection& TProgram::getPipeOutput(int index) const { return reflection->getPipeOutput(index); } +int TProgram::getNumBufferVariables() const { return reflection->getNumBufferVariables(); } const TObjectReflection& TProgram::getBufferVariable(int index) const { return reflection->getBufferVariable(index); } -int TProgram::getNumBufferBlocks() const { return reflection->getNumStorageBuffers(); } -const TObjectReflection& TProgram::getBufferBlock(int index) const { return reflection->getStorageBufferBlock(index); } -int TProgram::getNumAtomicCounters() const { return reflection->getNumAtomicCounters(); } -const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); } -void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); } +int TProgram::getNumBufferBlocks() const { return reflection->getNumStorageBuffers(); } +const TObjectReflection& TProgram::getBufferBlock(int index) const { return reflection->getStorageBufferBlock(index); } +int TProgram::getNumAtomicCounters() const { return reflection->getNumAtomicCounters(); } +const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); } +void TProgram::dumpReflection() +{ + if (reflection != nullptr) + reflection->dump(); +} // // I/O mapping implementation. // bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) { - if (! linked) + if (!linked) return false; TIoMapper* ioMapper = nullptr; TIoMapper defaultIOMapper; @@ -2103,7 +2103,7 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) ioMapper = pIoMapper; for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { - if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver)) + if (!ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver)) return false; } } diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index 44682379f7..055f7c37e0 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -114,7 +114,7 @@ void TType::buildMangledName(TString& mangledName) const default: break; // some compilers want this } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL if (sampler.hasReturnStruct()) { // Name mangle for sampler return struct uses struct table index. mangledName += "-tx-struct"; diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 1b2ecc942c..ab89e53121 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -963,7 +963,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase { } }; -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL /******************************************************************************** The following IO resolver maps types in HLSL register space, as follows: @@ -1068,7 +1068,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi return false; // if no resolver is provided, use the default resolver with the given shifts and auto map settings TDefaultIoResolver defaultResolver(intermediate); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL TDefaultHlslIoResolver defaultHlslResolver(intermediate); if (resolver == nullptr) { // TODO: use a passed in IO mapper for this diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 683290af74..80d9e6b728 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -376,7 +376,7 @@ class TIntermediate { } bool getInvertY() const { return invertY; } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL void setSource(EShSource s) { source = s; } EShSource getSource() const { return source; } #else @@ -575,7 +575,7 @@ class TIntermediate { } bool getAutoMapLocations() const { return autoMapLocations; } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; @@ -609,7 +609,7 @@ class TIntermediate { } bool usingVariablePointers() const { return useVariablePointers; } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL template T addCounterBufferName(const T& name) const { return name + implicitCounterName; } bool hasCounterBufferName(const TString& name) const { size_t len = strlen(implicitCounterName); @@ -761,7 +761,7 @@ class TIntermediate { bool getBinaryDoubleOutput() { return binaryDoubleOutput; } #endif // GLSLANG_WEB -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL void setHlslFunctionality1() { hlslFunctionality1 = true; } bool getHlslFunctionality1() const { return hlslFunctionality1; } void setHlslOffsets() diff --git a/glslang/MachineIndependent/parseVersions.h b/glslang/MachineIndependent/parseVersions.h index aa1964fc2e..5a4ce83763 100644 --- a/glslang/MachineIndependent/parseVersions.h +++ b/glslang/MachineIndependent/parseVersions.h @@ -204,7 +204,7 @@ class TParseVersions { void setCurrentString(int string) { currentScanner->setString(string); } void getPreamble(std::string&); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; } diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp index 6cdadec9f8..b92720f41c 100644 --- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -142,7 +142,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) ch = getChar(); int firstDecimal = len; -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL // 1.#INF or -1.#INF if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) { if ((len < 2) || diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index b09367113c..70eebc4755 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -1093,7 +1093,7 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat // build counter block index associations for buffers void TReflection::buildCounterIndices(const TIntermediate& intermediate) { -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL // search for ones that have counters for (int i = 0; i < int(indexToUniformBlock.size()); ++i) { const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str()); diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 7cfa57b6f0..bb1fca4edb 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -444,7 +444,7 @@ class TShader { void addUniformLocationOverride(const char* name, int loc); void setUniformLocationBase(int base); void setInvertY(bool invert); -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL void setHlslIoMapping(bool hlslIoMap); void setFlattenUniformArrays(bool flatten); #endif @@ -500,7 +500,7 @@ class TShader { void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; } -#ifdef ENABLE_HLSL +#ifdef GLSLANG_ENABLE_HLSL void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; } bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; } #else diff --git a/gtests/CMakeLists.txt b/gtests/CMakeLists.txt index dc53f5c329..5b2d810293 100644 --- a/gtests/CMakeLists.txt +++ b/gtests/CMakeLists.txt @@ -1,4 +1,4 @@ -if(BUILD_TESTING) +if(GLSLANG_BUILD_TESTING) if(TARGET gmock) message(STATUS "Google Mock found - building tests") @@ -58,9 +58,9 @@ if(BUILD_TESTING) set(LIBRARIES ${LIBRARIES} SPVRemapper) endif() - if(ENABLE_HLSL) + if(GLSLANG_ENABLE_HLSL) set(LIBRARIES ${LIBRARIES} HLSL) - endif(ENABLE_HLSL) + endif(GLSLANG_ENABLE_HLSL) target_link_libraries(glslangtests PRIVATE ${LIBRARIES} gmock) add_test(NAME glslang-gtests diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index f483536440..2acbf8d153 100755 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -41,15 +41,15 @@ namespace glslangtest { namespace { struct FileNameEntryPointPair { - const char* fileName; - const char* entryPoint; + const char* fileName; + const char* entryPoint; }; // We are using FileNameEntryPointPair objects as parameters for instantiating // the template, so the global FileNameAsCustomTestSuffix() won't work since // it assumes std::string as parameters. Thus, an overriding one here. -std::string FileNameAsCustomTestSuffix( - const ::testing::TestParamInfo& info) { +std::string FileNameAsCustomTestSuffix(const ::testing::TestParamInfo& info) +{ std::string name = info.param.fileName; // A valid test case suffix cannot have '.' and '-' inside. std::replace(name.begin(), name.end(), '.', '_'); @@ -69,51 +69,47 @@ using HlslLegalDebugTest = GlslangTest<::testing::TestWithParam