TOOLS: updated glslang
parent
8286f134b5
commit
9df9f884d2
3
Makefile
3
Makefile
|
@ -166,6 +166,9 @@ update-glslang:
|
|||
cp -r $(UPDATEDIR)/glslang.sync/SPIRV tools/glslang/
|
||||
rm -rf tools/glslang/StandAlone
|
||||
cp -r $(UPDATEDIR)/glslang.sync/StandAlone tools/glslang/
|
||||
cp $(UPDATEDIR)/glslang.sync/gen_extension_headers.py tools/glslang/
|
||||
cp $(UPDATEDIR)/glslang.sync/*.cmake tools/glslang/
|
||||
cp $(UPDATEDIR)/glslang.sync/README* tools/glslang/
|
||||
|
||||
update-simplecpp:
|
||||
$(call UPDATE_GIT,simplecpp,https://github.com/danmar/simplecpp.git)
|
||||
|
|
|
@ -1,3 +1,36 @@
|
|||
# Copyright (C) 2020 The Khronos Group Inc.
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# Neither the name of The Khronos Group Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# The macro choose_msvc_crt() takes a list of possible
|
||||
# C runtimes to choose from, in the form of compiler flags,
|
||||
# to present to the user. (MTd for /MTd, etc)
|
||||
|
|
|
@ -1,35 +1,77 @@
|
|||
Also see the Khronos landing page for glslang as a reference front end:
|
||||
# News
|
||||
|
||||
https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
|
||||
1. Visual Studio 2013 is no longer supported
|
||||
|
||||
The above page includes where to get binaries, and is kept up to date
|
||||
regarding the feature level of glslang.
|
||||
[As scheduled](https://github.com/KhronosGroup/glslang/blob/9eef54b2513ca6b40b47b07d24f453848b65c0df/README.md#planned-deprecationsremovals),
|
||||
Microsoft Visual Studio 2013 is no longer officially supported. \
|
||||
Please upgrade to at least Visual Studio 2015.
|
||||
|
||||
glslang
|
||||
=======
|
||||
2. The versioning scheme is being improved, and you might notice some differences. This is currently WIP, but will be coming soon. See, for example, PR #2277.
|
||||
|
||||
3. If you get a new **compilation error due to a missing header**, it might be caused by this planned removal:
|
||||
|
||||
**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.
|
||||
|
||||
If people are only using this location to get spirv.hpp, I recommend they get that from [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) instead.
|
||||
|
||||
[![Build Status](https://travis-ci.org/KhronosGroup/glslang.svg?branch=master)](https://travis-ci.org/KhronosGroup/glslang)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/q6fi9cb0qnhkla68/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)
|
||||
|
||||
An OpenGL and OpenGL ES shader front end and validator.
|
||||
# Glslang Components and Status
|
||||
|
||||
There are several components:
|
||||
|
||||
1. A GLSL/ESSL front-end for reference validation and translation of GLSL/ESSL into an AST.
|
||||
### Reference Validator and GLSL/ESSL -> AST Front End
|
||||
|
||||
2. An HLSL front-end for translation of a broad generic HLL into the AST.
|
||||
An OpenGL GLSL and OpenGL|ES GLSL (ESSL) front-end for reference validation and translation of GLSL/ESSL into an internal abstract syntax tree (AST).
|
||||
|
||||
3. A SPIR-V back end for translating the AST to SPIR-V.
|
||||
**Status**: Virtually complete, with results carrying similar weight as the specifications.
|
||||
|
||||
4. A standalone wrapper, `glslangValidator`, that can be used as a command-line tool for the above.
|
||||
### HLSL -> AST Front End
|
||||
|
||||
How to add a feature protected by a version/extension/stage/profile: See the
|
||||
comment in `glslang/MachineIndependent/Versions.cpp`.
|
||||
An HLSL front-end for translation of an approximation of HLSL to glslang's AST form.
|
||||
|
||||
**Status**: Partially complete. Semantics are not reference quality and input is not validated.
|
||||
This is in contrast to the [DXC project](https://github.com/Microsoft/DirectXShaderCompiler), which receives a much larger investment and attempts to have definitive/reference-level semantics.
|
||||
|
||||
See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
|
||||
|
||||
### AST -> SPIR-V Back End
|
||||
|
||||
Translates glslang's AST to the Khronos-specified SPIR-V intermediate language.
|
||||
|
||||
**Status**: Virtually complete.
|
||||
|
||||
### Reflector
|
||||
|
||||
An API for getting reflection information from the AST, reflection types/variables/etc. from the HLL source (not the SPIR-V).
|
||||
|
||||
**Status**: There is a large amount of functionality present, but no specification/goal to measure completeness against. It is accurate for the input HLL and AST, but only approximate for what would later be emitted for SPIR-V.
|
||||
|
||||
### Standalone Wrapper
|
||||
|
||||
`glslangValidator` is command-line tool for accessing the functionality above.
|
||||
|
||||
Status: Complete.
|
||||
|
||||
Tasks waiting to be done are documented as GitHub issues.
|
||||
|
||||
Execution of Standalone Wrapper
|
||||
-------------------------------
|
||||
## Other References
|
||||
|
||||
Also see the Khronos landing page for glslang as a reference front end:
|
||||
|
||||
https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
|
||||
|
||||
The above page, while not kept up to date, includes additional information regarding glslang as a reference validator.
|
||||
|
||||
# How to Use Glslang
|
||||
|
||||
## Execution of Standalone Wrapper
|
||||
|
||||
To use the standalone binary form, execute `glslangValidator`, and it will print
|
||||
a usage statement. Basic operation is to give it a file containing a shader,
|
||||
|
@ -46,24 +88,33 @@ The applied stage-specific rules are based on the file extension:
|
|||
There is also a non-shader extension
|
||||
* `.conf` for a configuration file of limits, see usage statement for example
|
||||
|
||||
Building
|
||||
--------
|
||||
## Building (CMake)
|
||||
|
||||
Instead of building manually, you can also download the binaries for your
|
||||
platform directly from the [master-tot release][master-tot-release] on GitHub.
|
||||
Those binaries are automatically uploaded by the buildbots after successful
|
||||
testing and they always reflect the current top of the tree of the master
|
||||
branch.
|
||||
|
||||
### Dependencies
|
||||
|
||||
* A C++11 compiler.
|
||||
(For MSVS: use 2015 or later.)
|
||||
* [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
|
||||
|
||||
#### 1) Check-Out this project
|
||||
The following steps assume a Bash shell. On Windows, that could be the Git Bash
|
||||
shell or some other shell of your choosing.
|
||||
|
||||
#### 1) Check-Out this project
|
||||
|
||||
```bash
|
||||
cd <parent of where you want glslang to be>
|
||||
# If using SSH
|
||||
git clone git@github.com:KhronosGroup/glslang.git
|
||||
# Or if using HTTPS
|
||||
git clone https://github.com/KhronosGroup/glslang.git
|
||||
```
|
||||
|
||||
|
@ -74,43 +125,104 @@ cd <the directory glslang was cloned to, "External" will be a subdirectory>
|
|||
git clone https://github.com/google/googletest.git External/googletest
|
||||
```
|
||||
|
||||
#### 3) Configure
|
||||
|
||||
Assume the source directory is `$SOURCE_DIR` and
|
||||
the build directory is `$BUILD_DIR`:
|
||||
|
||||
For building on Linux (assuming using the Ninja generator):
|
||||
TEMPORARY NOTICE: additionally perform the following to avoid a current
|
||||
breakage in googletest:
|
||||
|
||||
```bash
|
||||
cd $BUILD_DIR
|
||||
cd External/googletest
|
||||
git checkout 0c400f67fcf305869c5fb113dd296eca266c9725
|
||||
cd ../..
|
||||
```
|
||||
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \
|
||||
-DCMAKE_INSTALL_PREFIX=`pwd`/install $SOURCE_DIR
|
||||
If you wish to assure that SPIR-V generated from HLSL is legal for Vulkan,
|
||||
wish to invoke -Os to reduce SPIR-V size from HLSL or GLSL, or wish to run the
|
||||
integrated test suite, install spirv-tools with this:
|
||||
|
||||
```bash
|
||||
./update_glslang_sources.py
|
||||
```
|
||||
|
||||
#### 3) Configure
|
||||
|
||||
Assume the source directory is `$SOURCE_DIR` and the build directory is
|
||||
`$BUILD_DIR`. First ensure the build directory exists, then navigate to it:
|
||||
|
||||
```bash
|
||||
mkdir -p $BUILD_DIR
|
||||
cd $BUILD_DIR
|
||||
```
|
||||
|
||||
For building on Linux:
|
||||
|
||||
```bash
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR
|
||||
# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo"
|
||||
```
|
||||
|
||||
For building on Android:
|
||||
```bash
|
||||
cmake $SOURCE_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_STL=c++_static -DANDROID_PLATFORM=android-24 -DCMAKE_SYSTEM_NAME=Android -DANDROID_TOOLCHAIN=clang -DANDROID_ARM_MODE=arm -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK_ROOT/prebuilt/linux-x86_64/bin/make -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake
|
||||
# If on Windows will be -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make.exe
|
||||
# -G is needed for building on Windows
|
||||
# -DANDROID_ABI can also be armeabi-v7a for 32 bit
|
||||
```
|
||||
|
||||
For building on Windows:
|
||||
|
||||
```bash
|
||||
cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX=`pwd`/install
|
||||
cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
|
||||
# The CMAKE_INSTALL_PREFIX part is for testing (explained later).
|
||||
```
|
||||
|
||||
The CMake GUI also works for Windows (version 3.4.1 tested).
|
||||
|
||||
Also, consider using `git config --global core.fileMode false` (or with `--local`) on Windows
|
||||
to prevent the addition of execution permission on files.
|
||||
|
||||
#### 4) Build and Install
|
||||
|
||||
```bash
|
||||
# for Linux:
|
||||
ninja install
|
||||
make -j4 install
|
||||
|
||||
# for Windows:
|
||||
cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \
|
||||
--target install
|
||||
cmake --build . --config Release --target install
|
||||
# "Release" (for --config) could also be "Debug", "MinSizeRel", or "RelWithDebInfo"
|
||||
```
|
||||
|
||||
If using MSVC, after running CMake to configure, use the
|
||||
Configuration Manager to check the `INSTALL` project.
|
||||
|
||||
### Building (GN)
|
||||
|
||||
glslang can also be built with the [GN build system](https://gn.googlesource.com/gn/).
|
||||
|
||||
#### 1) Install `depot_tools`
|
||||
|
||||
Download [depot_tools.zip](https://storage.googleapis.com/chrome-infra/depot_tools.zip),
|
||||
extract to a directory, and add this directory to your `PATH`.
|
||||
|
||||
#### 2) Synchronize dependencies and generate build files
|
||||
|
||||
This only needs to be done once after updating `glslang`.
|
||||
|
||||
With the current directory set to your `glslang` checkout, type:
|
||||
|
||||
```bash
|
||||
./update_glslang_sources.py
|
||||
gclient sync --gclientfile=standalone.gclient
|
||||
gn gen out/Default
|
||||
```
|
||||
|
||||
#### 3) Build
|
||||
|
||||
With the current directory set to your `glslang` checkout, type:
|
||||
|
||||
```bash
|
||||
cd out/Default
|
||||
ninja
|
||||
```
|
||||
|
||||
### If you need to change the GLSL grammar
|
||||
|
||||
The grammar in `glslang/MachineIndependent/glslang.y` has to be recompiled with
|
||||
|
@ -122,16 +234,57 @@ changes are quite infrequent. For windows you can get binaries from
|
|||
The command to rebuild is:
|
||||
|
||||
```bash
|
||||
m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y
|
||||
bison --defines=MachineIndependent/glslang_tab.cpp.h
|
||||
-t MachineIndependent/glslang.y
|
||||
-o MachineIndependent/glslang_tab.cpp
|
||||
```
|
||||
|
||||
The above command is also available in the bash script at
|
||||
`glslang/updateGrammar`.
|
||||
The above commands are also available in the bash script in `updateGrammar`,
|
||||
when executed from the glslang subdirectory of the glslang repository.
|
||||
With no arguments it builds the full grammar, and with a "web" argument,
|
||||
the web grammar subset (see more about the web subset in the next section).
|
||||
|
||||
Testing
|
||||
-------
|
||||
### Building to WASM for the Web and Node
|
||||
### Building a standalone JS/WASM library for the Web and Node
|
||||
|
||||
Use the steps in [Build Steps](#build-steps), with the following notes/exceptions:
|
||||
* `emsdk` needs to be present in your executable search path, *PATH* for
|
||||
Bash-like environments:
|
||||
+ [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)
|
||||
* Wrap cmake call: `emcmake cmake`
|
||||
* Set `-DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF`.
|
||||
* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
|
||||
* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
|
||||
* For building a minimum-size web subset of core glslang:
|
||||
+ turn on `-DENABLE_GLSLANG_WEBMIN=ON` (disables HLSL)
|
||||
+ execute `updateGrammar web` from the glslang subdirectory
|
||||
(or if using your own scripts, `m4` needs a `-DGLSLANG_WEB` argument)
|
||||
+ optionally, for GLSL compilation error messages, turn on
|
||||
`-DENABLE_GLSLANG_WEBMIN_DEVEL=ON`
|
||||
* To get a fully minimized build, make sure to use `brotli` to compress the .js
|
||||
and .wasm files
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
emcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_JS=ON \
|
||||
-DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF ..
|
||||
```
|
||||
|
||||
## Building glslang - Using vcpkg
|
||||
|
||||
You can download and install glslang using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install glslang
|
||||
|
||||
The glslang port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Testing
|
||||
|
||||
Right now, there are two test harnesses existing in glslang: one is [Google
|
||||
Test](gtests/), one is the [`runtests` script](Test/runtests). The former
|
||||
|
@ -167,6 +320,11 @@ Running `runtests` script-backed tests:
|
|||
cd $SOURCE_DIR/Test && ./runtests
|
||||
```
|
||||
|
||||
If some tests fail with validation errors, there may be a mismatch between the
|
||||
version of `spirv-val` on the system and the version of glslang. In this
|
||||
case, it is necessary to run `update_glslang_sources.py`. See "Check-Out
|
||||
External Projects" above for more details.
|
||||
|
||||
### Contributing tests
|
||||
|
||||
Test results should always be included with a pull request that modifies
|
||||
|
@ -198,8 +356,7 @@ You can add your own private list of tests, not tracked publicly, by using
|
|||
`localtestlist` to list non-tracked tests. This is automatically read
|
||||
by `runtests` and included in the `diff` and `bump` process.
|
||||
|
||||
Programmatic Interfaces
|
||||
-----------------------
|
||||
## Programmatic Interfaces
|
||||
|
||||
Another piece of software can programmatically translate shaders to an AST
|
||||
using one of two different interfaces:
|
||||
|
@ -211,7 +368,8 @@ The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles.
|
|||
### C++ Class Interface (new, preferred)
|
||||
|
||||
This interface is in roughly the last 1/3 of `ShaderLang.h`. It is in the
|
||||
glslang namespace and contains the following.
|
||||
glslang namespace and contains the following, here with suggested calls
|
||||
for generating SPIR-V:
|
||||
|
||||
```cxx
|
||||
const char* GetEsslVersionString();
|
||||
|
@ -220,8 +378,11 @@ bool InitializeProcess();
|
|||
void FinalizeProcess();
|
||||
|
||||
class TShader
|
||||
setStrings(...);
|
||||
setEnvInput(EShSourceHlsl or EShSourceGlsl, stage, EShClientVulkan or EShClientOpenGL, 100);
|
||||
setEnvClient(EShClientVulkan or EShClientOpenGL, EShTargetVulkan_1_0 or EShTargetVulkan_1_1 or EShTargetOpenGL_450);
|
||||
setEnvTarget(EShTargetSpv, EShTargetSpv_1_0 or EShTargetSpv_1_3);
|
||||
bool parse(...);
|
||||
void setStrings(...);
|
||||
const char* getInfoLog();
|
||||
|
||||
class TProgram
|
||||
|
@ -231,16 +392,25 @@ class TProgram
|
|||
Reflection queries
|
||||
```
|
||||
|
||||
See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
|
||||
details.
|
||||
For just validating (not generating code), substitute these calls:
|
||||
|
||||
### C Functional Interface (orignal)
|
||||
```cxx
|
||||
setEnvInput(EShSourceHlsl or EShSourceGlsl, stage, EShClientNone, 0);
|
||||
setEnvClient(EShClientNone, 0);
|
||||
setEnvTarget(EShTargetNone, 0);
|
||||
```
|
||||
|
||||
See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
|
||||
details. There is a block comment giving more detail above the calls for
|
||||
`setEnvInput, setEnvClient, and setEnvTarget`.
|
||||
|
||||
### C Functional Interface (original)
|
||||
|
||||
This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
|
||||
as the `Sh*()` interface, as all the entry points start `Sh`.
|
||||
|
||||
The `Sh*()` interface takes a "compiler" call-back object, which it calls after
|
||||
building call back that is passed the AST and can then execute a backend on it.
|
||||
building call back that is passed the AST and can then execute a back end on it.
|
||||
|
||||
The following is a simplified resulting run-time call stack:
|
||||
|
||||
|
@ -251,8 +421,7 @@ ShCompile(shader, compiler) -> compiler(AST) -> <back end>
|
|||
In practice, `ShCompile()` takes shader strings, default version, and
|
||||
warning/error and other options for controlling compilation.
|
||||
|
||||
Basic Internal Operation
|
||||
------------------------
|
||||
## Basic Internal Operation
|
||||
|
||||
* Initial lexical analysis is done by the preprocessor in
|
||||
`MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
|
||||
|
@ -267,7 +436,7 @@ Basic Internal Operation
|
|||
* The intermediate representation is very high-level, and represented
|
||||
as an in-memory tree. This serves to lose no information from the
|
||||
original program, and to have efficient transfer of the result from
|
||||
parsing to the back-end. In the AST, constants are propogated and
|
||||
parsing to the back-end. In the AST, constants are propagated and
|
||||
folded, and a very small amount of dead code is eliminated.
|
||||
|
||||
To aid linking and reflection, the last top-level branch in the AST
|
||||
|
@ -299,8 +468,12 @@ Basic Internal Operation
|
|||
- the object does not come from the pool, and you have to do normal
|
||||
C++ memory management of what you `new`
|
||||
|
||||
* Features can be protected by version/extension/stage/profile:
|
||||
See the comment in `glslang/MachineIndependent/Versions.cpp`.
|
||||
|
||||
[cmake]: https://cmake.org/
|
||||
[python]: https://www.python.org/
|
||||
[bison]: https://www.gnu.org/software/bison/
|
||||
[googletest]: https://github.com/google/googletest
|
||||
[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
|
||||
[master-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/master-tot
|
||||
|
|
|
@ -101,12 +101,12 @@ if(ENABLE_OPT)
|
|||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
|
||||
else()
|
||||
target_link_libraries(SPIRV PRIVATE MachineIndependent)
|
||||
endif(ENABLE_OPT)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||
source_group("Source" FILES ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GLSLANG_INSTALL)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
|
@ -135,4 +135,4 @@ if(ENABLE_GLSLANG_INSTALL)
|
|||
install(EXPORT SPIRVTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
|
||||
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/SPIRV/)
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
||||
endif()
|
||||
|
|
|
@ -36,6 +36,8 @@ static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fu
|
|||
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
||||
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
|
||||
static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
|
||||
static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add";
|
||||
static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max";
|
||||
static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
|
||||
|
||||
#endif // #ifndef GLSLextEXT_H
|
||||
|
|
|
@ -51,5 +51,6 @@ static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_q
|
|||
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
|
||||
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
|
||||
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
|
||||
static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
|
||||
|
||||
#endif // #ifndef GLSLextKHR_H
|
||||
|
|
|
@ -69,6 +69,9 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
|
|||
//SPV_NV_raytracing
|
||||
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
|
||||
|
||||
//SPV_NV_ray_tracing_motion_blur
|
||||
const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur";
|
||||
|
||||
//SPV_NV_shading_rate
|
||||
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ protected:
|
|||
spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
|
||||
spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector<unsigned int>& operands) const;
|
||||
spv::StorageClass TranslateStorageClass(const glslang::TType&);
|
||||
void TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>&, std::vector<unsigned>&) const;
|
||||
void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType);
|
||||
spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType);
|
||||
spv::Id getSampledType(const glslang::TSampler&);
|
||||
|
@ -178,6 +179,7 @@ protected:
|
|||
spv::Id accessChainLoad(const glslang::TType& type);
|
||||
void accessChainStore(const glslang::TType& type, spv::Id rvalue);
|
||||
void multiTypeStore(const glslang::TType&, spv::Id rValue);
|
||||
spv::Id convertLoadedBoolInUniformToUint(const glslang::TType& type, spv::Id nominalTypeId, spv::Id loadedId);
|
||||
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
|
||||
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||
|
@ -1031,6 +1033,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|||
return spv::BuiltInIncomingRayFlagsKHR;
|
||||
case glslang::EbvGeometryIndex:
|
||||
return spv::BuiltInRayGeometryIndexKHR;
|
||||
case glslang::EbvCurrentRayTimeNV:
|
||||
builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
|
||||
builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
|
||||
return spv::BuiltInCurrentRayTimeNV;
|
||||
|
||||
// barycentrics
|
||||
case glslang::EbvBaryCoordNV:
|
||||
|
@ -1249,6 +1255,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
|||
{
|
||||
if (type.getBasicType() == glslang::EbtRayQuery)
|
||||
return spv::StorageClassPrivate;
|
||||
#ifndef GLSLANG_WEB
|
||||
if (type.getQualifier().isSpirvByReference())
|
||||
return spv::StorageClassFunction;
|
||||
#endif
|
||||
if (type.getQualifier().isPipeInput())
|
||||
return spv::StorageClassInput;
|
||||
if (type.getQualifier().isPipeOutput())
|
||||
|
@ -1297,6 +1307,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
|||
case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR;
|
||||
case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR;
|
||||
case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
|
||||
case glslang::EvqSpirvStorageClass: return static_cast<spv::StorageClass>(type.getQualifier().spirvStorageClass);
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -1306,6 +1317,52 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
|||
return spv::StorageClassFunction;
|
||||
}
|
||||
|
||||
// Translate glslang constants to SPIR-V literals
|
||||
void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>& constants,
|
||||
std::vector<unsigned>& literals) const
|
||||
{
|
||||
for (auto constant : constants) {
|
||||
if (constant->getBasicType() == glslang::EbtFloat) {
|
||||
float floatValue = static_cast<float>(constant->getConstArray()[0].getDConst());
|
||||
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
|
||||
literals.push_back(literal);
|
||||
} else if (constant->getBasicType() == glslang::EbtInt) {
|
||||
unsigned literal = constant->getConstArray()[0].getIConst();
|
||||
literals.push_back(literal);
|
||||
} else if (constant->getBasicType() == glslang::EbtUint) {
|
||||
unsigned literal = constant->getConstArray()[0].getUConst();
|
||||
literals.push_back(literal);
|
||||
} else if (constant->getBasicType() == glslang::EbtBool) {
|
||||
unsigned literal = constant->getConstArray()[0].getBConst();
|
||||
literals.push_back(literal);
|
||||
} else if (constant->getBasicType() == glslang::EbtString) {
|
||||
auto str = constant->getConstArray()[0].getSConst()->c_str();
|
||||
unsigned literal = 0;
|
||||
char* literalPtr = reinterpret_cast<char*>(&literal);
|
||||
unsigned charCount = 0;
|
||||
char ch = 0;
|
||||
do {
|
||||
ch = *(str++);
|
||||
*(literalPtr++) = ch;
|
||||
++charCount;
|
||||
if (charCount == 4) {
|
||||
literals.push_back(literal);
|
||||
literalPtr = reinterpret_cast<char*>(&literal);
|
||||
charCount = 0;
|
||||
}
|
||||
} while (ch != 0);
|
||||
|
||||
// Partial literal is padded with 0
|
||||
if (charCount > 0) {
|
||||
for (; charCount < 4; ++charCount)
|
||||
*(literalPtr++) = 0;
|
||||
literals.push_back(literal);
|
||||
}
|
||||
} else
|
||||
assert(0); // Unexpected type
|
||||
}
|
||||
}
|
||||
|
||||
// Add capabilities pertaining to how an array is indexed.
|
||||
void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
|
||||
const glslang::TType& indexType)
|
||||
|
@ -1526,6 +1583,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
if (glslangIntermediate->getSubgroupUniformControlFlow()) {
|
||||
builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int mode;
|
||||
switch (glslangIntermediate->getStage()) {
|
||||
case EShLangVertex:
|
||||
|
@ -1728,6 +1792,53 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
//
|
||||
// Add SPIR-V requirements (GL_EXT_spirv_intrinsics)
|
||||
//
|
||||
if (glslangIntermediate->hasSpirvRequirement()) {
|
||||
const glslang::TSpirvRequirement& spirvRequirement = glslangIntermediate->getSpirvRequirement();
|
||||
|
||||
// Add SPIR-V extension requirement
|
||||
for (auto& extension : spirvRequirement.extensions)
|
||||
builder.addExtension(extension.c_str());
|
||||
|
||||
// Add SPIR-V capability requirement
|
||||
for (auto capability : spirvRequirement.capabilities)
|
||||
builder.addCapability(static_cast<spv::Capability>(capability));
|
||||
}
|
||||
|
||||
//
|
||||
// Add SPIR-V execution mode qualifiers (GL_EXT_spirv_intrinsics)
|
||||
//
|
||||
if (glslangIntermediate->hasSpirvExecutionMode()) {
|
||||
const glslang::TSpirvExecutionMode spirvExecutionMode = glslangIntermediate->getSpirvExecutionMode();
|
||||
|
||||
// Add spirv_execution_mode
|
||||
for (auto& mode : spirvExecutionMode.modes) {
|
||||
if (!mode.second.empty()) {
|
||||
std::vector<unsigned> literals;
|
||||
TranslateLiterals(mode.second, literals);
|
||||
builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first), literals);
|
||||
} else
|
||||
builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first));
|
||||
}
|
||||
|
||||
// Add spirv_execution_mode_id
|
||||
for (auto& modeId : spirvExecutionMode.modeIds) {
|
||||
std::vector<spv::Id> operandIds;
|
||||
assert(!modeId.second.empty());
|
||||
for (auto extraOperand : modeId.second) {
|
||||
if (extraOperand->getType().getQualifier().isSpecConstant())
|
||||
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||
else
|
||||
operandIds.push_back(createSpvConstant(*extraOperand));
|
||||
}
|
||||
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Finish creating SPV, after the traversal is complete.
|
||||
|
@ -2125,6 +2236,49 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||
}
|
||||
}
|
||||
|
||||
spv::Id TGlslangToSpvTraverser::convertLoadedBoolInUniformToUint(const glslang::TType& type,
|
||||
spv::Id nominalTypeId,
|
||||
spv::Id loadedId)
|
||||
{
|
||||
if (builder.isScalarType(nominalTypeId)) {
|
||||
// Conversion for bool
|
||||
spv::Id boolType = builder.makeBoolType();
|
||||
if (nominalTypeId != boolType)
|
||||
return builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
|
||||
} else if (builder.isVectorType(nominalTypeId)) {
|
||||
// Conversion for bvec
|
||||
int vecSize = builder.getNumTypeComponents(nominalTypeId);
|
||||
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
|
||||
if (nominalTypeId != bvecType)
|
||||
loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
|
||||
makeSmearedConstant(builder.makeUintConstant(0), vecSize));
|
||||
} else if (builder.isArrayType(nominalTypeId)) {
|
||||
// Conversion for bool array
|
||||
spv::Id boolArrayTypeId = convertGlslangToSpvType(type);
|
||||
if (nominalTypeId != boolArrayTypeId)
|
||||
{
|
||||
// Use OpCopyLogical from SPIR-V 1.4 if available.
|
||||
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
|
||||
return builder.createUnaryOp(spv::OpCopyLogical, boolArrayTypeId, loadedId);
|
||||
|
||||
glslang::TType glslangElementType(type, 0);
|
||||
spv::Id elementNominalTypeId = builder.getContainedTypeId(nominalTypeId);
|
||||
std::vector<spv::Id> constituents;
|
||||
for (int index = 0; index < type.getOuterArraySize(); ++index) {
|
||||
// get the element
|
||||
spv::Id elementValue = builder.createCompositeExtract(loadedId, elementNominalTypeId, index);
|
||||
|
||||
// recursively convert it
|
||||
spv::Id elementConvertedValue = convertLoadedBoolInUniformToUint(glslangElementType, elementNominalTypeId, elementValue);
|
||||
constituents.push_back(elementConvertedValue);
|
||||
}
|
||||
return builder.createCompositeConstruct(boolArrayTypeId, constituents);
|
||||
}
|
||||
}
|
||||
|
||||
return loadedId;
|
||||
}
|
||||
|
||||
// Figure out what, if any, type changes are needed when accessing a specific built-in.
|
||||
// Returns <the type SPIR-V requires for declarion, the type to translate to on use>.
|
||||
// Also see comment for 'forceType', regarding tracking SPIR-V-required types.
|
||||
|
@ -2310,10 +2464,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
|||
node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
|
||||
node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
|
||||
node->getOp() == glslang::EOpRayQueryTerminate ||
|
||||
node->getOp() == glslang::EOpRayQueryConfirmIntersection) {
|
||||
node->getOp() == glslang::EOpRayQueryConfirmIntersection ||
|
||||
(node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) {
|
||||
operand = builder.accessChainGetLValue(); // Special case l-value operands
|
||||
lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
|
||||
lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
|
||||
} else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
|
||||
// Will be translated to a literal value, make a placeholder here
|
||||
operand = spv::NoResult;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -2334,6 +2492,38 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
|
|||
result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
|
||||
node->getOperand()->getBasicType(), lvalueCoherentFlags);
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// it could be attached to a SPIR-V intruction
|
||||
if (!result) {
|
||||
if (node->getOp() == glslang::EOpSpirvInst) {
|
||||
const auto& spirvInst = node->getSpirvInstruction();
|
||||
if (spirvInst.set == "") {
|
||||
spv::IdImmediate idImmOp = {true, operand};
|
||||
if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
|
||||
// Translate the constant to a literal value
|
||||
std::vector<unsigned> literals;
|
||||
glslang::TVector<const glslang::TIntermConstantUnion*> constants;
|
||||
constants.push_back(operandNode->getAsConstantUnion());
|
||||
TranslateLiterals(constants, literals);
|
||||
idImmOp = {false, literals[0]};
|
||||
}
|
||||
|
||||
if (node->getBasicType() == glslang::EbtVoid)
|
||||
builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), {idImmOp});
|
||||
else
|
||||
result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), {idImmOp});
|
||||
} else {
|
||||
result = builder.createBuiltinCall(
|
||||
resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
|
||||
spirvInst.id, {operand});
|
||||
}
|
||||
|
||||
if (node->getBasicType() == glslang::EbtVoid)
|
||||
return false; // done with this node
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (result) {
|
||||
if (invertedType) {
|
||||
result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
|
||||
|
@ -2832,6 +3022,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
case glslang::EOpIgnoreIntersectionNV:
|
||||
case glslang::EOpTerminateRayNV:
|
||||
case glslang::EOpTraceNV:
|
||||
case glslang::EOpTraceRayMotionNV:
|
||||
case glslang::EOpTraceKHR:
|
||||
case glslang::EOpExecuteCallableNV:
|
||||
case glslang::EOpExecuteCallableKHR:
|
||||
|
@ -3030,6 +3221,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
if (arg == 1)
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSpirvInst:
|
||||
if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference())
|
||||
lvalue = true;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
|
@ -3127,15 +3322,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
|
||||
operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
|
||||
} else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
|
||||
(arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) ||
|
||||
(arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) {
|
||||
const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1;
|
||||
const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1;
|
||||
const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1);
|
||||
const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0;
|
||||
|
||||
const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst();
|
||||
auto itNode = locationToSymbol[set].find(location);
|
||||
visitSymbol(itNode->second);
|
||||
spv::Id symId = getSymbolId(itNode->second);
|
||||
operands.push_back(symId);
|
||||
} else {
|
||||
#ifndef GLSLANG_WEB
|
||||
} else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) {
|
||||
// Will be translated to a literal value, make a placeholder here
|
||||
operands.push_back(spv::NoResult);
|
||||
#endif
|
||||
} else {
|
||||
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
|
||||
}
|
||||
}
|
||||
|
@ -3177,6 +3379,34 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
|
||||
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
|
||||
lvalueCoherentFlags);
|
||||
#ifndef GLSLANG_WEB
|
||||
} else if (node->getOp() == glslang::EOpSpirvInst) {
|
||||
const auto& spirvInst = node->getSpirvInstruction();
|
||||
if (spirvInst.set == "") {
|
||||
std::vector<spv::IdImmediate> idImmOps;
|
||||
for (unsigned int i = 0; i < glslangOperands.size(); ++i) {
|
||||
if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
|
||||
// Translate the constant to a literal value
|
||||
std::vector<unsigned> literals;
|
||||
glslang::TVector<const glslang::TIntermConstantUnion*> constants;
|
||||
constants.push_back(glslangOperands[i]->getAsConstantUnion());
|
||||
TranslateLiterals(constants, literals);
|
||||
idImmOps.push_back({false, literals[0]});
|
||||
} else
|
||||
idImmOps.push_back({true, operands[i]});
|
||||
}
|
||||
|
||||
if (node->getBasicType() == glslang::EbtVoid)
|
||||
builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), idImmOps);
|
||||
else
|
||||
result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), idImmOps);
|
||||
} else {
|
||||
result = builder.createBuiltinCall(
|
||||
resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
|
||||
spirvInst.id, operands);
|
||||
}
|
||||
noReturnValue = node->getBasicType() == glslang::EbtVoid;
|
||||
#endif
|
||||
} else if (node->getOp() == glslang::EOpDebugPrintf) {
|
||||
if (!nonSemanticDebugPrintf) {
|
||||
nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
|
||||
|
@ -3457,6 +3687,11 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
|
|||
|
||||
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
|
||||
{
|
||||
#ifndef GLSLANG_WEB
|
||||
if (node->getQualifier().isSpirvLiteral())
|
||||
return; // Translated to a literal value, skip further processing
|
||||
#endif
|
||||
|
||||
int nextConst = 0;
|
||||
spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false);
|
||||
|
||||
|
@ -3705,12 +3940,14 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
|
|||
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
|
||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||
return builder.makeFloatType(16);
|
||||
case glslang::EbtInt64: return builder.makeIntType(64);
|
||||
case glslang::EbtInt64:
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||
case glslang::EbtUint64: return builder.makeUintType(64);
|
||||
builder.addCapability(spv::CapabilityInt64ImageEXT);
|
||||
return builder.makeIntType(64);
|
||||
case glslang::EbtUint64:
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
|
||||
builder.addCapability(spv::CapabilityFloat16ImageAMD);
|
||||
builder.addCapability(spv::CapabilityInt64ImageEXT);
|
||||
return builder.makeUintType(64);
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -3905,6 +4142,67 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
case glslang::EbtString:
|
||||
// no type used for OpString
|
||||
return 0;
|
||||
#ifndef GLSLANG_WEB
|
||||
case glslang::EbtSpirvType: {
|
||||
// GL_EXT_spirv_intrinsics
|
||||
const auto& spirvType = type.getSpirvType();
|
||||
const auto& spirvInst = spirvType.spirvInst;
|
||||
|
||||
std::vector<spv::Id> operands;
|
||||
for (const auto& typeParam : spirvType.typeParams) {
|
||||
// Constant expression
|
||||
if (typeParam.constant->isLiteral()) {
|
||||
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
|
||||
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
|
||||
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
|
||||
operands.push_back(literal);
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
|
||||
operands.push_back(literal);
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
|
||||
operands.push_back(literal);
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
|
||||
operands.push_back(literal);
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
|
||||
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
|
||||
unsigned literal = 0;
|
||||
char* literalPtr = reinterpret_cast<char*>(&literal);
|
||||
unsigned charCount = 0;
|
||||
char ch = 0;
|
||||
do {
|
||||
ch = *(str++);
|
||||
*(literalPtr++) = ch;
|
||||
++charCount;
|
||||
if (charCount == 4) {
|
||||
operands.push_back(literal);
|
||||
literalPtr = reinterpret_cast<char*>(&literal);
|
||||
charCount = 0;
|
||||
}
|
||||
} while (ch != 0);
|
||||
|
||||
// Partial literal is padded with 0
|
||||
if (charCount > 0) {
|
||||
for (; charCount < 4; ++charCount)
|
||||
*(literalPtr++) = 0;
|
||||
operands.push_back(literal);
|
||||
}
|
||||
} else
|
||||
assert(0); // Unexpected type
|
||||
} else
|
||||
operands.push_back(createSpvConstant(*typeParam.constant));
|
||||
}
|
||||
|
||||
if (spirvInst.set == "")
|
||||
spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
|
||||
else {
|
||||
spvType = builder.createBuiltinCall(
|
||||
spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
@ -4101,7 +4399,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||
{
|
||||
// Name and decorate the non-hidden members
|
||||
int offset = -1;
|
||||
int locationOffset = 0; // for use within the members of this struct
|
||||
bool memberLocationInvalid = type.isArrayOfArrays() ||
|
||||
(type.isArray() && (type.getQualifier().isArrayedIo(glslangIntermediate->getStage()) == false));
|
||||
for (int i = 0; i < (int)glslangMembers->size(); i++) {
|
||||
|
@ -4159,10 +4456,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||
if (!memberLocationInvalid && memberQualifier.hasLocation())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
|
||||
|
||||
if (qualifier.hasLocation()) // track for upcoming inheritance
|
||||
locationOffset += glslangIntermediate->computeTypeLocationSize(
|
||||
glslangMember, glslangIntermediate->getStage());
|
||||
|
||||
// component, XFB, others
|
||||
if (glslangMember.getQualifier().hasComponent())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
|
||||
|
@ -4218,6 +4511,38 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||
}
|
||||
|
||||
//
|
||||
// Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
|
||||
//
|
||||
if (glslangMember.getQualifier().hasSprivDecorate()) {
|
||||
const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
|
||||
|
||||
// Add spirv_decorate
|
||||
for (auto& decorate : spirvDecorate.decorates) {
|
||||
if (!decorate.second.empty()) {
|
||||
std::vector<unsigned> literals;
|
||||
TranslateLiterals(decorate.second, literals);
|
||||
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
|
||||
}
|
||||
else
|
||||
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
|
||||
}
|
||||
|
||||
// spirv_decorate_id not applied to members
|
||||
assert(spirvDecorate.decorateIds.empty());
|
||||
|
||||
// Add spirv_decorate_string
|
||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
||||
std::vector<const char*> strings;
|
||||
assert(!decorateString.second.empty());
|
||||
for (auto extraOperand : decorateString.second) {
|
||||
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
|
||||
strings.push_back(string);
|
||||
}
|
||||
builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -4236,6 +4561,8 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
|
|||
glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
|
||||
if (specNode != nullptr) {
|
||||
builder.clearAccessChain();
|
||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
|
||||
specNode->traverse(this);
|
||||
return accessChainLoad(specNode->getAsTyped()->getType());
|
||||
}
|
||||
|
@ -4271,19 +4598,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
|
|||
|
||||
// Need to convert to abstract types when necessary
|
||||
if (type.getBasicType() == glslang::EbtBool) {
|
||||
if (builder.isScalarType(nominalTypeId)) {
|
||||
// Conversion for bool
|
||||
spv::Id boolType = builder.makeBoolType();
|
||||
if (nominalTypeId != boolType)
|
||||
loadedId = builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
|
||||
} else if (builder.isVectorType(nominalTypeId)) {
|
||||
// Conversion for bvec
|
||||
int vecSize = builder.getNumTypeComponents(nominalTypeId);
|
||||
spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
|
||||
if (nominalTypeId != bvecType)
|
||||
loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
|
||||
makeSmearedConstant(builder.makeUintConstant(0), vecSize));
|
||||
}
|
||||
loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId);
|
||||
}
|
||||
|
||||
return loadedId;
|
||||
|
@ -4605,6 +4920,9 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
|
|||
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
|
||||
return paramType.getBasicType() == glslang::EbtBlock;
|
||||
return paramType.containsOpaque() || // sampler, etc.
|
||||
#ifndef GLSLANG_WEB
|
||||
paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
|
||||
#endif
|
||||
(paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
|
||||
}
|
||||
|
||||
|
@ -4998,7 +5316,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||
|
||||
int components = node->getType().getVectorSize();
|
||||
|
||||
if (node->getOp() == glslang::EOpTextureFetch) {
|
||||
if (node->getOp() == glslang::EOpImageLoad ||
|
||||
node->getOp() == glslang::EOpImageLoadLod ||
|
||||
node->getOp() == glslang::EOpTextureFetch ||
|
||||
node->getOp() == glslang::EOpTextureFetchOffset) {
|
||||
// These must produce 4 components, per SPIR-V spec. We'll add a conversion constructor if needed.
|
||||
// This will only happen through the HLSL path for operator[], so we do not have to handle e.g.
|
||||
// the EOpTexture/Proj/Lod/etc family. It would be harmless to do so, but would need more logic
|
||||
|
@ -5560,7 +5881,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
|
|||
++lValueCount;
|
||||
} else {
|
||||
// process r-value, which involves a copy for a type mismatch
|
||||
if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
|
||||
if (function->getParamType(a) != builder.getTypeId(rValues[rValueCount]) ||
|
||||
TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a))
|
||||
{
|
||||
spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg");
|
||||
|
@ -6891,13 +7212,17 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|||
case glslang::EOpImageAtomicAdd:
|
||||
case glslang::EOpAtomicCounterAdd:
|
||||
opCode = spv::OpAtomicIAdd;
|
||||
if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
|
||||
if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
|
||||
opCode = spv::OpAtomicFAddEXT;
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
|
||||
if (typeProxy == glslang::EbtFloat)
|
||||
if (typeProxy == glslang::EbtFloat16) {
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add);
|
||||
builder.addCapability(spv::CapabilityAtomicFloat16AddEXT);
|
||||
} else if (typeProxy == glslang::EbtFloat) {
|
||||
builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
|
||||
else
|
||||
} else {
|
||||
builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case glslang::EOpAtomicSubtract:
|
||||
|
@ -6907,14 +7232,38 @@ 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;
|
||||
if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
|
||||
opCode = spv::OpAtomicFMinEXT;
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
|
||||
if (typeProxy == glslang::EbtFloat16)
|
||||
builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
|
||||
else if (typeProxy == glslang::EbtFloat)
|
||||
builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
|
||||
else
|
||||
builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
|
||||
} else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
|
||||
opCode = spv::OpAtomicUMin;
|
||||
} else {
|
||||
opCode = spv::OpAtomicSMin;
|
||||
}
|
||||
break;
|
||||
case glslang::EOpAtomicMax:
|
||||
case glslang::EOpImageAtomicMax:
|
||||
case glslang::EOpAtomicCounterMax:
|
||||
opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
|
||||
spv::OpAtomicUMax : spv::OpAtomicSMax;
|
||||
if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
|
||||
opCode = spv::OpAtomicFMaxEXT;
|
||||
builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
|
||||
if (typeProxy == glslang::EbtFloat16)
|
||||
builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
|
||||
else if (typeProxy == glslang::EbtFloat)
|
||||
builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
|
||||
else
|
||||
builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
|
||||
} else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
|
||||
opCode = spv::OpAtomicUMax;
|
||||
} else {
|
||||
opCode = spv::OpAtomicSMax;
|
||||
}
|
||||
break;
|
||||
case glslang::EOpAtomicAnd:
|
||||
case glslang::EOpImageAtomicAnd:
|
||||
|
@ -7149,6 +7498,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
|
|||
break;
|
||||
case glslang::EOpReadFirstInvocation:
|
||||
opCode = spv::OpSubgroupFirstInvocationKHR;
|
||||
if (builder.isVectorType(typeId))
|
||||
return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
|
||||
break;
|
||||
case glslang::EOpBallot:
|
||||
{
|
||||
|
@ -7273,7 +7624,7 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
|
|||
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::OpSubgroupReadInvocationKHR || op == spv::OpSubgroupFirstInvocationKHR ||
|
||||
op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
|
||||
op == spv::OpGroupSMinNonUniformAMD ||
|
||||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
|
||||
|
@ -7302,6 +7653,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
|
|||
spvGroupOperands.push_back(scalar);
|
||||
spv::IdImmediate operand = { true, operands[1] };
|
||||
spvGroupOperands.push_back(operand);
|
||||
} else if (op == spv::OpSubgroupFirstInvocationKHR) {
|
||||
spvGroupOperands.push_back(scalar);
|
||||
} else if (op == spv::OpGroupBroadcast) {
|
||||
spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
|
||||
spvGroupOperands.push_back(scope);
|
||||
|
@ -7972,6 +8325,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
|
|||
case glslang::EOpTraceNV:
|
||||
builder.createNoResultOp(spv::OpTraceNV, operands);
|
||||
return 0;
|
||||
case glslang::EOpTraceRayMotionNV:
|
||||
builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
|
||||
builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
|
||||
builder.createNoResultOp(spv::OpTraceRayMotionNV, operands);
|
||||
return 0;
|
||||
case glslang::EOpTraceKHR:
|
||||
builder.createNoResultOp(spv::OpTraceRayKHR, operands);
|
||||
return 0;
|
||||
|
@ -8456,6 +8814,48 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||
builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
|
||||
spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
|
||||
}
|
||||
|
||||
//
|
||||
// Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
|
||||
//
|
||||
if (symbol->getType().getQualifier().hasSprivDecorate()) {
|
||||
const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
|
||||
|
||||
// Add spirv_decorate
|
||||
for (auto& decorate : spirvDecorate.decorates) {
|
||||
if (!decorate.second.empty()) {
|
||||
std::vector<unsigned> literals;
|
||||
TranslateLiterals(decorate.second, literals);
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
|
||||
}
|
||||
else
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
|
||||
}
|
||||
|
||||
// Add spirv_decorate_id
|
||||
for (auto& decorateId : spirvDecorate.decorateIds) {
|
||||
std::vector<spv::Id> operandIds;
|
||||
assert(!decorateId.second.empty());
|
||||
for (auto extraOperand : decorateId.second) {
|
||||
if (extraOperand->getQualifier().isSpecConstant())
|
||||
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||
else
|
||||
operandIds.push_back(createSpvConstant(*extraOperand));
|
||||
}
|
||||
builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
|
||||
}
|
||||
|
||||
// Add spirv_decorate_string
|
||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
||||
std::vector<const char*> strings;
|
||||
assert(!decorateString.second.empty());
|
||||
for (auto extraOperand : decorateString.second) {
|
||||
const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
|
||||
strings.push_back(string);
|
||||
}
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return id;
|
||||
|
|
|
@ -544,6 +544,9 @@ namespace spv {
|
|||
// Extended instructions: currently, assume everything is an ID.
|
||||
// TODO: add whatever data we need for exceptions to that
|
||||
if (opCode == spv::OpExtInst) {
|
||||
|
||||
idFn(asId(word)); // Instruction set is an ID that also needs to be mapped
|
||||
|
||||
word += 2; // instruction set, and instruction from set
|
||||
numOperands -= 2;
|
||||
|
||||
|
|
|
@ -743,6 +743,26 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
|
|||
}
|
||||
}
|
||||
|
||||
// Figure out the final resulting type of the access chain.
|
||||
Id Builder::getResultingAccessChainType() const
|
||||
{
|
||||
assert(accessChain.base != NoResult);
|
||||
Id typeId = getTypeId(accessChain.base);
|
||||
|
||||
assert(isPointerType(typeId));
|
||||
typeId = getContainedTypeId(typeId);
|
||||
|
||||
for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
|
||||
if (isStructType(typeId)) {
|
||||
assert(isConstantScalar(accessChain.indexChain[i]));
|
||||
typeId = getContainedTypeId(typeId, getConstantScalar(accessChain.indexChain[i]));
|
||||
} else
|
||||
typeId = getContainedTypeId(typeId, accessChain.indexChain[i]);
|
||||
}
|
||||
|
||||
return typeId;
|
||||
}
|
||||
|
||||
// Return the immediately contained type of a given composite type.
|
||||
Id Builder::getContainedTypeId(Id typeId) const
|
||||
{
|
||||
|
@ -1585,16 +1605,7 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
|
|||
Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
|
||||
{
|
||||
// Figure out the final resulting type.
|
||||
spv::Id typeId = getTypeId(base);
|
||||
assert(isPointerType(typeId) && offsets.size() > 0);
|
||||
typeId = getContainedTypeId(typeId);
|
||||
for (int i = 0; i < (int)offsets.size(); ++i) {
|
||||
if (isStructType(typeId)) {
|
||||
assert(isConstantScalar(offsets[i]));
|
||||
typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
|
||||
} else
|
||||
typeId = getContainedTypeId(typeId, offsets[i]);
|
||||
}
|
||||
Id typeId = getResultingAccessChainType();
|
||||
typeId = makePointer(storageClass, typeId);
|
||||
|
||||
// Make the instruction
|
||||
|
@ -2543,7 +2554,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
|||
int row = 0;
|
||||
int col = 0;
|
||||
|
||||
for (int arg = 0; arg < (int)sources.size(); ++arg) {
|
||||
for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) {
|
||||
Id argComp = sources[arg];
|
||||
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
|
||||
if (getNumComponents(sources[arg]) > 1) {
|
||||
|
@ -2555,6 +2566,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
|||
row = 0;
|
||||
col++;
|
||||
}
|
||||
if (col == numCols) {
|
||||
// If more components are provided than fit the matrix, discard the rest.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2790,28 +2805,59 @@ void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAcce
|
|||
assert(accessChain.isRValue == false);
|
||||
|
||||
transferAccessChainSwizzle(true);
|
||||
Id base = collapseAccessChain();
|
||||
addDecoration(base, nonUniform);
|
||||
|
||||
Id source = rvalue;
|
||||
// If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores.
|
||||
if (accessChain.swizzle.size() > 0 &&
|
||||
getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() &&
|
||||
accessChain.component == NoResult) {
|
||||
for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
|
||||
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i]));
|
||||
accessChain.instr = NoResult;
|
||||
|
||||
// dynamic component should be gone
|
||||
assert(accessChain.component == NoResult);
|
||||
Id base = collapseAccessChain();
|
||||
addDecoration(base, nonUniform);
|
||||
|
||||
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
||||
// extract and insert elements to perform writeMask and/or swizzle.
|
||||
if (accessChain.swizzle.size() > 0) {
|
||||
Id tempBaseId = createLoad(base, spv::NoPrecision);
|
||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||
accessChain.indexChain.pop_back();
|
||||
accessChain.instr = NoResult;
|
||||
|
||||
// dynamic component should be gone
|
||||
assert(accessChain.component == NoResult);
|
||||
|
||||
Id source = createCompositeExtract(rvalue, getContainedTypeId(getTypeId(rvalue)), i);
|
||||
|
||||
// take LSB of alignment
|
||||
alignment = alignment & ~(alignment & (alignment-1));
|
||||
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
|
||||
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
|
||||
}
|
||||
|
||||
createStore(source, base, memoryAccess, scope, alignment);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Id base = collapseAccessChain();
|
||||
addDecoration(base, nonUniform);
|
||||
|
||||
// take LSB of alignment
|
||||
alignment = alignment & ~(alignment & (alignment-1));
|
||||
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
|
||||
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
|
||||
Id source = rvalue;
|
||||
|
||||
// dynamic component should be gone
|
||||
assert(accessChain.component == NoResult);
|
||||
|
||||
// If swizzle still exists, it may be out-of-order, we must load the target vector,
|
||||
// extract and insert elements to perform writeMask and/or swizzle.
|
||||
if (accessChain.swizzle.size() > 0) {
|
||||
Id tempBaseId = createLoad(base, spv::NoPrecision);
|
||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||
}
|
||||
|
||||
// take LSB of alignment
|
||||
alignment = alignment & ~(alignment & (alignment-1));
|
||||
if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
|
||||
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
|
||||
}
|
||||
|
||||
createStore(source, base, memoryAccess, scope, alignment);
|
||||
}
|
||||
|
||||
createStore(source, base, memoryAccess, scope, alignment);
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
|
|
|
@ -202,6 +202,7 @@ public:
|
|||
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
|
||||
ImageFormat getImageTypeFormat(Id typeId) const
|
||||
{ return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
|
||||
Id getResultingAccessChainType() const;
|
||||
|
||||
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
||||
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
||||
|
|
|
@ -44,10 +44,8 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "SpvBuilder.h"
|
||||
|
||||
#include "spirv.hpp"
|
||||
#include "GlslangToSpv.h"
|
||||
#include "SpvBuilder.h"
|
||||
|
||||
namespace spv {
|
||||
#include "GLSL.std.450.h"
|
||||
#include "GLSL.ext.KHR.h"
|
||||
|
@ -113,8 +111,6 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case OpAccessChain:
|
||||
case OpPtrAccessChain:
|
||||
case OpCopyObject:
|
||||
break;
|
||||
case OpFConvert:
|
||||
|
@ -161,26 +157,43 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
|
|||
switch (inst.getImmediateOperand(1)) {
|
||||
case GLSLstd450Frexp:
|
||||
case GLSLstd450FrexpStruct:
|
||||
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeInt, 16))
|
||||
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeInt, 16))
|
||||
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
|
||||
break;
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeFloat, 16))
|
||||
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeFloat, 16))
|
||||
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OpAccessChain:
|
||||
case OpPtrAccessChain:
|
||||
if (isPointerType(typeId))
|
||||
break;
|
||||
if (basicTypeOp == OpTypeInt) {
|
||||
if (width == 16)
|
||||
addCapability(CapabilityInt16);
|
||||
else if (width == 8)
|
||||
addCapability(CapabilityInt8);
|
||||
}
|
||||
default:
|
||||
if (basicTypeOp == OpTypeFloat && width == 16)
|
||||
addCapability(CapabilityFloat16);
|
||||
if (basicTypeOp == OpTypeInt && width == 16)
|
||||
addCapability(CapabilityInt16);
|
||||
if (basicTypeOp == OpTypeInt && width == 8)
|
||||
addCapability(CapabilityInt8);
|
||||
if (basicTypeOp == OpTypeInt) {
|
||||
if (width == 16)
|
||||
addCapability(CapabilityInt16);
|
||||
else if (width == 8)
|
||||
addCapability(CapabilityInt8);
|
||||
else if (width == 64)
|
||||
addCapability(CapabilityInt64);
|
||||
} else if (basicTypeOp == OpTypeFloat) {
|
||||
if (width == 16)
|
||||
addCapability(CapabilityFloat16);
|
||||
else if (width == 64)
|
||||
addCapability(CapabilityFloat64);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,6 +188,7 @@ const char* ExecutionModeString(int mode)
|
|||
case ExecutionModeRoundingModeRTE: return "RoundingModeRTE";
|
||||
case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ";
|
||||
case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT";
|
||||
case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
|
||||
|
||||
case ExecutionModeOutputLinesNV: return "OutputLinesNV";
|
||||
case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV";
|
||||
|
@ -425,6 +426,7 @@ const char* BuiltInString(int builtIn)
|
|||
case BuiltInSMCountNV: return "SMCountNV";
|
||||
case BuiltInWarpIDNV: return "WarpIDNV";
|
||||
case BuiltInSMIDNV: return "SMIDNV";
|
||||
case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV";
|
||||
|
||||
default: return "Bad";
|
||||
}
|
||||
|
@ -915,6 +917,7 @@ const char* CapabilityString(int info)
|
|||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
|
||||
case CapabilityRayTracingNV: return "RayTracingNV";
|
||||
case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
|
||||
case CapabilityRayTracingKHR: return "RayTracingKHR";
|
||||
case CapabilityRayQueryKHR: return "RayQueryKHR";
|
||||
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
|
||||
|
@ -965,8 +968,12 @@ const char* CapabilityString(int info)
|
|||
|
||||
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
|
||||
|
||||
case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT";
|
||||
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
|
||||
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
|
||||
case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT";
|
||||
case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT";
|
||||
case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT";
|
||||
|
||||
case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
|
||||
case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
|
||||
|
@ -1351,6 +1358,8 @@ const char* OpcodeString(int op)
|
|||
case 4432: return "OpSubgroupReadInvocationKHR";
|
||||
|
||||
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
|
||||
case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
|
||||
case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
|
||||
|
||||
case 5000: return "OpGroupIAddNonUniformAMD";
|
||||
case 5001: return "OpGroupFAddNonUniformAMD";
|
||||
|
@ -1375,6 +1384,7 @@ const char* OpcodeString(int op)
|
|||
case OpTerminateRayNV: return "OpTerminateRayNV";
|
||||
case OpTerminateRayKHR: return "OpTerminateRayKHR";
|
||||
case OpTraceNV: return "OpTraceNV";
|
||||
case OpTraceRayMotionNV: return "OpTraceRayMotionNV";
|
||||
case OpTraceRayKHR: return "OpTraceRayKHR";
|
||||
case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
|
||||
case OpExecuteCallableNV: return "OpExecuteCallableNV";
|
||||
|
@ -2341,6 +2351,16 @@ void Parameterize()
|
|||
InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||
InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'");
|
||||
|
||||
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'");
|
||||
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'");
|
||||
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||
InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'");
|
||||
|
||||
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'");
|
||||
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'");
|
||||
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||
InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'");
|
||||
|
||||
InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'");
|
||||
InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'");
|
||||
InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'");
|
||||
|
@ -2795,6 +2815,20 @@ void Parameterize()
|
|||
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
|
||||
InstructionDesc[OpTraceNV].setResultAndType(false, false);
|
||||
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'");
|
||||
InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'");
|
||||
InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false);
|
||||
|
||||
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'");
|
||||
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
|
||||
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
|
||||
|
|
|
@ -150,6 +150,7 @@ enum ExecutionMode {
|
|||
ExecutionModeSubgroupsPerWorkgroupId = 37,
|
||||
ExecutionModeLocalSizeId = 38,
|
||||
ExecutionModeLocalSizeHintId = 39,
|
||||
ExecutionModeSubgroupUniformControlFlowKHR = 4421,
|
||||
ExecutionModePostDepthCoverage = 4446,
|
||||
ExecutionModeDenormPreserve = 4459,
|
||||
ExecutionModeDenormFlushToZero = 4460,
|
||||
|
@ -409,6 +410,7 @@ enum FPRoundingMode {
|
|||
enum LinkageType {
|
||||
LinkageTypeExport = 0,
|
||||
LinkageTypeImport = 1,
|
||||
LinkageTypeLinkOnceODR = 2,
|
||||
LinkageTypeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -650,6 +652,7 @@ enum BuiltIn {
|
|||
BuiltInHitTNV = 5332,
|
||||
BuiltInHitKindKHR = 5333,
|
||||
BuiltInHitKindNV = 5333,
|
||||
BuiltInCurrentRayTimeNV = 5334,
|
||||
BuiltInIncomingRayFlagsKHR = 5351,
|
||||
BuiltInIncomingRayFlagsNV = 5351,
|
||||
BuiltInRayGeometryIndexKHR = 5352,
|
||||
|
@ -986,6 +989,7 @@ enum Capability {
|
|||
CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
|
||||
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||
CapabilityRayTracingNV = 5340,
|
||||
CapabilityRayTracingMotionBlurNV = 5341,
|
||||
CapabilityVulkanMemoryModel = 5345,
|
||||
CapabilityVulkanMemoryModelKHR = 5345,
|
||||
CapabilityVulkanMemoryModelDeviceScope = 5346,
|
||||
|
@ -1010,8 +1014,12 @@ enum Capability {
|
|||
CapabilityFunctionPointersINTEL = 5603,
|
||||
CapabilityIndirectReferencesINTEL = 5604,
|
||||
CapabilityAsmINTEL = 5606,
|
||||
CapabilityAtomicFloat32MinMaxEXT = 5612,
|
||||
CapabilityAtomicFloat64MinMaxEXT = 5613,
|
||||
CapabilityAtomicFloat16MinMaxEXT = 5616,
|
||||
CapabilityVectorComputeINTEL = 5617,
|
||||
CapabilityVectorAnyINTEL = 5619,
|
||||
CapabilityExpectAssumeKHR = 5629,
|
||||
CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
|
||||
CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
|
||||
CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
|
||||
|
@ -1035,6 +1043,7 @@ enum Capability {
|
|||
CapabilityAtomicFloat32AddEXT = 6033,
|
||||
CapabilityAtomicFloat64AddEXT = 6034,
|
||||
CapabilityLongConstantCompositeINTEL = 6089,
|
||||
CapabilityAtomicFloat16AddEXT = 6095,
|
||||
CapabilityMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -1102,15 +1111,15 @@ enum FragmentShadingRateMask {
|
|||
};
|
||||
|
||||
enum FPDenormMode {
|
||||
FPDenormModePreserve = 0,
|
||||
FPDenormModeFlushToZero = 1,
|
||||
FPDenormModeMax = 0x7fffffff,
|
||||
FPDenormModePreserve = 0,
|
||||
FPDenormModeFlushToZero = 1,
|
||||
FPDenormModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum FPOperationMode {
|
||||
FPOperationModeIEEE = 0,
|
||||
FPOperationModeALT = 1,
|
||||
FPOperationModeMax = 0x7fffffff,
|
||||
FPOperationModeIEEE = 0,
|
||||
FPOperationModeALT = 1,
|
||||
FPOperationModeMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum Op {
|
||||
|
@ -1496,6 +1505,8 @@ enum Op {
|
|||
OpIgnoreIntersectionNV = 5335,
|
||||
OpTerminateRayNV = 5336,
|
||||
OpTraceNV = 5337,
|
||||
OpTraceMotionNV = 5338,
|
||||
OpTraceRayMotionNV = 5339,
|
||||
OpTypeAccelerationStructureKHR = 5341,
|
||||
OpTypeAccelerationStructureNV = 5341,
|
||||
OpExecuteCallableNV = 5344,
|
||||
|
@ -1537,6 +1548,10 @@ enum Op {
|
|||
OpAsmTargetINTEL = 5609,
|
||||
OpAsmINTEL = 5610,
|
||||
OpAsmCallINTEL = 5611,
|
||||
OpAtomicFMinEXT = 5614,
|
||||
OpAtomicFMaxEXT = 5615,
|
||||
OpAssumeTrueKHR = 5630,
|
||||
OpExpectKHR = 5631,
|
||||
OpDecorateString = 5632,
|
||||
OpDecorateStringGOOGLE = 5632,
|
||||
OpMemberDecorateString = 5633,
|
||||
|
@ -2079,6 +2094,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTraceNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
|
||||
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
|
||||
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
|
||||
|
@ -2119,6 +2136,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
|
|||
case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAsmINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break;
|
||||
case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break;
|
||||
case OpExpectKHR: *hasResult = true; *hasResultType = true; break;
|
||||
case OpDecorateString: *hasResult = false; *hasResultType = false; break;
|
||||
case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
|
||||
case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
|
||||
|
|
|
@ -31,6 +31,22 @@
|
|||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
find_package(PythonInterp 3 REQUIRED)
|
||||
|
||||
set(GLSLANG_INTRINSIC_H "${GLSLANG_GENERATED_INCLUDEDIR}/glslang/glsl_intrinsic_header.h")
|
||||
set(GLSLANG_INTRINSIC_PY "${CMAKE_CURRENT_SOURCE_DIR}/../gen_extension_headers.py")
|
||||
set(GLSLANG_INTRINSIC_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../glslang/ExtensionHeaders")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${GLSLANG_INTRINSIC_H}
|
||||
COMMAND ${PYTHON_EXECUTABLE} "${GLSLANG_INTRINSIC_PY}"
|
||||
"-i" ${GLSLANG_INTRINSIC_HEADER_DIR}
|
||||
"-o" ${GLSLANG_INTRINSIC_H}
|
||||
DEPENDS ${GLSLANG_INTRINSIC_PY}
|
||||
COMMENT "Generating ${GLSLANG_INTRINSIC_H}")
|
||||
|
||||
#add_custom_target(glslangValidator DEPENDS ${GLSLANG_INTRINSIC_H})
|
||||
|
||||
add_library(glslang-default-resource-limits
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resource_limits_c.cpp)
|
||||
|
@ -41,7 +57,7 @@ target_include_directories(glslang-default-resource-limits
|
|||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
|
||||
|
||||
set(SOURCES StandAlone.cpp DirStackFileIncluder.h)
|
||||
set(SOURCES StandAlone.cpp DirStackFileIncluder.h ${GLSLANG_INTRINSIC_H})
|
||||
|
||||
add_executable(glslangValidator ${SOURCES})
|
||||
set_property(TARGET glslangValidator PROPERTY FOLDER tools)
|
||||
|
@ -62,7 +78,7 @@ elseif(UNIX)
|
|||
if(NOT ANDROID)
|
||||
set(LIBRARIES ${LIBRARIES} pthread)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
target_link_libraries(glslangValidator ${LIBRARIES})
|
||||
target_include_directories(glslangValidator PUBLIC
|
||||
|
@ -73,7 +89,7 @@ if(ENABLE_OPT)
|
|||
target_include_directories(glslangValidator
|
||||
PRIVATE ${spirv-tools_SOURCE_DIR}/include
|
||||
)
|
||||
endif(ENABLE_OPT)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SPVREMAPPER)
|
||||
set(REMAPPER_SOURCES spirv-remap.cpp)
|
||||
|
@ -85,7 +101,7 @@ endif()
|
|||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES})
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GLSLANG_INSTALL)
|
||||
install(TARGETS glslangValidator EXPORT glslangValidatorTargets
|
||||
|
@ -108,4 +124,4 @@ if(ENABLE_GLSLANG_INSTALL)
|
|||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(EXPORT glslang-default-resource-limitsTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
||||
endif()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||
// Copyright (C) 2016-2020 Google, Inc.
|
||||
// Modifications Copyright(C) 2021 Advanced Micro Devices, Inc.All rights reserved.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -65,6 +66,8 @@
|
|||
// Build-time generated includes
|
||||
#include "glslang/build_info.h"
|
||||
|
||||
#include "glslang/glsl_intrinsic_header.h"
|
||||
|
||||
extern "C" {
|
||||
GLSLANG_EXPORT void ShOutputHtml();
|
||||
}
|
||||
|
@ -263,6 +266,7 @@ protected:
|
|||
|
||||
// Track the user's #define and #undef from the command line.
|
||||
TPreamble UserPreamble;
|
||||
std::string PreambleString;
|
||||
|
||||
//
|
||||
// Create the default name for saving a binary if -o is not provided.
|
||||
|
@ -347,13 +351,13 @@ 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])) {
|
||||
do {
|
||||
const int baseNum = atoi(argv[arg++]);
|
||||
const int setNum = atoi(argv[arg++]);
|
||||
perSetBase[setNum] = baseNum;
|
||||
}
|
||||
} while ((argc - arg) >= 2 && isdigit(argv[arg + 0][0]) && isdigit(argv[arg + 1][0]));
|
||||
} else {
|
||||
// Parse single binding base
|
||||
singleBase = atoi(argv[arg++]);
|
||||
|
@ -1204,8 +1208,17 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
"Use '-e <name>'.\n");
|
||||
shader->setSourceEntryPoint(sourceEntryPointName);
|
||||
}
|
||||
|
||||
std::string intrinsicString = getIntrinsic(compUnit.text, compUnit.count);
|
||||
|
||||
PreambleString = "";
|
||||
if (UserPreamble.isSet())
|
||||
shader->setPreamble(UserPreamble.get());
|
||||
PreambleString.append(UserPreamble.get());
|
||||
|
||||
if (!intrinsicString.empty())
|
||||
PreambleString.append(intrinsicString);
|
||||
|
||||
shader->setPreamble(PreambleString.c_str());
|
||||
shader->addProcesses(Processes);
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2020 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import glob
|
||||
import sys
|
||||
import os
|
||||
|
||||
def generate_main(glsl_files, output_header_file):
|
||||
# Write commit ID to output header file
|
||||
with open(output_header_file, "w") as header_file:
|
||||
# Copyright Notice
|
||||
header_string = '/***************************************************************************\n'
|
||||
header_string += ' *\n'
|
||||
header_string += ' * Copyright (c) 2015-2021 The Khronos Group Inc.\n'
|
||||
header_string += ' * Copyright (c) 2015-2021 Valve Corporation\n'
|
||||
header_string += ' * Copyright (c) 2015-2021 LunarG, Inc.\n'
|
||||
header_string += ' * Copyright (c) 2015-2021 Google Inc.\n'
|
||||
header_string += ' * Copyright (c) 2021 Advanced Micro Devices, Inc.All rights reserved.\n'
|
||||
header_string += ' *\n'
|
||||
header_string += ' ****************************************************************************/\n'
|
||||
header_string += '#pragma once\n\n'
|
||||
header_string += '#ifndef _INTRINSIC_EXTENSION_HEADER_H_\n'
|
||||
header_string += '#define _INTRINSIC_EXTENSION_HEADER_H_\n\n'
|
||||
header_file.write(header_string)
|
||||
|
||||
symbol_name_list = []
|
||||
|
||||
for i in glsl_files:
|
||||
glsl_contents = open(i,"r").read()
|
||||
|
||||
filename = os.path.basename(i)
|
||||
symbol_name = filename.split(".")[0]
|
||||
symbol_name_list.append(symbol_name)
|
||||
header_name = symbol_name + ".h"
|
||||
header_str = 'std::string %s_GLSL = R"(\n%s\n)";\n' % (symbol_name, glsl_contents)
|
||||
header_str += '\n'
|
||||
header_file.write(header_str)
|
||||
|
||||
contents = ''
|
||||
contents += '\n'
|
||||
contents += 'std::string getIntrinsic(const char* const* shaders, int n) {\n'
|
||||
contents += '\tstd::string shaderString = "";\n';
|
||||
|
||||
contents += '\tfor (int i = 0; i < n; i++) {\n'
|
||||
|
||||
for symbol_name in symbol_name_list:
|
||||
contents += '\t\tif (strstr(shaders[i], "%s") != NULL) {\n' % (symbol_name)
|
||||
contents += '\t\t shaderString.append(%s_GLSL);\n' % (symbol_name)
|
||||
contents += '\t\t}\n'
|
||||
|
||||
contents += '\t}\n'
|
||||
contents += '\treturn shaderString;\n';
|
||||
contents += '}\n'
|
||||
|
||||
contents += '\n#endif\n'
|
||||
header_file.write(contents)
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
raise Exception("Invalid number of arguments")
|
||||
|
||||
i = 0
|
||||
while i < len(sys.argv):
|
||||
opt = sys.argv[i]
|
||||
i = i + 1
|
||||
|
||||
if opt == "-i" or opt == "-o":
|
||||
if i == len(sys.argv):
|
||||
raise Exception("Expected path after {}".format(opt))
|
||||
val = sys.argv[i]
|
||||
i = i + 1
|
||||
if (opt == "-i"):
|
||||
input_dir = val
|
||||
elif (opt == "-o"):
|
||||
output_file = val
|
||||
else:
|
||||
raise Exception("Unknown flag {}".format(opt))
|
||||
|
||||
glsl_files = glob.glob(input_dir + '/*.glsl')
|
||||
|
||||
# Generate main header
|
||||
generate_main(glsl_files, output_file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -35,14 +35,14 @@ if(WIN32)
|
|||
add_subdirectory(OSDependent/Windows)
|
||||
elseif(UNIX OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
|
||||
add_subdirectory(OSDependent/Unix)
|
||||
else(WIN32)
|
||||
else()
|
||||
message("unknown platform")
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
if(EMSCRIPTEN OR ENABLE_GLSLANG_JS)
|
||||
# May be enabled on non-Emscripten builds for binary-size testing.
|
||||
add_subdirectory(OSDependent/Web)
|
||||
endif(EMSCRIPTEN OR ENABLE_GLSLANG_JS)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# GenericCodeGen
|
||||
|
@ -73,6 +73,7 @@ set(MACHINEINDEPENDENT_SOURCES
|
|||
MachineIndependent/RemoveTree.cpp
|
||||
MachineIndependent/Scan.cpp
|
||||
MachineIndependent/ShaderLang.cpp
|
||||
MachineIndependent/SpirvIntrinsics.cpp
|
||||
MachineIndependent/SymbolTable.cpp
|
||||
MachineIndependent/Versions.cpp
|
||||
MachineIndependent/intermOut.cpp
|
||||
|
@ -128,7 +129,7 @@ if(ENABLE_HLSL)
|
|||
HLSL/hlslTokenStream.h
|
||||
HLSL/hlslGrammar.h
|
||||
HLSL/hlslParseables.h)
|
||||
endif(ENABLE_HLSL)
|
||||
endif()
|
||||
|
||||
add_library(MachineIndependent STATIC ${MACHINEINDEPENDENT_SOURCES} ${MACHINEINDEPENDENT_HEADERS})
|
||||
set_property(TARGET MachineIndependent PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
@ -160,6 +161,7 @@ set(GLSLANG_HEADERS
|
|||
Include/PoolAlloc.h
|
||||
Include/ResourceLimits.h
|
||||
Include/ShHandle.h
|
||||
Include/SpirvIntrinsics.h
|
||||
Include/Types.h)
|
||||
|
||||
add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${GLSLANG_SOURCES} ${GLSLANG_HEADERS})
|
||||
|
@ -192,7 +194,7 @@ if(WIN32)
|
|||
source_group("MachineIndependent\\Preprocessor" REGULAR_EXPRESSION "MachineIndependent/preprocessor/*")
|
||||
source_group("HLSL" REGULAR_EXPRESSION "HLSL/*")
|
||||
source_group("CInterface" REGULAR_EXPRESSION "CInterface/*")
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# install
|
||||
|
@ -223,4 +225,4 @@ if(ENABLE_GLSLANG_INSTALL)
|
|||
|
||||
install(FILES ${GLSLANG_BUILD_INFO_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang)
|
||||
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||
// Copyright (C) 2016-2020 Google, Inc.
|
||||
// Modifications Copyright(C) 2021 Advanced Micro Devices, Inc.All rights reserved.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#extension GL_EXT_spirv_intrinsics : enable
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
|
||||
uvec2 clockRealtime2x32EXT(void) {
|
||||
spirv_instruction (extensions = ["SPV_KHR_shader_clock"], capabilities = [5055], id = 5056)
|
||||
uvec2 clockRealtime2x32EXT_internal(uint scope);
|
||||
|
||||
return clockRealtime2x32EXT_internal(1 /*Device scope*/);
|
||||
}
|
||||
|
||||
uint64_t clockRealtimeEXT(void) {
|
||||
spirv_instruction (extensions = ["SPV_KHR_shader_clock"], capabilities = [5055], id = 5056)
|
||||
uint64_t clockRealtimeEXT_internal(uint scope);
|
||||
|
||||
return clockRealtimeEXT_internal(1 /*Device scope*/);
|
||||
}
|
|
@ -3244,7 +3244,7 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
|
|||
}
|
||||
|
||||
// hook it up
|
||||
node = parseContext.handleFunctionCall(arguments->getLoc(), constructorFunction, arguments);
|
||||
node = parseContext.handleFunctionCall(token.loc, constructorFunction, arguments);
|
||||
|
||||
return node != nullptr;
|
||||
}
|
||||
|
|
|
@ -4017,12 +4017,12 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
|||
txsample->getSequence().push_back(txcombine);
|
||||
txsample->getSequence().push_back(argCoord);
|
||||
|
||||
if (argBias != nullptr)
|
||||
txsample->getSequence().push_back(argBias);
|
||||
|
||||
if (argOffset != nullptr)
|
||||
txsample->getSequence().push_back(argOffset);
|
||||
|
||||
if (argBias != nullptr)
|
||||
txsample->getSequence().push_back(argBias);
|
||||
|
||||
node = convertReturn(txsample, sampler);
|
||||
|
||||
break;
|
||||
|
@ -6689,12 +6689,6 @@ void HlslParseContext::globalQualifierFix(const TSourceLoc&, TQualifier& qualifi
|
|||
|
||||
//
|
||||
// Merge characteristics of the 'src' qualifier into the 'dst'.
|
||||
// If there is duplication, issue error messages, unless 'force'
|
||||
// is specified, which means to just override default settings.
|
||||
//
|
||||
// Also, when force is false, it will be assumed that 'src' follows
|
||||
// 'dst', for the purpose of error checking order for versions
|
||||
// that require specific orderings of qualifiers.
|
||||
//
|
||||
void HlslParseContext::mergeQualifiers(TQualifier& dst, const TQualifier& src)
|
||||
{
|
||||
|
@ -6712,8 +6706,7 @@ void HlslParseContext::mergeQualifiers(TQualifier& dst, const TQualifier& src)
|
|||
mergeObjectLayoutQualifiers(dst, src, false);
|
||||
|
||||
// individual qualifiers
|
||||
bool repeated = false;
|
||||
#define MERGE_SINGLETON(field) repeated |= dst.field && src.field; dst.field |= src.field;
|
||||
#define MERGE_SINGLETON(field) dst.field |= src.field;
|
||||
MERGE_SINGLETON(invariant);
|
||||
MERGE_SINGLETON(noContraction);
|
||||
MERGE_SINGLETON(centroid);
|
||||
|
|
|
@ -665,8 +665,8 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
|||
{ "Sample", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangPS, true },
|
||||
{ "Sample", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangPS, true },
|
||||
|
||||
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangPS, true },
|
||||
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangPS, true },
|
||||
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,F", EShLangPS, true },
|
||||
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,F,I", EShLangPS, true },
|
||||
|
||||
// TODO: FXC accepts int/uint samplers here. unclear what that means.
|
||||
{ "SampleCmp", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,", EShLangPS, true },
|
||||
|
|
|
@ -65,6 +65,10 @@ enum TBasicType {
|
|||
EbtAccStruct,
|
||||
EbtReference,
|
||||
EbtRayQuery,
|
||||
#ifndef GLSLANG_WEB
|
||||
// SPIR-V type defined by spirv_type
|
||||
EbtSpirvType,
|
||||
#endif
|
||||
|
||||
// HLSL types that live only temporarily.
|
||||
EbtString,
|
||||
|
@ -91,6 +95,9 @@ enum TStorageQualifier {
|
|||
EvqUniform, // read only, shared with app
|
||||
EvqBuffer, // read/write, shared with app
|
||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||
#ifndef GLSLANG_WEB
|
||||
EvqSpirvStorageClass, // spirv_storage_class
|
||||
#endif
|
||||
|
||||
EvqPayload,
|
||||
EvqPayloadIn,
|
||||
|
@ -263,6 +270,7 @@ enum TBuiltInVariable {
|
|||
EbvWorldToObject,
|
||||
EbvWorldToObject3x4,
|
||||
EbvIncomingRayFlags,
|
||||
EbvCurrentRayTimeNV,
|
||||
// barycentrics
|
||||
EbvBaryCoordNV,
|
||||
EbvBaryCoordNoPerspNV,
|
||||
|
@ -321,6 +329,9 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
|
|||
case EvqGlobal: return "global"; break;
|
||||
case EvqConst: return "const"; break;
|
||||
case EvqConstReadOnly: return "const (read only)"; break;
|
||||
#ifndef GLSLANG_WEB
|
||||
case EvqSpirvStorageClass: return "spirv_storage_class"; break;
|
||||
#endif
|
||||
case EvqVaryingIn: return "in"; break;
|
||||
case EvqVaryingOut: return "out"; break;
|
||||
case EvqUniform: return "uniform"; break;
|
||||
|
@ -465,6 +476,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
|
||||
case EbvObjectToWorld: return "ObjectToWorldNV";
|
||||
case EbvWorldToObject: return "WorldToObjectNV";
|
||||
case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
|
||||
|
||||
case EbvBaryCoordNV: return "BaryCoordNV";
|
||||
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||
|
|
|
@ -61,7 +61,7 @@ std::string to_string(const T& val) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API
|
||||
#include <basetsd.h>
|
||||
#ifndef snprintf
|
||||
#define snprintf sprintf_s
|
||||
|
@ -194,6 +194,10 @@ template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_t
|
|||
class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
|
||||
};
|
||||
|
||||
template <class K, class CMP = std::less<K> >
|
||||
class TSet : public std::set<K, CMP, pool_allocator<K> > {
|
||||
};
|
||||
|
||||
//
|
||||
// Persistent string memory. Should only be used for strings that survive
|
||||
// across compiles/links.
|
||||
|
@ -209,7 +213,7 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
|
|||
//
|
||||
// Create a TString object from an integer.
|
||||
//
|
||||
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
|
||||
#if defined _MSC_VER || MINGW_HAS_SECURE_API
|
||||
inline const TString String(const int i, const int base = 10)
|
||||
{
|
||||
char text[16]; // 32 bit ints are at most 10 digits in base 10
|
||||
|
|
|
@ -306,6 +306,8 @@ public:
|
|||
|
||||
TPoolAllocator& getAllocator() const { return allocator; }
|
||||
|
||||
pool_allocator select_on_container_copy_construction() const { return pool_allocator{}; }
|
||||
|
||||
protected:
|
||||
pool_allocator& operator=(const pool_allocator&) { return *this; }
|
||||
TPoolAllocator& allocator;
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
//
|
||||
// Copyright(C) 2021 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
|
||||
//
|
||||
// GL_EXT_spirv_intrinsics
|
||||
//
|
||||
#include "Common.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TIntermTyped;
|
||||
class TIntermConstantUnion;
|
||||
class TType;
|
||||
|
||||
// SPIR-V requirements
|
||||
struct TSpirvRequirement {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
// capability = [..]
|
||||
TSet<TString> extensions;
|
||||
// extension = [..]
|
||||
TSet<int> capabilities;
|
||||
};
|
||||
|
||||
// SPIR-V execution modes
|
||||
struct TSpirvExecutionMode {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
// spirv_execution_mode
|
||||
TMap<int, TVector<const TIntermConstantUnion*>> modes;
|
||||
// spirv_execution_mode_id
|
||||
TMap<int, TVector<const TIntermTyped*> > modeIds;
|
||||
};
|
||||
|
||||
// SPIR-V decorations
|
||||
struct TSpirvDecorate {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
// spirv_decorate
|
||||
TMap<int, TVector<const TIntermConstantUnion*> > decorates;
|
||||
// spirv_decorate_id
|
||||
TMap<int, TVector<const TIntermTyped*>> decorateIds;
|
||||
// spirv_decorate_string
|
||||
TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
|
||||
};
|
||||
|
||||
// SPIR-V instruction
|
||||
struct TSpirvInstruction {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TSpirvInstruction() { set = ""; id = -1; }
|
||||
|
||||
bool operator==(const TSpirvInstruction& rhs) const { return set == rhs.set && id == rhs.id; }
|
||||
bool operator!=(const TSpirvInstruction& rhs) const { return !operator==(rhs); }
|
||||
|
||||
// spirv_instruction
|
||||
TString set;
|
||||
int id;
|
||||
};
|
||||
|
||||
// SPIR-V type parameter
|
||||
struct TSpirvTypeParameter {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TSpirvTypeParameter(const TIntermConstantUnion* arg) { constant = arg; }
|
||||
|
||||
bool operator==(const TSpirvTypeParameter& rhs) const { return constant == rhs.constant; }
|
||||
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
|
||||
|
||||
const TIntermConstantUnion* constant;
|
||||
};
|
||||
|
||||
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
|
||||
|
||||
// SPIR-V type
|
||||
struct TSpirvType {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
bool operator==(const TSpirvType& rhs) const
|
||||
{
|
||||
return spirvInst == rhs.spirvInst && typeParams == rhs.typeParams;
|
||||
}
|
||||
bool operator!=(const TSpirvType& rhs) const { return !operator==(rhs); }
|
||||
|
||||
// spirv_type
|
||||
TSpirvInstruction spirvInst;
|
||||
TSpirvTypeParameters typeParams;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // GLSLANG_WEB
|
|
@ -44,11 +44,14 @@
|
|||
#include "../Include/BaseTypes.h"
|
||||
#include "../Public/ShaderLang.h"
|
||||
#include "arrays.h"
|
||||
#include "SpirvIntrinsics.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TIntermAggregate;
|
||||
|
||||
const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
|
||||
|
||||
const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed
|
||||
|
@ -487,7 +490,6 @@ enum TShaderInterface
|
|||
EsiCount
|
||||
};
|
||||
|
||||
|
||||
class TQualifier {
|
||||
public:
|
||||
static const int layoutNotSet = -1;
|
||||
|
@ -501,6 +503,8 @@ public:
|
|||
#ifndef GLSLANG_WEB
|
||||
noContraction = false;
|
||||
nullInit = false;
|
||||
spirvByReference = false;
|
||||
spirvLiteral = false;
|
||||
#endif
|
||||
defaultBlock = false;
|
||||
}
|
||||
|
@ -518,6 +522,12 @@ public:
|
|||
nullInit = false;
|
||||
defaultBlock = false;
|
||||
clearLayout();
|
||||
#ifndef GLSLANG_WEB
|
||||
spirvStorageClass = -1;
|
||||
spirvDecorate = nullptr;
|
||||
spirvByReference = false;
|
||||
spirvLiteral = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void clearInterstage()
|
||||
|
@ -596,6 +606,10 @@ public:
|
|||
bool isPervertexNV() const { return false; }
|
||||
void setNullInit() { }
|
||||
bool isNullInit() const { return false; }
|
||||
void setSpirvByReference() { }
|
||||
bool isSpirvByReference() { return false; }
|
||||
void setSpirvLiteral() { }
|
||||
bool isSpirvLiteral() { return false; }
|
||||
#else
|
||||
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
|
||||
bool nopersp : 1;
|
||||
|
@ -618,6 +632,8 @@ public:
|
|||
bool shadercallcoherent : 1;
|
||||
bool nonprivate : 1;
|
||||
bool nullInit : 1;
|
||||
bool spirvByReference : 1;
|
||||
bool spirvLiteral : 1;
|
||||
bool isWriteOnly() const { return writeonly; }
|
||||
bool isReadOnly() const { return readonly; }
|
||||
bool isRestrict() const { return restrict; }
|
||||
|
@ -655,6 +671,10 @@ public:
|
|||
bool isPervertexNV() const { return pervertexNV; }
|
||||
void setNullInit() { nullInit = true; }
|
||||
bool isNullInit() const { return nullInit; }
|
||||
void setSpirvByReference() { spirvByReference = true; }
|
||||
bool isSpirvByReference() const { return spirvByReference; }
|
||||
void setSpirvLiteral() { spirvLiteral = true; }
|
||||
bool isSpirvLiteral() const { return spirvLiteral; }
|
||||
#endif
|
||||
|
||||
bool isPipeInput() const
|
||||
|
@ -721,6 +741,16 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool isUniform() const
|
||||
{
|
||||
switch (storage) {
|
||||
case EvqUniform:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isIo() const
|
||||
{
|
||||
switch (storage) {
|
||||
|
@ -948,6 +978,10 @@ public:
|
|||
bool layoutViewportRelative;
|
||||
int layoutSecondaryViewportRelativeOffset;
|
||||
bool layoutShaderRecord;
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
int spirvStorageClass;
|
||||
TSpirvDecorate* spirvDecorate;
|
||||
#endif
|
||||
|
||||
bool hasUniformLayout() const
|
||||
|
@ -1079,6 +1113,15 @@ public:
|
|||
{
|
||||
return nonUniform;
|
||||
}
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
|
||||
void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
|
||||
void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
|
||||
void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
|
||||
const TSpirvDecorate& getSpirvDecorate() const { assert(spirvDecorate); return *spirvDecorate; }
|
||||
TSpirvDecorate& getSpirvDecorate() { assert(spirvDecorate); return *spirvDecorate; }
|
||||
TString getSpirvDecorateQualifierString() const;
|
||||
#endif
|
||||
bool hasSpecConstantId() const
|
||||
{
|
||||
|
@ -1423,6 +1466,10 @@ public:
|
|||
const TType* userDef;
|
||||
TSourceLoc loc;
|
||||
TArraySizes* typeParameters;
|
||||
#ifndef GLSLANG_WEB
|
||||
// SPIR-V type defined by spirv_type directive
|
||||
TSpirvType* spirvType;
|
||||
#endif
|
||||
|
||||
#ifdef GLSLANG_WEB
|
||||
bool isCoopmat() const { return false; }
|
||||
|
@ -1441,6 +1488,9 @@ public:
|
|||
loc = l;
|
||||
typeParameters = nullptr;
|
||||
coopmat = false;
|
||||
#ifndef GLSLANG_WEB
|
||||
spirvType = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void initQualifiers(bool global = false)
|
||||
|
@ -1477,6 +1527,11 @@ public:
|
|||
return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// GL_EXT_spirv_intrinsics
|
||||
void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr);
|
||||
#endif
|
||||
|
||||
// "Image" is a superset of "Subpass"
|
||||
bool isImage() const { return basicType == EbtSampler && sampler.isImage(); }
|
||||
bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); }
|
||||
|
@ -1494,6 +1549,9 @@ public:
|
|||
bool isVector = false) :
|
||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
|
||||
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(nullptr)
|
||||
#endif
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.clear();
|
||||
|
@ -1505,6 +1563,9 @@ public:
|
|||
bool isVector = false) :
|
||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
|
||||
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(nullptr)
|
||||
#endif
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.clear();
|
||||
|
@ -1518,6 +1579,9 @@ public:
|
|||
basicType(p.basicType),
|
||||
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat),
|
||||
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(p.spirvType)
|
||||
#endif
|
||||
{
|
||||
if (basicType == EbtSampler)
|
||||
sampler = p.sampler;
|
||||
|
@ -1552,6 +1616,9 @@ public:
|
|||
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
|
||||
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
|
||||
sampler(sampler), typeParameters(nullptr)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(nullptr)
|
||||
#endif
|
||||
{
|
||||
qualifier.clear();
|
||||
qualifier.storage = q;
|
||||
|
@ -1602,6 +1669,9 @@ public:
|
|||
TType(TTypeList* userDef, const TString& n) :
|
||||
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
|
||||
arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(nullptr)
|
||||
#endif
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.clear();
|
||||
|
@ -1611,6 +1681,9 @@ public:
|
|||
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
|
||||
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
|
||||
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(nullptr)
|
||||
#endif
|
||||
{
|
||||
sampler.clear();
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
|
@ -1619,6 +1692,9 @@ public:
|
|||
explicit TType(TBasicType t, const TType &p, const TString& n) :
|
||||
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
|
||||
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
|
||||
#ifndef GLSLANG_WEB
|
||||
, spirvType(nullptr)
|
||||
#endif
|
||||
{
|
||||
assert(t == EbtReference);
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
|
@ -1649,6 +1725,9 @@ public:
|
|||
referentType = copyOf.referentType;
|
||||
}
|
||||
typeParameters = copyOf.typeParameters;
|
||||
#ifndef GLSLANG_WEB
|
||||
spirvType = copyOf.spirvType;
|
||||
#endif
|
||||
coopmat = copyOf.isCoopMat();
|
||||
}
|
||||
|
||||
|
@ -1770,7 +1849,7 @@ public:
|
|||
}
|
||||
virtual bool isOpaque() const { return basicType == EbtSampler
|
||||
#ifndef GLSLANG_WEB
|
||||
|| basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
|
||||
|| basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
|
||||
#endif
|
||||
; }
|
||||
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
|
||||
|
@ -2018,8 +2097,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* getBasicString() const
|
||||
{
|
||||
return TType::getBasicString(basicType);
|
||||
|
@ -2050,6 +2127,7 @@ public:
|
|||
case EbtRayQuery: return "rayQueryEXT";
|
||||
case EbtReference: return "reference";
|
||||
case EbtString: return "string";
|
||||
case EbtSpirvType: return "spirv_type";
|
||||
#endif
|
||||
default: return "unknown type";
|
||||
}
|
||||
|
@ -2070,6 +2148,9 @@ public:
|
|||
const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
|
||||
const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
|
||||
|
||||
if (qualifier.hasSprivDecorate())
|
||||
appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
|
||||
|
||||
if (qualifier.hasLayout()) {
|
||||
// To reduce noise, skip this if the only layout is an xfb_buffer
|
||||
// with no triggering xfb_offset.
|
||||
|
@ -2219,6 +2300,10 @@ public:
|
|||
appendStr(" nonuniform");
|
||||
if (qualifier.isNullInit())
|
||||
appendStr(" null-init");
|
||||
if (qualifier.isSpirvByReference())
|
||||
appendStr(" spirv_by_reference");
|
||||
if (qualifier.isSpirvLiteral())
|
||||
appendStr(" spirv_literal");
|
||||
appendStr(" ");
|
||||
appendStr(getStorageQualifierString());
|
||||
if (isArray()) {
|
||||
|
@ -2455,6 +2540,15 @@ public:
|
|||
(typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters));
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// See if two type's SPIR-V type contents match
|
||||
bool sameSpirvType(const TType& right) const
|
||||
{
|
||||
return ((spirvType == nullptr && right.spirvType == nullptr) ||
|
||||
(spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType));
|
||||
}
|
||||
#endif
|
||||
|
||||
// See if two type's elements match in all ways except basic type
|
||||
bool sameElementShape(const TType& right) const
|
||||
{
|
||||
|
@ -2493,7 +2587,11 @@ public:
|
|||
// See if two types match in all ways (just the actual type, not qualification)
|
||||
bool operator==(const TType& right) const
|
||||
{
|
||||
#ifndef GLSLANG_WEB
|
||||
return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameSpirvType(right);
|
||||
#else
|
||||
return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator!=(const TType& right) const
|
||||
|
@ -2512,6 +2610,10 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// Require consumer to pick between deep copy and shallow copy.
|
||||
TType(const TType& type);
|
||||
|
@ -2524,6 +2626,19 @@ protected:
|
|||
{
|
||||
shallowCopy(copyOf);
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// GL_EXT_spirv_intrinsics
|
||||
if (copyOf.qualifier.spirvDecorate) {
|
||||
qualifier.spirvDecorate = new TSpirvDecorate;
|
||||
*qualifier.spirvDecorate = *copyOf.qualifier.spirvDecorate;
|
||||
}
|
||||
|
||||
if (copyOf.spirvType) {
|
||||
spirvType = new TSpirvType;
|
||||
*spirvType = *copyOf.spirvType;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (copyOf.arraySizes) {
|
||||
arraySizes = new TArraySizes;
|
||||
*arraySizes = *copyOf.arraySizes;
|
||||
|
@ -2583,6 +2698,9 @@ protected:
|
|||
TString *typeName; // for structure type name
|
||||
TSampler sampler;
|
||||
TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types
|
||||
#ifndef GLSLANG_WEB
|
||||
TSpirvType* spirvType; // SPIR-V type defined by spirv_type directive
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
|
|
@ -71,6 +71,9 @@ enum TOperator {
|
|||
EOpFunctionCall,
|
||||
EOpFunction, // For function definition
|
||||
EOpParameters, // an aggregate listing the parameters to a function
|
||||
#ifndef GLSLANG_WEB
|
||||
EOpSpirvInst,
|
||||
#endif
|
||||
|
||||
//
|
||||
// Unary operators
|
||||
|
@ -923,6 +926,7 @@ enum TOperator {
|
|||
EOpMul32x16,
|
||||
|
||||
EOpTraceNV,
|
||||
EOpTraceRayMotionNV,
|
||||
EOpTraceKHR,
|
||||
EOpReportIntersection,
|
||||
EOpIgnoreIntersectionNV,
|
||||
|
@ -1616,8 +1620,15 @@ public:
|
|||
virtual TIntermUnary* getAsUnaryNode() { return this; }
|
||||
virtual const TIntermUnary* getAsUnaryNode() const { return this; }
|
||||
virtual void updatePrecision();
|
||||
#ifndef GLSLANG_WEB
|
||||
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
|
||||
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
|
||||
#endif
|
||||
protected:
|
||||
TIntermTyped* operand;
|
||||
#ifndef GLSLANG_WEB
|
||||
TSpirvInstruction spirvInst;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef TVector<TIntermNode*> TIntermSequence;
|
||||
|
@ -1632,6 +1643,7 @@ public:
|
|||
~TIntermAggregate() { delete pragmaTable; }
|
||||
virtual TIntermAggregate* getAsAggregate() { return this; }
|
||||
virtual const TIntermAggregate* getAsAggregate() const { return this; }
|
||||
virtual void updatePrecision();
|
||||
virtual void setOperator(TOperator o) { op = o; }
|
||||
virtual TIntermSequence& getSequence() { return sequence; }
|
||||
virtual const TIntermSequence& getSequence() const { return sequence; }
|
||||
|
@ -1648,6 +1660,10 @@ public:
|
|||
bool getDebug() const { return debug; }
|
||||
void setPragmaTable(const TPragmaTable& pTable);
|
||||
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
||||
#ifndef GLSLANG_WEB
|
||||
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
|
||||
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
|
||||
#endif
|
||||
protected:
|
||||
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
||||
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
|
||||
|
@ -1658,6 +1674,9 @@ protected:
|
|||
bool optimize;
|
||||
bool debug;
|
||||
TPragmaTable* pragmaTable;
|
||||
#ifndef GLSLANG_WEB
|
||||
TSpirvInstruction spirvInst;
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -1677,7 +1696,9 @@ public:
|
|||
virtual TIntermTyped* getCondition() const { return condition; }
|
||||
virtual void setCondition(TIntermTyped* c) { condition = c; }
|
||||
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||
virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
|
||||
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||
virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
|
||||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
||||
|
||||
|
|
|
@ -529,7 +529,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||
case EbtDouble:
|
||||
case EbtFloat16:
|
||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
||||
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
||||
// Note: avoid UBSAN error regarding negating 0x80000000
|
||||
case EbtInt: newConstArray[i].setIConst(
|
||||
static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
|
||||
? -0x7FFFFFFF - 1
|
||||
: -unionArray[i].getIConst());
|
||||
break;
|
||||
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
||||
#ifndef GLSLANG_WEB
|
||||
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||
// Copyright (C) 2015-2020 Google, Inc.
|
||||
// Copyright (C) 2017 ARM Limited.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
// Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
|
@ -483,7 +483,8 @@ void TBuiltIns::relateTabledBuiltins(int /* version */, EProfile /* profile */,
|
|||
|
||||
inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion)
|
||||
{
|
||||
return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && ARBCompatibility) || profile == ECompatibilityProfile);
|
||||
return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && version == 140 && ARBCompatibility) ||
|
||||
profile == ECompatibilityProfile);
|
||||
}
|
||||
|
||||
// Construct TBuiltInParseables base class. This can be used for language-common constructs.
|
||||
|
@ -1261,6 +1262,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"bvec3 notEqual(u64vec3, u64vec3);"
|
||||
"bvec4 notEqual(u64vec4, u64vec4);"
|
||||
|
||||
"int64_t bitCount(int64_t);"
|
||||
"i64vec2 bitCount(i64vec2);"
|
||||
"i64vec3 bitCount(i64vec3);"
|
||||
"i64vec4 bitCount(i64vec4);"
|
||||
|
||||
"int64_t bitCount(uint64_t);"
|
||||
"i64vec2 bitCount(u64vec2);"
|
||||
"i64vec3 bitCount(u64vec3);"
|
||||
"i64vec4 bitCount(u64vec4);"
|
||||
|
||||
"int64_t findLSB(int64_t);"
|
||||
"i64vec2 findLSB(i64vec2);"
|
||||
"i64vec3 findLSB(i64vec3);"
|
||||
|
@ -1426,11 +1437,23 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
" int64_t atomicMin(coherent volatile inout int64_t, int64_t);"
|
||||
"uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||
" int64_t atomicMin(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||
"float16_t atomicMin(coherent volatile inout float16_t, float16_t);"
|
||||
"float16_t atomicMin(coherent volatile inout float16_t, float16_t, int, int, int);"
|
||||
" float atomicMin(coherent volatile inout float, float);"
|
||||
" float atomicMin(coherent volatile inout float, float, int, int, int);"
|
||||
" double atomicMin(coherent volatile inout double, double);"
|
||||
" double atomicMin(coherent volatile inout double, double, int, int, int);"
|
||||
|
||||
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
|
||||
" int64_t atomicMax(coherent volatile inout int64_t, int64_t);"
|
||||
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||
" int64_t atomicMax(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||
"float16_t atomicMax(coherent volatile inout float16_t, float16_t);"
|
||||
"float16_t atomicMax(coherent volatile inout float16_t, float16_t, int, int, int);"
|
||||
" float atomicMax(coherent volatile inout float, float);"
|
||||
" float atomicMax(coherent volatile inout float, float, int, int, int);"
|
||||
" double atomicMax(coherent volatile inout double, double);"
|
||||
" double atomicMax(coherent volatile inout double, double, int, int, int);"
|
||||
|
||||
"uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
|
||||
" int64_t atomicAnd(coherent volatile inout int64_t, int64_t);"
|
||||
|
@ -1451,6 +1474,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t);"
|
||||
"uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||
"float16_t atomicAdd(coherent volatile inout float16_t, float16_t);"
|
||||
"float16_t atomicAdd(coherent volatile inout float16_t, float16_t, int, int, int);"
|
||||
" float atomicAdd(coherent volatile inout float, float);"
|
||||
" float atomicAdd(coherent volatile inout float, float, int, int, int);"
|
||||
" double atomicAdd(coherent volatile inout double, double);"
|
||||
|
@ -1460,6 +1485,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t);"
|
||||
"uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||
"float16_t atomicExchange(coherent volatile inout float16_t, float16_t);"
|
||||
"float16_t atomicExchange(coherent volatile inout float16_t, float16_t, int, int, int);"
|
||||
" float atomicExchange(coherent volatile inout float, float);"
|
||||
" float atomicExchange(coherent volatile inout float, float, int, int, int);"
|
||||
" double atomicExchange(coherent volatile inout double, double);"
|
||||
|
@ -1472,11 +1499,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
|
||||
"uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);"
|
||||
" int64_t atomicLoad(coherent volatile in int64_t, int, int, int);"
|
||||
"float16_t atomicLoad(coherent volatile in float16_t, int, int, int);"
|
||||
" float atomicLoad(coherent volatile in float, int, int, int);"
|
||||
" double atomicLoad(coherent volatile in double, int, int, int);"
|
||||
|
||||
"void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);"
|
||||
"void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);"
|
||||
"void atomicStore(coherent volatile out float16_t, float16_t, int, int, int);"
|
||||
"void atomicStore(coherent volatile out float, float, int, int, int);"
|
||||
"void atomicStore(coherent volatile out double, double, int, int, int);"
|
||||
"\n");
|
||||
|
@ -1835,6 +1864,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
|
||||
"\n");
|
||||
}
|
||||
if (profile != EEsProfile && version == 450) {
|
||||
commonBuiltins.append(
|
||||
"uint atomicCounterAddARB(atomic_uint, uint);"
|
||||
"uint atomicCounterSubtractARB(atomic_uint, uint);"
|
||||
"uint atomicCounterMinARB(atomic_uint, uint);"
|
||||
"uint atomicCounterMaxARB(atomic_uint, uint);"
|
||||
"uint atomicCounterAndARB(atomic_uint, uint);"
|
||||
"uint atomicCounterOrARB(atomic_uint, uint);"
|
||||
"uint atomicCounterXorARB(atomic_uint, uint);"
|
||||
"uint atomicCounterExchangeARB(atomic_uint, uint);"
|
||||
"uint atomicCounterCompSwapARB(atomic_uint, uint, uint);"
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
commonBuiltins.append(
|
||||
"uint atomicCounterAdd(atomic_uint, uint);"
|
||||
|
@ -4114,106 +4159,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"u16vec4 unpack16(uint64_t);"
|
||||
"i32vec2 unpack32(int64_t);"
|
||||
"u32vec2 unpack32(uint64_t);"
|
||||
|
||||
"float64_t radians(float64_t);"
|
||||
"f64vec2 radians(f64vec2);"
|
||||
"f64vec3 radians(f64vec3);"
|
||||
"f64vec4 radians(f64vec4);"
|
||||
|
||||
"float64_t degrees(float64_t);"
|
||||
"f64vec2 degrees(f64vec2);"
|
||||
"f64vec3 degrees(f64vec3);"
|
||||
"f64vec4 degrees(f64vec4);"
|
||||
|
||||
"float64_t sin(float64_t);"
|
||||
"f64vec2 sin(f64vec2);"
|
||||
"f64vec3 sin(f64vec3);"
|
||||
"f64vec4 sin(f64vec4);"
|
||||
|
||||
"float64_t cos(float64_t);"
|
||||
"f64vec2 cos(f64vec2);"
|
||||
"f64vec3 cos(f64vec3);"
|
||||
"f64vec4 cos(f64vec4);"
|
||||
|
||||
"float64_t tan(float64_t);"
|
||||
"f64vec2 tan(f64vec2);"
|
||||
"f64vec3 tan(f64vec3);"
|
||||
"f64vec4 tan(f64vec4);"
|
||||
|
||||
"float64_t asin(float64_t);"
|
||||
"f64vec2 asin(f64vec2);"
|
||||
"f64vec3 asin(f64vec3);"
|
||||
"f64vec4 asin(f64vec4);"
|
||||
|
||||
"float64_t acos(float64_t);"
|
||||
"f64vec2 acos(f64vec2);"
|
||||
"f64vec3 acos(f64vec3);"
|
||||
"f64vec4 acos(f64vec4);"
|
||||
|
||||
"float64_t atan(float64_t, float64_t);"
|
||||
"f64vec2 atan(f64vec2, f64vec2);"
|
||||
"f64vec3 atan(f64vec3, f64vec3);"
|
||||
"f64vec4 atan(f64vec4, f64vec4);"
|
||||
|
||||
"float64_t atan(float64_t);"
|
||||
"f64vec2 atan(f64vec2);"
|
||||
"f64vec3 atan(f64vec3);"
|
||||
"f64vec4 atan(f64vec4);"
|
||||
|
||||
"float64_t sinh(float64_t);"
|
||||
"f64vec2 sinh(f64vec2);"
|
||||
"f64vec3 sinh(f64vec3);"
|
||||
"f64vec4 sinh(f64vec4);"
|
||||
|
||||
"float64_t cosh(float64_t);"
|
||||
"f64vec2 cosh(f64vec2);"
|
||||
"f64vec3 cosh(f64vec3);"
|
||||
"f64vec4 cosh(f64vec4);"
|
||||
|
||||
"float64_t tanh(float64_t);"
|
||||
"f64vec2 tanh(f64vec2);"
|
||||
"f64vec3 tanh(f64vec3);"
|
||||
"f64vec4 tanh(f64vec4);"
|
||||
|
||||
"float64_t asinh(float64_t);"
|
||||
"f64vec2 asinh(f64vec2);"
|
||||
"f64vec3 asinh(f64vec3);"
|
||||
"f64vec4 asinh(f64vec4);"
|
||||
|
||||
"float64_t acosh(float64_t);"
|
||||
"f64vec2 acosh(f64vec2);"
|
||||
"f64vec3 acosh(f64vec3);"
|
||||
"f64vec4 acosh(f64vec4);"
|
||||
|
||||
"float64_t atanh(float64_t);"
|
||||
"f64vec2 atanh(f64vec2);"
|
||||
"f64vec3 atanh(f64vec3);"
|
||||
"f64vec4 atanh(f64vec4);"
|
||||
|
||||
"float64_t pow(float64_t, float64_t);"
|
||||
"f64vec2 pow(f64vec2, f64vec2);"
|
||||
"f64vec3 pow(f64vec3, f64vec3);"
|
||||
"f64vec4 pow(f64vec4, f64vec4);"
|
||||
|
||||
"float64_t exp(float64_t);"
|
||||
"f64vec2 exp(f64vec2);"
|
||||
"f64vec3 exp(f64vec3);"
|
||||
"f64vec4 exp(f64vec4);"
|
||||
|
||||
"float64_t log(float64_t);"
|
||||
"f64vec2 log(f64vec2);"
|
||||
"f64vec3 log(f64vec3);"
|
||||
"f64vec4 log(f64vec4);"
|
||||
|
||||
"float64_t exp2(float64_t);"
|
||||
"f64vec2 exp2(f64vec2);"
|
||||
"f64vec3 exp2(f64vec3);"
|
||||
"f64vec4 exp2(f64vec4);"
|
||||
|
||||
"float64_t log2(float64_t);"
|
||||
"f64vec2 log2(f64vec2);"
|
||||
"f64vec3 log2(f64vec3);"
|
||||
"f64vec4 log2(f64vec4);"
|
||||
"\n");
|
||||
}
|
||||
|
||||
|
@ -4608,13 +4553,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"\n");
|
||||
}
|
||||
|
||||
// GL_ARB_shader_clock & GL_EXT_shader_realtime_clock
|
||||
// GL_ARB_shader_clock
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
commonBuiltins.append(
|
||||
"uvec2 clock2x32ARB();"
|
||||
"uint64_t clockARB();"
|
||||
"uvec2 clockRealtime2x32EXT();"
|
||||
"uint64_t clockRealtimeEXT();"
|
||||
"\n");
|
||||
}
|
||||
|
||||
|
@ -4632,7 +4575,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"\n");
|
||||
}
|
||||
|
||||
// Builtins for GL_NV_ray_tracing/GL_EXT_ray_tracing/GL_EXT_ray_query
|
||||
// Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);"
|
||||
"void rayQueryTerminateEXT(rayQueryEXT);"
|
||||
|
@ -4661,6 +4604,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
|
||||
stageBuiltins[EShLangRayGen].append(
|
||||
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
|
||||
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
|
||||
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
|
||||
"void executeCallableNV(uint, int);"
|
||||
"void executeCallableEXT(uint, int);"
|
||||
|
@ -4675,12 +4619,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"\n");
|
||||
stageBuiltins[EShLangClosestHit].append(
|
||||
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
|
||||
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
|
||||
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
|
||||
"void executeCallableNV(uint, int);"
|
||||
"void executeCallableEXT(uint, int);"
|
||||
"\n");
|
||||
stageBuiltins[EShLangMiss].append(
|
||||
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
|
||||
"void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
|
||||
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
|
||||
"void executeCallableNV(uint, int);"
|
||||
"void executeCallableEXT(uint, int);"
|
||||
|
@ -5126,9 +5072,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
);
|
||||
}
|
||||
|
||||
if (version >= 450)
|
||||
if (version >= 430)
|
||||
stageBuiltins[EShLangVertex].append(
|
||||
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||
);
|
||||
|
||||
if (version >= 450)
|
||||
stageBuiltins[EShLangVertex].append(
|
||||
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||
|
@ -5264,9 +5214,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in int gl_InvocationID;"
|
||||
);
|
||||
|
||||
if (version >= 450)
|
||||
if (version >= 430)
|
||||
stageBuiltins[EShLangGeometry].append(
|
||||
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||
);
|
||||
|
||||
if (version >= 450)
|
||||
stageBuiltins[EShLangGeometry].append(
|
||||
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||
|
@ -5342,7 +5296,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
if (version >= 450)
|
||||
stageBuiltins[EShLangTessControl].append(
|
||||
"float gl_CullDistance[];"
|
||||
);
|
||||
if (version >= 430)
|
||||
stageBuiltins[EShLangTessControl].append(
|
||||
"int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||
);
|
||||
if (version >= 450)
|
||||
stageBuiltins[EShLangTessControl].append(
|
||||
"vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||
"int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||
"vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||
|
@ -5445,9 +5405,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"out int gl_Layer;"
|
||||
"\n");
|
||||
|
||||
if (version >= 450)
|
||||
if (version >= 430)
|
||||
stageBuiltins[EShLangTessEvaluation].append(
|
||||
"out int gl_ViewportMask[];" // GL_NV_viewport_array2
|
||||
);
|
||||
|
||||
if (version >= 450)
|
||||
stageBuiltins[EShLangTessEvaluation].append(
|
||||
"out vec4 gl_SecondaryPositionNV;" // GL_NV_stereo_view_rendering
|
||||
"out int gl_SecondaryViewportMaskNV[];" // GL_NV_stereo_view_rendering
|
||||
"out vec4 gl_PositionPerViewNV[];" // GL_NVX_multiview_per_view_attributes
|
||||
|
@ -5889,6 +5853,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in mat3x4 gl_WorldToObject3x4EXT;"
|
||||
"in uint gl_IncomingRayFlagsNV;"
|
||||
"in uint gl_IncomingRayFlagsEXT;"
|
||||
"in float gl_CurrentRayTimeNV;"
|
||||
"\n";
|
||||
const char *hitDecls =
|
||||
"in uvec3 gl_LaunchIDNV;"
|
||||
|
@ -5924,6 +5889,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in mat3x4 gl_WorldToObject3x4EXT;"
|
||||
"in uint gl_IncomingRayFlagsNV;"
|
||||
"in uint gl_IncomingRayFlagsEXT;"
|
||||
"in float gl_CurrentRayTimeNV;"
|
||||
"\n";
|
||||
const char *missDecls =
|
||||
"in uvec3 gl_LaunchIDNV;"
|
||||
|
@ -5942,6 +5908,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in float gl_RayTmaxEXT;"
|
||||
"in uint gl_IncomingRayFlagsNV;"
|
||||
"in uint gl_IncomingRayFlagsEXT;"
|
||||
"in float gl_CurrentRayTimeNV;"
|
||||
"\n";
|
||||
|
||||
const char *callableDecls =
|
||||
|
@ -6468,6 +6435,24 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
|
|||
commonBuiltins.append(imageParams);
|
||||
commonBuiltins.append(", float");
|
||||
commonBuiltins.append(", int, int, int);\n");
|
||||
|
||||
commonBuiltins.append("float imageAtomicMin(volatile coherent ");
|
||||
commonBuiltins.append(imageParams);
|
||||
commonBuiltins.append(", float);\n");
|
||||
|
||||
commonBuiltins.append("float imageAtomicMin(volatile coherent ");
|
||||
commonBuiltins.append(imageParams);
|
||||
commonBuiltins.append(", float");
|
||||
commonBuiltins.append(", int, int, int);\n");
|
||||
|
||||
commonBuiltins.append("float imageAtomicMax(volatile coherent ");
|
||||
commonBuiltins.append(imageParams);
|
||||
commonBuiltins.append(", float);\n");
|
||||
|
||||
commonBuiltins.append("float imageAtomicMax(volatile coherent ");
|
||||
commonBuiltins.append(imageParams);
|
||||
commonBuiltins.append(", float");
|
||||
commonBuiltins.append(", int, int, int);\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7236,6 +7221,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors);
|
||||
s.append(builtInConstant);
|
||||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors);
|
||||
s.append(builtInConstant);
|
||||
}
|
||||
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
|
||||
|
@ -7268,7 +7256,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||
snprintf(builtInConstant, maxSize, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents);
|
||||
s.append(builtInConstant);
|
||||
|
||||
if (version < 150 || ARBCompatibility) {
|
||||
// Moved from just being deprecated into compatibility profile only as of 4.20
|
||||
if (version < 420 || profile == ECompatibilityProfile) {
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats);
|
||||
s.append(builtInConstant);
|
||||
}
|
||||
|
@ -7628,6 +7617,11 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT
|
|||
symQualifier.builtIn = builtIn;
|
||||
}
|
||||
|
||||
static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
|
||||
{
|
||||
symbolTable.retargetSymbol(from, to);
|
||||
}
|
||||
|
||||
//
|
||||
// For built-in variables inside a named block.
|
||||
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
|
||||
|
@ -7695,8 +7689,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
|
||||
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
|
||||
// treat these built-ins as aliases of VertexIndex and InstanceIndex
|
||||
BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
|
||||
BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
|
||||
RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
|
||||
RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile) {
|
||||
|
@ -8210,6 +8204,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters);
|
||||
}
|
||||
|
||||
// E_GL_ARB_shader_atomic_counter_ops
|
||||
if (profile != EEsProfile && version == 450) {
|
||||
symbolTable.setFunctionExtensions("atomicCounterAddARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterSubtractARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterMinARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterMaxARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterAndARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterOrARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterXorARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterExchangeARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
symbolTable.setFunctionExtensions("atomicCounterCompSwapARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
|
||||
}
|
||||
|
||||
// E_GL_ARB_derivative_control
|
||||
if (profile != EEsProfile && version < 450) {
|
||||
symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control);
|
||||
|
@ -8317,9 +8324,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock);
|
||||
symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock);
|
||||
|
||||
symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
|
||||
symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
|
||||
|
||||
if (profile == EEsProfile && version < 320) {
|
||||
symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader);
|
||||
symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader);
|
||||
|
@ -8738,11 +8742,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing);
|
||||
symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing);
|
||||
symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing);
|
||||
symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur);
|
||||
|
||||
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||
|
||||
|
||||
symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing);
|
||||
symbolTable.setFunctionExtensions("traceRayMotionNV", 1, &E_GL_NV_ray_tracing_motion_blur);
|
||||
symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing);
|
||||
symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing);
|
||||
symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing);
|
||||
|
@ -8786,6 +8792,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable);
|
||||
BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable);
|
||||
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||
BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable);
|
||||
|
||||
// GL_ARB_shader_ballot
|
||||
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
|
||||
|
@ -9210,6 +9217,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR);
|
||||
symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR);
|
||||
|
||||
if (profile != EEsProfile && version == 450) {
|
||||
symbolTable.relateToOperator("atomicCounterAddARB", EOpAtomicCounterAdd);
|
||||
symbolTable.relateToOperator("atomicCounterSubtractARB", EOpAtomicCounterSubtract);
|
||||
symbolTable.relateToOperator("atomicCounterMinARB", EOpAtomicCounterMin);
|
||||
symbolTable.relateToOperator("atomicCounterMaxARB", EOpAtomicCounterMax);
|
||||
symbolTable.relateToOperator("atomicCounterAndARB", EOpAtomicCounterAnd);
|
||||
symbolTable.relateToOperator("atomicCounterOrARB", EOpAtomicCounterOr);
|
||||
symbolTable.relateToOperator("atomicCounterXorARB", EOpAtomicCounterXor);
|
||||
symbolTable.relateToOperator("atomicCounterExchangeARB", EOpAtomicCounterExchange);
|
||||
symbolTable.relateToOperator("atomicCounterCompSwapARB", EOpAtomicCounterCompSwap);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd);
|
||||
symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract);
|
||||
|
@ -9617,6 +9636,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
case EShLangMiss:
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
symbolTable.relateToOperator("traceNV", EOpTraceNV);
|
||||
symbolTable.relateToOperator("traceRayMotionNV", EOpTraceRayMotionNV);
|
||||
symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR);
|
||||
symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV);
|
||||
symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR);
|
||||
|
|
|
@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
|
|||
// TODO: but, did this bypass constant folding?
|
||||
//
|
||||
switch (op) {
|
||||
case EOpConstructInt8:
|
||||
case EOpConstructUint8:
|
||||
case EOpConstructInt16:
|
||||
case EOpConstructUint16:
|
||||
case EOpConstructInt:
|
||||
case EOpConstructUint:
|
||||
case EOpConstructInt64:
|
||||
case EOpConstructUint64:
|
||||
case EOpConstructBool:
|
||||
case EOpConstructFloat:
|
||||
case EOpConstructDouble:
|
||||
case EOpConstructFloat16:
|
||||
return child;
|
||||
default: break; // some compilers want this
|
||||
case EOpConstructInt8:
|
||||
case EOpConstructUint8:
|
||||
case EOpConstructInt16:
|
||||
case EOpConstructUint16:
|
||||
case EOpConstructInt:
|
||||
case EOpConstructUint:
|
||||
case EOpConstructInt64:
|
||||
case EOpConstructUint64:
|
||||
case EOpConstructBool:
|
||||
case EOpConstructFloat:
|
||||
case EOpConstructDouble:
|
||||
case EOpConstructFloat16: {
|
||||
TIntermUnary* unary_node = child->getAsUnaryNode();
|
||||
if (unary_node != nullptr)
|
||||
unary_node->updatePrecision();
|
||||
return child;
|
||||
}
|
||||
default: break; // some compilers want this
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1739,7 +1743,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
|
|||
case EbtUint:
|
||||
switch (from) {
|
||||
case EbtInt:
|
||||
return version >= 400 || getSource() == EShSourceHlsl;
|
||||
return version >= 400 || getSource() == EShSourceHlsl || IsRequestedExtension(E_GL_ARB_gpu_shader5);
|
||||
case EbtBool:
|
||||
return getSource() == EShSourceHlsl;
|
||||
case EbtInt16:
|
||||
|
@ -2676,7 +2680,11 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
|
|||
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
|
||||
// a valid part of the dereference chain.
|
||||
//
|
||||
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
|
||||
// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
|
||||
//
|
||||
//
|
||||
|
||||
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
|
||||
{
|
||||
do {
|
||||
const TIntermBinary* binary = node->getAsBinaryNode();
|
||||
|
@ -2694,6 +2702,8 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
|
|||
return nullptr;
|
||||
}
|
||||
node = node->getAsBinaryNode()->getLeft();
|
||||
if (bufferReferenceOk && node->isReference())
|
||||
return node;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
@ -3770,6 +3780,28 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Propagate precision qualifiers *up* from children to parent, and then
|
||||
// back *down* again to the children's subtrees.
|
||||
void TIntermAggregate::updatePrecision()
|
||||
{
|
||||
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
|
||||
getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
|
||||
TPrecisionQualifier maxPrecision = EpqNone;
|
||||
TIntermSequence operands = getSequence();
|
||||
for (unsigned int i = 0; i < operands.size(); ++i) {
|
||||
TIntermTyped* typedNode = operands[i]->getAsTyped();
|
||||
assert(typedNode);
|
||||
maxPrecision = std::max(maxPrecision, typedNode->getQualifier().precision);
|
||||
}
|
||||
getQualifier().precision = maxPrecision;
|
||||
for (unsigned int i = 0; i < operands.size(); ++i) {
|
||||
TIntermTyped* typedNode = operands[i]->getAsTyped();
|
||||
assert(typedNode);
|
||||
typedNode->propagatePrecision(maxPrecision);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate precision qualifiers *up* from children to parent, and then
|
||||
// back *down* again to the children's subtrees.
|
||||
void TIntermBinary::updatePrecision()
|
||||
|
|
|
@ -622,6 +622,19 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
|
|||
globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
|
||||
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
|
||||
|
||||
// Check for declarations of this default uniform that already exist due to other compilation units.
|
||||
TSymbol* symbol = symbolTable.find(memberName);
|
||||
if (symbol) {
|
||||
if (memberType != symbol->getType()) {
|
||||
TString err;
|
||||
err += "\"" + memberType.getCompleteString() + "\"";
|
||||
err += " versus ";
|
||||
err += "\"" + symbol->getType().getCompleteString() + "\"";
|
||||
error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the requested member as a member to the global block.
|
||||
TType* type = new TType;
|
||||
type->shallowCopy(memberType);
|
||||
|
|
|
@ -327,6 +327,16 @@ void TParseContext::setAtomicCounterBlockDefaults(TType& block) const
|
|||
block.getQualifier().layoutMatrix = ElmRowMajor;
|
||||
}
|
||||
|
||||
void TParseContext::setInvariant(const TSourceLoc& loc, const char* builtin) {
|
||||
TSymbol* symbol = symbolTable.find(builtin);
|
||||
if (symbol && symbol->getType().getQualifier().isPipeOutput()) {
|
||||
if (intermediate.inIoAccessed(builtin))
|
||||
warn(loc, "changing qualification after use", "invariant", builtin);
|
||||
TSymbol* csymbol = symbolTable.copyUp(symbol);
|
||||
csymbol->getWritableType().getQualifier().invariant = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
|
||||
{
|
||||
#ifndef GLSLANG_WEB
|
||||
|
@ -404,8 +414,33 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||
intermediate.setUseVariablePointers();
|
||||
} else if (tokens[0].compare("once") == 0) {
|
||||
warn(loc, "not implemented", "#pragma once", "");
|
||||
} else if (tokens[0].compare("glslang_binary_double_output") == 0)
|
||||
} else if (tokens[0].compare("glslang_binary_double_output") == 0) {
|
||||
intermediate.setBinaryDoubleOutput();
|
||||
} else if (spvVersion.spv > 0 && tokens[0].compare("STDGL") == 0 &&
|
||||
tokens[1].compare("invariant") == 0 && tokens[3].compare("all") == 0) {
|
||||
intermediate.setInvariantAll();
|
||||
// Set all builtin out variables invariant if declared
|
||||
setInvariant(loc, "gl_Position");
|
||||
setInvariant(loc, "gl_PointSize");
|
||||
setInvariant(loc, "gl_ClipDistance");
|
||||
setInvariant(loc, "gl_CullDistance");
|
||||
setInvariant(loc, "gl_TessLevelOuter");
|
||||
setInvariant(loc, "gl_TessLevelInner");
|
||||
setInvariant(loc, "gl_PrimitiveID");
|
||||
setInvariant(loc, "gl_Layer");
|
||||
setInvariant(loc, "gl_ViewportIndex");
|
||||
setInvariant(loc, "gl_FragDepth");
|
||||
setInvariant(loc, "gl_SampleMask");
|
||||
setInvariant(loc, "gl_ClipVertex");
|
||||
setInvariant(loc, "gl_FrontColor");
|
||||
setInvariant(loc, "gl_BackColor");
|
||||
setInvariant(loc, "gl_FrontSecondaryColor");
|
||||
setInvariant(loc, "gl_BackSecondaryColor");
|
||||
setInvariant(loc, "gl_TexCoord");
|
||||
setInvariant(loc, "gl_FogFragCoord");
|
||||
setInvariant(loc, "gl_FragColor");
|
||||
setInvariant(loc, "gl_FragData");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1092,12 +1127,31 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct
|
|||
TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
|
||||
if (symbol && symbol->getAsFunction() && builtIn)
|
||||
requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
|
||||
#ifndef GLSLANG_WEB
|
||||
// Check the validity of using spirv_literal qualifier
|
||||
for (int i = 0; i < function.getParamCount(); ++i) {
|
||||
if (function[i].type->getQualifier().isSpirvLiteral() && function.getBuiltInOp() != EOpSpirvInst)
|
||||
error(loc, "'spirv_literal' can only be used on functions defined with 'spirv_instruction' for argument",
|
||||
function.getName().c_str(), "%d", i + 1);
|
||||
}
|
||||
|
||||
// For function declaration with SPIR-V instruction qualifier, always ignore the built-in function and
|
||||
// respect this redeclared one.
|
||||
if (symbol && builtIn && function.getBuiltInOp() == EOpSpirvInst)
|
||||
symbol = nullptr;
|
||||
#endif
|
||||
const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
|
||||
if (prevDec) {
|
||||
if (prevDec->isPrototyped() && prototype)
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function");
|
||||
if (prevDec->getType() != function.getType())
|
||||
error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
|
||||
#ifndef GLSLANG_WEB
|
||||
if (prevDec->getSpirvInstruction() != function.getSpirvInstruction()) {
|
||||
error(loc, "overloaded functions must have the same qualifiers", function.getName().c_str(),
|
||||
"spirv_instruction");
|
||||
}
|
||||
#endif
|
||||
for (int i = 0; i < prevDec->getParamCount(); ++i) {
|
||||
if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
|
||||
error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
|
||||
|
@ -1299,6 +1353,15 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
|||
if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
|
||||
error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
|
||||
}
|
||||
#ifndef GLSLANG_WEB
|
||||
if (formalQualifier.isSpirvLiteral()) {
|
||||
if (!arg->getAsTyped()->getQualifier().isFrontEndConstant()) {
|
||||
error(arguments->getLoc(),
|
||||
"Non front-end constant expressions cannot be passed for 'spirv_literal' parameters.",
|
||||
"spirv_literal", "");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
const TType& argType = arg->getAsTyped()->getType();
|
||||
const TQualifier& argQualifier = argType.getQualifier();
|
||||
if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) {
|
||||
|
@ -1353,6 +1416,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
|||
if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) {
|
||||
// A function call mapped to a built-in operation.
|
||||
result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
|
||||
#ifndef GLSLANG_WEB
|
||||
} else if (fnCandidate->getBuiltInOp() == EOpSpirvInst) {
|
||||
// When SPIR-V instruction qualifier is specified, the function call is still mapped to a built-in operation.
|
||||
result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
|
||||
#endif
|
||||
} else {
|
||||
// This is a function call not mapped to built-in operator.
|
||||
// It could still be a built-in function, but only if PureOperatorBuiltins == false.
|
||||
|
@ -1430,6 +1498,35 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
|
|||
} else if (result->getAsOperator())
|
||||
builtInOpCheck(loc, function, *result->getAsOperator());
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// Special handling for function call with SPIR-V instruction qualifier specified
|
||||
if (function.getBuiltInOp() == EOpSpirvInst) {
|
||||
if (auto agg = result->getAsAggregate()) {
|
||||
// Propogate spirv_by_reference/spirv_literal from parameters to arguments
|
||||
auto& sequence = agg->getSequence();
|
||||
for (unsigned i = 0; i < sequence.size(); ++i) {
|
||||
if (function[i].type->getQualifier().isSpirvByReference())
|
||||
sequence[i]->getAsTyped()->getQualifier().setSpirvByReference();
|
||||
if (function[i].type->getQualifier().isSpirvLiteral())
|
||||
sequence[i]->getAsTyped()->getQualifier().setSpirvLiteral();
|
||||
}
|
||||
|
||||
// Attach the function call to SPIR-V intruction
|
||||
agg->setSpirvInstruction(function.getSpirvInstruction());
|
||||
} else if (auto unaryNode = result->getAsUnaryNode()) {
|
||||
// Propogate spirv_by_reference/spirv_literal from parameters to arguments
|
||||
if (function[0].type->getQualifier().isSpirvByReference())
|
||||
unaryNode->getOperand()->getQualifier().setSpirvByReference();
|
||||
if (function[0].type->getQualifier().isSpirvLiteral())
|
||||
unaryNode->getOperand()->getQualifier().setSpirvLiteral();
|
||||
|
||||
// Attach the function call to SPIR-V intruction
|
||||
unaryNode->setSpirvInstruction(function.getSpirvInstruction());
|
||||
} else
|
||||
assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2211,6 +2308,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
if (!(*argp)[10]->getAsConstantUnion())
|
||||
error(loc, "argument must be compile-time constant", "payload number", "a");
|
||||
break;
|
||||
case EOpTraceRayMotionNV:
|
||||
if (!(*argp)[11]->getAsConstantUnion())
|
||||
error(loc, "argument must be compile-time constant", "payload number", "a");
|
||||
break;
|
||||
case EOpTraceKHR:
|
||||
if (!(*argp)[10]->getAsConstantUnion())
|
||||
error(loc, "argument must be compile-time constant", "payload number", "a");
|
||||
|
@ -2279,18 +2380,23 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
error(loc, "only supported on image with format r64i", fnCandidate.getName().c_str(), "");
|
||||
else if (callNode.getType().getBasicType() == EbtUint64 && imageType.getQualifier().getFormat() != ElfR64ui)
|
||||
error(loc, "only supported on image with format r64ui", fnCandidate.getName().c_str(), "");
|
||||
} else {
|
||||
bool isImageAtomicOnFloatAllowed = ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
|
||||
(fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
|
||||
(fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0) ||
|
||||
(fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0));
|
||||
if (imageType.getSampler().type == EbtFloat && isImageAtomicOnFloatAllowed &&
|
||||
(fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)) // imageAtomicExchange doesn't require GL_EXT_shader_atomic_float
|
||||
} else if (imageType.getSampler().type == EbtFloat) {
|
||||
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0) {
|
||||
// imageAtomicExchange doesn't require an extension
|
||||
} else if ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
|
||||
(fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
|
||||
(fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0)) {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
|
||||
if (!isImageAtomicOnFloatAllowed)
|
||||
} else if ((fnCandidate.getName().compare(0, 14, "imageAtomicMin") == 0) ||
|
||||
(fnCandidate.getName().compare(0, 14, "imageAtomicMax") == 0)) {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
|
||||
} else {
|
||||
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
|
||||
else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
|
||||
}
|
||||
if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
|
||||
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
||||
} else {
|
||||
error(loc, "not supported on this image type", fnCandidate.getName().c_str(), "");
|
||||
}
|
||||
|
||||
const size_t maxArgs = imageType.getSampler().isMultiSample() ? 5 : 4;
|
||||
|
@ -2319,17 +2425,37 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
memorySemanticsCheck(loc, fnCandidate, callNode);
|
||||
if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
|
||||
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore) &&
|
||||
(arg0->getType().isFloatingDomain())) {
|
||||
(arg0->getType().getBasicType() == EbtFloat ||
|
||||
arg0->getType().getBasicType() == EbtDouble)) {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
|
||||
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
|
||||
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore ||
|
||||
callNode.getOp() == EOpAtomicMin || callNode.getOp() == EOpAtomicMax) &&
|
||||
arg0->getType().isFloatingDomain()) {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
|
||||
}
|
||||
} else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) {
|
||||
const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
|
||||
E_GL_EXT_shader_atomic_int64 };
|
||||
requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
|
||||
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) &&
|
||||
(arg0->getType().isFloatingDomain())) {
|
||||
(arg0->getType().getBasicType() == EbtFloat ||
|
||||
arg0->getType().getBasicType() == EbtDouble)) {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
|
||||
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
|
||||
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore ||
|
||||
callNode.getOp() == EOpAtomicMin || callNode.getOp() == EOpAtomicMax) &&
|
||||
arg0->getType().isFloatingDomain()) {
|
||||
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
|
||||
}
|
||||
|
||||
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
|
||||
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
|
||||
const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
|
||||
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer)
|
||||
error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.",
|
||||
fnCandidate.getName().c_str(), "");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2903,11 +3029,14 @@ void TParseContext::constantValueCheck(TIntermTyped* node, const char* token)
|
|||
|
||||
//
|
||||
// Both test, and if necessary spit out an error, to see if the node is really
|
||||
// an integer.
|
||||
// a 32-bit integer or can implicitly convert to one.
|
||||
//
|
||||
void TParseContext::integerCheck(const TIntermTyped* node, const char* token)
|
||||
{
|
||||
if ((node->getBasicType() == EbtInt || node->getBasicType() == EbtUint) && node->isScalar())
|
||||
auto from_type = node->getBasicType();
|
||||
if ((from_type == EbtInt || from_type == EbtUint ||
|
||||
intermediate.canImplicitlyPromote(from_type, EbtInt, EOpNull) ||
|
||||
intermediate.canImplicitlyPromote(from_type, EbtUint, EOpNull)) && node->isScalar())
|
||||
return;
|
||||
|
||||
error(node->getLoc(), "scalar integer expression required", token, "");
|
||||
|
@ -2931,7 +3060,8 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide
|
|||
// "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
|
||||
// declared in a shader; this results in a compile-time error."
|
||||
if (! symbolTable.atBuiltInLevel()) {
|
||||
if (builtInName(identifier))
|
||||
if (builtInName(identifier) && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
|
||||
// The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "gl_".
|
||||
error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
|
||||
|
||||
// "__" are not supposed to be an error. ES 300 (and desktop) added the clarification:
|
||||
|
@ -2939,7 +3069,8 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide
|
|||
// reserved; using such a name does not itself result in an error, but may result
|
||||
// in undefined behavior."
|
||||
// however, before that, ES tests required an error.
|
||||
if (identifier.find("__") != TString::npos) {
|
||||
if (identifier.find("__") != TString::npos && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) {
|
||||
// The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "__".
|
||||
if (isEsProfile() && version < 300)
|
||||
error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version < 300", identifier.c_str(), "");
|
||||
else
|
||||
|
@ -2960,14 +3091,16 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden
|
|||
// single underscore) are also reserved, and defining such a name results in a
|
||||
// compile-time error."
|
||||
// however, before that, ES tests required an error.
|
||||
if (strncmp(identifier, "GL_", 3) == 0)
|
||||
if (strncmp(identifier, "GL_", 3) == 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
|
||||
// The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "GL_".
|
||||
ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op, identifier);
|
||||
else if (strncmp(identifier, "defined", 8) == 0)
|
||||
if (relaxedErrors())
|
||||
ppWarn(loc, "\"defined\" is (un)defined:", op, identifier);
|
||||
else
|
||||
ppError(loc, "\"defined\" can't be (un)defined:", op, identifier);
|
||||
else if (strstr(identifier, "__") != 0) {
|
||||
else if (strstr(identifier, "__") != 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) {
|
||||
// The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "__".
|
||||
if (isEsProfile() && version >= 300 &&
|
||||
(strcmp(identifier, "__LINE__") == 0 ||
|
||||
strcmp(identifier, "__FILE__") == 0 ||
|
||||
|
@ -3115,6 +3248,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||
bool matrixInMatrix = false;
|
||||
bool arrayArg = false;
|
||||
bool floatArgument = false;
|
||||
bool intArgument = false;
|
||||
for (int arg = 0; arg < function.getParamCount(); ++arg) {
|
||||
if (function[arg].type->isArray()) {
|
||||
if (function[arg].type->isUnsizedArray()) {
|
||||
|
@ -3145,6 +3279,8 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||
specConstType = true;
|
||||
if (function[arg].type->isFloatingDomain())
|
||||
floatArgument = true;
|
||||
if (function[arg].type->isIntegerDomain())
|
||||
intArgument = true;
|
||||
if (type.isStruct()) {
|
||||
if (function[arg].type->contains16BitFloat()) {
|
||||
requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type");
|
||||
|
@ -3250,6 +3386,15 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
|
|||
// and aren't making an array.
|
||||
makeSpecConst = ! floatArgument && ! type.isArray();
|
||||
break;
|
||||
|
||||
case EOpConstructVec2:
|
||||
case EOpConstructVec3:
|
||||
case EOpConstructVec4:
|
||||
// This was the list of valid ones, if they aren't converting from int
|
||||
// and aren't making an array.
|
||||
makeSpecConst = ! intArgument && !type.isArray();
|
||||
break;
|
||||
|
||||
default:
|
||||
// anything else wasn't white-listed in the spec as a conversion
|
||||
makeSpecConst = false;
|
||||
|
@ -3556,6 +3701,8 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
|
|||
profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, "out for stage outputs");
|
||||
qualifier.storage = EvqVaryingOut;
|
||||
if (intermediate.isInvariantAll())
|
||||
qualifier.invariant = true;
|
||||
break;
|
||||
case EvqInOut:
|
||||
qualifier.storage = EvqVaryingIn;
|
||||
|
@ -3572,7 +3719,7 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
|
|||
if (blockName == nullptr &&
|
||||
qualifier.layoutPacking == ElpStd430)
|
||||
{
|
||||
error(loc, "it is invalid to declare std430 qualifier on uniform", "", "");
|
||||
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "default std430 layout for uniform");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -3582,6 +3729,14 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
|
|||
if (!nonuniformOkay && qualifier.isNonUniform())
|
||||
error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
if (qualifier.isSpirvByReference())
|
||||
error(loc, "can only apply to parameter", "spirv_by_reference", "");
|
||||
|
||||
if (qualifier.isSpirvLiteral())
|
||||
error(loc, "can only apply to parameter", "spirv_literal", "");
|
||||
#endif
|
||||
|
||||
// Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
|
||||
if (!isMemberCheck || structNestingLevel > 0)
|
||||
invariantCheck(loc, qualifier);
|
||||
|
@ -3843,6 +3998,41 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
|||
MERGE_SINGLETON(nonUniform);
|
||||
#endif
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// SPIR-V storage class qualifier (GL_EXT_spirv_intrinsics)
|
||||
dst.spirvStorageClass = src.spirvStorageClass;
|
||||
|
||||
// SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
|
||||
if (src.hasSprivDecorate()) {
|
||||
if (dst.hasSprivDecorate()) {
|
||||
const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
|
||||
TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
|
||||
for (auto& decorate : srcSpirvDecorate.decorates) {
|
||||
if (dstSpirvDecorate.decorates.find(decorate.first) != dstSpirvDecorate.decorates.end())
|
||||
error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate", "(decoration=%u)", decorate.first);
|
||||
else
|
||||
dstSpirvDecorate.decorates.insert(decorate);
|
||||
}
|
||||
|
||||
for (auto& decorateId : srcSpirvDecorate.decorateIds) {
|
||||
if (dstSpirvDecorate.decorateIds.find(decorateId.first) != dstSpirvDecorate.decorateIds.end())
|
||||
error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_id", "(decoration=%u)", decorateId.first);
|
||||
else
|
||||
dstSpirvDecorate.decorateIds.insert(decorateId);
|
||||
}
|
||||
|
||||
for (auto& decorateString : srcSpirvDecorate.decorateStrings) {
|
||||
if (dstSpirvDecorate.decorates.find(decorateString.first) != dstSpirvDecorate.decorates.end())
|
||||
error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_string", "(decoration=%u)", decorateString.first);
|
||||
else
|
||||
dstSpirvDecorate.decorates.insert(decorateString);
|
||||
}
|
||||
} else {
|
||||
dst.spirvDecorate = src.spirvDecorate;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (repeated)
|
||||
error(loc, "replicated qualifiers", "", "");
|
||||
}
|
||||
|
@ -4806,6 +4996,17 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
|
|||
}
|
||||
if (qualifier.isNonUniform())
|
||||
type.getQualifier().nonUniform = qualifier.nonUniform;
|
||||
#ifndef GLSLANG_WEB
|
||||
if (qualifier.isSpirvByReference())
|
||||
type.getQualifier().setSpirvByReference();
|
||||
if (qualifier.isSpirvLiteral()) {
|
||||
if (type.getBasicType() == EbtFloat || type.getBasicType() == EbtInt || type.getBasicType() == EbtUint ||
|
||||
type.getBasicType() == EbtBool)
|
||||
type.getQualifier().setSpirvLiteral();
|
||||
else
|
||||
error(loc, "cannot use spirv_literal qualifier", type.getBasicTypeString().c_str(), "");
|
||||
#endif
|
||||
}
|
||||
|
||||
paramCheckFixStorage(loc, qualifier.storage, type);
|
||||
}
|
||||
|
@ -5873,6 +6074,9 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
|||
case EvqVaryingIn:
|
||||
case EvqVaryingOut:
|
||||
if (!type.getQualifier().isTaskMemory() &&
|
||||
#ifndef GLSLANG_WEB
|
||||
!type.getQualifier().hasSprivDecorate() &&
|
||||
#endif
|
||||
(type.getBasicType() != EbtBlock ||
|
||||
(!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
|
||||
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
|
||||
|
@ -5934,6 +6138,11 @@ void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool m
|
|||
// Do layout error checking with respect to a type.
|
||||
void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||
{
|
||||
#ifndef GLSLANG_WEB
|
||||
if (extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
|
||||
return; // Skip any check if GL_EXT_spirv_intrinsics is turned on
|
||||
#endif
|
||||
|
||||
const TQualifier& qualifier = type.getQualifier();
|
||||
|
||||
// first, intra-layout qualifier-only error checking
|
||||
|
@ -7485,7 +7694,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return intermediate.setAggregateOperator(aggrNode, op, type, loc);
|
||||
TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
|
||||
|
||||
TIntermAggregate *agg_node = ret_node->getAsAggregate();
|
||||
if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
|
||||
agg_node->updatePrecision();
|
||||
|
||||
return ret_node;
|
||||
}
|
||||
|
||||
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
|
||||
|
@ -7940,6 +8155,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||
memberQualifier.perViewNV = currentBlockQualifier.perViewNV;
|
||||
if (currentBlockQualifier.perTaskNV)
|
||||
memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV;
|
||||
if (memberQualifier.storage == EvqSpirvStorageClass)
|
||||
error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
|
||||
if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
|
||||
error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
|
||||
#endif
|
||||
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
||||
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
||||
|
@ -9027,11 +9246,14 @@ TIntermNode* TParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expre
|
|||
// "it is an error to have no statement between a label and the end of the switch statement."
|
||||
// The specifications were updated to remove this (being ill-defined what a "statement" was),
|
||||
// so, this became a warning. However, 3.0 tests still check for the error.
|
||||
if (isEsProfile() && version <= 300 && ! relaxedErrors())
|
||||
if (isEsProfile() && (version <= 300 || version >= 320) && ! relaxedErrors())
|
||||
error(loc, "last case/default label not followed by statements", "switch", "");
|
||||
else if (!isEsProfile() && (version <= 430 || version >= 460))
|
||||
error(loc, "last case/default label not followed by statements", "switch", "");
|
||||
else
|
||||
warn(loc, "last case/default label not followed by statements", "switch", "");
|
||||
|
||||
|
||||
// emulate a break for error recovery
|
||||
lastStatements = intermediate.makeAggregate(intermediate.addBranch(EOpBreak, loc));
|
||||
lastStatements->setOperator(EOpSequence);
|
||||
|
|
|
@ -241,6 +241,7 @@ protected:
|
|||
// override this to set the language-specific name
|
||||
virtual const char* getAtomicCounterBlockName() const { return ""; }
|
||||
virtual void setAtomicCounterBlockDefaults(TType&) const {}
|
||||
virtual void setInvariant(const TSourceLoc&, const char*) {}
|
||||
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
|
||||
bool isAtomicCounterBlock(const TSymbol& symbol) {
|
||||
const TVariable* var = symbol.getAsVariable();
|
||||
|
@ -470,6 +471,21 @@ public:
|
|||
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
||||
// Determine loop control from attributes
|
||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||
// Function attributes
|
||||
void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
|
||||
const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
|
||||
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
|
||||
TSpirvRequirement* spirvReq2);
|
||||
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
|
||||
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
|
||||
TSpirvTypeParameters* spirvTypeParams2);
|
||||
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
|
||||
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
|
||||
TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
|
||||
TSpirvInstruction* spirvInst2);
|
||||
#endif
|
||||
|
||||
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
|
||||
|
@ -495,6 +511,7 @@ protected:
|
|||
virtual const char* getAtomicCounterBlockName() const override;
|
||||
virtual void finalizeAtomicCounterBlockLayout(TVariable&) override;
|
||||
virtual void setAtomicCounterBlockDefaults(TType& block) const override;
|
||||
virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override;
|
||||
|
||||
public:
|
||||
//
|
||||
|
|
|
@ -586,6 +586,18 @@ void TScanContext::fillInKeywordMap()
|
|||
(*KeywordMap)["f64mat4x2"] = F64MAT4X2;
|
||||
(*KeywordMap)["f64mat4x3"] = F64MAT4X3;
|
||||
(*KeywordMap)["f64mat4x4"] = F64MAT4X4;
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
(*KeywordMap)["spirv_instruction"] = SPIRV_INSTRUCTION;
|
||||
(*KeywordMap)["spirv_execution_mode"] = SPIRV_EXECUTION_MODE;
|
||||
(*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID;
|
||||
(*KeywordMap)["spirv_decorate"] = SPIRV_DECORATE;
|
||||
(*KeywordMap)["spirv_decorate_id"] = SPIRV_DECORATE_ID;
|
||||
(*KeywordMap)["spirv_decorate_string"] = SPIRV_DECORATE_STRING;
|
||||
(*KeywordMap)["spirv_type"] = SPIRV_TYPE;
|
||||
(*KeywordMap)["spirv_storage_class"] = SPIRV_STORAGE_CLASS;
|
||||
(*KeywordMap)["spirv_by_reference"] = SPIRV_BY_REFERENCE;
|
||||
(*KeywordMap)["spirv_literal"] = SPIRV_LITERAL;
|
||||
#endif
|
||||
|
||||
(*KeywordMap)["sampler2D"] = SAMPLER2D;
|
||||
|
@ -1747,6 +1759,21 @@ int TScanContext::tokenizeIdentifier()
|
|||
return keyword;
|
||||
else
|
||||
return identifierOrType();
|
||||
|
||||
case SPIRV_INSTRUCTION:
|
||||
case SPIRV_EXECUTION_MODE:
|
||||
case SPIRV_EXECUTION_MODE_ID:
|
||||
case SPIRV_DECORATE:
|
||||
case SPIRV_DECORATE_ID:
|
||||
case SPIRV_DECORATE_STRING:
|
||||
case SPIRV_TYPE:
|
||||
case SPIRV_STORAGE_CLASS:
|
||||
case SPIRV_BY_REFERENCE:
|
||||
case SPIRV_LITERAL:
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
|
||||
return keyword;
|
||||
return identifierOrType();
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
|
|
@ -0,0 +1,350 @@
|
|||
//
|
||||
// Copyright(C) 2021 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
|
||||
//
|
||||
// GL_EXT_spirv_intrinsics
|
||||
//
|
||||
#include "../Include/intermediate.h"
|
||||
#include "../Include/SpirvIntrinsics.h"
|
||||
#include "../Include/Types.h"
|
||||
#include "ParseHelper.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
//
|
||||
// Handle SPIR-V requirements
|
||||
//
|
||||
TSpirvRequirement* TParseContext::makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
|
||||
const TIntermAggregate* extensions,
|
||||
const TIntermAggregate* capabilities)
|
||||
{
|
||||
TSpirvRequirement* spirvReq = new TSpirvRequirement;
|
||||
|
||||
if (name == "extensions") {
|
||||
assert(extensions);
|
||||
for (auto extension : extensions->getSequence()) {
|
||||
assert(extension->getAsConstantUnion());
|
||||
spirvReq->extensions.insert(*extension->getAsConstantUnion()->getConstArray()[0].getSConst());
|
||||
}
|
||||
} else if (name == "capabilities") {
|
||||
assert(capabilities);
|
||||
for (auto capability : capabilities->getSequence()) {
|
||||
assert(capability->getAsConstantUnion());
|
||||
spirvReq->capabilities.insert(capability->getAsConstantUnion()->getConstArray()[0].getIConst());
|
||||
}
|
||||
} else
|
||||
error(loc, "unknow SPIR-V requirement", name.c_str(), "");
|
||||
|
||||
return spirvReq;
|
||||
}
|
||||
|
||||
TSpirvRequirement* TParseContext::mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
|
||||
TSpirvRequirement* spirvReq2)
|
||||
{
|
||||
// Merge the second SPIR-V requirement to the first one
|
||||
if (!spirvReq2->extensions.empty()) {
|
||||
if (spirvReq1->extensions.empty())
|
||||
spirvReq1->extensions = spirvReq2->extensions;
|
||||
else
|
||||
error(loc, "too many SPIR-V requirements", "extensions", "");
|
||||
}
|
||||
|
||||
if (!spirvReq2->capabilities.empty()) {
|
||||
if (spirvReq1->capabilities.empty())
|
||||
spirvReq1->capabilities = spirvReq2->capabilities;
|
||||
else
|
||||
error(loc, "too many SPIR-V requirements", "capabilities", "");
|
||||
}
|
||||
|
||||
return spirvReq1;
|
||||
}
|
||||
|
||||
void TIntermediate::insertSpirvRequirement(const TSpirvRequirement* spirvReq)
|
||||
{
|
||||
if (!spirvRequirement)
|
||||
spirvRequirement = new TSpirvRequirement;
|
||||
|
||||
for (auto extension : spirvReq->extensions)
|
||||
spirvRequirement->extensions.insert(extension);
|
||||
|
||||
for (auto capability : spirvReq->capabilities)
|
||||
spirvRequirement->capabilities.insert(capability);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle SPIR-V execution modes
|
||||
//
|
||||
void TIntermediate::insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args)
|
||||
{
|
||||
if (!spirvExecutionMode)
|
||||
spirvExecutionMode = new TSpirvExecutionMode;
|
||||
|
||||
TVector<const TIntermConstantUnion*> extraOperands;
|
||||
if (args) {
|
||||
for (auto arg : args->getSequence()) {
|
||||
auto extraOperand = arg->getAsConstantUnion();
|
||||
assert(extraOperand != nullptr);
|
||||
extraOperands.push_back(extraOperand);
|
||||
}
|
||||
}
|
||||
spirvExecutionMode->modes[executionMode] = extraOperands;
|
||||
}
|
||||
|
||||
void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args)
|
||||
{
|
||||
if (!spirvExecutionMode)
|
||||
spirvExecutionMode = new TSpirvExecutionMode;
|
||||
|
||||
assert(args);
|
||||
TVector<const TIntermTyped*> extraOperands;
|
||||
|
||||
for (auto arg : args->getSequence()) {
|
||||
auto extraOperand = arg->getAsTyped();
|
||||
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
|
||||
extraOperands.push_back(extraOperand);
|
||||
}
|
||||
spirvExecutionMode->modeIds[executionMode] = extraOperands;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle SPIR-V decorate qualifiers
|
||||
//
|
||||
void TQualifier::setSpirvDecorate(int decoration, const TIntermAggregate* args)
|
||||
{
|
||||
if (!spirvDecorate)
|
||||
spirvDecorate = new TSpirvDecorate;
|
||||
|
||||
TVector<const TIntermConstantUnion*> extraOperands;
|
||||
if (args) {
|
||||
for (auto arg : args->getSequence()) {
|
||||
auto extraOperand = arg->getAsConstantUnion();
|
||||
assert(extraOperand != nullptr);
|
||||
extraOperands.push_back(extraOperand);
|
||||
}
|
||||
}
|
||||
spirvDecorate->decorates[decoration] = extraOperands;
|
||||
}
|
||||
|
||||
void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args)
|
||||
{
|
||||
if (!spirvDecorate)
|
||||
spirvDecorate = new TSpirvDecorate;
|
||||
|
||||
assert(args);
|
||||
TVector<const TIntermTyped*> extraOperands;
|
||||
for (auto arg : args->getSequence()) {
|
||||
auto extraOperand = arg->getAsTyped();
|
||||
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
|
||||
extraOperands.push_back(extraOperand);
|
||||
}
|
||||
spirvDecorate->decorateIds[decoration] = extraOperands;
|
||||
}
|
||||
|
||||
void TQualifier::setSpirvDecorateString(int decoration, const TIntermAggregate* args)
|
||||
{
|
||||
if (!spirvDecorate)
|
||||
spirvDecorate = new TSpirvDecorate;
|
||||
|
||||
assert(args);
|
||||
TVector<const TIntermConstantUnion*> extraOperands;
|
||||
for (auto arg : args->getSequence()) {
|
||||
auto extraOperand = arg->getAsConstantUnion();
|
||||
assert(extraOperand != nullptr);
|
||||
extraOperands.push_back(extraOperand);
|
||||
}
|
||||
spirvDecorate->decorateStrings[decoration] = extraOperands;
|
||||
}
|
||||
|
||||
TString TQualifier::getSpirvDecorateQualifierString() const
|
||||
{
|
||||
assert(spirvDecorate);
|
||||
|
||||
TString qualifierString;
|
||||
|
||||
const auto appendFloat = [&](float f) { qualifierString.append(std::to_string(f).c_str()); };
|
||||
const auto appendInt = [&](int i) { qualifierString.append(std::to_string(i).c_str()); };
|
||||
const auto appendUint = [&](unsigned int u) { qualifierString.append(std::to_string(u).c_str()); };
|
||||
const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
|
||||
const auto appendStr = [&](const char* s) { qualifierString.append(s); };
|
||||
|
||||
const auto appendDecorate = [&](const TIntermTyped* constant) {
|
||||
auto& constArray = constant->getAsConstantUnion() != nullptr ? constant->getAsConstantUnion()->getConstArray()
|
||||
: constant->getAsSymbolNode()->getConstArray();
|
||||
if (constant->getBasicType() == EbtFloat) {
|
||||
float value = static_cast<float>(constArray[0].getDConst());
|
||||
appendFloat(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtInt) {
|
||||
int value = constArray[0].getIConst();
|
||||
appendInt(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtUint) {
|
||||
unsigned value = constArray[0].getUConst();
|
||||
appendUint(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtBool) {
|
||||
bool value = constArray[0].getBConst();
|
||||
appendBool(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtString) {
|
||||
const TString* value = constArray[0].getSConst();
|
||||
appendStr(value->c_str());
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
};
|
||||
|
||||
for (auto& decorate : spirvDecorate->decorates) {
|
||||
appendStr("spirv_decorate(");
|
||||
appendInt(decorate.first);
|
||||
for (auto extraOperand : decorate.second) {
|
||||
appendStr(", ");
|
||||
appendDecorate(extraOperand);
|
||||
}
|
||||
appendStr(") ");
|
||||
}
|
||||
|
||||
for (auto& decorateId : spirvDecorate->decorateIds) {
|
||||
appendStr("spirv_decorate_id(");
|
||||
appendInt(decorateId.first);
|
||||
for (auto extraOperand : decorateId.second) {
|
||||
appendStr(", ");
|
||||
appendDecorate(extraOperand);
|
||||
}
|
||||
appendStr(") ");
|
||||
}
|
||||
|
||||
for (auto& decorateString : spirvDecorate->decorateStrings) {
|
||||
appendStr("spirv_decorate_string(");
|
||||
appendInt(decorateString.first);
|
||||
for (auto extraOperand : decorateString.second) {
|
||||
appendStr(", ");
|
||||
appendDecorate(extraOperand);
|
||||
}
|
||||
appendStr(") ");
|
||||
}
|
||||
|
||||
return qualifierString;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle SPIR-V type specifiers
|
||||
//
|
||||
void TPublicType::setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams)
|
||||
{
|
||||
if (!spirvType)
|
||||
spirvType = new TSpirvType;
|
||||
|
||||
basicType = EbtSpirvType;
|
||||
spirvType->spirvInst = spirvInst;
|
||||
if (typeParams)
|
||||
spirvType->typeParams = *typeParams;
|
||||
}
|
||||
|
||||
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant)
|
||||
{
|
||||
TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
|
||||
if (constant->getBasicType() != EbtFloat &&
|
||||
constant->getBasicType() != EbtInt &&
|
||||
constant->getBasicType() != EbtUint &&
|
||||
constant->getBasicType() != EbtBool &&
|
||||
constant->getBasicType() != EbtString)
|
||||
error(loc, "this type not allowed", constant->getType().getBasicString(), "");
|
||||
else {
|
||||
assert(constant);
|
||||
spirvTypeParams->push_back(TSpirvTypeParameter(constant));
|
||||
}
|
||||
|
||||
return spirvTypeParams;
|
||||
}
|
||||
|
||||
TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
|
||||
{
|
||||
// Merge SPIR-V type parameters of the second one to the first one
|
||||
for (const auto& spirvTypeParam : *spirvTypeParams2)
|
||||
spirvTypeParams1->push_back(spirvTypeParam);
|
||||
return spirvTypeParams1;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle SPIR-V instruction qualifiers
|
||||
//
|
||||
TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value)
|
||||
{
|
||||
TSpirvInstruction* spirvInst = new TSpirvInstruction;
|
||||
if (name == "set")
|
||||
spirvInst->set = value;
|
||||
else
|
||||
error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
|
||||
|
||||
return spirvInst;
|
||||
}
|
||||
|
||||
TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value)
|
||||
{
|
||||
TSpirvInstruction* spirvInstuction = new TSpirvInstruction;
|
||||
if (name == "id")
|
||||
spirvInstuction->id = value;
|
||||
else
|
||||
error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
|
||||
|
||||
return spirvInstuction;
|
||||
}
|
||||
|
||||
TSpirvInstruction* TParseContext::mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, TSpirvInstruction* spirvInst2)
|
||||
{
|
||||
// Merge qualifiers of the second SPIR-V instruction to those of the first one
|
||||
if (!spirvInst2->set.empty()) {
|
||||
if (spirvInst1->set.empty())
|
||||
spirvInst1->set = spirvInst2->set;
|
||||
else
|
||||
error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(set)");
|
||||
}
|
||||
|
||||
if (spirvInst2->id != -1) {
|
||||
if (spirvInst1->id == -1)
|
||||
spirvInst1->id = spirvInst2->id;
|
||||
else
|
||||
error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(id)");
|
||||
}
|
||||
|
||||
return spirvInst1;
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // GLSLANG_WEB
|
|
@ -77,6 +77,7 @@ void TType::buildMangledName(TString& mangledName) const
|
|||
case EbtAtomicUint: mangledName += "au"; break;
|
||||
case EbtAccStruct: mangledName += "as"; break;
|
||||
case EbtRayQuery: mangledName += "rq"; break;
|
||||
case EbtSpirvType: mangledName += "spv-t"; break;
|
||||
#endif
|
||||
case EbtSampler:
|
||||
switch (sampler.type) {
|
||||
|
@ -278,8 +279,14 @@ TFunction::~TFunction()
|
|||
//
|
||||
TSymbolTableLevel::~TSymbolTableLevel()
|
||||
{
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
|
||||
delete (*it).second;
|
||||
for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
|
||||
const TString& name = it->first;
|
||||
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
|
||||
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
|
||||
if (retargetIter == retargetedSymbols.end())
|
||||
delete (*it).second;
|
||||
}
|
||||
|
||||
|
||||
delete [] defaultPrecision;
|
||||
}
|
||||
|
@ -390,6 +397,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
|
|||
implicitThis = copyOf.implicitThis;
|
||||
illegalImplicitThis = copyOf.illegalImplicitThis;
|
||||
defaultParamCount = copyOf.defaultParamCount;
|
||||
#ifndef GLSLANG_WEB
|
||||
spirvInst = copyOf.spirvInst;
|
||||
#endif
|
||||
}
|
||||
|
||||
TFunction* TFunction::clone() const
|
||||
|
@ -414,6 +424,15 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
|||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||
symTableLevel->anonId = anonId;
|
||||
symTableLevel->thisLevel = thisLevel;
|
||||
symTableLevel->retargetedSymbols.clear();
|
||||
for (auto &s : retargetedSymbols) {
|
||||
// Extra constructions to make sure they use the correct allocator pool
|
||||
TString newFrom;
|
||||
newFrom = s.first;
|
||||
TString newTo;
|
||||
newTo = s.second;
|
||||
symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
|
||||
}
|
||||
std::vector<bool> containerCopied(anonId, false);
|
||||
tLevel::const_iterator iter;
|
||||
for (iter = level.begin(); iter != level.end(); ++iter) {
|
||||
|
@ -429,8 +448,25 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
|||
symTableLevel->insert(*container, false);
|
||||
containerCopied[anon->getAnonId()] = true;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
const TString& name = iter->first;
|
||||
auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
|
||||
[&name](const std::pair<TString, TString>& i) { return i.first == name; });
|
||||
if (retargetIter != retargetedSymbols.end())
|
||||
continue;
|
||||
symTableLevel->insert(*iter->second->clone(), false);
|
||||
}
|
||||
}
|
||||
// Now point retargeted symbols to the newly created versions of them
|
||||
for (auto &s : retargetedSymbols) {
|
||||
TSymbol* sym = symTableLevel->find(s.second);
|
||||
if (!sym)
|
||||
continue;
|
||||
|
||||
// Need to declare and assign so newS is using the correct pool allocator
|
||||
TString newS;
|
||||
newS = s.first;
|
||||
symTableLevel->insert(newS, sym);
|
||||
}
|
||||
|
||||
return symTableLevel;
|
||||
|
|
|
@ -319,6 +319,15 @@ public:
|
|||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
virtual void setSpirvInstruction(const TSpirvInstruction& inst)
|
||||
{
|
||||
relateToOperator(EOpSpirvInst);
|
||||
spirvInst = inst;
|
||||
}
|
||||
virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
|
||||
#endif
|
||||
|
||||
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
|
||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
||||
#endif
|
||||
|
@ -342,6 +351,10 @@ protected:
|
|||
// This is important for a static member function that has member variables in scope,
|
||||
// but is not allowed to use them, or see hidden symbols instead.
|
||||
int defaultParamCount;
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
|
||||
#endif
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -400,13 +413,20 @@ public:
|
|||
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
|
||||
~TSymbolTableLevel();
|
||||
|
||||
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
||||
bool insert(const TString& name, TSymbol* symbol) {
|
||||
return level.insert(tLevelPair(name, symbol)).second;
|
||||
}
|
||||
|
||||
bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
|
||||
{
|
||||
//
|
||||
// returning true means symbol was added to the table with no semantic errors
|
||||
//
|
||||
const TString& name = symbol.getName();
|
||||
if (name == "") {
|
||||
if (forcedKeyName.length()) {
|
||||
return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
|
||||
}
|
||||
else if (name == "") {
|
||||
symbol.getAsVariable()->setAnonId(anonId++);
|
||||
// An empty name means an anonymous container, exposing its members to the external scope.
|
||||
// Give it a name and insert its members in the symbol table, pointing to the container.
|
||||
|
@ -458,6 +478,16 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void retargetSymbol(const TString& from, const TString& to) {
|
||||
tLevel::const_iterator fromIt = level.find(from);
|
||||
tLevel::const_iterator toIt = level.find(to);
|
||||
if (fromIt == level.end() || toIt == level.end())
|
||||
return;
|
||||
delete fromIt->second;
|
||||
level[from] = toIt->second;
|
||||
retargetedSymbols.push_back({from, to});
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name) const
|
||||
{
|
||||
tLevel::const_iterator it = level.find(name);
|
||||
|
@ -570,6 +600,8 @@ protected:
|
|||
|
||||
tLevel level; // named mappings
|
||||
TPrecisionQualifier *defaultPrecision;
|
||||
// pair<FromName, ToName>
|
||||
TVector<std::pair<TString, TString>> retargetedSymbols;
|
||||
int anonId;
|
||||
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
|
||||
// that are supposed to see anonymous access to member variables.
|
||||
|
@ -775,6 +807,12 @@ public:
|
|||
return symbol;
|
||||
}
|
||||
|
||||
void retargetSymbol(const TString& from, const TString& to) {
|
||||
int level = currentLevel();
|
||||
table[level]->retargetSymbol(from, to);
|
||||
}
|
||||
|
||||
|
||||
// Find of a symbol that returns how many layers deep of nested
|
||||
// structures-with-member-functions ('this' scopes) deep the symbol was
|
||||
// found in.
|
||||
|
|
|
@ -165,7 +165,9 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
EShTargetLanguageVersion minSpvVersion;
|
||||
} extensionData;
|
||||
|
||||
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} };
|
||||
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
|
||||
{E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}
|
||||
};
|
||||
|
||||
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
|
||||
// Add only extensions which require > spv1.0 to save space in map
|
||||
|
@ -198,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shader_atomic_counter_ops] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
|
||||
|
@ -251,6 +254,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
|
||||
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable;
|
||||
|
||||
// #line and #include
|
||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||
|
@ -280,6 +284,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_ray_tracing_motion_blur] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
||||
|
@ -332,6 +337,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shared_memory_block] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable;
|
||||
|
||||
// OVR extensions
|
||||
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
||||
|
@ -353,6 +359,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_atomic_float2] = EBhDisable;
|
||||
}
|
||||
|
||||
#endif // GLSLANG_WEB
|
||||
|
@ -415,6 +422,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
}
|
||||
if (version >= 310) {
|
||||
preamble += "#define GL_EXT_null_initializer 1\n";
|
||||
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
|
||||
}
|
||||
|
||||
} else { // !isEsProfile()
|
||||
|
@ -474,6 +482,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_EXT_debug_printf 1\n"
|
||||
"#define GL_EXT_fragment_shading_rate 1\n"
|
||||
"#define GL_EXT_shared_memory_block 1\n"
|
||||
"#define GL_EXT_shader_integer_mix 1\n"
|
||||
|
||||
// GL_KHR_shader_subgroup
|
||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||
|
@ -491,6 +500,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_EXT_ray_tracing 1\n"
|
||||
"#define GL_EXT_ray_query 1\n"
|
||||
"#define GL_EXT_ray_flags_primitive_culling 1\n"
|
||||
"#define GL_EXT_spirv_intrinsics 1\n"
|
||||
|
||||
"#define GL_AMD_shader_ballot 1\n"
|
||||
"#define GL_AMD_shader_trinary_minmax 1\n"
|
||||
|
@ -513,6 +523,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_NV_shader_subgroup_partitioned 1\n"
|
||||
"#define GL_NV_shading_rate_image 1\n"
|
||||
"#define GL_NV_ray_tracing 1\n"
|
||||
"#define GL_NV_ray_tracing_motion_blur 1\n"
|
||||
"#define GL_NV_fragment_shader_barycentric 1\n"
|
||||
"#define GL_NV_compute_shader_derivatives 1\n"
|
||||
"#define GL_NV_shader_texture_footprint 1\n"
|
||||
|
@ -535,6 +546,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_EXT_shader_subgroup_extended_types_float16 1\n"
|
||||
|
||||
"#define GL_EXT_shader_atomic_float 1\n"
|
||||
"#define GL_EXT_shader_atomic_float2 1\n"
|
||||
;
|
||||
|
||||
if (version >= 150) {
|
||||
|
@ -546,6 +558,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
}
|
||||
if (version >= 140) {
|
||||
preamble += "#define GL_EXT_null_initializer 1\n";
|
||||
preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
|
||||
}
|
||||
#endif // GLSLANG_WEB
|
||||
}
|
||||
|
@ -599,6 +612,29 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
preamble += "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// GL_EXT_spirv_intrinsics
|
||||
if (!isEsProfile()) {
|
||||
switch (language) {
|
||||
case EShLangVertex: preamble += "#define GL_VERTEX_SHADER 1 \n"; break;
|
||||
case EShLangTessControl: preamble += "#define GL_TESSELLATION_CONTROL_SHADER 1 \n"; break;
|
||||
case EShLangTessEvaluation: preamble += "#define GL_TESSELLATION_EVALUATION_SHADER 1 \n"; break;
|
||||
case EShLangGeometry: preamble += "#define GL_GEOMETRY_SHADER 1 \n"; break;
|
||||
case EShLangFragment: preamble += "#define GL_FRAGMENT_SHADER 1 \n"; break;
|
||||
case EShLangCompute: preamble += "#define GL_COMPUTE_SHADER 1 \n"; break;
|
||||
case EShLangRayGen: preamble += "#define GL_RAY_GENERATION_SHADER_EXT 1 \n"; break;
|
||||
case EShLangIntersect: preamble += "#define GL_INTERSECTION_SHADER_EXT 1 \n"; break;
|
||||
case EShLangAnyHit: preamble += "#define GL_ANY_HIT_SHADER_EXT 1 \n"; break;
|
||||
case EShLangClosestHit: preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n"; break;
|
||||
case EShLangMiss: preamble += "#define GL_MISS_SHADER_EXT 1 \n"; break;
|
||||
case EShLangCallable: preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n"; break;
|
||||
case EShLangTaskNV: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break;
|
||||
case EShLangMeshNV: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -136,6 +136,7 @@ const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attri
|
|||
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
|
||||
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
|
||||
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
|
||||
const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops";
|
||||
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
|
||||
const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote";
|
||||
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
|
||||
|
@ -204,6 +205,8 @@ const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_s
|
|||
const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64";
|
||||
const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer";
|
||||
const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
|
||||
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
|
||||
const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics";
|
||||
|
||||
// Arrays of extensions for the above viewportEXTs duplications
|
||||
|
||||
|
@ -245,6 +248,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_
|
|||
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
|
||||
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
|
||||
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
|
||||
const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur";
|
||||
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
|
||||
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
|
||||
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
|
||||
|
@ -305,6 +309,7 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shad
|
|||
const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation";
|
||||
|
||||
const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
|
||||
const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2";
|
||||
|
||||
// Arrays of extensions for the above AEP duplications
|
||||
|
||||
|
|
|
@ -123,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
|
|||
return EatPeelCount;
|
||||
else if (name == "partial_count")
|
||||
return EatPartialCount;
|
||||
else if (name == "subgroup_uniform_control_flow")
|
||||
return EatSubgroupUniformControlFlow;
|
||||
else
|
||||
return EatNone;
|
||||
}
|
||||
|
@ -341,6 +343,29 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Function attributes
|
||||
//
|
||||
void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes)
|
||||
{
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
if (it->size() > 0) {
|
||||
warn(loc, "attribute with arguments not recognized, skipping", "", "");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (it->name) {
|
||||
case EatSubgroupUniformControlFlow:
|
||||
intermediate.setSubgroupUniformControlFlow();
|
||||
break;
|
||||
default:
|
||||
warn(loc, "attribute does not apply to a function", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // GLSLANG_WEB
|
||||
|
|
|
@ -118,7 +118,8 @@ namespace glslang {
|
|||
EatFormatR8ui,
|
||||
EatFormatUnknown,
|
||||
EatNonWritable,
|
||||
EatNonReadable
|
||||
EatNonReadable,
|
||||
EatSubgroupUniformControlFlow,
|
||||
};
|
||||
|
||||
class TIntermAggregate;
|
||||
|
|
|
@ -116,6 +116,9 @@ using namespace glslang;
|
|||
glslang::TIntermNodePair nodePair;
|
||||
glslang::TIntermTyped* intermTypedNode;
|
||||
glslang::TAttributes* attributes;
|
||||
glslang::TSpirvRequirement* spirvReq;
|
||||
glslang::TSpirvInstruction* spirvInst;
|
||||
glslang::TSpirvTypeParameters* spirvTypeParams;
|
||||
};
|
||||
union {
|
||||
glslang::TPublicType type;
|
||||
|
@ -271,6 +274,11 @@ GLSLANG_WEB_EXCLUDE_ON
|
|||
%token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS
|
||||
%token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS
|
||||
|
||||
// spirv intrinsics
|
||||
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
|
||||
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
|
||||
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
|
||||
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
|
||||
%token <lex> LEFT_OP RIGHT_OP
|
||||
|
@ -362,6 +370,19 @@ GLSLANG_WEB_EXCLUDE_ON
|
|||
%type <interm.attributes> attribute attribute_list single_attribute
|
||||
%type <interm.intermNode> demote_statement
|
||||
%type <interm.intermTypedNode> initializer_list
|
||||
%type <interm.spirvReq> spirv_requirements_list spirv_requirements_parameter
|
||||
%type <interm.intermNode> spirv_extension_list spirv_capability_list
|
||||
%type <interm.intermNode> spirv_execution_mode_qualifier
|
||||
%type <interm.intermNode> spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list
|
||||
%type <interm.type> spirv_storage_class_qualifier
|
||||
%type <interm.type> spirv_decorate_qualifier
|
||||
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
|
||||
%type <interm.intermNode> spirv_decorate_id_parameter_list
|
||||
%type <interm.intermNode> spirv_decorate_string_parameter_list
|
||||
%type <interm.type> spirv_type_specifier
|
||||
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
|
||||
%type <interm.spirvInst> spirv_instruction_qualifier
|
||||
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
|
||||
%start translation_unit
|
||||
|
@ -875,6 +896,20 @@ declaration
|
|||
$$ = 0;
|
||||
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
|
||||
}
|
||||
GLSLANG_WEB_EXCLUDE_ON
|
||||
| spirv_instruction_qualifier function_prototype SEMICOLON {
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
|
||||
$2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
|
||||
parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */);
|
||||
$$ = 0;
|
||||
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
|
||||
}
|
||||
| spirv_execution_mode_qualifier SEMICOLON {
|
||||
parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier");
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
|
||||
$$ = 0;
|
||||
}
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
| init_declarator_list SEMICOLON {
|
||||
if ($1.intermNode && $1.intermNode->getAsAggregate())
|
||||
$1.intermNode->getAsAggregate()->setOperator(EOpSequence);
|
||||
|
@ -944,6 +979,25 @@ function_prototype
|
|||
$$.function = $1;
|
||||
$$.loc = $2.loc;
|
||||
}
|
||||
| function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $1;
|
||||
$$.loc = $2.loc;
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||
}
|
||||
;
|
||||
|
||||
function_declarator
|
||||
|
@ -1347,6 +1401,25 @@ GLSLANG_WEB_EXCLUDE_ON
|
|||
| non_uniform_qualifier {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_storage_class_qualifier {
|
||||
parseContext.globalCheck($1.loc, "spirv_storage_class");
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier");
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_decorate_qualifier {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier");
|
||||
$$ = $1;
|
||||
}
|
||||
| SPIRV_BY_REFERENCE {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference");
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvByReference();
|
||||
}
|
||||
| SPIRV_LITERAL {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal");
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvLiteral();
|
||||
}
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
;
|
||||
|
||||
|
@ -3407,6 +3480,10 @@ GLSLANG_WEB_EXCLUDE_ON
|
|||
$$.basicType = EbtUint;
|
||||
$$.coopmat = true;
|
||||
}
|
||||
| spirv_type_specifier {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
|
||||
$$ = $1;
|
||||
}
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
| struct_specifier {
|
||||
$$ = $1;
|
||||
|
@ -3713,6 +3790,7 @@ selection_statement
|
|||
}
|
||||
GLSLANG_WEB_EXCLUDE_ON
|
||||
| attribute selection_statement_nonattributed {
|
||||
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
parseContext.handleSelectionAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
@ -3760,6 +3838,7 @@ switch_statement
|
|||
}
|
||||
GLSLANG_WEB_EXCLUDE_ON
|
||||
| attribute switch_statement_nonattributed {
|
||||
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
parseContext.handleSwitchAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
@ -3824,6 +3903,7 @@ iteration_statement
|
|||
}
|
||||
GLSLANG_WEB_EXCLUDE_ON
|
||||
| attribute iteration_statement_nonattributed {
|
||||
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
parseContext.handleLoopAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
@ -3846,6 +3926,7 @@ iteration_statement_nonattributed
|
|||
--parseContext.controlFlowNestingLevel;
|
||||
}
|
||||
| DO {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
++parseContext.statementNestingLevel;
|
||||
++parseContext.controlFlowNestingLevel;
|
||||
|
@ -3857,6 +3938,7 @@ iteration_statement_nonattributed
|
|||
parseContext.boolCheck($8.loc, $6);
|
||||
|
||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
--parseContext.loopNestingLevel;
|
||||
--parseContext.statementNestingLevel;
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
@ -4027,7 +4109,6 @@ GLSLANG_WEB_EXCLUDE_ON
|
|||
attribute
|
||||
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
|
||||
$$ = $3;
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
}
|
||||
|
||||
attribute_list
|
||||
|
@ -4047,4 +4128,270 @@ single_attribute
|
|||
}
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
|
||||
GLSLANG_WEB_EXCLUDE_ON
|
||||
spirv_requirements_list
|
||||
: spirv_requirements_parameter {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_requirements_list COMMA spirv_requirements_parameter {
|
||||
$$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3);
|
||||
}
|
||||
|
||||
spirv_requirements_parameter
|
||||
: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET {
|
||||
$$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr);
|
||||
}
|
||||
| IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET {
|
||||
$$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate());
|
||||
}
|
||||
|
||||
spirv_extension_list
|
||||
: STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
|
||||
}
|
||||
| spirv_extension_list COMMA STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
|
||||
}
|
||||
|
||||
spirv_capability_list
|
||||
: INTCONSTANT {
|
||||
$$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true));
|
||||
}
|
||||
| spirv_capability_list COMMA INTCONSTANT {
|
||||
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true));
|
||||
}
|
||||
|
||||
spirv_execution_mode_qualifier
|
||||
: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvExecutionMode($3.i);
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
parseContext.intermediate.insertSpirvExecutionMode($5.i);
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
|
||||
spirv_execution_mode_parameter_list
|
||||
: spirv_execution_mode_parameter {
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter {
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_execution_mode_parameter
|
||||
: FLOATCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
|
||||
}
|
||||
| INTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
|
||||
}
|
||||
| BOOLCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
|
||||
}
|
||||
| STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
|
||||
}
|
||||
|
||||
spirv_execution_mode_id_parameter_list
|
||||
: constant_expression {
|
||||
if ($1->getBasicType() != EbtFloat &&
|
||||
$1->getBasicType() != EbtInt &&
|
||||
$1->getBasicType() != EbtUint &&
|
||||
$1->getBasicType() != EbtBool &&
|
||||
$1->getBasicType() != EbtString)
|
||||
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_execution_mode_id_parameter_list COMMA constant_expression {
|
||||
if ($3->getBasicType() != EbtFloat &&
|
||||
$3->getBasicType() != EbtInt &&
|
||||
$3->getBasicType() != EbtUint &&
|
||||
$3->getBasicType() != EbtBool &&
|
||||
$3->getBasicType() != EbtString)
|
||||
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_storage_class_qualifier
|
||||
: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.storage = EvqSpirvStorageClass;
|
||||
$$.qualifier.spirvStorageClass = $3.i;
|
||||
}
|
||||
| SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.storage = EvqSpirvStorageClass;
|
||||
$$.qualifier.spirvStorageClass = $5.i;
|
||||
}
|
||||
|
||||
spirv_decorate_qualifier
|
||||
: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorate($3.i);
|
||||
}
|
||||
| SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorate($5.i);
|
||||
}
|
||||
| SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate());
|
||||
}
|
||||
|
||||
spirv_decorate_parameter_list
|
||||
: spirv_decorate_parameter {
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_decorate_parameter_list COMMA spirv_decorate_parameter {
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_decorate_parameter
|
||||
: FLOATCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
|
||||
}
|
||||
| INTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
|
||||
}
|
||||
| BOOLCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
|
||||
}
|
||||
|
||||
spirv_decorate_id_parameter_list
|
||||
: constant_expression {
|
||||
if ($1->getBasicType() != EbtFloat &&
|
||||
$1->getBasicType() != EbtInt &&
|
||||
$1->getBasicType() != EbtUint &&
|
||||
$1->getBasicType() != EbtBool)
|
||||
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_decorate_id_parameter_list COMMA constant_expression {
|
||||
if ($3->getBasicType() != EbtFloat &&
|
||||
$3->getBasicType() != EbtInt &&
|
||||
$3->getBasicType() != EbtUint &&
|
||||
$3->getBasicType() != EbtBool)
|
||||
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_decorate_string_parameter_list
|
||||
: STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.makeAggregate(
|
||||
parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
|
||||
}
|
||||
| spirv_decorate_string_parameter_list COMMA STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
|
||||
}
|
||||
|
||||
spirv_type_specifier
|
||||
: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.setSpirvType(*$3, $5);
|
||||
}
|
||||
| SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.setSpirvType(*$5, $7);
|
||||
}
|
||||
| SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.setSpirvType(*$3);
|
||||
}
|
||||
| SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.setSpirvType(*$5);
|
||||
}
|
||||
|
||||
spirv_type_parameter_list
|
||||
: spirv_type_parameter {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_type_parameter_list COMMA spirv_type_parameter {
|
||||
$$ = parseContext.mergeSpirvTypeParameters($1, $3);
|
||||
}
|
||||
|
||||
spirv_type_parameter
|
||||
: constant_expression {
|
||||
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
|
||||
}
|
||||
|
||||
spirv_instruction_qualifier
|
||||
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
$$ = $3;
|
||||
}
|
||||
| SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$ = $5;
|
||||
}
|
||||
|
||||
spirv_instruction_qualifier_list
|
||||
: spirv_instruction_qualifier_id {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id {
|
||||
$$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3);
|
||||
}
|
||||
|
||||
spirv_instruction_qualifier_id
|
||||
: IDENTIFIER EQUAL STRING_LITERAL {
|
||||
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string);
|
||||
}
|
||||
| IDENTIFIER EQUAL INTCONSTANT {
|
||||
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
|
||||
}
|
||||
GLSLANG_WEB_EXCLUDE_OFF
|
||||
|
||||
%%
|
||||
|
|
|
@ -116,6 +116,9 @@ using namespace glslang;
|
|||
glslang::TIntermNodePair nodePair;
|
||||
glslang::TIntermTyped* intermTypedNode;
|
||||
glslang::TAttributes* attributes;
|
||||
glslang::TSpirvRequirement* spirvReq;
|
||||
glslang::TSpirvInstruction* spirvInst;
|
||||
glslang::TSpirvTypeParameters* spirvTypeParams;
|
||||
};
|
||||
union {
|
||||
glslang::TPublicType type;
|
||||
|
@ -271,6 +274,11 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
|||
%token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS
|
||||
%token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS
|
||||
|
||||
// spirv intrinsics
|
||||
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
|
||||
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
|
||||
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
|
||||
|
||||
|
||||
|
||||
%token <lex> LEFT_OP RIGHT_OP
|
||||
|
@ -362,6 +370,19 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
|||
%type <interm.attributes> attribute attribute_list single_attribute
|
||||
%type <interm.intermNode> demote_statement
|
||||
%type <interm.intermTypedNode> initializer_list
|
||||
%type <interm.spirvReq> spirv_requirements_list spirv_requirements_parameter
|
||||
%type <interm.intermNode> spirv_extension_list spirv_capability_list
|
||||
%type <interm.intermNode> spirv_execution_mode_qualifier
|
||||
%type <interm.intermNode> spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list
|
||||
%type <interm.type> spirv_storage_class_qualifier
|
||||
%type <interm.type> spirv_decorate_qualifier
|
||||
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
|
||||
%type <interm.intermNode> spirv_decorate_id_parameter_list
|
||||
%type <interm.intermNode> spirv_decorate_string_parameter_list
|
||||
%type <interm.type> spirv_type_specifier
|
||||
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
|
||||
%type <interm.spirvInst> spirv_instruction_qualifier
|
||||
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
|
||||
|
||||
|
||||
%start translation_unit
|
||||
|
@ -875,6 +896,20 @@ declaration
|
|||
$$ = 0;
|
||||
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
|
||||
}
|
||||
|
||||
| spirv_instruction_qualifier function_prototype SEMICOLON {
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
|
||||
$2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
|
||||
parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */);
|
||||
$$ = 0;
|
||||
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
|
||||
}
|
||||
| spirv_execution_mode_qualifier SEMICOLON {
|
||||
parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier");
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
|
||||
$$ = 0;
|
||||
}
|
||||
|
||||
| init_declarator_list SEMICOLON {
|
||||
if ($1.intermNode && $1.intermNode->getAsAggregate())
|
||||
$1.intermNode->getAsAggregate()->setOperator(EOpSequence);
|
||||
|
@ -944,6 +979,25 @@ function_prototype
|
|||
$$.function = $1;
|
||||
$$.loc = $2.loc;
|
||||
}
|
||||
| function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $1;
|
||||
$$.loc = $2.loc;
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $2;
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||
}
|
||||
;
|
||||
|
||||
function_declarator
|
||||
|
@ -1347,6 +1401,25 @@ single_type_qualifier
|
|||
| non_uniform_qualifier {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_storage_class_qualifier {
|
||||
parseContext.globalCheck($1.loc, "spirv_storage_class");
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier");
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_decorate_qualifier {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier");
|
||||
$$ = $1;
|
||||
}
|
||||
| SPIRV_BY_REFERENCE {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference");
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvByReference();
|
||||
}
|
||||
| SPIRV_LITERAL {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal");
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvLiteral();
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
@ -3407,6 +3480,10 @@ type_specifier_nonarray
|
|||
$$.basicType = EbtUint;
|
||||
$$.coopmat = true;
|
||||
}
|
||||
| spirv_type_specifier {
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
| struct_specifier {
|
||||
$$ = $1;
|
||||
|
@ -3713,6 +3790,7 @@ selection_statement
|
|||
}
|
||||
|
||||
| attribute selection_statement_nonattributed {
|
||||
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
parseContext.handleSelectionAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
@ -3760,6 +3838,7 @@ switch_statement
|
|||
}
|
||||
|
||||
| attribute switch_statement_nonattributed {
|
||||
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
parseContext.handleSwitchAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
@ -3824,6 +3903,7 @@ iteration_statement
|
|||
}
|
||||
|
||||
| attribute iteration_statement_nonattributed {
|
||||
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
parseContext.handleLoopAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
@ -3846,6 +3926,7 @@ iteration_statement_nonattributed
|
|||
--parseContext.controlFlowNestingLevel;
|
||||
}
|
||||
| DO {
|
||||
parseContext.symbolTable.push();
|
||||
++parseContext.loopNestingLevel;
|
||||
++parseContext.statementNestingLevel;
|
||||
++parseContext.controlFlowNestingLevel;
|
||||
|
@ -3857,6 +3938,7 @@ iteration_statement_nonattributed
|
|||
parseContext.boolCheck($8.loc, $6);
|
||||
|
||||
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
--parseContext.loopNestingLevel;
|
||||
--parseContext.statementNestingLevel;
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
@ -4027,7 +4109,6 @@ function_definition
|
|||
attribute
|
||||
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
|
||||
$$ = $3;
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
}
|
||||
|
||||
attribute_list
|
||||
|
@ -4047,4 +4128,270 @@ single_attribute
|
|||
}
|
||||
|
||||
|
||||
|
||||
spirv_requirements_list
|
||||
: spirv_requirements_parameter {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_requirements_list COMMA spirv_requirements_parameter {
|
||||
$$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3);
|
||||
}
|
||||
|
||||
spirv_requirements_parameter
|
||||
: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET {
|
||||
$$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr);
|
||||
}
|
||||
| IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET {
|
||||
$$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate());
|
||||
}
|
||||
|
||||
spirv_extension_list
|
||||
: STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
|
||||
}
|
||||
| spirv_extension_list COMMA STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
|
||||
}
|
||||
|
||||
spirv_capability_list
|
||||
: INTCONSTANT {
|
||||
$$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true));
|
||||
}
|
||||
| spirv_capability_list COMMA INTCONSTANT {
|
||||
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true));
|
||||
}
|
||||
|
||||
spirv_execution_mode_qualifier
|
||||
: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvExecutionMode($3.i);
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
parseContext.intermediate.insertSpirvExecutionMode($5.i);
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
| SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate());
|
||||
$$ = 0;
|
||||
}
|
||||
|
||||
spirv_execution_mode_parameter_list
|
||||
: spirv_execution_mode_parameter {
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter {
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_execution_mode_parameter
|
||||
: FLOATCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
|
||||
}
|
||||
| INTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
|
||||
}
|
||||
| BOOLCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
|
||||
}
|
||||
| STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
|
||||
}
|
||||
|
||||
spirv_execution_mode_id_parameter_list
|
||||
: constant_expression {
|
||||
if ($1->getBasicType() != EbtFloat &&
|
||||
$1->getBasicType() != EbtInt &&
|
||||
$1->getBasicType() != EbtUint &&
|
||||
$1->getBasicType() != EbtBool &&
|
||||
$1->getBasicType() != EbtString)
|
||||
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_execution_mode_id_parameter_list COMMA constant_expression {
|
||||
if ($3->getBasicType() != EbtFloat &&
|
||||
$3->getBasicType() != EbtInt &&
|
||||
$3->getBasicType() != EbtUint &&
|
||||
$3->getBasicType() != EbtBool &&
|
||||
$3->getBasicType() != EbtString)
|
||||
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_storage_class_qualifier
|
||||
: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.storage = EvqSpirvStorageClass;
|
||||
$$.qualifier.spirvStorageClass = $3.i;
|
||||
}
|
||||
| SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.storage = EvqSpirvStorageClass;
|
||||
$$.qualifier.spirvStorageClass = $5.i;
|
||||
}
|
||||
|
||||
spirv_decorate_qualifier
|
||||
: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorate($3.i);
|
||||
}
|
||||
| SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorate($5.i);
|
||||
}
|
||||
| SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate());
|
||||
}
|
||||
| SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc);
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate());
|
||||
}
|
||||
|
||||
spirv_decorate_parameter_list
|
||||
: spirv_decorate_parameter {
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_decorate_parameter_list COMMA spirv_decorate_parameter {
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_decorate_parameter
|
||||
: FLOATCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
|
||||
}
|
||||
| INTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
|
||||
}
|
||||
| BOOLCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
|
||||
}
|
||||
|
||||
spirv_decorate_id_parameter_list
|
||||
: constant_expression {
|
||||
if ($1->getBasicType() != EbtFloat &&
|
||||
$1->getBasicType() != EbtInt &&
|
||||
$1->getBasicType() != EbtUint &&
|
||||
$1->getBasicType() != EbtBool)
|
||||
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_decorate_id_parameter_list COMMA constant_expression {
|
||||
if ($3->getBasicType() != EbtFloat &&
|
||||
$3->getBasicType() != EbtInt &&
|
||||
$3->getBasicType() != EbtUint &&
|
||||
$3->getBasicType() != EbtBool)
|
||||
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_decorate_string_parameter_list
|
||||
: STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.makeAggregate(
|
||||
parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
|
||||
}
|
||||
| spirv_decorate_string_parameter_list COMMA STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
|
||||
}
|
||||
|
||||
spirv_type_specifier
|
||||
: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.setSpirvType(*$3, $5);
|
||||
}
|
||||
| SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.setSpirvType(*$5, $7);
|
||||
}
|
||||
| SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.setSpirvType(*$3);
|
||||
}
|
||||
| SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$.setSpirvType(*$5);
|
||||
}
|
||||
|
||||
spirv_type_parameter_list
|
||||
: spirv_type_parameter {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_type_parameter_list COMMA spirv_type_parameter {
|
||||
$$ = parseContext.mergeSpirvTypeParameters($1, $3);
|
||||
}
|
||||
|
||||
spirv_type_parameter
|
||||
: constant_expression {
|
||||
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
|
||||
}
|
||||
|
||||
spirv_instruction_qualifier
|
||||
: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
$$ = $3;
|
||||
}
|
||||
| SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
|
||||
parseContext.intermediate.insertSpirvRequirement($3);
|
||||
$$ = $5;
|
||||
}
|
||||
|
||||
spirv_instruction_qualifier_list
|
||||
: spirv_instruction_qualifier_id {
|
||||
$$ = $1;
|
||||
}
|
||||
| spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id {
|
||||
$$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3);
|
||||
}
|
||||
|
||||
spirv_instruction_qualifier_id
|
||||
: IDENTIFIER EQUAL STRING_LITERAL {
|
||||
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string);
|
||||
}
|
||||
| IDENTIFIER EQUAL INTCONSTANT {
|
||||
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
|
||||
}
|
||||
|
||||
|
||||
%%
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -368,134 +368,144 @@ extern int yydebug;
|
|||
USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */
|
||||
F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */
|
||||
F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */
|
||||
LEFT_OP = 572, /* LEFT_OP */
|
||||
RIGHT_OP = 573, /* RIGHT_OP */
|
||||
INC_OP = 574, /* INC_OP */
|
||||
DEC_OP = 575, /* DEC_OP */
|
||||
LE_OP = 576, /* LE_OP */
|
||||
GE_OP = 577, /* GE_OP */
|
||||
EQ_OP = 578, /* EQ_OP */
|
||||
NE_OP = 579, /* NE_OP */
|
||||
AND_OP = 580, /* AND_OP */
|
||||
OR_OP = 581, /* OR_OP */
|
||||
XOR_OP = 582, /* XOR_OP */
|
||||
MUL_ASSIGN = 583, /* MUL_ASSIGN */
|
||||
DIV_ASSIGN = 584, /* DIV_ASSIGN */
|
||||
ADD_ASSIGN = 585, /* ADD_ASSIGN */
|
||||
MOD_ASSIGN = 586, /* MOD_ASSIGN */
|
||||
LEFT_ASSIGN = 587, /* LEFT_ASSIGN */
|
||||
RIGHT_ASSIGN = 588, /* RIGHT_ASSIGN */
|
||||
AND_ASSIGN = 589, /* AND_ASSIGN */
|
||||
XOR_ASSIGN = 590, /* XOR_ASSIGN */
|
||||
OR_ASSIGN = 591, /* OR_ASSIGN */
|
||||
SUB_ASSIGN = 592, /* SUB_ASSIGN */
|
||||
STRING_LITERAL = 593, /* STRING_LITERAL */
|
||||
LEFT_PAREN = 594, /* LEFT_PAREN */
|
||||
RIGHT_PAREN = 595, /* RIGHT_PAREN */
|
||||
LEFT_BRACKET = 596, /* LEFT_BRACKET */
|
||||
RIGHT_BRACKET = 597, /* RIGHT_BRACKET */
|
||||
LEFT_BRACE = 598, /* LEFT_BRACE */
|
||||
RIGHT_BRACE = 599, /* RIGHT_BRACE */
|
||||
DOT = 600, /* DOT */
|
||||
COMMA = 601, /* COMMA */
|
||||
COLON = 602, /* COLON */
|
||||
EQUAL = 603, /* EQUAL */
|
||||
SEMICOLON = 604, /* SEMICOLON */
|
||||
BANG = 605, /* BANG */
|
||||
DASH = 606, /* DASH */
|
||||
TILDE = 607, /* TILDE */
|
||||
PLUS = 608, /* PLUS */
|
||||
STAR = 609, /* STAR */
|
||||
SLASH = 610, /* SLASH */
|
||||
PERCENT = 611, /* PERCENT */
|
||||
LEFT_ANGLE = 612, /* LEFT_ANGLE */
|
||||
RIGHT_ANGLE = 613, /* RIGHT_ANGLE */
|
||||
VERTICAL_BAR = 614, /* VERTICAL_BAR */
|
||||
CARET = 615, /* CARET */
|
||||
AMPERSAND = 616, /* AMPERSAND */
|
||||
QUESTION = 617, /* QUESTION */
|
||||
INVARIANT = 618, /* INVARIANT */
|
||||
HIGH_PRECISION = 619, /* HIGH_PRECISION */
|
||||
MEDIUM_PRECISION = 620, /* MEDIUM_PRECISION */
|
||||
LOW_PRECISION = 621, /* LOW_PRECISION */
|
||||
PRECISION = 622, /* PRECISION */
|
||||
PACKED = 623, /* PACKED */
|
||||
RESOURCE = 624, /* RESOURCE */
|
||||
SUPERP = 625, /* SUPERP */
|
||||
FLOATCONSTANT = 626, /* FLOATCONSTANT */
|
||||
INTCONSTANT = 627, /* INTCONSTANT */
|
||||
UINTCONSTANT = 628, /* UINTCONSTANT */
|
||||
BOOLCONSTANT = 629, /* BOOLCONSTANT */
|
||||
IDENTIFIER = 630, /* IDENTIFIER */
|
||||
TYPE_NAME = 631, /* TYPE_NAME */
|
||||
CENTROID = 632, /* CENTROID */
|
||||
IN = 633, /* IN */
|
||||
OUT = 634, /* OUT */
|
||||
INOUT = 635, /* INOUT */
|
||||
STRUCT = 636, /* STRUCT */
|
||||
VOID = 637, /* VOID */
|
||||
WHILE = 638, /* WHILE */
|
||||
BREAK = 639, /* BREAK */
|
||||
CONTINUE = 640, /* CONTINUE */
|
||||
DO = 641, /* DO */
|
||||
ELSE = 642, /* ELSE */
|
||||
FOR = 643, /* FOR */
|
||||
IF = 644, /* IF */
|
||||
DISCARD = 645, /* DISCARD */
|
||||
RETURN = 646, /* RETURN */
|
||||
SWITCH = 647, /* SWITCH */
|
||||
CASE = 648, /* CASE */
|
||||
DEFAULT = 649, /* DEFAULT */
|
||||
TERMINATE_INVOCATION = 650, /* TERMINATE_INVOCATION */
|
||||
TERMINATE_RAY = 651, /* TERMINATE_RAY */
|
||||
IGNORE_INTERSECTION = 652, /* IGNORE_INTERSECTION */
|
||||
UNIFORM = 653, /* UNIFORM */
|
||||
SHARED = 654, /* SHARED */
|
||||
BUFFER = 655, /* BUFFER */
|
||||
FLAT = 656, /* FLAT */
|
||||
SMOOTH = 657, /* SMOOTH */
|
||||
LAYOUT = 658, /* LAYOUT */
|
||||
DOUBLECONSTANT = 659, /* DOUBLECONSTANT */
|
||||
INT16CONSTANT = 660, /* INT16CONSTANT */
|
||||
UINT16CONSTANT = 661, /* UINT16CONSTANT */
|
||||
FLOAT16CONSTANT = 662, /* FLOAT16CONSTANT */
|
||||
INT32CONSTANT = 663, /* INT32CONSTANT */
|
||||
UINT32CONSTANT = 664, /* UINT32CONSTANT */
|
||||
INT64CONSTANT = 665, /* INT64CONSTANT */
|
||||
UINT64CONSTANT = 666, /* UINT64CONSTANT */
|
||||
SUBROUTINE = 667, /* SUBROUTINE */
|
||||
DEMOTE = 668, /* DEMOTE */
|
||||
PAYLOADNV = 669, /* PAYLOADNV */
|
||||
PAYLOADINNV = 670, /* PAYLOADINNV */
|
||||
HITATTRNV = 671, /* HITATTRNV */
|
||||
CALLDATANV = 672, /* CALLDATANV */
|
||||
CALLDATAINNV = 673, /* CALLDATAINNV */
|
||||
PAYLOADEXT = 674, /* PAYLOADEXT */
|
||||
PAYLOADINEXT = 675, /* PAYLOADINEXT */
|
||||
HITATTREXT = 676, /* HITATTREXT */
|
||||
CALLDATAEXT = 677, /* CALLDATAEXT */
|
||||
CALLDATAINEXT = 678, /* CALLDATAINEXT */
|
||||
PATCH = 679, /* PATCH */
|
||||
SAMPLE = 680, /* SAMPLE */
|
||||
NONUNIFORM = 681, /* NONUNIFORM */
|
||||
COHERENT = 682, /* COHERENT */
|
||||
VOLATILE = 683, /* VOLATILE */
|
||||
RESTRICT = 684, /* RESTRICT */
|
||||
READONLY = 685, /* READONLY */
|
||||
WRITEONLY = 686, /* WRITEONLY */
|
||||
DEVICECOHERENT = 687, /* DEVICECOHERENT */
|
||||
QUEUEFAMILYCOHERENT = 688, /* QUEUEFAMILYCOHERENT */
|
||||
WORKGROUPCOHERENT = 689, /* WORKGROUPCOHERENT */
|
||||
SUBGROUPCOHERENT = 690, /* SUBGROUPCOHERENT */
|
||||
NONPRIVATE = 691, /* NONPRIVATE */
|
||||
SHADERCALLCOHERENT = 692, /* SHADERCALLCOHERENT */
|
||||
NOPERSPECTIVE = 693, /* NOPERSPECTIVE */
|
||||
EXPLICITINTERPAMD = 694, /* EXPLICITINTERPAMD */
|
||||
PERVERTEXNV = 695, /* PERVERTEXNV */
|
||||
PERPRIMITIVENV = 696, /* PERPRIMITIVENV */
|
||||
PERVIEWNV = 697, /* PERVIEWNV */
|
||||
PERTASKNV = 698, /* PERTASKNV */
|
||||
PRECISE = 699 /* PRECISE */
|
||||
SPIRV_INSTRUCTION = 572, /* SPIRV_INSTRUCTION */
|
||||
SPIRV_EXECUTION_MODE = 573, /* SPIRV_EXECUTION_MODE */
|
||||
SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID */
|
||||
SPIRV_DECORATE = 575, /* SPIRV_DECORATE */
|
||||
SPIRV_DECORATE_ID = 576, /* SPIRV_DECORATE_ID */
|
||||
SPIRV_DECORATE_STRING = 577, /* SPIRV_DECORATE_STRING */
|
||||
SPIRV_TYPE = 578, /* SPIRV_TYPE */
|
||||
SPIRV_STORAGE_CLASS = 579, /* SPIRV_STORAGE_CLASS */
|
||||
SPIRV_BY_REFERENCE = 580, /* SPIRV_BY_REFERENCE */
|
||||
SPIRV_LITERAL = 581, /* SPIRV_LITERAL */
|
||||
LEFT_OP = 582, /* LEFT_OP */
|
||||
RIGHT_OP = 583, /* RIGHT_OP */
|
||||
INC_OP = 584, /* INC_OP */
|
||||
DEC_OP = 585, /* DEC_OP */
|
||||
LE_OP = 586, /* LE_OP */
|
||||
GE_OP = 587, /* GE_OP */
|
||||
EQ_OP = 588, /* EQ_OP */
|
||||
NE_OP = 589, /* NE_OP */
|
||||
AND_OP = 590, /* AND_OP */
|
||||
OR_OP = 591, /* OR_OP */
|
||||
XOR_OP = 592, /* XOR_OP */
|
||||
MUL_ASSIGN = 593, /* MUL_ASSIGN */
|
||||
DIV_ASSIGN = 594, /* DIV_ASSIGN */
|
||||
ADD_ASSIGN = 595, /* ADD_ASSIGN */
|
||||
MOD_ASSIGN = 596, /* MOD_ASSIGN */
|
||||
LEFT_ASSIGN = 597, /* LEFT_ASSIGN */
|
||||
RIGHT_ASSIGN = 598, /* RIGHT_ASSIGN */
|
||||
AND_ASSIGN = 599, /* AND_ASSIGN */
|
||||
XOR_ASSIGN = 600, /* XOR_ASSIGN */
|
||||
OR_ASSIGN = 601, /* OR_ASSIGN */
|
||||
SUB_ASSIGN = 602, /* SUB_ASSIGN */
|
||||
STRING_LITERAL = 603, /* STRING_LITERAL */
|
||||
LEFT_PAREN = 604, /* LEFT_PAREN */
|
||||
RIGHT_PAREN = 605, /* RIGHT_PAREN */
|
||||
LEFT_BRACKET = 606, /* LEFT_BRACKET */
|
||||
RIGHT_BRACKET = 607, /* RIGHT_BRACKET */
|
||||
LEFT_BRACE = 608, /* LEFT_BRACE */
|
||||
RIGHT_BRACE = 609, /* RIGHT_BRACE */
|
||||
DOT = 610, /* DOT */
|
||||
COMMA = 611, /* COMMA */
|
||||
COLON = 612, /* COLON */
|
||||
EQUAL = 613, /* EQUAL */
|
||||
SEMICOLON = 614, /* SEMICOLON */
|
||||
BANG = 615, /* BANG */
|
||||
DASH = 616, /* DASH */
|
||||
TILDE = 617, /* TILDE */
|
||||
PLUS = 618, /* PLUS */
|
||||
STAR = 619, /* STAR */
|
||||
SLASH = 620, /* SLASH */
|
||||
PERCENT = 621, /* PERCENT */
|
||||
LEFT_ANGLE = 622, /* LEFT_ANGLE */
|
||||
RIGHT_ANGLE = 623, /* RIGHT_ANGLE */
|
||||
VERTICAL_BAR = 624, /* VERTICAL_BAR */
|
||||
CARET = 625, /* CARET */
|
||||
AMPERSAND = 626, /* AMPERSAND */
|
||||
QUESTION = 627, /* QUESTION */
|
||||
INVARIANT = 628, /* INVARIANT */
|
||||
HIGH_PRECISION = 629, /* HIGH_PRECISION */
|
||||
MEDIUM_PRECISION = 630, /* MEDIUM_PRECISION */
|
||||
LOW_PRECISION = 631, /* LOW_PRECISION */
|
||||
PRECISION = 632, /* PRECISION */
|
||||
PACKED = 633, /* PACKED */
|
||||
RESOURCE = 634, /* RESOURCE */
|
||||
SUPERP = 635, /* SUPERP */
|
||||
FLOATCONSTANT = 636, /* FLOATCONSTANT */
|
||||
INTCONSTANT = 637, /* INTCONSTANT */
|
||||
UINTCONSTANT = 638, /* UINTCONSTANT */
|
||||
BOOLCONSTANT = 639, /* BOOLCONSTANT */
|
||||
IDENTIFIER = 640, /* IDENTIFIER */
|
||||
TYPE_NAME = 641, /* TYPE_NAME */
|
||||
CENTROID = 642, /* CENTROID */
|
||||
IN = 643, /* IN */
|
||||
OUT = 644, /* OUT */
|
||||
INOUT = 645, /* INOUT */
|
||||
STRUCT = 646, /* STRUCT */
|
||||
VOID = 647, /* VOID */
|
||||
WHILE = 648, /* WHILE */
|
||||
BREAK = 649, /* BREAK */
|
||||
CONTINUE = 650, /* CONTINUE */
|
||||
DO = 651, /* DO */
|
||||
ELSE = 652, /* ELSE */
|
||||
FOR = 653, /* FOR */
|
||||
IF = 654, /* IF */
|
||||
DISCARD = 655, /* DISCARD */
|
||||
RETURN = 656, /* RETURN */
|
||||
SWITCH = 657, /* SWITCH */
|
||||
CASE = 658, /* CASE */
|
||||
DEFAULT = 659, /* DEFAULT */
|
||||
TERMINATE_INVOCATION = 660, /* TERMINATE_INVOCATION */
|
||||
TERMINATE_RAY = 661, /* TERMINATE_RAY */
|
||||
IGNORE_INTERSECTION = 662, /* IGNORE_INTERSECTION */
|
||||
UNIFORM = 663, /* UNIFORM */
|
||||
SHARED = 664, /* SHARED */
|
||||
BUFFER = 665, /* BUFFER */
|
||||
FLAT = 666, /* FLAT */
|
||||
SMOOTH = 667, /* SMOOTH */
|
||||
LAYOUT = 668, /* LAYOUT */
|
||||
DOUBLECONSTANT = 669, /* DOUBLECONSTANT */
|
||||
INT16CONSTANT = 670, /* INT16CONSTANT */
|
||||
UINT16CONSTANT = 671, /* UINT16CONSTANT */
|
||||
FLOAT16CONSTANT = 672, /* FLOAT16CONSTANT */
|
||||
INT32CONSTANT = 673, /* INT32CONSTANT */
|
||||
UINT32CONSTANT = 674, /* UINT32CONSTANT */
|
||||
INT64CONSTANT = 675, /* INT64CONSTANT */
|
||||
UINT64CONSTANT = 676, /* UINT64CONSTANT */
|
||||
SUBROUTINE = 677, /* SUBROUTINE */
|
||||
DEMOTE = 678, /* DEMOTE */
|
||||
PAYLOADNV = 679, /* PAYLOADNV */
|
||||
PAYLOADINNV = 680, /* PAYLOADINNV */
|
||||
HITATTRNV = 681, /* HITATTRNV */
|
||||
CALLDATANV = 682, /* CALLDATANV */
|
||||
CALLDATAINNV = 683, /* CALLDATAINNV */
|
||||
PAYLOADEXT = 684, /* PAYLOADEXT */
|
||||
PAYLOADINEXT = 685, /* PAYLOADINEXT */
|
||||
HITATTREXT = 686, /* HITATTREXT */
|
||||
CALLDATAEXT = 687, /* CALLDATAEXT */
|
||||
CALLDATAINEXT = 688, /* CALLDATAINEXT */
|
||||
PATCH = 689, /* PATCH */
|
||||
SAMPLE = 690, /* SAMPLE */
|
||||
NONUNIFORM = 691, /* NONUNIFORM */
|
||||
COHERENT = 692, /* COHERENT */
|
||||
VOLATILE = 693, /* VOLATILE */
|
||||
RESTRICT = 694, /* RESTRICT */
|
||||
READONLY = 695, /* READONLY */
|
||||
WRITEONLY = 696, /* WRITEONLY */
|
||||
DEVICECOHERENT = 697, /* DEVICECOHERENT */
|
||||
QUEUEFAMILYCOHERENT = 698, /* QUEUEFAMILYCOHERENT */
|
||||
WORKGROUPCOHERENT = 699, /* WORKGROUPCOHERENT */
|
||||
SUBGROUPCOHERENT = 700, /* SUBGROUPCOHERENT */
|
||||
NONPRIVATE = 701, /* NONPRIVATE */
|
||||
SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */
|
||||
NOPERSPECTIVE = 703, /* NOPERSPECTIVE */
|
||||
EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */
|
||||
PERVERTEXNV = 705, /* PERVERTEXNV */
|
||||
PERPRIMITIVENV = 706, /* PERPRIMITIVENV */
|
||||
PERVIEWNV = 707, /* PERVIEWNV */
|
||||
PERTASKNV = 708, /* PERTASKNV */
|
||||
PRECISE = 709 /* PRECISE */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
#endif
|
||||
|
@ -527,6 +537,9 @@ union YYSTYPE
|
|||
glslang::TIntermNodePair nodePair;
|
||||
glslang::TIntermTyped* intermTypedNode;
|
||||
glslang::TAttributes* attributes;
|
||||
glslang::TSpirvRequirement* spirvReq;
|
||||
glslang::TSpirvInstruction* spirvInst;
|
||||
glslang::TSpirvTypeParameters* spirvTypeParams;
|
||||
};
|
||||
union {
|
||||
glslang::TPublicType type;
|
||||
|
@ -540,7 +553,7 @@ union YYSTYPE
|
|||
glslang::TArraySizes* typeParameters;
|
||||
} interm;
|
||||
|
||||
#line 544 "MachineIndependent/glslang_tab.cpp.h"
|
||||
#line 557 "MachineIndependent/glslang_tab.cpp.h"
|
||||
|
||||
};
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
|
|
@ -696,6 +696,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||
|
||||
case EOpConstructReference: out.debug << "Construct reference type"; break;
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
|
||||
#endif
|
||||
|
||||
default: out.debug.message(EPrefixError, "Bad unary op");
|
||||
}
|
||||
|
||||
|
@ -1085,6 +1089,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||
|
||||
case EOpTraceNV: out.debug << "traceNV"; break;
|
||||
case EOpTraceRayMotionNV: out.debug << "traceRayMotionNV"; break;
|
||||
case EOpTraceKHR: out.debug << "traceRayKHR"; break;
|
||||
case EOpReportIntersection: out.debug << "reportIntersectionNV"; break;
|
||||
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
|
||||
|
@ -1126,6 +1131,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
|
||||
case EOpDebugPrintf: out.debug << "Debug printf"; break;
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
|
||||
#endif
|
||||
|
||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||
}
|
||||
|
||||
|
@ -1487,6 +1496,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||
if (xfbMode)
|
||||
infoSink.debug << "in xfb mode\n";
|
||||
|
||||
if (getSubgroupUniformControlFlow())
|
||||
infoSink.debug << "subgroup_uniform_control_flow\n";
|
||||
|
||||
switch (language) {
|
||||
case EShLangVertex:
|
||||
break;
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
target = &inputList;
|
||||
else if (base->getQualifier().storage == EvqVaryingOut)
|
||||
target = &outputList;
|
||||
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant())
|
||||
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant() && !base->getQualifier().isShaderRecord())
|
||||
target = &uniformList;
|
||||
// If a global is being visited, then we should also traverse it incase it's evaluation
|
||||
// ends up visiting inputs we want to tag as live
|
||||
|
@ -748,7 +748,7 @@ private:
|
|||
};
|
||||
|
||||
TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate)
|
||||
: intermediate(intermediate)
|
||||
: referenceIntermediate(intermediate)
|
||||
, nextUniformLocation(intermediate.getUniformLocationBase())
|
||||
, nextInputLocation(0)
|
||||
, nextOutputLocation(0)
|
||||
|
@ -760,17 +760,17 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate
|
|||
|
||||
int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
|
||||
return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set))
|
||||
: selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
|
||||
: selectBaseBinding(referenceIntermediate.getShiftBinding(res), referenceIntermediate.getShiftBindingForSet(res, set));
|
||||
}
|
||||
|
||||
const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const {
|
||||
return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding()
|
||||
: intermediate.getResourceSetBinding();
|
||||
: referenceIntermediate.getResourceSetBinding();
|
||||
}
|
||||
|
||||
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
|
||||
bool TDefaultIoResolverBase::doAutoBindingMapping() const { return referenceIntermediate.getAutoMapBindings(); }
|
||||
|
||||
bool TDefaultIoResolverBase::doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
|
||||
bool TDefaultIoResolverBase::doAutoLocationMapping() const { return referenceIntermediate.getAutoMapLocations(); }
|
||||
|
||||
TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) {
|
||||
return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
|
||||
|
@ -827,7 +827,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||
}
|
||||
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
|
||||
type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
|
||||
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
|
||||
return ent.newLocation = -1;
|
||||
}
|
||||
// no locations on blocks of built-in variables
|
||||
|
@ -839,7 +839,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||
return ent.newLocation = -1;
|
||||
}
|
||||
}
|
||||
int location = intermediate.getUniformLocationOverride(name);
|
||||
int location = referenceIntermediate.getUniformLocationOverride(name);
|
||||
if (location != -1) {
|
||||
return ent.newLocation = location;
|
||||
}
|
||||
|
@ -1024,7 +1024,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||
} else {
|
||||
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
|
||||
type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) {
|
||||
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
|
||||
return ent.newLocation = -1;
|
||||
}
|
||||
// no locations on blocks of built-in variables
|
||||
|
@ -1037,7 +1037,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||
}
|
||||
}
|
||||
}
|
||||
int location = intermediate.getUniformLocationOverride(name.c_str());
|
||||
int location = referenceIntermediate.getUniformLocationOverride(name.c_str());
|
||||
if (location != -1) {
|
||||
return ent.newLocation = location;
|
||||
}
|
||||
|
@ -1086,7 +1086,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
|
|||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = ent.symbol->getAccessName();
|
||||
// On OpenGL arrays of opaque types take a separate binding for each element
|
||||
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
TResourceType resource = getResourceType(type);
|
||||
// don't need to handle uniform symbol, it will be handled in resolveUniformLocation
|
||||
if (resource == EResUbo && type.getBasicType() != EbtBlock) {
|
||||
|
@ -1095,7 +1095,7 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
|
|||
// There is no 'set' qualifier in OpenGL shading language, each resource has its own
|
||||
// binding name space, so remap the 'set' to resource type which make each resource
|
||||
// binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
|
||||
int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet;
|
||||
int set = referenceIntermediate.getSpv().openGl != 0 ? resource : ent.newSet;
|
||||
int resourceKey = set;
|
||||
if (resource < EResCount) {
|
||||
if (type.getQualifier().hasBinding()) {
|
||||
|
@ -1223,7 +1223,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
|
|||
const TType& type = ent.symbol->getType();
|
||||
const TString& name = ent.symbol->getAccessName();
|
||||
TResourceType resource = getResourceType(type);
|
||||
int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
|
||||
int set = referenceIntermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
|
||||
int resourceKey = set;
|
||||
|
||||
if (type.getQualifier().hasBinding()) {
|
||||
|
@ -1233,7 +1233,7 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
|
|||
|
||||
if (iter == varSlotMap.end()) {
|
||||
// Reserve the slots for the ubo, ssbo and opaques who has explicit binding
|
||||
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
varSlotMap[name] = binding;
|
||||
reserveSlot(resourceKey, binding, numBindings);
|
||||
} else {
|
||||
|
@ -1288,7 +1288,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
|
|||
const TType& type = ent.symbol->getType();
|
||||
const int set = getLayoutSet(type);
|
||||
// On OpenGL arrays of opaque types take a seperate binding for each element
|
||||
int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
|
||||
TResourceType resource = getResourceType(type);
|
||||
if (resource < EResCount) {
|
||||
if (type.getQualifier().hasBinding()) {
|
||||
|
@ -1633,6 +1633,37 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
|
|||
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
|
||||
});
|
||||
resolver->endResolve(EShLangCount);
|
||||
if (autoPushConstantBlockName.length()) {
|
||||
bool upgraded = false;
|
||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||
if (intermediates[stage] != nullptr) {
|
||||
TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
|
||||
auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
|
||||
if (at == pUniformVarMap[stage]->end())
|
||||
continue;
|
||||
TQualifier& qualifier = at->second.symbol->getQualifier();
|
||||
if (!qualifier.isUniform())
|
||||
continue;
|
||||
TType& t = at->second.symbol->getWritableType();
|
||||
int size, stride;
|
||||
TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
|
||||
qualifier.layoutMatrix == ElmRowMajor);
|
||||
if (size <= int(autoPushConstantMaxSize)) {
|
||||
qualifier.setBlockStorage(EbsPushConstant);
|
||||
qualifier.layoutPacking = autoPushConstantBlockPacking;
|
||||
upgraded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If it's been upgraded to push_constant, then remove it from the uniformVector
|
||||
// so it doesn't get a set/binding assigned to it.
|
||||
if (upgraded) {
|
||||
auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
|
||||
[this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
|
||||
if (at != uniformVector.end())
|
||||
uniformVector.erase(at);
|
||||
}
|
||||
}
|
||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||
if (intermediates[stage] != nullptr) {
|
||||
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
|
||||
|
|
|
@ -165,7 +165,7 @@ public:
|
|||
protected:
|
||||
TDefaultIoResolverBase(TDefaultIoResolverBase&);
|
||||
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
|
||||
const TIntermediate& intermediate;
|
||||
const TIntermediate& referenceIntermediate;
|
||||
int nextUniformLocation;
|
||||
int nextInputLocation;
|
||||
int nextOutputLocation;
|
||||
|
@ -291,7 +291,7 @@ public:
|
|||
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
||||
};
|
||||
|
||||
// I/O mapper for OpenGL
|
||||
// I/O mapper for GLSL
|
||||
class TGlslIoMapper : public TIoMapper {
|
||||
public:
|
||||
TGlslIoMapper() {
|
||||
|
@ -301,6 +301,8 @@ public:
|
|||
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
||||
profile = ENoProfile;
|
||||
version = 0;
|
||||
autoPushConstantMaxSize = 128;
|
||||
autoPushConstantBlockPacking = ElpStd430;
|
||||
}
|
||||
virtual ~TGlslIoMapper() {
|
||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||
|
@ -320,6 +322,13 @@ public:
|
|||
intermediates[stage] = nullptr;
|
||||
}
|
||||
}
|
||||
// If set, the uniform block with the given name will be changed to be backed by
|
||||
// push_constant if it's size is <= maxSize
|
||||
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
|
||||
autoPushConstantBlockName = name;
|
||||
autoPushConstantMaxSize = maxSize;
|
||||
autoPushConstantBlockPacking = packing;
|
||||
}
|
||||
// grow the reflection stage by stage
|
||||
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
||||
bool doMap(TIoMapResolver*, TInfoSink&) override;
|
||||
|
@ -329,6 +338,11 @@ public:
|
|||
bool hadError = false;
|
||||
EProfile profile;
|
||||
int version;
|
||||
|
||||
private:
|
||||
TString autoPushConstantBlockName;
|
||||
unsigned int autoPushConstantMaxSize;
|
||||
TLayoutPacking autoPushConstantBlockPacking;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
|
|
@ -316,6 +316,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||
MERGE_TRUE(useUnknownFormat);
|
||||
MERGE_TRUE(hlslOffsets);
|
||||
MERGE_TRUE(useStorageBuffer);
|
||||
MERGE_TRUE(invariantAll);
|
||||
MERGE_TRUE(hlslIoMapping);
|
||||
|
||||
// TODO: sourceFile
|
||||
|
@ -953,10 +954,10 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||
// current implementation only has one offset.
|
||||
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
|
||||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
|
||||
symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation ||
|
||||
(symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) ||
|
||||
symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent ||
|
||||
symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex ||
|
||||
symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding ||
|
||||
(symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) ||
|
||||
(symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) {
|
||||
error(infoSink, "Layout qualification must match:");
|
||||
writeTypeComparison = true;
|
||||
|
@ -1933,7 +1934,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
|
|||
}
|
||||
|
||||
// rule 9
|
||||
if (type.getBasicType() == EbtStruct) {
|
||||
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
|
||||
const TTypeList& memberList = *type.getStruct();
|
||||
|
||||
size = 0;
|
||||
|
@ -2158,8 +2159,9 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
|
|||
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
|
||||
return type.isArray() &&
|
||||
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
|
||||
(language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
|
||||
(language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut) &&
|
||||
! type.getQualifier().patch) ||
|
||||
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
|
||||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
|
||||
type.getQualifier().pervertexNV) ||
|
||||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
|
||||
|
|
|
@ -291,6 +291,7 @@ public:
|
|||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||
invertY(false),
|
||||
useStorageBuffer(false),
|
||||
invariantAll(false),
|
||||
nanMinMaxClamp(false),
|
||||
depthReplacing(false),
|
||||
uniqueId(0),
|
||||
|
@ -328,7 +329,10 @@ public:
|
|||
textureSamplerTransformMode(EShTexSampTransKeep),
|
||||
needToLegalize(false),
|
||||
binaryDoubleOutput(false),
|
||||
subgroupUniformControlFlow(false),
|
||||
usePhysicalStorageBuffer(false),
|
||||
spirvRequirement(nullptr),
|
||||
spirvExecutionMode(nullptr),
|
||||
uniformLocationBase(0)
|
||||
#endif
|
||||
{
|
||||
|
@ -535,7 +539,7 @@ public:
|
|||
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
|
||||
|
||||
// Tree ops
|
||||
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
|
||||
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
|
||||
|
||||
// Linkage related
|
||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||
|
@ -557,6 +561,8 @@ public:
|
|||
|
||||
void setUseStorageBuffer() { useStorageBuffer = true; }
|
||||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||
void setInvariantAll() { invariantAll = true; }
|
||||
bool isInvariantAll() const { return invariantAll; }
|
||||
void setDepthReplacing() { depthReplacing = true; }
|
||||
bool isDepthReplacing() const { return depthReplacing; }
|
||||
bool setLocalSize(int dim, int size)
|
||||
|
@ -864,6 +870,18 @@ public:
|
|||
|
||||
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
|
||||
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
|
||||
|
||||
void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
|
||||
bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
|
||||
|
||||
// GL_EXT_spirv_intrinsics
|
||||
void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
|
||||
bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
|
||||
const TSpirvRequirement& getSpirvRequirement() const { return *spirvRequirement; }
|
||||
void insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args = nullptr);
|
||||
void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args);
|
||||
bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; }
|
||||
const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; }
|
||||
#endif // GLSLANG_WEB
|
||||
|
||||
void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
|
||||
|
@ -911,6 +929,11 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool IsRequestedExtension(const char* extension) const
|
||||
{
|
||||
return (requestedExtensions.find(extension) != requestedExtensions.end());
|
||||
}
|
||||
|
||||
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
||||
void merge(TInfoSink&, TIntermediate&);
|
||||
void finalCheck(TInfoSink&, bool keepUncalled);
|
||||
|
@ -1048,6 +1071,7 @@ protected:
|
|||
bool recursive;
|
||||
bool invertY;
|
||||
bool useStorageBuffer;
|
||||
bool invariantAll;
|
||||
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
|
||||
bool depthReplacing;
|
||||
int localSize[3];
|
||||
|
@ -1115,8 +1139,12 @@ protected:
|
|||
|
||||
bool needToLegalize;
|
||||
bool binaryDoubleOutput;
|
||||
bool subgroupUniformControlFlow;
|
||||
bool usePhysicalStorageBuffer;
|
||||
|
||||
TSpirvRequirement* spirvRequirement;
|
||||
TSpirvExecutionMode* spirvExecutionMode;
|
||||
|
||||
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||
int uniformLocationBase;
|
||||
TNumericFeatures numericFeatures;
|
||||
|
|
|
@ -166,31 +166,30 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
|||
}
|
||||
} else {
|
||||
// matrix from vector or scalar
|
||||
int count = 0;
|
||||
const int startIndex = index;
|
||||
int nodeComps = node->getType().computeNumComponents();
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
if (i >= instanceSize)
|
||||
return;
|
||||
if (nodeComps == 1) {
|
||||
// If there is a single scalar parameter to a matrix
|
||||
// constructor, it is used to initialize all the
|
||||
// components on the matrix's diagonal, with the
|
||||
// remaining components initialized to 0.0.
|
||||
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
|
||||
leftUnionArray[i] = rightUnionArray[count];
|
||||
else
|
||||
leftUnionArray[i].setDConst(0.0);
|
||||
} else {
|
||||
if (nodeComps == 1) {
|
||||
for (int c = 0; c < matrixCols; ++c) {
|
||||
for (int r = 0; r < matrixRows; ++r) {
|
||||
if (r == c)
|
||||
leftUnionArray[index] = rightUnionArray[0];
|
||||
else
|
||||
leftUnionArray[index].setDConst(0.0);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int count = 0;
|
||||
for (int i = index; i < endIndex; i++) {
|
||||
if (i >= instanceSize)
|
||||
return;
|
||||
|
||||
// construct the matrix in column-major order, from
|
||||
// the components provided, in order
|
||||
leftUnionArray[i] = rightUnionArray[count];
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (nodeComps > 1)
|
||||
index++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1191,9 +1191,11 @@ int TPpContext::tokenize(TPpToken& ppToken)
|
|||
// HLSL allows string literals.
|
||||
// GLSL allows string literals with GL_EXT_debug_printf.
|
||||
if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
|
||||
parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal");
|
||||
if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf))
|
||||
continue;
|
||||
const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics };
|
||||
parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal");
|
||||
if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) &&
|
||||
!parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case '\'':
|
||||
|
|
|
@ -56,4 +56,4 @@ if(ENABLE_GLSLANG_INSTALL)
|
|||
install(TARGETS OSDependent EXPORT OSDependentTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
||||
endif()
|
||||
|
|
|
@ -55,7 +55,7 @@ if(ENABLE_GLSLANG_JS)
|
|||
|
||||
if(ENABLE_EMSCRIPTEN_SINGLE_FILE)
|
||||
target_link_libraries(glslang.js "-s SINGLE_FILE=1")
|
||||
endif(ENABLE_EMSCRIPTEN_SINGLE_FILE)
|
||||
endif()
|
||||
|
||||
if(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE)
|
||||
target_link_libraries(glslang.js "-s ENVIRONMENT=node -s BINARYEN_ASYNC_COMPILATION=0")
|
||||
|
@ -67,5 +67,5 @@ if(ENABLE_GLSLANG_JS)
|
|||
add_custom_command(TARGET glslang.js POST_BUILD
|
||||
COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/glslang.after.js >> ${CMAKE_CURRENT_BINARY_DIR}/glslang.js)
|
||||
endif()
|
||||
endif(EMSCRIPTEN)
|
||||
endif(ENABLE_GLSLANG_JS)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -45,10 +45,10 @@ endif()
|
|||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES})
|
||||
endif(WIN32)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GLSLANG_INSTALL)
|
||||
install(TARGETS OSDependent EXPORT OSDependentTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(EXPORT OSDependentTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
||||
endif()
|
||||
|
|
|
@ -722,7 +722,7 @@ class TObjectReflection {
|
|||
public:
|
||||
GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
|
||||
|
||||
GLSLANG_EXPORT const TType* getType() const { return type; }
|
||||
const TType* getType() const { return type; }
|
||||
GLSLANG_EXPORT int getBinding() const;
|
||||
GLSLANG_EXPORT void dump() const;
|
||||
static TObjectReflection badReflection() { return TObjectReflection(); }
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright (C) 2020 Google, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# parse_version() reads and parses the version string from FILE, assigning the
|
||||
# version string to ${PROJECT}_VERSION and the parsed version to
|
||||
# ${PROJECT}_VERSION_MAJOR, ${PROJECT}_VERSION_MINOR, ${PROJECT}_VERSION_PATCH,
|
||||
# and the optional ${PROJECT}_VERSION_FLAVOR.
|
||||
#
|
||||
# The version string take one of the forms:
|
||||
# <major>.<minor>.<patch>
|
||||
# <major>.<minor>.<patch>-<flavor>
|
||||
function(parse_version FILE PROJECT)
|
||||
configure_file(${FILE} "${CMAKE_CURRENT_BINARY_DIR}/CHANGES.md") # Required to re-run cmake on version change
|
||||
file(READ ${FILE} CHANGES)
|
||||
if(${CHANGES} MATCHES "#+ *([0-9]+)\\.([0-9]+)\\.([0-9]+)(-[a-zA-Z0-9]+)?")
|
||||
set(FLAVOR "")
|
||||
if(NOT "${CMAKE_MATCH_4}" STREQUAL "")
|
||||
string(SUBSTRING ${CMAKE_MATCH_4} 1 -1 FLAVOR)
|
||||
endif()
|
||||
set("${PROJECT}_VERSION_MAJOR" ${CMAKE_MATCH_1} PARENT_SCOPE)
|
||||
set("${PROJECT}_VERSION_MINOR" ${CMAKE_MATCH_2} PARENT_SCOPE)
|
||||
set("${PROJECT}_VERSION_PATCH" ${CMAKE_MATCH_3} PARENT_SCOPE)
|
||||
set("${PROJECT}_VERSION_FLAVOR" ${FLAVOR} PARENT_SCOPE)
|
||||
set("${PROJECT}_VERSION"
|
||||
"${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}${CMAKE_MATCH_4}"
|
||||
PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to parse version from '${FILE}'")
|
||||
endif()
|
||||
endfunction()
|
Loading…
Reference in New Issue